Unity/정보

[Unity] 스텐실 버퍼(Stencil Buffer)

달시_Dalsi 2023. 10. 26. 16:13

스텐실 버퍼 소개

스텐실 버퍼 쉐이더를 이용하여 특정 투명한 물체를 통해서 볼때만 볼 수 있는 물체를 만들고자 한다.

아래 영상을 처음보고 신기하여 만들어 보았다.  

 

https://www.youtube.com/watch?v=4zAt8YKoso4

 

위 영상을 기반으로 만든것이 아니라 좀 더 자세히 알고 싶어서 아래 주소를 알아내어 따라해봤다.

https://www.alanzucconi.com/2015/12/09/3873/

 


주요 기능

1. StencilGeometry (보여지는 물체)

Shader "Stencils/StencilGeometry" {
	Properties {
		_StencilMask("Stencil Mask", Int) = 0

		_Color ("Color", Color) = (1,1,1,1)
		_MainTex ("Albedo (RGB)", 2D) = "white" {}
		_Glossiness ("Smoothness", Range(0,1)) = 0.5
		_Metallic ("Metallic", Range(0,1)) = 0.0
	}
	SubShader {
		Tags { "RenderType"="Opaque" }
		LOD 200
		Stencil
		{
			Ref[_StencilMask]
			Comp equal
			Pass keep
			Fail keep
		}

		CGPROGRAM
		// Physically based Standard lighting model, and enable shadows on all light types
		#pragma surface surf Standard fullforwardshadows

		// Use shader model 3.0 target, to get nicer looking lighting
		#pragma target 3.0

		sampler2D _MainTex;

		struct Input {
			float2 uv_MainTex;
		};

		half _Glossiness;
		half _Metallic;
		fixed4 _Color;

		void surf (Input IN, inout SurfaceOutputStandard o) {
			// Albedo comes from a texture tinted by color
			fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
			o.Albedo = c.rgb;
			// Metallic and smoothness come from slider variables
			o.Metallic = _Metallic;
			o.Smoothness = _Glossiness;
			o.Alpha = c.a;
		}
		ENDCG
	} 
	FallBack "Diffuse"
}

 

2. StencilMask (보여주는 물체)

Shader "Stencils/StencilMask"
{
	Properties
	{
		_StencilMask("Stencil Mask", Int) = 0
	}
	SubShader
	{
		Tags
		{
			"RenderType" = "Opaque"
			"Queue" = "Geometry-100"
		}
		ColorMask 0
		ZWrite off
		Stencil
		{
			Ref[_StencilMask]
			Comp always
			Pass replace
		}

		Pass
		{
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag

			struct appdata
			{
				float4 vertex : POSITION;
			};

			struct v2f
			{
				float4 pos : SV_POSITION;
			};

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

			half4 frag(v2f i) : COLOR
			{
				return half4(1,1,0,1);
			}
			ENDCG
		}
	}
}

 

사용법 안내

우선 창문 역할을 할 물체를 생성 시켜준다. 뭐든 된다. 그 크기 만큼 마스크해서 보여주기 때문이다. 편하게 Quad을 생성하고 여기에 StencilMask 쉐이더를 입혀줬다. 그리고 Stencil Mask를 1로 변경했다.

 

그리고 그 뒤에 보여질 물체에 StencilGeometry 쉐이더를 넣고 Stencil Mask 값을 마스크와 동일하게 하면 된다.

같은 값을 가진 쉐이더끼리 반응한다.

 

이걸 반복하여 아래와 같은 결과를 만들었다.

 

만일 아래사진과 같이 화면에 겹친 상황이 되고 뚫려 보인다면 랜더 큐를 변경해주자.

 

'Unity > 정보' 카테고리의 다른 글

[Unity] DOTween 사용하기  (0) 2023.11.27
[Unity] 구글 스프레드시트 연동  (0) 2023.11.14
[Unity] Boids 군집 알고리즘  (0) 2023.10.16
[Unity] 고급네비메쉬  (0) 2023.09.23
[Unity] Poisson Disk Sampling  (0) 2023.09.16