Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Help with adding displacement to my reflection shader

Discussion in 'Shaders' started by NerdRageStudios, Sep 9, 2017.

  1. NerdRageStudios

    NerdRageStudios

    Joined:
    Nov 1, 2013
    Posts:
    167
    Hi, I am really struggling here to add displacement into my reflection shader.

    Firstly here is the shader code:

    Code (CSharp):
    1.  
    2. Shader "FX/2D Reflection"
    3. {
    4.     Properties
    5.     {
    6.         _MainTex ("Sprite Texture", 2D) = "white" {}
    7.         _DispTex ("Disp Texture", 2D) = "gray" {}
    8.         _Displacement ("Displacement", Range(0, 1.0)) = 0.3
    9.         _Color ("Tint", Color) = (1,1,1,1)
    10.         [HideInInspector] _ReflectionTex ("", 2D) = "white" {}
    11.     }
    12.     SubShader
    13.     {
    14.         Tags  { "RenderType"="Opaque" }
    15.         LOD 100
    16.         Pass
    17.         {
    18.             CGPROGRAM
    19.             #pragma vertex vert
    20.             #pragma fragment frag
    21.             #include "UnityCG.cginc"
    22.  
    23.             struct appdata_t
    24.             {
    25.                 float2 uv : TEXCOORD0;
    26.                 float4 refl : TEXCOORD1;
    27.                 float4 pos : POSITION;
    28.                 float4 col: COLOR;
    29.             };
    30.             struct v2f
    31.             {
    32.                 half2 uv : TEXCOORD0;
    33.                 float4 refl : TEXCOORD1;
    34.                 float4 pos : SV_POSITION;
    35.                 fixed4 col: COLOR;
    36.             };
    37.             float4 _MainTex_ST;
    38.             fixed4 _Color;
    39.             v2f vert(appdata_t i)
    40.             {
    41.                 v2f o;
    42.                 o.pos = UnityObjectToClipPos (i.pos);
    43.                 o.uv = TRANSFORM_TEX(i.uv, _MainTex);
    44.                 o.col = i.col * _Color;
    45.                 o.refl = ComputeScreenPos (o.pos);
    46.                 return o;
    47.             }
    48.             sampler2D _MainTex;
    49.             sampler2D _ReflectionTex;
    50.             fixed4 frag(v2f i) : SV_Target
    51.             {
    52.                 fixed4 tex = tex2D(_MainTex, i.uv) * i.col;
    53.                 tex.rgb *= tex.a;
    54.                 fixed4 refl = tex2Dproj(_ReflectionTex, UNITY_PROJ_COORD(i.refl));
    55.                 return tex * refl;
    56.             }
    57.             ENDCG
    58.         }
    59.     }
    60. }
    Now I assume I would have have to somehow use the displacement map on the return texture from the fragment function, but I am not sure how.

    I found that someone else has used a displacement map like this:

    Code (CSharp):
    1. half2 displacement1 = tex2D( _Displacement1Tex, i.uv.xy );
    2. float2 adjusted = i.uv.xy + (displacement1.rg - .5);
    3. half4 output = tex2D(_MainTex, adjusted);
    But I tried to replace the _MainTex with the reflection texture as that seemed to make sense, but that didnt work at all.

    Any ideas on how I can get this to work, so that I can adjust the displacement amount at runtime to create water ripples?
     
  2. NerdRageStudios

    NerdRageStudios

    Joined:
    Nov 1, 2013
    Posts:
    167
    I have managed to get this to compile, but the displacement map still isnt applying at all... Can anyone see why this might be?

    Code (CSharp):
    1. Shader "FX/2D Reflection"
    2. {
    3.     Properties
    4.     {
    5.         _MainTex ("Sprite Texture", 2D) = "white" {}
    6.         _DispTex ("Disp Texture", 2D) = "gray" {}
    7.         _Displacement ("Displacement", Range(0, 1.0)) = 0.3
    8.         _Color ("Tint", Color) = (1,1,1,1)
    9.         [HideInInspector] _ReflectionTex ("", 2D) = "white" {}
    10.     }
    11.     SubShader
    12.     {
    13.         Tags  { "RenderType"="Opaque" }
    14.         LOD 100
    15.         Pass
    16.         {
    17.             CGPROGRAM
    18.             #pragma vertex vert
    19.             #pragma fragment frag
    20.             #include "UnityCG.cginc"
    21.             struct appdata_t
    22.             {
    23.                 float2 uv : TEXCOORD0;
    24.                 float4 refl : TEXCOORD1;
    25.                 float4 pos : POSITION;
    26.                 float4 col: COLOR;
    27.             };
    28.             struct v2f
    29.             {
    30.                 half2 uv : TEXCOORD0;
    31.                 float4 refl : TEXCOORD1;
    32.                 float4 pos : SV_POSITION;
    33.                 fixed4 col: COLOR;
    34.             };
    35.             float4 _MainTex_ST;
    36.             fixed4 _Color;
    37.             v2f vert(appdata_t i)
    38.             {
    39.                 v2f o;
    40.                 o.pos = UnityObjectToClipPos (i.pos);
    41.                 o.uv = TRANSFORM_TEX(i.uv, _MainTex);
    42.                 o.col = i.col * _Color;
    43.                 o.refl = ComputeScreenPos (o.pos);
    44.                 return o;
    45.             }
    46.             sampler2D _MainTex;
    47.             sampler2D _ReflectionTex;
    48.             sampler2D _DispTex;
    49.             float _Displacement;
    50.             fixed4 frag(v2f i) : SV_Target
    51.             {
    52.                 fixed4 tex = tex2D(_MainTex, i.uv) * i.col;
    53.                 tex.rgb *= tex.a;
    54.  
    55.                 fixed4 refl = tex2Dproj(_ReflectionTex, UNITY_PROJ_COORD(i.refl));
    56.                
    57.                 half2 displacement1 = tex2D( _DispTex, i.uv.xy *_Displacement);
    58.                 float2 adjusted = i.uv.xy + (displacement1.rg - .5);
    59.  
    60.                 half4 output = tex2D(_MainTex, adjusted);
    61.                 return output * refl * tex;
    62.             }
    63.             ENDCG
    64.         }
    65.     }
    66. }
     
    Last edited: Sep 10, 2017
  3. mgear

    mgear

    Joined:
    Aug 3, 2010
    Posts:
    8,998
  4. NerdRageStudios

    NerdRageStudios

    Joined:
    Nov 1, 2013
    Posts:
    167
    Uh... hang on, the code works?

    Ok, I'm seriously confused now becuase it doesnt for me!!
     
  5. NerdRageStudios

    NerdRageStudios

    Joined:
    Nov 1, 2013
    Posts:
    167
    I still cannot get this to work, when I place the shader material on a plane, I get the reflection but no displacement is applying. Can anyone see if I have done something obviously wrong??
     
  6. brownboot67

    brownboot67

    Joined:
    Jan 5, 2013
    Posts:
    375
    You have a ton of casts and mismatched types, which could be why it compiles fine on some gpus but not on yours.

    Code (csharp):
    1. tex.rgb *= tex.a
    Even stuff like this which seems super tame and CG is "supposed" to handle I've been bitten by on certain mobile gpus. Much safer to be explicit and do:

    Code (csharp):
    1. tex.rgb *= tex.aaa
    and...

    Code (csharp):
    1. float2 adjusted = i.uv.xy + (displacement1.rg - 0.5.xx);
    Plus you're all over the place between floats, halves, fixed, etc.
     
  7. NerdRageStudios

    NerdRageStudios

    Joined:
    Nov 1, 2013
    Posts:
    167
    Thanks for the help, to be honest i'm not surprised its a mess as I am really making this up as I go along. I have tried to learn how to write shader code but I only seem to find info on the basics, and this kind of stuff ends up like some form of dark magic!

    Basically, I took the surface reflection shader from the wiki here: http://wiki.unity3d.com/index.php/SurfaceReflection#Script_-_SurfaceReflection.cs

    That works fine, but it just looks like a mirror, and I need to get some form of ripple or displacement, so I was taking the info found in this thread here: https://forums.tigsource.com/index.php?topic=40539.20

    I was trying to get that into the reflection shader, but nothing I try seems to work.

    I think I may have to give up on this and pay someone to write one as this is beyond my level of understanding and comprehension.