ares777
ares777

Reputation: 3628

Moving an image using Metal shader

I am trying to write a simple Metal shader to use in Swift, which takes a picture and move it from left to right. Let's say I want the picture x starts in screenwidth - image.size.width and moves x until image.x = screenwidth.x. I used Metalpetal and my code distorts image.

         fragment float4 SimplePanFragmentRight(VertexOut vertexIn [[ stage_in ]],
                                    texture2d<float, access::sample> fromTexture [[ texture(0) ]],
                                    texture2d<float, access::sample> toTexture [[ texture(1) ]],
                                    constant float & scale [[ buffer(0) ]],
                                    constant float & rotations [[ buffer(1) ]],
                                    constant float2 & center [[ buffer(2) ]],
                                    constant float4 & backColor [[ buffer(3) ]],
                                    constant float & ratio [[ buffer(4) ]],
                                    constant float & progress [[ buffer(5) ]],
                                    sampler textureSampler [[ sampler(0) ]])
     {
     float2 uv = vertexIn.textureCoordinate;
     uv.y = 1.0 - uv.y;
     float _fromR = float(fromTexture.get_width())/float(fromTexture.get_height());
     float _toR = float(toTexture.get_width())/float(toTexture.get_height());
     float t = 1.0;
     float pro = progress / 0.25;
     // hence bad code
     uv = adjustPos( uv, pro);
    // ****
  return mix(
         getFromColor(uv, fromTexture, ratio, _fromR),
         getToColor(uv, toTexture, ratio, _toR),
         t);
   }

and my "simple function" to manipulate x position is

     float2 adjustPos(
             float2 uv, float amount) {
      uv.x = uv.x * amount;
     return uv;
  }

How to move linear x position based on a progress ratio without any image distortion ?

Upvotes: 0

Views: 547

Answers (1)

Chip Jarred
Chip Jarred

Reputation: 2805

You want to do vertex translation in your vertex shader not in your fragment shader. Basically the vertex shader is where transformations of your model's (image's) vertices happen, which can be either because you moved your "camera" (ie. change of perspective) or because the thing moves in the environment. On entry the grid coordinates will be in your picture's coordinates, or in your virtual world coordinates, depending on exactly how you call the shader. You translate that to coordinates relative to your view frustum (ie. relative to your camera's position, direction, and orientation). For 2-D rendering, you can usually ignore the z part of the frustum coordinates (just set it to 0, so it's exactly on the view plane), which makes it the same as screen coordinates.

Your fragment shader is where you'd do effects on the image itself, for example blurring, or color mapping, texture mapping, etc...

Upvotes: 1

Related Questions