Hi all,
I’ve got a shader which generates texture coordinates based on the position of the vertex in the world, this was fairly simple:
Shader "XY"
{
Properties
{
_MainTex ("Base (RGB)", 2D) = "white" {}
_Color ("Tint", Color) = (1,1,1,1)
}
SubShader
{
Tags { "RenderType"="Opaque" }
CGPROGRAM
#pragma surface surf Lambert
sampler2D _MainTex;
float4 _MainTex_ST;
fixed4 _Color;
struct Input
{
float3 worldPos;
};
void surf( Input IN, inout SurfaceOutput o )
{
fixed4 c = tex2D( _MainTex, TRANSFORM_TEX( IN.worldPos.xy, _MainTex ) ) * _Color;
o.Albedo = c.rgb;
o.Alpha = c.a;
}
ENDCG
}
Fallback "Diffuse"
}
But I want to be able to freeze the texture coordinates at certain times, I figured that worldPos is equal to:
worldPos = mul( _Object2World, v.vertex );
So this could be achieved by passing the Renderer’s localToWorldMatrix to the shader:
renderer.sharedMaterial.SetMatrix( "_CustomMatrix", renderer.localToWorldMatrix );
My shader looks like this:
Shader "XY Fixed"
{
Properties
{
_MainTex ("Base (RGB)", 2D) = "white" {}
_Color ("Tint", Color) = (1,1,1,1)
}
SubShader
{
Tags { "RenderType"="Opaque" }
CGPROGRAM
#pragma surface surf Lambert vertex:vert
sampler2D _MainTex;
float4 _MainTex_ST;
fixed4 _Color;
float4x4 _CustomMatrix;
struct Input
{
float3 altWorldPos;
};
void vert( inout appdata_full v, out Input o )
{
o.altWorldPos = mul( _CustomMatrix, v.vertex ).xyz;
}
void surf( Input IN, inout SurfaceOutput o )
{
fixed4 c = tex2D( _MainTex, TRANSFORM_TEX( IN.altWorldPos.xy, _MainTex ) ) * _Color;
o.Albedo = c.rgb;
o.Alpha = c.a;
}
ENDCG
}
Fallback "Diffuse"
}
For anything with non-uniform scale, the texture appears stretched. I don’t think the shader is the problem, as if I multiply the vertex by _Object2World then it looks just the same as when I use the automatically generated worldPos. So it looks like renderer.localToWorldMatrix is incorrect instead, what do I need to do to make it scale properly?
Thanks
J