SHADER HELP - Shader 2nd Texture Offset and Tilliing not Working

Hi All.

I am learning some basic of shaders. Trying to create one for my water. What I got is a Texture with 2 Displacement Maps.

The First one works as expected but adding the Second Displacement Texture, the second texture it just doesn't offset or tile at all.
Can someone please have a look at my shader for me and maybe tell me where I am going wrong.

Regards

// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

Shader "Setti/Water"
{
   Properties
   {
      _MainTex ("MainTex", 2D) = "white" {}
      _DisplTex ("DisplTex", 2D) = "white" {}
      _DisplScale("DisplScale", Range(0, 1)) = 0.25
      
       _DisplTex1 ("DisplTex1", 2D) = "white" {}
      _DisplScale1("DisplScale1", Range(0, 1)) = 0.25

   }
   SubShader
   {
        Tags { "Queue" = "Transparent" }
        Blend SrcAlpha OneMinusSrcAlpha
        ZWrite Off
 
      Pass
      {    
         CGPROGRAM
 
         #pragma vertex vert  
         #pragma fragment frag
 
         uniform sampler2D _MainTex; 
         uniform float4 _MainTex_ST;            
            
         uniform sampler2D _DisplTex;   
         uniform float4 _DisplTex_ST; 
         uniform float _DisplScale;
         
         uniform sampler2D _DisplTex1;   
         uniform float4 _DisplTex_ST1;
         uniform float _DisplScale1;            
          
                   
 
         struct vertexInput
         {
            float4 vertex : POSITION;
            float4 texcoord : TEXCOORD0;
         };
         struct vertexOutput
         {
            float4 pos : SV_POSITION;
            float4 tex : TEXCOORD0;
         };
 
         vertexOutput vert(vertexInput input)
         {
            vertexOutput output;
 
            output.tex = input.texcoord;
            output.pos = UnityObjectToClipPos(input.vertex);
            return output;
         }
 
         float4 frag(vertexOutput input) : COLOR
         {
           float dipl = (tex2D(_DisplTex, input.tex.xy *_DisplTex_ST.xy + _DisplTex_ST.zw).a-0.5)*2*_DisplScale;
            
            fixed4 col = tex2D(_MainTex, _MainTex_ST.xy * input.tex.xy + _MainTex_ST.zw + float2(dipl.x, 0));
            
            float dipl2 = (tex2D(_DisplTex1, input.tex.xy *_DisplTex_ST1.xy + _DisplTex_ST1.zw).a-0.5)*2*_DisplScale1;
            
            fixed4 col1 = tex2D(_MainTex, _MainTex_ST.xy * input.tex.xy + _MainTex_ST.zw + float2(dipl2.x, 0));
            return (col+col1)/2;
        // return col1;
         }
 
         ENDCG
      }
   }
}

