简体   繁体   中英

How to implement a simple height map to an Unity Shader

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.

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);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM