How to move texture UV offset

I need to create the illusion of movement of a spaceship by moving the texture offset of a starfield background image. The camera and starfield image keep track of the spaceship as it moves and I am using a APaperSpriteActor to display the background image, however I am unable to figure out how I change the background texture UV offset at runtime (there is a UPaperSprite::GetSourceUV() method, but no equivalent Set method).

I’m sure I could get this working by using Material, but then I am unsure how to present the material as a flat image (perhaps using a plane?).

Can anyone provide some guidance on this please?

I haven’t messed around with Sprites yet, but what you’re trying to do can be easily accomplished with a plane and a Material, as you said yourself.

The material setup (using Customized UVs to move coordinates in an optimized way):

Customized UVs change the same UVs Texture Samples use, but once for each vertex instead of each pixel. As Texture Samples use the coordinate index 0 by default, customizing UV0 already alters the default textures coordinate.

Changing the coordinates Scalar Parameters in Blueprint:

Result:

104462-animation.gif

2 Likes

Personally I would use something called Material Parameter Collection to change these values. This is much cheaper than what has been proposed and is more flexible.

Just create a material paramter collection in your editor and use material parameter nodes in your material. Then, inside some blueprint you simply update the values in a tick event and you are good to go. I am not at a PC until monday so I cant give you a screenshot. Sorry for that.

Hey! Cheaper is always good! =D Why are MPCs cheaper?

It is cheaper because you dont have to create a new dynamic material instance, you simply send in a uniform.

1 Like

Thanks to RVillani and NoobsDeSroobs, this is now working ([Animated GIF; 47.2MB][1]).

I basically used the set-up suggested by RVillani, exposing UOffset and VOffset as parameters and then using a Material Instance for the starfield material.

The base C++ CameraActor class does the movement:

FVector Position = GetActorLocation();
FVector Diff = Position - LastPosition;
LastPosition = Position;

if (StarfieldMID) {
    float UOffset, VOffset;
    if (StarfieldMID->GetScalarParameterValue(TEXT("UOffset"), UOffset) &&
        StarfieldMID->GetScalarParameterValue(TEXT("VOffset"), VOffset)) {
        UOffset += Diff.X * UVOffsetScale;
        VOffset -= Diff.Z * UVOffsetScale;

        StarfieldMID->SetScalarParameterValue(TEXT("UOffset"), UOffset);
        StarfieldMID->SetScalarParameterValue(TEXT("VOffset"), VOffset);
    } else {
        UE_LOG(LogGame, Error, TEXT("[%s] Failed to get U/V offset parameter values"), *GetName());
    }
}

and the blueprint-subclass creates the Material Instance Dynamic in the BeginPlay event and passes it to the base class:

I don’t think using a Material Parameter Collection was at all straight forward and I didn’t see what advantage it gave me over a material instance as I will be adding a total of 3 textures to the starfield to give a parallax effect and MPCs seem to be global, unless I have misunderstood their use? Thanks anyway for the suggestion.

MPCs are global, indeed, and if you’d like to synchronize the effect across multiple materials, it would be really useful.

Nice catch on creating the Dynamic Material Instance on BeginPlay. I always do that, but I messed up when making the example for you XD Glad you saw that!

And thanks for sharing your solution! =D

Sorry about waking up an old post but I was looking for something similar for some hours now, and I found on another post something which could be useful in that case and without using MPC, dynamic material and blueprints, only a node in the Material editor.

So, i’m posting it here, just in case someone was in the same case as me and arrive on this post while asking google “offset UV UE4” or “moving dynamically UV in UE4” etc…

And here is my saver : The node “Panner”.

You have to put the pin out of the “TexCoords” in the “Panner” and then “TextureSample”. Easy and less cost than dynamic material apparently ! =)
It also exists another node named “Rotator” to rotate these UVs in real-time.

=) Hope it helps another nooby like me ! =)

1 Like