250405

lililllilillll·2025년 4월 5일

개발 일지

목록 보기
132/350

✅ What I did today


  • Udemy Course : Unity Shader


🎞️ Udemy Course : Unity Shader


Glass with distortion

Shader "Holistic/Glass"
{
    Properties
    {
        _MainTex("Texture", 2D) = "white" {}
        _BumpMap("Normalmap", 2D) = "bump" {}
        _ScaleUV("Scale", Range(1,1000)) = 1
    }
    SubShader
    {
        Tags{"Queue" = "Transparent"}
        GrabPass{}
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            
            #include "UnityCG.cginc"

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

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 uvgrab : TEXCOORD1;
                float2 uvbump : TEXCOORD2;
                float4 vertex : SV_POSITION;
            };

            sampler2D _GrabTexture;
            float4 _GrabTexture_TexelSize;
            sampler2D _MainTex;
            float4 _MainTex_ST;
            sampler2D _BumpMap;
            float4 _BumpMap_ST;
            float _ScaleUV;

            v2f vert (appdata v)
            {
                v2f o;
                // vertex의 좌표를 클립 공간으로 변환
                o.vertex = UnityObjectToClipPos(v.vertex);

                // 그래픽 API별 Y축 방향 차이를 보정
                #if UNITY_UV_STARTS_AT_TOP
                float scale = -1.0;
                #else
                float scale = 1.0;
                #endif
                
                // 투영 좌표 : z(깊이)가 커질수록 → x/w, y/w 값이 작아지게 하여 원근감 표현
                // 클립 공간의 x, y를 변환하여 투영 텍스쳐 좌표 생성
                o.uvgrab.xy = (float2(o.vertex.x, o.vertex.y*scale) + o.vertex.w) * 0.5;
                // tex2Dproj 호출에 필요한 z/w 보간과 w 값 보존을 위해 그대로 전달
                o.uvgrab.zw = o.vertex.zw;
                // 텍스쳐 uv에 타일링과 오프셋 적용
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                o.uvbump = TRANSFORM_TEX(v.uv, _BumpMap);
                return o;
            }

            // SV_Target: 픽셀 셰이더의 반환값이 최종 화면(또는 렌더 타겟)의 픽셀 색상임을 명시
            fixed4 frag (v2f i) : SV_Target
            {
                half2 bump = UnpackNormal(tex2D(_BumpMap, i.uvbump)).rg;
                // _GrabTexture_TexelSize.xy는 UV 기준으로 "1픽셀"이 얼마인지를 알려주는 값이며,
                // 이걸 곱해야 왜곡 효과가 해상도에 관계없이 자연스럽게 작동
                float2 offset = bump * _ScaleUV * _GrabTexture_TexelSize.xy;
                i.uvgrab.xy = offset * i.uvgrab.z + i.uvgrab.xy;

                // tex2Dproj : 투영 텍스쳐 좌표를 이용해 샘플링
                fixed4 col = tex2Dproj(_GrabTexture, i.uvgrab);
                float4 tint = tex2D(_MainTex, i.uv);
                col *= tint;
                return col;
            }
            ENDCG
        }
    }
}

tex2D와 tex2DProj의 차이

항목tex2Dtex2Dproj
입력 타입float2 (UV)float4 (투영 좌표)
내부 동작그대로 사용(x / w, y / w)로 계산
보간 방식선형 보간 (float2 기준)투영 보간 (정점 간의 w 보정 포함)
사용 목적일반적인 UV 샘플링GrabPass, Projector, ShadowMap 등 투영 필요 시
필요 조건일반 텍스처 좌표만 있으면 됨클립 공간 또는 투영 좌표 필요
예시 사용일반 메시 텍스처, 라이트맵 등화면 왜곡, 그림자 투사, 스크린 공간 이펙트 등

시스템 예약 시맨틱(System Semantic)
: 각 셰이더 단계에서 "이 값이 어떤 용도로 쓰이는지" GPU에게 알려준다.

시맨틱의미
SV_Position정점 셰이더의 출력 위치 (클립 공간)
SV_Target픽셀 셰이더의 출력 색상
SV_Depth픽셀 셰이더가 직접 깊이값을 쓸 때
SV_VertexID정점 인덱스
SV_InstanceID인스턴싱된 개체의 ID


profile
너 정말 **핵심**을 찔렀어

0개의 댓글