Surface Shader: World space unwrapped uv with fixed position?

Hi everyone,

right now, I am having a working surface shader that has the UVs unwrapped in world space. As a result, my texture has the same scale (that can be adjusted by _TexScale_1), but I am trying to make the texture “move with the object” and only have the global scale as a result. I don´t know much about shaders, but I could make it this far. Anyone smart who can help out?

        float3 worldNormal = WorldNormalVector(IN, o.Normal);

        float2 topUV_1 = float2(IN.worldPos.x,IN.worldPos.z) / float2(-1.0 * abs(_TexScale_1), -1.0 * abs(_TexScale_1));
        float2 frontUV_1 = float2(IN.worldPos.x, IN.worldPos.y) / float2(-1.0 * abs(_TexScale_1), -1.0 * abs(_TexScale_1));
        float2 sideUV_1 = float2(IN.worldPos.z, IN.worldPos.y) / float2(-1.0 * abs(_TexScale_1), -1.0 * abs(_TexScale_1));

        float4 topTex_1 = tex2D(_MainTex, topUV_1 );
        float4 frontTex_1 = tex2D(_MainTex, frontUV_1 );
        float4 sideTex_1 = tex2D(_MainTex, sideUV_1);

        float3 Tex_1 = lerp(topTex_1, frontTex_1, abs(worldNormal.z));
        Tex_1 = lerp(Tex_1, sideTex_1, abs(worldNormal.x));

        o.Albedo = Tex_1 * _Color;

Thanks!

Hello @marcell123455 ! If I understand correctly you want the UV’s to tile forever, but be pinned to the object rather than the world?

In which case, you’ll need to pass in the object vertex position ( rather than the transformed worldPos ).
I don’t know what the rest of your shader looks like but in your vertex program you need to pass v.vertex into the out Input struct.

something like this ( based on your code );


struct Input {
            float3 objPos;
        };
 
        void vert (inout appdata_full v, out Input o) {
            UNITY_INITIALIZE_OUTPUT(Input,o);
            o.objPos = v.vertex; // this is the position of the vertex in its un transformed position in space.
        }
 
        void surf (Input IN, inout SurfaceOutput o) {
                     float3 worldNormal = WorldNormalVector(IN, o.Normal);
         float2 topUV_1 = float2(IN.objPos.x,IN.objPos.z) / float2(-1.0 * abs(_TexScale_1), -1.0 * abs(_TexScale_1));
         float2 frontUV_1 = float2(IN.objPos.x, IN.objPos.y) / float2(-1.0 * abs(_TexScale_1), -1.0 * abs(_TexScale_1));
         float2 sideUV_1 = float2(IN.objPos.z, IN.objPos.y) / float2(-1.0 * abs(_TexScale_1), -1.0 * abs(_TexScale_1));
         float4 topTex_1 = tex2D(_MainTex, topUV_1 );
         float4 frontTex_1 = tex2D(_MainTex, frontUV_1 );
         float4 sideTex_1 = tex2D(_MainTex, sideUV_1);
         float3 Tex_1 = lerp(topTex_1, frontTex_1, abs(worldNormal.z));
         Tex_1 = lerp(Tex_1, sideTex_1, abs(worldNormal.x));
         o.Albedo = Tex_1 * _Color;
            o.Alpha = 1;
        }

I also had to add #pragma vertex vert . now it works. THANKS :slight_smile: