티스토리 뷰

Unity/Shader

Fragment Shader

연홍 2021. 1. 21. 12:54
728x90

프래그먼트 셰이더는 픽셀 출력 (알파 포함)의 색상을 결정합니다. unlit셰이더의 경우 이것은 상당히 단순한 단색이거나 입력 텍스처를 샘플링하여 얻은 색상 일 수 있습니다. 조명 셰이더의 경우 조금 더 복잡하지만 URP는 조명 섹션에서 살펴볼 몇 가지 편리한 기능을 제공합니다.

 

프래그먼트 셰이더가 수신하는 Varyings데이터는 프래그먼트가 속한 삼각형을 구성하는 세 개의 정점 사이에 선형 보간됩니다. 이것이 바로 정점 셰이더에서 삼각형의 각 정점에 대해 (1,0,0), (0,1,0)(0,0,1)을 출력 할 수있는 이유입니다. 그러나 프래그먼트에서는 다음과 같은 결과를 얻게됩니다.

이 데이터가 노멀 용 (lighting/shading에 사용됨) 인 경우 보간으로 인해 값이 더 이상 단위 벡터가 아님을 알 수 있습니다. 예 : 이 결과는 무게 중심 좌표계와 유사하므로 중심점은 크기가 1 인 단위 벡터가 아니라 크기가 약 0.577 인 (0.33,0.33,0.33)입니다.이 때문에 법선을 정규화해야합니다. (normalize function) 사용하기 전에 프래그먼트단계에서, 각 vertex의 법선이 매우 다른 극단적 인 경우입니다. 대부분의 경우 크기는 1에 가까워서 셰이더의 복잡성을 줄이기 위해 건너 뛸 수 있습니다. (예 : 낮은 품질 설정 용).

 

현재 셰이더는 Unlit이므로 필요한 것은 다음과 같습니다.

half4 frag(Varyings IN) : SV_Target {
    half4 baseMap = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, IN.uv);
 
    return baseMap * _BaseColor * IN.color;
}

이렇게하면 _BaseColor 및 정점 색상 (IN.color)으로 착색 된 _BaseMap 텍스처를 기반으로 half4 색상을 출력하는 셰이더가 생성됩니다.

 

SV_Target 부분은 half4 출력과 함께 사용할 의미 체계로, 셰이더에게 색상 출력임을 알려줍니다. 픽셀 당 Z 버퍼 값을 재정의하는 데 사용되는 부동 소수점 인 SV_Depth 출력도 있습니다. (SV_Target 및 SV_Depth를 모두 출력하기 위해 구조체에 넣을 수 있습니다). 대부분의 경우이를 재정의 할 필요가 없으며이 Unity 문서 페이지에 따르면 많은 GPU의 경우 일부 깊이 버퍼 기반 최적화가 꺼 지므로 수행중인 작업과 필요한 작업을 알지 못하는 경우 재정의하지 마십시오.

 

프래그먼트 셰이더는 텍스처, 샘플러 및 UV를 입력으로 사용하는 URP ShaderLibrary에서 제공하는 SAMPLE_TEXTURE2D 매크로를 사용하여 _BaseMap 텍스처를 샘플링합니다.

 

알파 값이 특정 임계 값 미만인 경우 픽셀을 버리고 전체 메시가 표시되지 않도록하는 것도 우리가 원할 수있는 작업입니다. 쿼드의 잔디 / 잎 텍스처 용. 이것은 투명뿐만 아니라 불투명 한 셰이더에서도 수행 할 수 있으며 일반적으로 알파 클립 / 컷오프라고합니다. 셰이더 그래프에 익숙하다면 마스터 노드의 Alpha Clip Threshold 입력으로 처리됩니다.

이를 처리하는 일반적인 방법은 임계 값을 제어하는 _Cutoff 속성을 제공하고 다음을 수행하는 것입니다. (이 속성은 SRP Batcher 호환성을 위해 UnityPerMaterial CBUFFER뿐만 아니라 Shaderlab 속성에 추가되어야합니다.)

if (_BaseMap.a < _Cutoff){
    discard;
}
// OR
clip(_BaseMap.a - _Cutoff);
// inside the fragment function, before returning
// Example Shader for Universal RP
// Written by @Cyanilux
// https://cyangamedev.wordpress.com/urp-shader-code/
Shader "Custom/UnlitShaderExample" {
	Properties {
		_BaseMap ("Example Texture", 2D) = "white" {}
		_BaseColor ("Example Colour", Color) = (0, 0.66, 0.73, 1)
		//_ExampleDir ("Example Vector", Vector) = (0, 1, 0, 0)
		//_ExampleFloat ("Example Float (Vector1)", Float) = 0.5
	}
	SubShader {
		Tags { "RenderType"="Opaque" "RenderPipeline"="UniversalPipeline" }
 
		HLSLINCLUDE
			#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
 
			CBUFFER_START(UnityPerMaterial)
			float4 _BaseMap_ST;
			float4 _BaseColor;
			//float4 _ExampleDir;
			//float _ExampleFloat;
			CBUFFER_END
		ENDHLSL
 
		Pass {
			Name "Example"
			Tags { "LightMode"="UniversalForward" }
 
			HLSLPROGRAM
			#pragma vertex vert
			#pragma fragment frag
 
			struct Attributes {
				float4 positionOS	: POSITION;
				float2 uv		: TEXCOORD0;
				float4 color		: COLOR;
			};
 
			struct Varyings {
				float4 positionCS 	: SV_POSITION;
				float2 uv		: TEXCOORD0;
				float4 color		: COLOR;
			};
 
			TEXTURE2D(_BaseMap);
			SAMPLER(sampler_BaseMap);
 
			Varyings vert(Attributes IN) {
				Varyings OUT;
 
				VertexPositionInputs positionInputs = GetVertexPositionInputs(IN.positionOS.xyz);
				OUT.positionCS = positionInputs.positionCS;
				// Or this :
				//OUT.positionCS = TransformObjectToHClip(IN.positionOS.xyz);
				OUT.uv = TRANSFORM_TEX(IN.uv, _BaseMap);
				OUT.color = IN.color;
				return OUT;
			}
 
			half4 frag(Varyings IN) : SV_Target {
				half4 baseMap = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, IN.uv);
 
				return baseMap * _BaseColor * IN.color;
			}
			ENDHLSL
		}
	}
}

 

'Unity > Shader' 카테고리의 다른 글

Lighting Introduction  (0) 2021.01.22
Keywords & Shader Variants  (0) 2021.01.22
Vertex Shader  (0) 2021.01.21
Post Processing in the Universal RP  (0) 2021.01.20
Structs  (0) 2021.01.20
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/10   »
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 31