Hi all,
Been having some fun and games trying to generate uv’s in the vertex shader (of a surface shader) for use with ‘Texture Fetch’, as I couldn’t find any relevant examples online or in the builtin shaders.
I’ve finally got it working including the textures scale and offset values, but can only get it to work with UNITY_MATRIX_TEXTURE0. Try as I might I cannot get it to give me the TextureMatrix of the second texture in my material!
This is the simplest way to get TEXTURE0 is using the built in method TRANSFORM_UV(id);
half2 newTC = TRANSFORM_UV(0);
float nativeHeight = tex2Dlod( _HeightMap, half4 (newTC.xy, 0, 0)).r;
This works, but if I replace TRANSFORM_UV(0) with TRANSFORM_UV(1) it doesn’t, looks like the result back is (0,0)
As an aside, as far as I can tell this will only work with first uv co-ordinate set, as v.texcoord is hardcoded, where as you’d need v.texcoord1 for a second set of uv’s. Though thats not an issue in this case and the long version of the code below should fix that.
If I do it the long way
half4 newTC = half4(v.texcoord.x, v.texcoord.y, 0, 1);
newTC = mul( UNITY_MATRIX_TEXTURE1, newTC);
float nativeHeight = tex2Dlod( _HeightMap, half4 (newTC.xy, 0, 0)).r;
Again it works for UNITY_MATRIX_TEXTURE0, but not for UNITY_MATRIX_TEXTURE1, my vertices in the mesh remain flat and not offset via the heightmap as though the returned uv = (0,0) everytime.
I’ve tried adding a second set of uv’s (though don’t see why they should be needed) and adding uv_HeightMap to my input struct. I’ve double checked that both my textures have different scales and offsets and have even added the heightmap to my base map in the pixel shader to see that there they have different texture matrices and that the code works. e.g
half4 c = tex2D (_MainTex, IN.uv_MainTex);
half4 h = tex2D (_HeightMap, IN.uv_HeightMap);
So I guess I must be missing something?
Here is the full vertex shader, don’t forget this is in a surface shader, so trying to use _HeightMap_ST wont work as it gets redefined by unity when it compiles the shader.
void VertexFetchFunct (inout appdata_full v)
{
// Get UV - Simple version use _MainTex uv, no scale or offset matrix applied
// float nativeHeight = tex2Dlod( _HeightMap, half4(v.texcoord.xy, 0, 0)).r ;
// Get UV - TextureMatrix version - Caution: only works with v.texcoord not v.texcoord1
half2 newTC = TRANSFORM_UV(1);
float nativeHeight = tex2Dlod( _HeightMap, half4 (newTC.xy, 0, 0)).r;
// half4 newTC = half4(v.texcoord.x, v.texcoord.y, 0, 1);
// newTC = mul( UNITY_MATRIX_TEXTURE1, newTC);
// float nativeHeight = tex2Dlod( _HeightMap, half4 (newTC.xy, 0, 0)).r;
// Original vertex.y is either 1 or 0 to denote front or back position
v.vertex.y = v.vertex.y*(nativeHeight*_HeightMod);
}
Neither the uncomment nor the commented version of the code will give me the first set of uv’s * TextureMatrix for second texture in my material.
Edit:
Something I thought a bit strange when debugging this is that I found
v2f_img vert_img( appdata_img v )
which is meant to be used for image effect shaders according to the comment in UnityCG.cginc only applys textureMatrix scaling to uv’s and not the offset. Since I copied the
MultiplyUV( UNITY_MATRIX_TEXTURE0, v.texcoord );
originally for my tests it took me ages to work out why offset was not being included.
Not sure if that has any relevance to image effects? Would you expect to be able to translate a texture?
if so is this a bug in UnityCG.cginc?