Study/Unity

Unity Shader - 등고선 shader만들기

꽁따리 2022. 7. 30. 17:11

일을 하면서 unity상의 지형 모델에 등고선을 표시해줘야 하는 일이 생겼다.

이를 유니티의 Shader를 이용하여 간단한 등고선 Shader를 구현하려 한다.

 

간단하게 구현한 만큼 고쳐야할 부분도 많으니 참고하길 바란다....

 

고쳐져야 할부분:

1. 높이값이 0인부분에 선을 그릴 수 없음.

2. 높이값이 음수일 때와 양수일 때의 선이 그려지는 방향이 반대

Shader "Custom/ContourLine"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _Color ("Main Color", Color) = (1,1,1,1)
        _LineColor ("Line Color", Color) = (1,1,1,1)
        _LineSharpness("Line Sharpness", float) = 6
        _LineBrightness("Line Brightness", Range(1,100)) = 1
        _LineSpacing("Line Spacing", Float) = 2
        _OffsetY("Offset Y", Float) = 0.0
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

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

            #include "UnityCG.cginc"

            fixed4 _Color;
            fixed4 _LineColor;
            fixed _LineSharpness;
            fixed _LineSpacing;
            fixed _LineBrightness;
            fixed _OffsetY;
            sampler2D _MainTex;
            float4 _MainTex_ST;

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                UNITY_FOG_COORDS(1)
                float4 vertex : SV_POSITION;
                float3 worldPos : TEXCOORD1;
            };

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                o.worldPos = mul(unity_ObjectToWorld, v.vertex);
                UNITY_TRANSFER_FOG(o,o.vertex);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 texcol = tex2D (_MainTex, i.uv);
                float rl = 0.0;
                float gl = 0.0;
                float bl = 0.0;
                float _y = i.worldPos.y + _OffsetY;

                float temp = 1;
                for(int i = 0; i < _LineSharpness; i++)
                {
                    temp = temp * ((_y % _LineSpacing) / _LineSpacing);
                }
                //기존의 pow를 이용한 제곱 계산은 밑이 음수일경우 내부 계산 로직에서 overflow로 인한 NaN오류값이 반환됨.. 따라서 반복문으로 제곱을 구했다.

                rl = 1.0 + abs(_LineBrightness * temp * _LineColor.r);
                gl = 1.0 + abs(_LineBrightness * temp * _LineColor.g);
                bl = 1.0 + abs(_LineBrightness * temp * _LineColor.b);
                
                fixed4 hl = fixed4( (fixed3(rl,gl,bl)), 1);

                return texcol * hl;

            }
            ENDCG 

        }
    }
}

https://youtu.be/o4gAacP4LNQ

 

 

 

-참고한 url

https://answers.unity.com/questions/300106/shader-height-lines.html

 

Shader height lines - Unity Answers

 

answers.unity.com