3

Let me start off by saying I know very little about shader programming. A lot of what I have here is stitched together from online resources and existing assets. I just need to know how to correctly integrate a height map into a unity shader. It doesn't have to be more complex than the standard Unity shader's. I can't use the Standard shader because I need a shader that tiles together multiple textures, which is probably why I haven't found a solution to this problem yet.

I've mixed and moved around the code, deleted some variables, renamed some variables, and looked online for anyone who had a similar problem.

Shader "Unlit/TRUE_EARTH"
{
    Properties
    {
        _TexA1 ("Tex A1", 2D) = "white" {}
        _TexA2 ("Tex A2", 2D) = "white" {}
        _TexB1 ("Tex B1", 2D) = "white" {}
        _TexB2 ("Tex B2", 2D) = "white" {}
        _TexC1 ("Tex C1", 2D) = "white" {}
        _TexC2 ("Tex C2", 2D) = "white" {}
        _TexD1 ("Tex D1", 2D) = "white" {}
        _TexD2 ("Tex D2", 2D) = "white" {}
    _BumpScale("Scale", Float) = 1.0
    [Normal] _BumpMap("Normal Map", 2D) = "bump" {}

    _Height("Height Scale", Range(0.005, 0.08)) = 0.02
    _HeightMap("Height Map", 2D) = "black" {}

    _OcclusionStrength("Strength", Range(0.0, 1.0)) = 1.0
    _OcclusionMap("Occlusion", 2D) = "white" {}
}
SubShader
{
    Tags { "RenderType"="Opaque" }
    Lighting Off
    ZWrite Off

    Pass
    {
        CGPROGRAM
        #pragma vertex vert
        #pragma fragment frag
        // make fog work
        #pragma multi_compile_fog

        #include "UnityCG.cginc"

        sampler2D _TexA1;
        sampler2D _TexA2;   
        sampler2D _TexB1;
        sampler2D _TexB2;
        sampler2D _TexC1;
        sampler2D _TexC2;   
        sampler2D _TexD1;
        sampler2D _TexD2;
        sampler2D _NormalMap;
        sampler2D _HeightMap;
        half _BumpAmount;
        half _Height;

        struct v2f
        {
           float4 pos     : SV_POSITION;
           float2 uv      : TEXCOORD0;
           half3 normal: TEXCOORD1;
           #if WPM_BUMPMAP_ENABLED
           half3 tspace0 : TEXCOORD2; // tangent.x, bitangent.x, normal.x
           half3 tspace1 : TEXCOORD3; // tangent.y, bitangent.y, normal.y
           half3 tspace2 : TEXCOORD4; // tangent.z, bitangent.z, normal.z
           #endif
        };


        v2f vert (float4 vertex : POSITION, half3 normal : NORMAL, half4 tangent : TANGENT, float2 uv : TEXCOORD5, appdata_full v) {
            v2f o;
            float4 heightMap = tex2Dlod(_HeightMap, float4(v.texcoord.xy, 0, 0));
            vertex.z += heightMap.b * _Height;
            o.pos               = UnityObjectToClipPos (vertex);
            o.uv                = uv;
            half3 wNormal       = UnityObjectToWorldNormal(normal);
            o.normal            = wNormal;


            #if WPM_BUMPMAP_ENABLED
            half3 wTangent = UnityObjectToWorldDir(tangent.xyz);
            half tangentSign = tangent.w * unity_WorldTransformParams.w;
            half3 wBitangent = cross(wNormal, wTangent) * tangentSign;
            //output the tangent space matrix
            o.tspace0 = half3(wTangent.x, wBitangent.x, wNormal.x);
            o.tspace1 = half3(wTangent.y, wBitangent.y, wNormal.y);
            o.tspace2 = half3(wTangent.z, wBitangent.z, wNormal.z);
            #endif

            return o;
        }

        half4 frag (v2f i) : SV_Target
        {
            // compute Earth pixel color
                half4 color;

                // compute Earth pixel color
                if (i.uv.x<0.25) 
                {
                    if (i.uv.y>0.4999) 
                    {
                        color = tex2Dlod(_TexA1, float4(i.uv.x * 4.0, (i.uv.y - 0.5) * 2.0, 0, 0));
                    } 
                    else 
                    {
                        color = tex2Dlod(_TexA2, float4(i.uv.x * 4.0, i.uv.y * 2.0, 0, 0));
                    }
                } 
                else if (i.uv.x < 0.5) 
                {
                    if (i.uv.y>0.4999) 
                    {
                        color = tex2Dlod(_TexB1, float4((i.uv.x - 0.25) * 4.0f, (i.uv.y - 0.5) * 2.0, 0, 0));
                    } 
                    else 
                    {
                        color = tex2Dlod(_TexB2, float4((i.uv.x - 0.25) * 4.0f, i.uv.y * 2.0, 0, 0));
                    }
                }
                else if (i.uv.x < 0.75) 
                {
                    if (i.uv.y>0.4999) 
                    {
                        color = tex2Dlod(_TexC1, float4((i.uv.x - 0.50) * 4.0f, (i.uv.y - 0.5) * 2.0, 0, 0));
                    } 
                    else 
                    {
                        color = tex2Dlod(_TexC2, float4((i.uv.x - 0.50) * 4.0f, i.uv.y * 2.0, 0, 0));
                    }
                }
                else if (i.uv.x < 1.01) 
                {
                    if (i.uv.y>0.4999) 
                    {
                        color = tex2Dlod(_TexD1, float4((i.uv.x - 0.75) * 4.0f, (i.uv.y - 0.5) * 2.0, 0, 0));
                    } 
                    else 
                    {
                        color = tex2Dlod(_TexD2, float4((i.uv.x - 0.75) * 4.0f, i.uv.y * 2.0, 0, 0));
                    }
                }

                // sphere normal (without bump-map)
                half3 snormal = normalize(i.normal);

                // transform normal from tangent to world space
                #if WPM_BUMPMAP_ENABLED
                half3 tnormal = UnpackNormal(tex2D(_NormalMap, i.uv)); 
                half3 worldNormal;
                worldNormal.x = dot(i.tspace0, tnormal);
                worldNormal.y = dot(i.tspace1, tnormal);
                worldNormal.z = dot(i.tspace2, tnormal);
                half3 normal = normalize(lerp(snormal, worldNormal, _BumpAmount));
                #else
                half3 normal = snormal;
                #endif

                return color;
        }
        ENDCG
    }
}
}

The texture comes out fine, but there is no semblance of heightmapping. It's all flat.

Mike OD
  • 107
  • 1
  • 9
  • Actually, try getting rid of the `float4 heightMap...;` and `v.vertex.z ...;` lines and putting these before the `o.pos = ...;` line: `float4 heightMap = tex2Dlod(_Height, float4(v.texcoord.xy, 0, 0));` and `vertex.z += heightMap.b * _HeightMap;` – Ruzihm Jul 24 '19 at 17:11
  • Hmm, no change there. – Mike OD Jul 24 '19 at 17:30
  • I'm surprised this even compiles but it's probably that your height/heightmap properties and your height/heightmap variables don't match up. Try changing `sampler2D _Height;` to `sampler2D _HeightMap;`, `half _HeightMap;` to `half _Height;`, `tex2Dlod(_Height, float4(v.texcoord.xy, 0, 0));` to `tex2Dlod(_HeightMap, float4(v.texcoord.xy, 0, 0));`, and `vertex.z += heightMap.b * _Height;` – Ruzihm Jul 24 '19 at 17:48
  • 1
    Ok that certainly had an effect, though an odd one. Increasing the height scale now warps the texture awkwardly to the side, instead of adding height depth. – Mike OD Jul 24 '19 at 18:01
  • 1
    Ooh that's good news. Try `vertex.y` instead of `vertex.z`. – Ruzihm Jul 24 '19 at 18:03
  • 1
    Ok yeah, that definitely produces a height effect. Looks awkward when viewed from sideways angles but I know that's the nature of heightmaps in general, they don't actually affect the geometry. I'll have to look into a more complex solution for editing terrain, but this certainly answers my question for now, thanks a ton. How do I mark your answer as accepted? – Mike OD Jul 24 '19 at 18:09

1 Answers1

3

There were 3 parts that needed to change.

  1. Make sure your properties match up with your variables:

    _Height("Height Scale", Range(0.005, 0.08)) = 0.02
    _HeightMap("Height Map", 2D) = "black" {}
    
    ....
    
    sampler2D _HeightMap;
    half _Height;
    
  2. Make modifications to the vertex before it gets stored in o

  3. Modify the y component of the vertex instead of the z:

    float4 heightMap = tex2Dlod(_HeightMap, float4(v.texcoord.xy, 0, 0));
    vertex.y += heightMap.b * _Height;
    o.pos               = UnityObjectToClipPos (vertex);
    
Ruzihm
  • 16,769
  • 3
  • 27
  • 40