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. Dismiss Notice

Question Recaulculating Normals in Displacement Shader

Discussion in 'Shaders' started by Jabbasmakt, Sep 6, 2023.

  1. Jabbasmakt

    Jabbasmakt

    Joined:
    Feb 17, 2020
    Posts:
    3
    So following the tutorial on https://www.ronja-tutorials.com/post/015-wobble-displacement/ my implementation looks off. I end up with symmetrical normals that doesn't look right.


    (Sun is from the right but the normals still look symmetrical)

    In the Ronja tutorial, the displacement happens only in Y, while my implementation displaces in XYZ. The tutorial also only uses a sinewave to displace, while I use an array of points and a gradient texture to displace the geometry. Basically, everything else should be the same and I don't understand what would cause my result to look so vastly different. Thank you for your time!

    This is the code I'm trying to apply from the Ronja tutorial:
    Code (CSharp):
    1.  
    2. void vert(inout appdata_full data) {
    3.  
    4.     //Displace the geometry
    5.     float4 modifiedPos = data.vertex;
    6.     modifiedPos.y += sin(data.vertex.x * _Frequency) * _Amplitude;
    7.  
    8.     float3 posPlusTangent = data.vertex + data.tangent * 0.01;
    9.  
    10.     //Displace the tangent
    11.     posPlusTangent.y += sin(posPlusTangent.x * _Frequency) * _Amplitude;
    12.  
    13.     float3 bitangent = cross(data.normal, data.tangent);
    14.     float3 posPlusBitangent = data.vertex + bitangent * 0.01;
    15.  
    16.     //Displace the bitangent
    17.     posPlusBitangent.y += sin(posPlusBitangent.x * _Frequency) * _Amplitude;
    18.  
    19.     float3 modifiedTangent = posPlusTangent - modifiedPos;
    20.     float3 modifiedBitangent = posPlusBitangent - modifiedPos;
    21.  
    22.     float3 modifiedNormal = cross(modifiedTangent, modifiedBitangent);
    23.  
    24.     //Apply the new normal
    25.     data.normal = normalize(modifiedNormal);
    26.     data.vertex = modifiedPos;
    27. }
    28.  
    My implementation:
    Code (CSharp):
    1.  
    2. void disp(inout appdata v)
    3.         {
    4.             v.originalPos = v.vertex.xyz;
    5.             float disp = _Displacement * clamp(v.color.r * 2 - 1,0,1);
    6.             float d = 0;
    7.      
    8.             float4 modifiedPos = v.vertex;
    9.  
    10.  
    11.             float3 worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
    12.             float texCoords = 0;
    13.             for (int i = 0; i < _PointsSize; i++) {
    14.                 fixed4 newC = max(0, 1 - distance(_Points[i].xyz, worldPos.xyz));
    15.                 if (newC.x > texCoords.r) {
    16.                     texCoords = newC;
    17.                 }
    18.             }
    19.             float gradientHeight = tex2Dlod(_Gradient, float4(clamp((texCoords) * 1.0f, 0.02f, 1.0f), 0, 0, 0)).r - 1.15f;
    20.             d = -gradientHeight * disp;
    21.  
    22.             //Displace the geometry
    23.             modifiedPos.xyz -= v.normal * d * 0.1;
    24.             modifiedPos.xyz += v.normal * disp * 0.1;
    25.          
    26.  
    27.             float3 posPlusTangent = v.vertex + v.tangent * 0.001;
    28.             worldPos = mul(unity_ObjectToWorld, posPlusTangent).xyz;
    29.             texCoords = 0;
    30.             for (int i = 0; i < _PointsSize; i++) {
    31.                 fixed4 newC = max(0, 1 - distance(_Points[i].xyz, worldPos.xyz));
    32.                 if (newC.x > texCoords.r) {
    33.                     texCoords = newC;
    34.                 }
    35.             }
    36.             gradientHeight = tex2Dlod(_Gradient, float4(clamp((texCoords) * 1.0f, 0.02f, 1.0f), 0, 0, 0)).r - 1.15f;
    37.             d = -gradientHeight * disp;
    38.  
    39.             //Displace the tangent
    40.             posPlusTangent.xyz -= v.normal * d * 0.1;
    41.             posPlusTangent.xyz += v.normal * disp * 0.1;
    42.  
    43.  
    44.             float3 bitangent = cross(v.normal, v.tangent);
    45.             float3 posPlusBitangent = v.vertex + bitangent * 0.001;
    46.             worldPos = mul(unity_ObjectToWorld, posPlusBitangent).xyz;
    47.             texCoords = 0;
    48.             for (int i = 0; i < _PointsSize; i++) {
    49.                 fixed4 newC = max(0, 1 - distance(_Points[i].xyz, worldPos.xyz));
    50.                 if (newC.x > texCoords.r) {
    51.                     texCoords = newC;
    52.                 }
    53.             }
    54.             gradientHeight = tex2Dlod(_Gradient, float4(clamp((texCoords) * 1.0f, 0.02f, 1.0f), 0, 0, 0)).r - 1.15f;
    55.             d = -gradientHeight * disp;
    56.  
    57.             //Displace the bitangent
    58.             posPlusBitangent.xyz -= v.normal * d * 0.1;
    59.             posPlusBitangent.xyz += v.normal * disp * 0.1;
    60.          
    61.             float3 modifiedTangent = posPlusTangent - modifiedPos;
    62.             float3 modifiedBitangent = posPlusBitangent - modifiedPos;
    63.  
    64.             float3 modifiedNormal = cross(modifiedTangent, modifiedBitangent);
    65.  
    66.             //Apply the new normal
    67.             v.normal = normalize(modifiedNormal);
    68.             v.vertex = modifiedPos;
    69.         }
    70.  
     
  2. neoshaman

    neoshaman

    Joined:
    Feb 11, 2011
    Posts:
    6,469
  3. POOKSHANK

    POOKSHANK

    Joined:
    Feb 8, 2022
    Posts:
    73