1. Help us improve the editor usability and artist workflows. Join our discussion to provide your feedback.
    Dismiss Notice
  2. We're looking for feedback on Unity Starter Kits! Let us know what you’d like.
    Dismiss Notice
  3. We’re giving 2017.1 beta testers a chance to win t-shirts and a Nintendo Switch. Read more on the blog.
    Dismiss Notice
  4. Unity 2017.1 beta is now available for download.
    Dismiss Notice
  5. Unity 5.6 is now released.
    Dismiss Notice
  6. Get further faster with the Unity Plus Accelerator Pack, free for new Unity Plus subscribers for a limited time. Click here for more details.
    Dismiss Notice
  7. Check out all the fixes for 5.6 on the patch releases page.
    Dismiss Notice
  8. Learn how you'll soon be able to publish your games to China in four simple steps with Xiaomi. Sign up now for early access.
    Dismiss Notice

Surface Shader Height Map

Discussion in 'Shaders' started by Harrison_Hough, Mar 16, 2017.

  1. Harrison_Hough

    Harrison_Hough

    Joined:
    Dec 3, 2015
    Posts:
    43
    Hey Guys,

    I like to know the correct way to calculate/use a height map in a surface shader?

    I'm making a Standard (metallic) shader with a heightmap texture. Here is what I currently have not sure if this is the right way to go about it.

    Code (CSharp):
    1. Shader "Custom/PBR/Standard Height" {
    2.     Properties {
    3.         _Color ("Color", Color) = (1,1,1,1)
    4.         _MainTex ("Albedo (RGB)", 2D) = "white" {}
    5.         _BumpMap("Normal Map", 2D) = "bump" {}
    6.         _BumpScale ("Normal ", Float) = 1
    7.             _HeightMap ("Height Map", 2D) = "white" {}
    8.         _HeightMapScale ("Height", Float) = 1
    9.         _Glossiness ("Smoothness", Range(0,1)) = 0.5
    10.         _MetallicGlossMap ("Metallic", 2D) = "white" {}
    11.         _Metallic ("Metallic", Range(0,1)) = 0.0
    12.         _OcclusionMap("OcclusionMap", 2D) = "white" {}
    13.         _OcclusionStrength("Occlusion Strength", Float) = 1
    14.  
    15.     }
    16.     SubShader {
    17.         Tags { "RenderType"="Opaque" }
    18.         LOD 200
    19.      
    20.         CGPROGRAM
    21.         // Physically based Standard lighting model, and enable shadows on all light types
    22.         #pragma surface surf Standard fullforwardshadows vertex:vert
    23.  
    24.         // Use shader model 3.0 target, to get nicer looking lighting
    25.         #pragma target 3.0
    26.         #pragma glsl
    27.  
    28.         sampler2D _MainTex;
    29.         sampler2D _OcclusionMap;
    30.         sampler2D _BumpMap;
    31.         sampler2D _MetallicGlossMap;
    32.         sampler2D _HeightMap;
    33.  
    34.         struct Input {
    35.             float2 uv_MainTex;
    36.         };
    37.  
    38.         half _HeightMapScale;
    39.         half _Glossiness;
    40.         half _Metallic;
    41.         half _BumpScale;
    42.         half _OcclusionStrength;
    43.         fixed4 _Color;
    44.  
    45.         void vert(inout appdata_full v,  out Input o) {
    46.             UNITY_INITIALIZE_OUTPUT(Input, o);
    47.             float4 heightMap = tex2Dlod(_HeightMap, float4(v.texcoord.xy,0,0));
    48.             //fixed4 heightMap = _HeightMap;
    49.             v.vertex.z += heightMap.b * _HeightMapScale;
    50.         }
    51.  
    52.         void surf (Input IN, inout SurfaceOutputStandard o) {
    53.             // Albedo comes from a texture tinted by color
    54.             fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
    55.             o.Albedo = c.rgb;
    56.             // Metallic and smoothness come from slider variables
    57.             fixed4 gloss = tex2D(_MetallicGlossMap, IN.uv_MainTex);
    58.             o.Metallic = gloss.r * _Metallic;
    59.             o.Smoothness = gloss.a * _Glossiness;
    60.  
    61.             o.Normal = UnpackScaleNormal(tex2D(_BumpMap, IN.uv_MainTex), _BumpScale);
    62.             o.Occlusion = tex2D(_OcclusionMap, IN.uv_MainTex) * _OcclusionStrength;
    63.  
    64.             o.Alpha = c.a;
    65.         }
    66.         ENDCG
    67.     }
    68.     FallBack "Diffuse"
    69. }
    70.  
     
    Last edited: Mar 16, 2017
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    2,683
    What effect are you expecting? There are many ways to use a heightmap with a surface shader, and the method you're using is a perfectly valid option, but I get the impression it isn't producing the result you want.

    A height map is just description of data in a texture, it doesn't really say anything about how you use it.

    If you're trying to replicate what the standard shader does with the heightmap, that's parallax offset mapping, which uses a heightmap to distort UVs to give a very basic appeance of additional surface depth. If you're looking to implement that in your surface shader see this post which includes an example of using ParallaxOffset, as well as a link to the more expensive, but better looking Parallax Occlusions Mapping.
    https://forum.unity3d.com/threads/surface-shader-parallaxoffset-issue.438089/