Search Unity

  1. Unity 2020.1 has been released.
    Dismiss Notice
  2. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice

How do I use a Heightmap in Shader Graph?

Discussion in 'Shaders' started by bienenstockhd, Jun 28, 2018.

  1. bienenstockhd

    bienenstockhd

    Joined:
    Jun 28, 2018
    Posts:
    1
    Hello,
    I would like to add a Height Map to my Shader i created with Shader Graph, but it is missing on the Master. How do I add a Height Map?
    upload_2018-6-28_5-25-10.png upload_2018-6-28_5-27-34.png
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    8,976
    The original Standard shader's height map parameter is used to drive a version of Parallax Offset Mapping, sometimes just called Offset Mapping, or in Unity's code referred to as Parallax Bump Mapping. This is a simple approximation that basically just smudges the UVs a little based on a height map.

    Here's the code Unity uses:

    Copied from UnityCG.cginc
    Code (CSharp):
    1. // Calculates UV offset for parallax bump mapping
    2. inline float2 ParallaxOffset( half h, half height, half3 viewDir )
    3. {
    4.     h = h * height - height/2.0;
    5.     float3 v = normalize(viewDir);
    6.     v.z += 0.42;
    7.     return h * (v.xy / v.z);
    8. }
    You can add this yourself by building a node graph to do the same. the h is the greyscale value from the height map texture, the height is the scale factor (which should be very, very small; Standard uses a range of 0.005 to 0.08), and the viewDir is the tangent space view direction. The output value should be added to the texture UV.

    The HD pipeline's Lit shaders also have a height map, but it uses it for tessellation displacement (which isn't supported by Shader Graph yet), or for Parallax Occlusion Mapping, which is a much more accurate technique that raymarches through the height field to find an appropriate UV, and is much more expensive than Parallax Offset Mapping. It also requires the use of dynamic loops which node graphs aren't great at handling. And by not great I mean cannot be handled at all without a custom node.

    If replicating the existing Standard Shader's implementation is good enough, the above code should let you recreate it in your own node graph, or let you create a subgraph you can reuse elsewhere. If you want something like what the HD Lit shaders have you'll have to wait for Unity to add support or you can request a Parallax Occlusion Mapping node.
     
    shamsfk, Xury46, Simplestar and 3 others like this.
  3. Andrey_Graphics

    Andrey_Graphics

    Joined:
    Oct 29, 2015
    Posts:
    109
    Whole set of nodes for Shader graph
    http://u3d.as/1gkf
    - SSS Color,
    - SSS gradient,
    - Parallax mapping,
    - Parallax Mapping iterrations,
    - Parallax Occlusion Mapping,
    - PerturbedNormals (World normal с учетом NormalMap),
    - CreateNormalChannel (для каждого канала текстуры),
    - CreateNormalFloat (для любого значения float, можно делать нормали из процедурных шумов),
    - LightDirection,
    - ProceduralRock (процедурный шум),
    - Range ,
    - TilingShape .
     
  4. francois85

    francois85

    Joined:
    Aug 11, 2015
    Posts:
    1,287
    I’m a bit confused how to implement a height map in the shader graph, can some one please please provide an example

    Thanks so much
     
  5. SmoothPulsar

    SmoothPulsar

    Joined:
    Apr 21, 2018
    Posts:
    2
    Hello I would like to know more as well, do you have a documentation somewhere ? I can't seem to find it or reproduce it
     
  6. Andrey_Graphics

    Andrey_Graphics

    Joined:
    Oct 29, 2015
    Posts:
    109
    Hello, instead of documentation there are ready examples, shaders are in the folder "Shaders", you need Parallax.
     
  7. GlitchInTheMatrix

    GlitchInTheMatrix

    Joined:
    Apr 12, 2010
    Posts:
    285
    It seems like High map is not supported. Been looking for tessellation without luck.
     
  8. V0odo0

    V0odo0

    Joined:
    Jan 8, 2012
    Posts:
    285
    Here is Sub Graph version of this code:
     
  9. DINKmod

    DINKmod

    Joined:
    Jan 25, 2017
    Posts:
    14
    This is a great literal conversion - but if the master node doesn't have a parallax input, then where would you plug the output of this sub-graph in your main shader graph?

    How would one go about adding some sort of a height field to the LWRP's Master node? Is this just an addition that Unity would be responsible for? The HDRP master lit node doesn't seem to have straight forward parallax support either.
     
    roccobruno78 likes this.
  10. TimNick151297

    TimNick151297

    Joined:
    Apr 21, 2013
    Posts:
    16
    As bgolus said, parallax mapping is just a special way of distorting uvs of a texture sample. If you want to add the illusion of height to your shader, you just need to plug the return of the subgraph above into the UVs of your texture sampler.
     
  11. binaristudios

    binaristudios

    Joined:
    Jun 18, 2018
    Posts:
    2

    Might be a dumb question, but where could i plug a heightmap texture into this shadergraph?
     
  12. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    8,976
    The graph @V0odo0 showed is a Sub Graph, which means it becomes a node in another graph that you would pass the output of other nodes into. To use a texture, add it to the Shader Graph's properties (via the blackboard), then add that texture as a property node along with a Sample Texture 2D node. You'd then pipe the output of that into the Height input of the Sub Shader node.

    Alternatively you could just put all of those nodes into your Shader Graph shader directly and replace the Height node with the Sample Texture 2D node.
     
  13. Pivetta

    Pivetta

    Joined:
    Oct 11, 2013
    Posts:
    19
    I can't manage to get this shader to work properly,
    I put it on a quad and used 2 checker textures just to test, everything works fine until I either rotate the quad or I rotate the UVs, then it becomes a mess. I am using the node setup as translate from the code by VOodoO
    How does this apply to local space? I am smashing my head the whole day trying to understand how to get UVs rotation but I bet I'm working in the wrong direction.
    Any clues?

     
  14. Pivetta

    Pivetta

    Joined:
    Oct 11, 2013
    Posts:
    19
    I bought the asset package from Andrey_Graphics and found the solution, I am still not fit enough to read shader code.
    There the node FixedViewDirectionTangent did the trick, I converted it to node tree from code snippet and now I can go on developing my lo-fi parallax.

    PS: Andrey, please do some better naming convention on your package, it's really nice but it's a mess
     
  15. m0nkeybl1tz

    m0nkeybl1tz

    Joined:
    Feb 10, 2013
    Posts:
    11
    @Pivetta I believe you're missing a "height" parameter (the one @bgolus said usually goes from .005 to .08). Use that value to multiply and divide in the top left corner, instead of the checkerboard.

    If you do want to use the checkerboard for your height map, plug it into the 'A' slot in the multiply node instead of the Property + Add .5 nodes (I think those just allow you to set a manual offset for the entire texture). @binaristudios you can plug any texture + a texture sampler into that top left slot and it will act as a height map (see attached).
     

    Attached Files:

unityunity