# 2-3 [Transparent Shader, Culling]

Ricon·2024년 8월 7일

URP Shader Basic

목록 보기
8/17

본 게시물은 Unity Korea 채널의 URP Shader Training 시리즈와 강의에 사용된 도큐먼트를 공부하며 정리한 게시물입니다.

강의 링크
도큐먼트 링크


Transparent Shader란?

해당 픽셀의 값을 알파값에 따라 덧 그려 반투명으로 그려진다.
자동으로 정렬되는 2500까지의 Shader와 달리 해당 쉐이더부턴 사용자가 렌더큐를 직접 관리해야함.

모든 Shader가 실행되고, 모든 Texture가 적용된 후 픽셀이 화면에 작성되게 되며, 이런 Pixel이 기존 Pixel에 결합되는 방법은 Blend Command(Operation)으로 제어하게 됨.

Blending 과정은 아래와 같이 AlphaTest가 수행된 이후 진행함.

// Shader 시작. 셰이더의 폴더와 이름을 여기서 결정합니다.
Shader "URPTraining/07_Transparent"
{
	Properties
	{
		// Properties Block : 셰이더에서 사용할 변수를 선언하고 이를 material inspector에 노출시킵니다
		_TintColor("Test Color", Color) = (1, 1, 1, 1)
		_Intensity("Range Sample", Range(0, 1)) = 0.5
		_MainTex("Main Texture", 2D) = "white"{}
		_Alpha("Alpha", Range(0, 1))= 0.5 
	}

	SubShader
	{
		Tags
		{
			//Render type과 Render Queue를 여기서 결정합니다.
			"RenderPipeline" = "UniversalPipeline"
			"RederType" = "Transparent"
			"Queue" = "Transparent"
		}
		Pass
		{
			Blend SrcAlpha OneMinusSrcAlpha //Traditional transparency

			Name "Universal Forward"
			Tags { "LightMode" = "UniversalForward"}

			HLSLPROGRAM
			#pragma prefer_hlslcc gles
			#pragma exclude_renderers d3d11_9x
			#pragma vertex vert
			#pragma fragment frag

			//cg shader는 .cginc를 hlsl shader는 .hlsl을 include하게 됩니다.
			#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"

			//vertex buffer에서 읽어올 정보를 선언합니다. 
			struct VertexInput
			{
				float4 vertex	: POSITION;
				float2 uv		: TEXCOORD0;
			};

			//보간기를 통해 버텍스 셰이더에서 픽셀 셰이더로 전달할 정보를 선언합니다.
			struct VertexOutput
			{
				float4 vertex	: SV_POSITION;
				float2 uv		: TEXCOORD0;
			};

			half4 _TintColor;
			float _Intensity;

			float4 _MainTex_ST;
			Texture2D _MainTex;
			SamplerState sampler_MainTex;

			float _Alpha;

			//버텍스 셰이더
			VertexOutput vert(VertexInput v)
			{
				VertexOutput o;
				o.vertex = TransformObjectToHClip(v.vertex.xyz);
				o.uv = v.uv.xy * _MainTex_ST.xy + _MainTex_ST.zw;

				return o;
			}
			
			//픽셀 셰이더
			half4 frag(VertexOutput i) : SV_TARGET
			{
				float4 color = _MainTex.Sample(sampler_MainTex, i.uv);

				color.rgb *= _TintColor * _Intensity;
				color.a = color.a * _Alpha;

				return color;
			}

			ENDHLSL
		}
	}
}

Blend Operation 선언

Blend Operation은 해당 픽셀을 그릴때 앞에 그려진 픽셀과 현재 픽셀을 어떻게 계산할 것인지를 선언하는 과정.

Blend SrcFactor DstFactor
Src(Source)는 계산된 컬러, Dst(Destination)은 이미 화면에 표시된 컬러

일반적인 Blend Operation type
Blend SrcAlpha OneMinusSrcAlpha //Traditional transparency
Blend One OneMinusSrcAlpha // Premultiplied transparency
Blend One One // Additive
Blend OneMinusDstColor One // Soft Additive
Blend DstColor Zero // Multiplicative
Blend DstColor SrcColor // 2x Multiplicative

Blend Operation 인자 계산은 아래와 같다

인자설명
One1값. Src 또는 Dst 컬러가 완전히 표시되도록 하려면 One 사용
Zero0값. Src 또는 Dst 값을 제거하려면 Zero 사용
SrcColor스테이지 값을 Src Color값으로 곱함
SrcAlpha스테이지 값을 Src Alpha값으로 곱함
DstColor스테이지 값을 프레임 버퍼 Src Color값으로 곱함
DstAlpha스테이지 값을 프레임 버퍼 Src Alpha값으로 곱함
OneMinusSrcColor스테이지 값을 (1-SrcColor)값으로 곱함
OneMinusSrcAlpha스테이지 값을 (1-SrcAlpha)값으로 곱함
OneMinusDstColor스테이지 값을 (1-DstColor)값으로 곱함
OneMinusDstAlpha스테이지 값을 (1-DstAlpha)값으로 곱함

예시

Shader에서 Enum으로 api를 불러와 제어할 수 있음

Properties
{
	// Properties Block : 셰이더에서 사용할 변수를 선언하고 이를 material inspector에 노출시킵니다
	//중략
	[Enum(UnityEngine.Rendering.BlendMode)] _SrcBlend ("Src Blend", Float) = 1
	[Enum(UnityEngine.Rendering.BlendMode)] _DstBlend ("Dst Blend", Float) = 0

}

SubShader
{
	Tags
	{
		//중략
	}
	Pass
	{
		// Blend Operation 선언
		// Blend Operation은 해당 픽셀을 그릴때 앞에 그려진 픽셀과 현재 픽셀을 어떻게 계산할 것인지를 선언하는 과정.
		Blend [_SrcBlend] [_DstBlend]


Culling

Culling은 화면에 그려지는 삼각형의 앞, 뒷면을 그릴지 여부를 결정하는 방법이다.
기본값은 면이 보여지는 기본 방향이지만, 사용자가 앞면, 뒷면 혹은 양쪽 전부를 그릴 수 있다.

Pass
{
	Blend SrcFactor DstFactor
    Cull Back | Front | off
    
    //중략
}
  • Back : 보는 반대 방향을 그리지 않는다(Default)
  • Front : 보는 방향을 그리지 않는다 (보통 오브젝트를 뒤집는데 사용)
  • Off : 컬링을 비활성화 한다. (앞뒤면을 모두 그린다) (보통 2-Side라고 부르는 양면을 모두 그리는 방식이 이에 해당함. 하지만 양면을 모두 그리면 Triangle Counter도 2배로 늘어남)

Shader에서 Culling Mode를 api를 통해 제어할 수 있음

Properties
{
	// Properties Block : 셰이더에서 사용할 변수를 선언하고 이를 material inspector에 노출시킵니다
	//중략
	[Enum(UnityEngine.Rendering.CullMode)] _Cull ("Cull Mode", Float) = 1

}

SubShader
{
	Tags
	{
		//중략
	}
	Pass
	{
		Cull [_Cull]

Cull Mode : Front

Cull Mode : Back

Cull Mode : Off

0개의 댓글