odyssey

#2 odyssey 개발일지: 지형 외각선 만들기

san10 2022. 11. 8. 18:14

 

 

컨셉아트에서 땅부분만 따왔다

컨셉아트를 보면 알겠지만 odyssey에는 모든 물체에 얇은 선이 있다.

대부분 리소스는 그려서 넣기에 선이 있는 채로 존재하겠지만

지형은 유니티에서 직접 만들기 때문에 선이 존재하지 않는다.

그래서 외각선을 만들어주는 쉐이더를 만들려고 한다.

 

 

외각선 쉐이더는 테크니컬 아티스트를 위한 유니티 쉐이더 스타트업이라는 책을 많이 참고했다.

책에서는 외각선을 만들기 위한 2가지 방법을 소개하는데

1. 2Pass를 이용한 외각선 제작

2. fresnel을 이용한 외각선 제작

두가지 중에서 2Pass를 이용하여 만들기로 했다.

 

2Pass란 말 그대로 두번 그리는 것을 뜻한다.

1Pass에서 검정색 외각선을 먼저 그리고,  2Pass는 원래 그려야하는 오브젝트를 그린다.

원래는 1Pass에서 크기를 키우고, 노말을 뒤집어야 하는데, odyssey의 지형은 2d라서 뒤집을 필요까진 없었다.

 

 

1Pass에서 버텍스 쉐이더를 통해 버텍스를 확장한다.

void vert(inout appdata_full v) {
            v.vertex.xyz = v.vertex.xyz + v.vertex.xyz * 0.1f;
          }

scene뷰
game뷰

보면 알겠지만, 외각선이 고르게 그려지지 않는다.

버텍스가 확장이 되긴 했지만, 위치가 좀 이상하다.

 

1Pass때 그린 버텍스의 중점과 2Pass때 그리는 버텍스의 중점이 같으면 될것 같아서

이를 해결하기 위해 여러 자료들을 찾아봤지만...

쉐이더에 대해 아는게 너무 없어서인지 뾰족한 수가 없었다.

 

그래서 버텍스를 확장하지 않고, 1Pass때 그리는 버텍스를 y축으로 조금 이동시키기로 했다.

void vert(inout appdata_full v) {
             v.vertex.y = v.vertex.y + 0.05f;
        }

 

이렇게 만들면 아래쪽은 외각선이 없어지지만, 어차피 윗쪽만 외각선이 필요하기에 이렇게 만들기로 했다. ^__^

 

Shader "Custom/GroundShader"
{
    Properties
    {
        _Color ("Color", Color) = (1,1,1,1)
        _MainTex ("Albedo (RGB)", 2D) = "white" {}

    }
    SubShader
    {
        Tags { "RenderType"="Opaque"}
        LOD 200


        //1Pass
        CGPROGRAM
        #pragma surface surf Standard vertex:vert noshadow no ambient

        sampler2D _MainTex;
        fixed4 _Color;

        void vert(inout appdata_full v) {
             v.vertex.y = v.vertex.y + 0.05f;
        }

        struct Input
        {
            float2 uv_MainTex;
        };

        void surf (Input IN, inout SurfaceOutputStandard o)
        {
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
            o.Emission = float4(0.15, 0.001, 0, 1);
            o.Alpha = c.a;
        }
        ENDCG

      
        //2Pass
        CGPROGRAM
        #pragma surface surf Standard 

        sampler2D _MainTex;
        fixed4 _Color;

        struct Input
        {
            float2 uv_MainTex;
        };
        
        void surf(Input IN, inout SurfaceOutputStandard o)
        {
            fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
            o.Emission = c.rgb;
            o.Alpha = c.a;
        }
        ENDCG
    }
    FallBack "Diffuse"
}