Search Unity

  1. Unity 2019.2 is now released.
    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:
    7,253
    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/
     
    creative_vlad likes this.