Notice
Recent Posts
Recent Comments
Link
«   2025/06   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
Tags
more
Archives
Today
Total
관리 메뉴

1vdlrwnsv1 님의 블로그

유니티 레드토드사이트 셰이더 만들기 본문

Unity 최종

유니티 레드토드사이트 셰이더 만들기

1vdlrwnsv1 2025. 4. 14. 20:47

렌즈를 통해서만 도트(조준점)가 보이도록 구현하는 것이 목적.
즉 유리판을 직접 눈으로 봐야만 도트가 보이고, 그렇지 않으면 안 보이는 시스템.

 

핵심 개념 요약

요소설명
렌즈 유리판 Stencil 값을 기록하는 역할 (Ref 1)
도트(조준점) Always 렌더링 되지만, Stencil 값이 1인 픽셀에서만 보이도록 설정
ZTest Always 도트가 어떤 오브젝트 뒤에 있어도 항상 보이게
Bloom 효과 도트를 빛나게 하기 위한 후처리 효과

 

구현 내용

1. 렌즈용 Shader (RedDot_Lens.shader)

  • 역할: 렌즈 오브젝트에 할당해서 Stencil 버퍼에 Ref=1 기록
  • Shader 특징:
    • Stencil { Ref 1, Comp Always, Pass Replace }
    • Blend SrcAlpha OneMinusSrcAlpha로 유리 느낌 유지

2. 도트용 Shader (RedDot_Dot.shader)

  • 역할: 항상 씬에 존재하지만, 렌즈를 통해서만 보이게
  • Shader 특징:
    • ZTest Always + Blend One One (Additive)
    • Stencil { Ref 1, Comp Equal } → 렌즈 통과 시에만 렌더링
    • _DotColor는 HDR 값 (예: (5, 0, 0, 1))로 세팅 → Bloom으로 빛남

계층 구조 예시

WeaponRoot
├── RedDotSight
│   ├── LensMesh (렌즈 재질 = RedDot_Lens)
│   └── DotPlane (Quad, 재질 = RedDot_Dot)
  • DotPlane: 렌즈보다 살짝 뒤에 위치, 도트의 중심 역할
  • 카메라가 정면에서 렌즈를 통해 DotPlane을 보면 → 도트가 보임

레드도트사이트 렌즈의 셰이더

Shader "Custom/Lens"
{
    Properties
    {
        _Color("Color", Color) = (0.2, 0.5, 0.7, 0.3)
    }
    SubShader
    {
        Tags { "RenderType"="Transparent" "Queue"="Transparent" }
        LOD 100

        Pass
        {
            ZWrite Off
            Blend SrcAlpha OneMinusSrcAlpha
            Stencil
            {
                Ref 1
                Comp Always
                Pass Replace
            }

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

            fixed4 _Color;

            struct appdata
            {
                float4 vertex : POSITION;
            };

            struct v2f
            {
                float4 pos : SV_POSITION;
            };

            v2f vert(appdata v)
            {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
                return o;
            }

            fixed4 frag(v2f i) : SV_Target
            {
                return _Color;
            }
            ENDCG
        }
    }
}

 

파트설명

_Color 유리판의 색.
Tags 렌즈는 반투명 물체니까 "Queue"="Transparent" 로 설정
ZWrite Off 깊이 버퍼에 기록 안 함 (투명 오브젝트는 일반적으로 Off)
Blend SrcAlpha OneMinusSrcAlpha → 알파 투명도 블렌딩
Stencil 이게 핵심!! 렌즈가 지나가는 픽셀에 Ref=1 찍어줌
Comp Always, Pass Replace 무조건 1로 찍음
frag() 단순히 _Color 출력 (렌즈 색깔만 표현)

 

 

레드 도트 셰이더

렌즈를 통해서만 보이는 빨간 점

 

Shader "Custom/RedDotSight"
{
    Properties
    {
        _DotColor ("Dot Color", Color) = (5, 0, 0, 1)
    }

    SubShader
    {
        Tags { "RenderType"="Transparent" "Queue"="Transparent+10" }
        LOD 100

        Pass
        {
            ZTest Always
            ZWrite Off
            Blend One One // Additive
            Cull Off

            Stencil
            {
                Ref 1
                Comp Equal
            }

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

            fixed4 _DotColor;

            struct appdata
            {
                float4 vertex : POSITION;
            };

            struct v2f
            {
                float4 pos : SV_POSITION;
            };

            v2f vert (appdata v)
            {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                return _DotColor;
            }
            ENDCG
        }
    }
}
_DotColor 도트 색상. HDR 값 (5,0,0,1) 주면 Bloom으로 강하게 빛남
"Transparent+10" 렌즈보다 뒤에 그려지도록 렌더 큐 우선순위 조절
ZTest Always 깊이 무시하고 항상 보이게 (렌즈 뒤라도 항상 렌더됨)
Blend One One Additive 블렌딩 → 화면 위에 빛처럼 겹쳐짐
Cull Off 앞/뒤면 다 렌더
Stencil { Ref 1, Comp Equal } Stencil 값이 1인 픽셀에서만 도트 보임 (즉, 렌즈를 통해서만 보임)