Comments

  • Hey @dark_seth

    I think you need to change "_DisplTex_ST1" to "_DisplTex1_ST". Let me know if that helps?
    Thanked by 2dark_seth Elyaradine
  • Hey @dark_seth

    I think you need to change "_DisplTex_ST1" to "_DisplTex1_ST". Let me know if that helps?
    Your A star!!!!! Thank you.

    Now I just need both offset x scroll at different speeds.

    Should this be avail in the shader or via c# script. Hoping directly in shader
  • When you're working out your UVs, use the _Time.y variable to have it offset based on time. (There are other multiples of time that you can use.)

    e.g.
    float dipl2 = (tex2D(_DisplTex1, input.tex.xy *_DisplTex1_ST.xy + _DisplTex1_ST.zw * _Time.y).a-0.5)*2*_DisplScale1;


    Not that important yet maybe, but in general, it'd be better to move your UV calculations into your vertex shader. The vertex shader is run for each vertex, whereas the fragment shader is run for each pixel. In general, objects take up many more pixels on screen than the number of vertices they have, so you typically try to move as much as you can into the vertex shader.

    e.g.
    struct vertexInput
    {
       float4 vertex : POSITION;
       float4 texcoord : TEXCOORD0;
    };
    
    struct vertexOutput
    {
       float4 pos : SV_POSITION;
       float2 disp0_uv : TEXCOORD0;
       float2 disp1_uv : TEXCOORD1;
    };
    
    vertexOutput vert(vertexInput input)
    {
       vertexOutput output;
    
       output.pos = UnityObjectToClipPos(input.vertex);
       
       output.disp0_uv = input.texcoord.xy *_DisplTex_ST.xy + _DisplTex_ST.zw * _Time.y;
       output.disp1_uv = input.texcoord.xy *_DisplTex1_ST.xy + _DisplTex1_ST.zw * _Time.y;
       
       return output;
    }
    
    float4 frag(vertexOutput input) : COLOR
    {
       float dipl = (tex2D(_DisplTex, input.disp0_uv).a-0.5)*2*_DisplScale;   
       float dipl2 = (tex2D(_DisplTex1, input.disp1_uv).a-0.5)*2*_DisplScale1;
       
       // etc.
    }
  • dark_seth said:
    Hey @dark_seth

    I think you need to change "_DisplTex_ST1" to "_DisplTex1_ST". Let me know if that helps?
    Your A star!!!!! Thank you.

    Now I just need both offset x scroll at different speeds.

    Should this be avail in the shader or via c# script. Hoping directly in shader
    Glad I could help!

    Also, thanks @Elyaradine for the tip about doing calculations in the vert shader, makes a lot of sense. Hadn't thought about that :)
    Thanked by 2dark_seth Elyaradine
  • When you're working out your UVs, use the _Time.y variable to have it offset based on time. (There are other multiples of time that you can use.)

    e.g.
    float dipl2 = (tex2D(_DisplTex1, input.tex.xy *_DisplTex1_ST.xy + _DisplTex1_ST.zw * _Time.y).a-0.5)*2*_DisplScale1;


    Not that important yet maybe, but in general, it'd be better to move your UV calculations into your vertex shader. The vertex shader is run for each vertex, whereas the fragment shader is run for each pixel. In general, objects take up many more pixels on screen than the number of vertices they have, so you typically try to move as much as you can into the vertex shader.

    e.g.
    struct vertexInput
    {
       float4 vertex : POSITION;
       float4 texcoord : TEXCOORD0;
    };
    
    struct vertexOutput
    {
       float4 pos : SV_POSITION;
       float2 disp0_uv : TEXCOORD0;
       float2 disp1_uv : TEXCOORD1;
    };
    
    vertexOutput vert(vertexInput input)
    {
       vertexOutput output;
    
       output.pos = UnityObjectToClipPos(input.vertex);
       
       output.disp0_uv = input.texcoord.xy *_DisplTex_ST.xy + _DisplTex_ST.zw * _Time.y;
       output.disp1_uv = input.texcoord.xy *_DisplTex1_ST.xy + _DisplTex1_ST.zw * _Time.y;
       
       return output;
    }
    
    float4 frag(vertexOutput input) : COLOR
    {
       float dipl = (tex2D(_DisplTex, input.disp0_uv).a-0.5)*2*_DisplScale;   
       float dipl2 = (tex2D(_DisplTex1, input.disp1_uv).a-0.5)*2*_DisplScale1;
       
       // etc.
    }


    Busy looking at it. But I think I broke it....

    // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
    
    Shader "Setti/Water1"
    {
       Properties
       {
          _MainTex ("MainTex", 2D) = "white" {}
          _DisplTex ("DisplTex", 2D) = "white" {}
          _DisplScale("DisplScale", Range(0, 1)) = 0.25
          
           _DisplTex1 ("DisplTex1", 2D) = "white" {}
          _DisplScale1("DisplScale1", Range(0, 1)) = 0.25
    
       }
       SubShader
       {
            Tags { "Queue" = "Transparent" }
            Blend SrcAlpha OneMinusSrcAlpha
            ZWrite Off
     
          Pass
          {    
             CGPROGRAM
     
             #pragma vertex vert  
             #pragma fragment frag
     
             uniform sampler2D _MainTex; 
             uniform float4 _MainTex_ST;            
                
             uniform sampler2D _DisplTex;   
             uniform float4 _DisplTex_ST; 
             uniform float _DisplScale;
             
             uniform sampler2D _DisplTex1;   
             uniform float4 _DisplTex1_ST;
             uniform float _DisplScale1;            
              
                       
     
             struct vertexInput
             {
                float4 vertex : POSITION;
                float4 texcoord : TEXCOORD0;
             };
             struct vertexOutput
             {
                float4 pos : SV_POSITION;
                   float2 disp0_uv : TEXCOORD0;
                    float2 disp1_uv : TEXCOORD1;
             };
     
                vertexOutput vert(vertexInput input)
                {
                   vertexOutput output;
    
                   output.pos = UnityObjectToClipPos(input.vertex);
                   
                   output.disp0_uv = input.texcoord.xy *_DisplTex_ST.xy + _DisplTex_ST.zw ;//* _Time.y;
                   output.disp1_uv = input.texcoord.xy *_DisplTex1_ST.xy + _DisplTex1_ST.zw;//* _Time.y;
                   
                   return output;
                }
     
             float4 frag(vertexOutput input) : COLOR
             {
             
             
                float dipl = (tex2D(_DisplTex, input.disp0_uv).a-0.5)*2*_DisplScale;   
                float dipl2 = (tex2D(_DisplTex1, input.disp1_uv).a-0.5)*2*_DisplScale1;
                
                fixed4 col = tex2D(_MainTex, _MainTex_ST.xy * input.disp0_uv + _MainTex_ST.zw + float2(dipl.x, 0));
                
                fixed4 col1 = tex2D(_MainTex, _MainTex_ST.xy * input.disp1_uv + _MainTex_ST.zw + float2(dipl2.x, 0));
                return (col+col1)/2;
            // return col1;
             }
     
             ENDCG
          }
       }
    }


  • You'll have to better describe what your expected result is, but part of the problem is likely that you're using the same UV coordinates from your displacement texture lookup as you are with your colour lookup. Usually you'd want a separate TEXCOORD for each set of UVs that you're using to lookup a texture, unless you're sure that two textures would share the same data. (e.g. Textures for diffuse, normal and roughness are going to use the same coordinates 99.9% of the time, so maybe it's fine to assume that those would be shared.)

    Shader "Setti/Water1"
    {
       Properties
       {
          _MainTex ("MainTex", 2D) = "white" {}
          _DisplTex ("DisplTex", 2D) = "white" {}
          _DisplScale("DisplScale", Range(0, 1)) = 0.25      
          _DisplTex1 ("DisplTex1", 2D) = "white" {}
          _DisplScale1("DisplScale1", Range(0, 1)) = 0.25
    
       }
       SubShader
       {
            Tags 
            { 
                "Queue" = "Transparent" 
            }
            Blend SrcAlpha OneMinusSrcAlpha
            ZWrite Off
     
            Pass
            {    
                CGPROGRAM
    
                #pragma vertex vert  
                #pragma fragment frag
    
                uniform sampler2D _MainTex; 
                uniform float4 _MainTex_ST;            
    
                uniform sampler2D _DisplTex;   
                uniform float4 _DisplTex_ST; 
                uniform float _DisplScale;
    
                uniform sampler2D _DisplTex1;   
                uniform float4 _DisplTex1_ST;
                uniform float _DisplScale1;            
    
                   
    
                struct vertexInput
                {
                    float4 vertex : POSITION;
                    float4 texcoord : TEXCOORD0;
                };
    
                struct vertexOutput
                {
                    float4 pos : SV_POSITION;
                    float2 disp0_uv : TEXCOORD0;
                    float2 disp1_uv : TEXCOORD1;
                    float2 col_uv: TEXCOORD2;
                };
    
                vertexOutput vert(vertexInput input)
                {
                    vertexOutput output;
    
                    output.pos = UnityObjectToClipPos(input.vertex);
    
                    output.col_uv = input.texcoord.xy;
                    output.disp0_uv = input.texcoord.xy *_DisplTex_ST.xy + _DisplTex_ST.zw ;//* _Time.y;
                    output.disp1_uv = input.texcoord.xy *_DisplTex1_ST.xy + _DisplTex1_ST.zw;//* _Time.y;
    
                    return output;
                }
    
                float4 frag(vertexOutput input) : COLOR
                {
    
    
                    float dipl = (tex2D(_DisplTex, input.disp0_uv).a-0.5)*2*_DisplScale;
                    float dipl2 = (tex2D(_DisplTex1, input.disp1_uv).a-0.5)*2*_DisplScale1;
    
                    fixed4 col = tex2D(_MainTex, _MainTex_ST.xy * input.col_uv + _MainTex_ST.zw + float2(dipl.x, 0));
    
                    fixed4 col1 = tex2D(_MainTex, _MainTex_ST.xy * input.col_uv + _MainTex_ST.zw + float2(dipl2.x, 0));
                    return (col+col1)/2;
                    // return col1;
                }
    
                ENDCG
          }
       }
    }


    Another aside, but usually "displacement" is a word used to describe vertices themselves being offset. I don't know if the thing you're trying to do has a more standard name, but I think it might be called "distortion". This could help you in the future if you're Googling stuff, because most things to do with shader displacement are going to land you in threads about tessellation or vertex offsets or something.
    Thanked by 1dark_seth
  • edited
    You'll have to better describe what your expected result is, but part of the problem is likely that you're using the same UV coordinates from your displacement texture lookup as you are with your colour lookup. Usually you'd want a separate TEXCOORD for each set of UVs that you're using to lookup a texture, unless you're sure that two textures would share the same data. (e.g. Textures for diffuse, normal and roughness are going to use the same coordinates 99.9% of the time, so maybe it's fine to assume that those would be shared.)


    Another aside, but usually "displacement" is a word used to describe vertices themselves being offset. I don't know if the thing you're trying to do has a more standard name, but I think it might be called "distortion". This could help you in the future if you're Googling stuff, because most things to do with shader displacement are going to land you in threads about tessellation or vertex offsets or something.
    Yeah. Distortion is the correct term. Made additional changes. KINGDOM Anyone ......
    So This Shader case study was a great success . Result.

    Next Case study for me. 2d Wind. Maybe interactive Grass

    image
    Thanked by 1Elyaradine
  • Ah, cool! That's looking so good! Is that a game you're working on? Those animations look really nice!

    In case you haven't considered it, you can blend your two noise textures together at different speeds, and use the result of that to distort your colours, instead of blending two versions of your colour together. Which one you use depends on your art direction, but I personally prefer blending the noises, because with pixel art I find that you usually want to avoid semi-transparent pixels.
    Thanked by 1dark_seth
  • edited
    Ah, cool! That's looking so good! Is that a game you're working on? Those animations look really nice!

    In case you haven't considered it, you can blend your two noise textures together at different speeds, and use the result of that to distort your colours, instead of blending two versions of your colour together. Which one you use depends on your art direction, but I personally prefer blending the noises, because with pixel art I find that you usually want to avoid semi-transparent pixels.
    Hi man. Trying to post here but keep getting errors. I understand what you sying but I am not sure how to do that. Do you mind showing me ?

    Also thank you for your feedback and input.

    Will post my update on my interactive grass soon.
  • edited
    It'd help if you posted what error you're getting. :P

    In essence you'd be mixing your noises together, and then using the result to offset your colour.

    There are lots of different ways to mix noises together, and which way you do it depends on the visual you're after. It could just be taking the average of the two, or it could be multiplying them, or using various Photoshop blending maths. (The link is in GLSL, so you might have to find the HLSL equivalents of some of their functions.)
    Thanked by 1Denzil
  • @Elyaradine Thanks for the info!. I wouldn't ask you to write it for me then I don't learn anything. Will Look into that!.

    Not a game yet. Just doing some case studies on shaders. Using some sprites found on itch.io . But starting to get an idea for an game. Gonna purchase Pyxel editor to creates sprites with.

    Thanks for you feedback!!!
  • So the little I have read on it. I feel that multiplying them will be best for what I want.
    Thanks for mentioning this.
  • So here is my interactive grass shader. Showing the effect when player moves over it. Then I activate the Weather system. All crass moves. Every grass object that can move has a script that interacts with the Shader.

    image
    Thanked by 1Elyaradine
  • Some Slight Adjustment in my shader for the water.

    image
  • edited
    @Elyaradine I think I broke my head trying to figure this out but I believe I got the blending to work.... some what.
    1st section of my gif is old shader mixing my colors. Then you will see me change it to V4 in the inspector. This blends the noise first. I really love the look of that reflections.

    Thank you again for your imput!!!!

    image
  • edited
    A larger resolution gif.
    Same as above. First color blending. Then the switch to new version
    image
    Thanked by 1Denzil
  • Looks great, well done! I think the water can still use some tweaks to make it less flat / clear - I feel like the reflections are preserving the colour too perfectly. I think maybe even filtering the colour a bit would go far. Like make it a little grayer or maybe slight green-blue tinge. Something else that might be cool would be to distort things more the further away it is
    image
    maxresdefault.jpg
    1280 x 720 - 128K
    Thanked by 1dark_seth
  • Denzil said:
    Looks great, well done! I think the water can still use some tweaks to make it less flat / clear - I feel like the reflections are preserving the colour too perfectly. I think maybe even filtering the colour a bit would go far. Like make it a little grayer or maybe slight green-blue tinge. Something else that might be cool would be to distort things more the further away it is
    Hi Denzil.

    I agree. I have done some more changes on the look. added some tints to it. It works to match the Sky and suns input. I have been looking into distorting things closer to the camera more. Got stuck on this.

    Thank you for your input.



Sign In or Register to comment.