Search Unity

Adding a water shader to another, existing, shader

Discussion in 'Shaders' started by PhoenixAdvanced, Nov 7, 2018.

  1. PhoenixAdvanced

    PhoenixAdvanced

    Joined:
    Sep 30, 2016
    Posts:
    316
    Hello.

    I have written a custom shader which I am using for a custom terrain implementation. This shader takes in several textures, and blends them together based on the height of the terrain, producing a smooth gradient between, for example, grass, soil, rock, snow, etc, etc.

    However, I now have a problem. I want the lowermost layer to be an ocean or water layer. I can't create a water volume because my terrain is planet-sized (and spherical) so any water volume would be far too big to work properly.

    So, what I have decided to do, at least for the time being, is to try to add a water shader effect to my existing terrain shader.

    Part of my existing code is here:

    Code (CSharp):
    1.        
    2. if (scaledheight > 40)
    3. {
    4.             if (scaledheight > 40 + blendregion){                      
    5.                 o.Albedo = tex2D(_firsttex, IN.uv_firsttex).rgb;
    6.  
    7.               //This is where the water effect should go
    8.  
    9. }          
    10.             else
    11. {
    12.                 float OldMin = 40;
    13.                 float OldMax = 40 + blendregion;
    14.                 float NewValue = (((scaledheight - OldMin) * (1 - 0)) / (OldMax - OldMin)) + 0;
    15.                 float a1 = 1 - NewValue;
    16.                 float a2 = NewValue;      
    17.                 o.Albedo = (tex2*a1)+(tex1*a2);
    18.                 }
    19.   }
    20.  
    This is all inside a regular Unity subshader. I can provide the rest of the code if necessary.

    The question is, how would I apply a water effect to only the terrain texture at a particular height? Is this possible, or is there some other way that I could do this?

    Thanks in advance!
     
  2. PhoenixAdvanced

    PhoenixAdvanced

    Joined:
    Sep 30, 2016
    Posts:
    316
    What I am now doing is trying to use a colour value in a texture to determine where the water effect should go.

    Can anyone tell me why this code doesn't work?


    Code (CSharp):
    1.  
    2.     void surf(Input IN, inout SurfaceOutput o) {
    3.  
    4.          const float3 ColorToReplace = float3(1,0,0);
    5.          const float3 NewColor = float3(0,1,0);
    6.  
    7.           half4 tex1 = tex2D (_firsttex, IN.uv_firsttex);
    8.           float isColorToReplace = step(0.999, dot(tex1.rgb, ColorToReplace));
    9.  
    10.                if(tex1.x > 0.999)
    11.                tex1.rgb = float4(0,128,0,255);
    12.                else
    13.                tex1.rgb = float4(0,0,128,255);    
    14.  
    15.              o.Albedo = tex1.rgb;
    16.              o.Alpha = tex1.a;
    17.        
    18.     }
    I have a simple texture which is split between a white part and a red part, and the code above should be changing the colour of the red part of the texture to green, and the other part to blue, but it stays almost all one colour, with a few streaks of the second colour.

    I can't see anything obviously wrong with this?
     
  3. brownboot67

    brownboot67

    Joined:
    Jan 5, 2013
    Posts:
    375
    Generally speaking, you should not be using branching for your masks, just do a lerp.
     
  4. PhoenixAdvanced

    PhoenixAdvanced

    Joined:
    Sep 30, 2016
    Posts:
    316
    Thank you, I've started to replace my existing code using lerps. My knowledge of shader code is quite limited, so I'm grateful for the advice!
     
    brownboot67 likes this.