Quick answer: Keep mesh vertex coordinates in sprite-local space (0..1 normalized). For screen-space effects, recompute vertices per tick based on camera offset.

A water sprite uses Mesh distortion to add a wavy surface. Looks great when the camera is centered; when you pan, the distortion shifts incorrectly. The vertex math used screen position rather than sprite UV.

Sprite-Local Coordinates

Mesh vertices are normalized [0, 1] within the sprite’s bounding box. A vertex at (0.5, 0.5) is the sprite’s center regardless of where the sprite is on screen. Use these for stable distortions:

Every tick:
    For each mesh vertex (i, j):
        var u = i / mesh_width
        var v = j / mesh_height
        var wave = sin(u * 6.28 + time) * 0.05
        Sprite Mesh Set vertex at (i, j) to (u + wave, v)

Wave depends on u (sprite-local) and time, never on camera position. Distortion stays consistent regardless of pan.

Screen-Space Effects

For effects that should look like camera-relative ripples (e.g., heat haze that stays put on screen):

Every tick:
    var cam_x = ViewportLeft("Gameplay")
    var cam_y = ViewportTop("Gameplay")
    For each vertex:
        var world_x = sprite.X + u * sprite.Width
        var screen_x = world_x - cam_x
        var wave = sin(screen_x * 0.05 + time) * 0.03
        Set vertex offset Y to wave

Now wave depends on screen position; updates correctly as camera pans because you recompute each tick.

Performance Note

Per-tick vertex updates cost CPU. For 100 distorted sprites with 64 vertices each = 6400 vertex updates/tick. If perf suffers, use an Effect (shader) on the sprite instead — GPU handles per-pixel distortion with no CPU cost.

Verifying

Pan the camera around the water sprite. Distortion should remain stable on the sprite (sprite-local) or move with the screen (screen-space) depending on your intent. Match the math to the desired behavior.

“Sprite-local for sprite-bound distortions; screen-space for screen-bound. Compute vertices in the right coordinate space.”

For heavy mesh effects, profile early — shaders are often the better choice for 60 Hz updates on many sprites.