Search Unity

Shadergraph triplanar object space normal mapping help

Discussion in 'Shaders' started by mattbirkettsmith, Aug 21, 2018.

  1. Rokis533

    Rokis533

    Joined:
    Sep 15, 2019
    Posts:
    6
    Yes it is a normal map.

    upload_2022-11-23_21-3-15.png
     
    Last edited: Nov 23, 2022
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,339
    The bump texture in that github is not a normal map texture. It's a grey scale texture like a displacement map. (Its not even a proper height or displacement map, it's just a greyscale version of the diffuse texture with increased contrast. But that's a different conversation.)

    Using the texture you provided with the settings above does produce the same issue you were complaining about, as it is not actually a normal map. Clicking on "create from greyscale", which converts the greyscale texture provided into a proper normal map no longer has any issues.
     
  3. Rokis533

    Rokis533

    Joined:
    Sep 15, 2019
    Posts:
    6
    Thanks, this was one of the problems, but still did not work with my older shader. I did a few adjustments and used the build in triplanar and added a Normal Unpack node and that fixed everything. Once again thank you, @bgolus you are a true hero with your knowledge of shaders. :)

    upload_2022-11-23_22-50-27.png
     
  4. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,339
    oh no ... My entire article on triplanar normal mapping is an attempt to stop people from doing that exact setup.

    Again, you need to set the built in triplanar node to Type Normal, and then you need to use the
    upload_2022-11-23_13-38-5.png

    And then you need to add the Tangent to World and Object to Tangent Transform nodes to get the correct object space normal.


    Or use the provided object space triplanar normals subgraph you were using before, just with an actual normal map as the input.
     
    Rokis533 likes this.
  5. Rokis533

    Rokis533

    Joined:
    Sep 15, 2019
    Posts:
    6
    Thank you, now it works perfectly.

    upload_2022-11-24_10-9-4.png
     
  6. kcastagnini

    kcastagnini

    Joined:
    Dec 14, 2019
    Posts:
    61
    Hello bgolus,
    I have been trying to port your subgraph and the triplanar node in HLSL for my Surface Shader.
    In ShaderGraph you need a normal in tangent space in the fragment shader, and this is true also for SurfaceOutput.normal (tell me if I'm wrong).
    So I was thinking about implementing the Unity default triplanar node first to see if it was working, and then your triplanar subgraph.
    I took the node code from here: https://docs.unity3d.com/Packages/com.unity.shadergraph@10.3/manual/Triplanar-Node.html

    Unluckily this is not working properly, here I am trying to output the triplanar node as albedo (btw, I am using the built-in render pipeline in ShaderGraph).
    The bottom cube and sphere shader is in ShaderGraph, the other two with magenta artifacts are from my SurfaceShader.
    triplanarNotWorking.png

    Here is the shader graph:
    triplanarWorkingGraph.png

    Here is the porting of the triplanar nodes:
    Code (CSharp):
    1. #ifndef TOOLKIT_TRIPLANAR
    2. #define TOOLKIT_TRIPLANAR
    3.  
    4. float3 TransformWorldToTangent(float3 dirWS, float3x3 worldToTangent)
    5. {
    6.     return mul(worldToTangent, dirWS);
    7. }
    8.  
    9. //triplanar node: https://docs.unity3d.com/Packages/com.unity.shadergraph@10.3/manual/Triplanar-Node.html
    10. //tex2D vs SAMPLE_TEXTURE2D: https://forum.unity.com/threads/difference-between-tex2d-and-sample_texture2d-post-processing-effect.651580/
    11. //
    12. //Works with both WS (world space) and OS (object space)
    13. float3 Triplanar(sampler2D Texture, float3 Position, float3 Normal, float Tile, float Blend)
    14. {
    15.     float3 Node_UV = Position * Tile;
    16.     float3 Node_Blend = pow(abs(Normal), Blend);
    17.     Node_Blend /= dot(Node_Blend, 1.0);
    18.     float4 Node_X = tex2D(Texture, Node_UV.zy);
    19.     float4 Node_Y = tex2D(Texture, Node_UV.xz);
    20.     float4 Node_Z = tex2D(Texture, Node_UV.xy);
    21.  
    22.     return Node_X * Node_Blend.x + Node_Y * Node_Blend.y + Node_Z * Node_Blend.z;
    23. }
    24.  
    25. //triplanar node: https://docs.unity3d.com/Packages/com.unity.shadergraph@10.3/manual/Triplanar-Node.html
    26. //only for WS triplanar
    27. float3 TriplanarNormal_WS(sampler2D Texture, float3 PositionWS, float3 NormalWS, float3 TangentWS, float Tile, float Blend)
    28. {
    29.     float3 Node_UV = PositionWS * Tile;
    30.     float3 Node_Blend = max(pow(abs(NormalWS), Blend), 0);
    31.     Node_Blend /= (Node_Blend.x + Node_Blend.y + Node_Blend.z).xxx;
    32.  
    33.     float3 Node_X = UnpackNormal(tex2D(Texture, Node_UV.zy));
    34.     float3 Node_Y = UnpackNormal(tex2D(Texture, Node_UV.xz));
    35.     float3 Node_Z = UnpackNormal(tex2D(Texture, Node_UV.xy));
    36.  
    37.     Node_X = float3(Node_X.xy + NormalWS.zy, abs(Node_X.z) * NormalWS.x);
    38.     Node_Y = float3(Node_Y.xy + NormalWS.xz, abs(Node_Y.z) * NormalWS.y);
    39.     Node_Z = float3(Node_Z.xy + NormalWS.xy, abs(Node_Z.z) * NormalWS.z);
    40.  
    41.     float3 Out =
    42.         float4(normalize(Node_X.zyx * Node_Blend.x + Node_Y.xzy * Node_Blend.y + Node_Z.xyz * Node_Blend.z), 1);
    43.    
    44.     //original shader graph code, I calculate WorldSpaceBiTangent from normal and tanget in WS
    45.     //float3x3 Node_Transform = float3x3(IN.WorldSpaceTangent, IN.WorldSpaceBiTangent, IN.WorldSpaceNormal);
    46.     float3 biTangentWS = normalize(cross(NormalWS, TangentWS));
    47.     float3x3 Node_Transform = float3x3(TangentWS, biTangentWS, NormalWS);
    48.  
    49.     Out.rgb = TransformWorldToTangent(Out.rgb, Node_Transform);
    50.     return Out;
    51. }
    52.  
    53. //source: https://forum.unity.com/threads/shadergraph-triplanar-object-space-normal-mapping-help.546322/
    54. //only for OS triplanar
    55. float3 TriplanarNormal_OS(sampler2D Texture, float3 PositionOS, float3 NormalOS, float Tile, float Blend)
    56. {
    57.     //TODO:
    58.     return float4(0, 0, 0, 0);
    59. }
    60.  
    61. #endif

    I am attaching my surface shader down below, maybe you can help me understand what I'm not understanding.
    Thanks for your time!
     

    Attached Files:

  7. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,339
  8. danBourquin

    danBourquin

    Joined:
    Nov 16, 2016
    Posts:
    34
    Thanks you bgolus your subgraph is nice!
    I just added an offset (i.e. moving wave) and the possibility to add the actual normal (being able to make multipass into the subgraph i.e. for two different wave normal map texture).
    upload_2023-2-23_14-1-20.png
    upload_2023-2-23_14-2-32.png
     

    Attached Files: