상세 컨텐츠

본문 제목

유니티 UnlitShader 코드 분석(렌더링 파이프라인 기반)

Tech/Unity 유니티

by 2024. 1. 31. 13:30

본문

이번 글에서는 유니티 Unlit 쉐이더 코드를 분석해볼 것이다.

직접 짜기는 어려울 수 있지만, 쉐이더 코드를 보면서 이건 이 부분이구나! 를 이해하면

나중에도 그래픽 관련해서 파악하기 쉬울 것 같아 정리한다.

 

유니티 버전은 2021.3.13f1 을 사용하였다.

 

Unlit 쉐이더를 생성하면, 다음과 같이 스크립트가 생성된다.

 

Shader "Unlit/NewUnlitShader"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

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

            #include "UnityCG.cginc"

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

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

            sampler2D _MainTex;
            float4 _MainTex_ST;

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

            fixed4 frag (v2f i) : SV_Target
            {
                // sample the texture
                fixed4 col = tex2D(_MainTex, i.uv);
                // apply fog
                UNITY_APPLY_FOG(i.fogCoord, col);
                return col;
            }
            ENDCG
        }
    }
}

 

 

이전에 공부했던 렌더링 파이프라인 개념을 참고해서 코드를 간단히 이해해보자.

 

https://techtoart.tistory.com/142

 

쉐이더(Shader) 와 랜더링 파이프라인(Rendering Pipeline)

쉐이더(Shader) 쉐이더(Shader)는 픽셀의 색을 정하는 함수를 말한다. 그치만 조금 더 아트 관점의 시각을 첨가해서 말하면, 쉐이더(Shader)는 오브젝트의 음영과 색상을 계산하여 다양한 재질을 표현

techtoart.tistory.com

 

 

 

먼저 쉐이더 코드의 가장 위에는 쉐이더 이름이 표시된다.

Shader "Unlit/NewUnlitShader"
{
}

 

Unlit/NewUnlitShader 이므로, Unlit 이라는 카테고리 아래 NewUnlitShader 의 이름으로 쉐이더가 생기게 된다.

 

 

 

 

그 아래에는 다음과 같은 Properties 코드가 있다.

쉐이더가 가지는 속성들을 표시한 곳이다.

    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
    }

 

_MainTex 속성, 즉 메인텍스처라는 속성을 갖는다는 뜻이고,

이 쉐이더를 메터리얼에 적용시켜보면 "Texture"라는 이름으로 저 속성이 Inspector에 뜨게 된다.

 

Unlit/NewUnlitShader 매터리얼 정보

 

 

 

 

 

다음은 SubShader라는 구역 안에 Tags로 RenderType과 LOD 정보를 적어주고 있다.

 

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

 

 

 

그 밑에는 Pass 라는게 있다.

Pass는 여러 개 가질 수 있다.

 

그리고 CGPROGRAM ... ENDCG 라는 것이 있는데

이 안에 CG 라는 쉐이더 언어로 작성하는 것이다.

 

그 외 나머지 스크립트는 ShaderLab 코드로 되어있고, 이 부분만 쉐이더 코드로 짜여진 부분이다.

SubShader
{
    Pass
    {
        CGPROGRAM
        ...
        ENDCG
    }
}

 

 

그리고 버텍스 함수랑 프래그먼트 함수가 정의되어있다.

 

    #pragma vertex vert
    #pragma fragment frag

 

 

렌더링 파이프라인에서 공부했던 것처럼 렌더링 순서는

 

1. 버텍스함수에서 좌표변환

2. 프래그먼트함수에서 색상결정

 

으로 나눌 수 있는데

 

이 둘을 쉐이더 스크립트에서 정의해주는 것이다.

 

먼저 appdata라는 이름으로 버텍스 정보와 그에 따른 uv가 정의되어 있다.

그리고 v2f라는 이름으로 버텍스에서 프래그먼트로 보내는 중간 매개체가 정의되어 있다.

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };
            
            
            struct v2f
            {
                float2 uv : TEXCOORD0;
                UNITY_FOG_COORDS(1)
                float4 vertex : SV_POSITION;
            };

 

 

 

다음은 버텍스 쉐이더 함수와 프래그먼트 쉐이더 함수 정의 부분이다.

버텍스 쉐이더 함수에서는 카메라에 보이는 부분을 Clip 하고, ViewModelProjection 을 통해 좌표를 변환하고

프래그먼트 쉐이더 함수에서는 픽셀이 화면에 어떻게 보일지 그 색상 위주로 결정하고 있는 것을 알 수 있다.

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

            fixed4 frag (v2f i) : SV_Target
            {
                // sample the texture
                fixed4 col = tex2D(_MainTex, i.uv);
                // apply fog
                UNITY_APPLY_FOG(i.fogCoord, col);
                return col;
            }

관련글 더보기