[Unity] 53. 셰이더(Shader)

Connected Brain·2025년 5월 9일

면접 질문 대비

목록 보기
53/60

셰이더를 활용해본 경험이 있을까요? 어떻게 활용했는지 설명해주세요.

셰이더(Shader)

  • 3D 모델의 정점 위치를 계산하거나 최종 색상을 결정하는데 영향을 주는 프로그램
    = 렌더링 되는 오브젝트의 최종적인 시각적인 형태를 결정

셰이더의 활용

BillboardShader 활용

  • 맵은 3D 오브젝트를, 플레이어는 2D 스프라이트를 사용하는 게임 개발에서 카메라 방향에 따른 스프라이트 왜곡을 방지하기 위해 Billboard 셰이더를 활용
Shader "Custom/Billboard"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
    }

    SubShader
    {
        Tags { "RenderType"="Transparent" "Queue"="Transparent" }
        LOD 100
        Blend SrcAlpha OneMinusSrcAlpha
        ZWrite Off
        Cull Off

        Pass
        {
            HLSLPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

            sampler2D _MainTex;
            float4 _MainTex_ST;

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

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };

            v2f vert(appdata v)
            {
                v2f o;

                // billboard 중심 위치
                float3 center = float3(0, 0, 0);

                // 현재 월드 공간에서 카메라 방향
                float3 camRight = UNITY_MATRIX_V._m00_m01_m02;
                float3 camUp = UNITY_MATRIX_V._m10_m11_m12;

                // 빌보드 오프셋
                float3 worldPos = center + v.vertex.x * camRight + v.vertex.y * camUp;

                // 클립 공간으로 변환
                o.vertex = UnityObjectToClipPos(float4(worldPos, 1));
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                return o;
            }

            fixed4 frag(v2f i) : SV_Target
            {
                return tex2D(_MainTex, i.uv);
            }
            ENDHLSL
        }
    }
}
  • 현재 월드 공간에서의 카메라 위치에 따른 스프라이트 회전을 통해 빌보드를 구현
 #pragma vertex vert // vert 함수가 정점 셰이더 프로그램임을 컴파일러에 지시
#pragma fragment frag // frag 함수가 프래그먼트(픽셀) 셰이더 프로그램임을 컴파일러에 지시
  • 해당 셰이더가 렌더 파이프라인에서 어떤 단계에 사용되어야하는지 명시
  • 이 셰이더는 버텍스 셰이더와 프래그먼트 셰이더를 처리하는 단계에서 사용됨
// 빌보드 오프셋 계산:
// 원래 모델의 정점 위치 (v.vertex)를 사용하여 빌보드 중심(center)으로부터의 상대적인 오프셋을 계산
// v.vertex.x * camRight: 원래 모델의 x축 방향 오프셋을 카메라의 월드 공간 오른쪽 방향으로 변환
// v.vertex.y * camUp: 원래 모델의 y축 방향 오프셋을 카메라의 월드 공간 위쪽 방향으로 변환
// 이렇게 하면 모델의 각 정점은 카메라의 오른쪽과 위쪽 방향을 기준으로 배치되어 항상 카메라를 바라봄
float3 worldPos = center + v.vertex.x * camRight + v.vertex.y * camUp; // 최종 월드 공간 위치
  • 카메라 위치에 따른 정점 위치를 재배치에 항상 카메라를 바라보도록 함

0개의 댓글