I’m struggling a bit with my vertex shader. The following code is giving me the colors of my lookup texture (_AnimationTex) and I distort the vertices of my main texture with it.
float4 distortion = tex2Dlod(_AnimationTex, float4(IN.texcoord0.xy,0,0)); // texcoord0 is for the main texture, not the _AnimationTex
// distortion.x = textures red channel
// distortion.y = textures green channel
// distortion.z = textures blue channel
// distortion.w = textures alpha channel
distortedPosition.x += distortion.r * _xDistortionFactor * distortionFactor; // red color used for x-axis
distortedPosition.y += distortion.g * _yDistortionFactor * distortionFactor; // green used for y-axis
distortedPosition.z += distortion.b * _yDistortionFactor * distortionFactor; // blue used for z-axis
IN.vertex = distortedPosition;
OUT.pos = UnityObjectToClipPos(IN.vertex);
That seems to work, but now I wonder if my lookup texture has to be the same size as my main texture. I attached both textures, which differ in size and format. When I’m running my shader, the distortion is not at the positions I would like them to have, but bigger (like the lookup texture is streched up). Is it possible to have different texture sized or do both textures have to be the same size?
The textures does not have to be the same size, but if both textures are using the same UVs they do need to match positionally. UVs are a normalized positions within the texture, their pixel dimensions are irrelevant.
To explain that differently, UVs usually have a range of 0.0 to 1.0 where 0.0, 0.0 is the bottom left of the image, and 1.0, 1.0 is the top right. 0.5, 0.5 is the center of the image, regardless of the texture resolution, or aspect ratio.
Since your lookup texture appears to be cropped down from the original image you either need to un-crop it, or you need to adjust the UVs it uses to offset & scale it to line up with the area you want it to overlap.
Ok, thank you for the explanation. Is there an easy way to achieve that uncropping or to calculate this offset and scale? And if not, how would I start with the calculation? I would know how to do it in C# for a transform, but I’m not that familiar with shader code.
By default any texture you add to a shader properties list gets a scale offset parameter that shows up on the material inspector. The values you set there gets passed to the shader via a _*TextureName*_ST variable. Default shaders usually have a _MainTex_ST already pre-defined. Within the shader there’s usually also a TRANSFORM_TEX(v.uv, _MainTex) or something like that, and that’s a shader macro to apply that _ST variable.
Here’s what that macro does (copy / pasted from UnityCG.cginc):
What you’ll want to do is use something like:
tex2Dlod(_AnimationTex, float4(TRANSFORM_TEX(IN.texcoord.xy, _AnimationTex),0,0));
Then modify the scale and offset settings for the animation tex to position it where you want. If you want to be precise about it rather than just fiddling with the numbers then you’ll need to do the math for it.
Scale = _MainTex Resolution / _AnimationTex Resolution
Offset = Pixel offset from bottom left / _AnimationTex Resolution * Scale
In the case of your textures that would be
scale = (4096, 1489) / (3074, 432) = (1.3325, 3.4468)
offset = (694, 511) / (3074, 432) * (1.3325, 3.4468) = (0.124259, 0.0914931)
Put those numbers into the scale and offset values and it should line up (assuming I didn’t f up someplace)