URP Pass tags: LightMode (ShaderTag)
Unity가 주어진 프레임 동안 패스를 실행할지,
프레임 동안 Unity가 패스를 실행하는 시기 및 Unity가 출력으로 수행하는 작업을 결정하는 데
사용하는 미리 정의된 패스 태그입니다.
조명의 모드와는 상관없습니다.
“LightMode” = “[value]” 형식으로 사용하며,
유니티에서 기본적으로 사용하는 태그는 다음과 같습니다.
Custom LightMode
이걸 이제 마음대로 설정해서 사용할 수 있습니다.
ShaderLab에서 사용하는 기능이므로 HLSLPROGRAM 정의 전에 설정합니다.
그다음 렌더설정을 합니다.
일단 기본렌더링에서 Prop을 제외합니다.
시각적으로 확실한 테스트를 위해서요.
그다음 렌더설정을 합니다.
그러면 깊이검사가 큰 값들은
다음과 같이 CustomPass라고 명명한 태그를 사용한
다른 패스를 사용해서 그릴 수 있음을 확인할 수 있습니다.
ShdaerLab Properties Attribute
대략적인 구성에 대한 내용은 저번주차에서 했으니 넘어가겠습니다.
[MainColor]와 [MainTexture]는 무엇일까요? 이런 [어쩌구]를 보통 Attribute라고 일컫습니다.
정리해보면 다음과 같습니다
[Gamma]
float 또는 vector 속성이 sRGB 값을 사용함을 나타냅니다.
즉, 프로젝트의 색상 공간에서 이를 요구하는 경우 다른 sRGB 값과 함께 변환해야 합니다.
[HDR]
텍스처 혹은 색상속성이 HDR을 사용함을 나타냅니다.
텍스처 프로퍼티의 경우 LDR 텍스처가 할당되면 Unity 편집기에 경고가 표시됩니다.
색상 프로퍼티의 경우 Unity 편집기는 HDR 색상 선택기를 사용하여 이 값을 편집합니다.
[HideInInspector]
말 그대로 인스펙터에서 표시하지 않습니다.
[MainTexture] & [MainColor]
코드나 애니메이터 등에서 머테리얼에 접근하면 몇가지 수정할 수 있는 값들이 있습니다.
바로 Material.mainTexture와 Materia.color입니다.
기본값은 _MainTex와 _Color 로 선언된 프로퍼티지만, 해당 어트리뷰트를 통해 대상을 변경할 수 있습니다.
중복 사용시 처음 사용된 프로퍼티를 적용합니다.
[NoScaleOffset]
이 텍스처 속성에 대한 타일링 및 오프셋 필드를 숨기도록 Unity 편집기에 지시합니다.
_BaseMap_ST를 적용하지 않을 때, 애초에 숨겨버리자는 것이죠.
[Normal]
텍스처 속성에 노멀 맵이 필요함을 나타냅니다.
호환되지 않는 텍스처를 할당하면 Unity 에디터에 경고가 표시됩니다.
[PerRendererData]
텍스처 프로퍼티가 렌더러별 데이터에서 MaterialPropertyBlock 형태로 나올 것임을 나타냅니다.
머티리얼 인스펙터는 이러한 속성을 읽기 전용으로 표시합니다.
Tags
RenderPipeline tag
“RenderPipeline” = “[name]”
이것에 대해서는
UniversalRenderPipeline,HighDefinitionRenderPipeline 등이 될 수 있습니다.
Queue
“Queue” = “[queue name]”
“Queue” = “[queue name] + [offset]”
과 같은 형식으로 사용합니다. 강의에는 숫자도 넣을 수 있다고 말씀하셨는데.. 잘 모르겠습니다?
아무튼 해당하는queue name은 익숙한 그것들입니다.
Background (1000)
Geometry (2000)
AlphaTest (2450)
여기까지 불투명(2500이하)
Transparent(3000)
Overlay(4000)
즉 “Queue” = “Transparent+5”
이런식으로 선언할 수 있다는 것입니다.
RenderType
“RenderType” = “[renderType]”
어떤방식으로 렌더링 할 것인지를 지정합니다.
대게 Opaque, Transparent를 사용하며, 기타 아래의 것들이 존재합니다.
여기부터는 이제 살짝 쓸모없습니다.
ForceNoShadowCasting
“ForceNoShadowCasting” = “[boolean]”
그림자를 받을지에 대한 여부입니다.
기본값은 false이며, true로 한다면 Forward(URP,HDRP-Forward), Legacy Vertex Lit(레거시 렌더파이프라인의 버텍스라이트), Legacy Deferred에서 그림자를 받는걸 방지합니다.
DisableBatching
“DisableBatching” = “[state]”
DynamicBatching을 방지합니다.
모델링 공간에서 연산을 처리할땐 필요할 수 있습니다.
IgnoreProjector
“IgnoreProjector” = “[boolean]”
true로 설정하면 프로젝터의 영향을 받지 않습니다.
PreviewType
“PreviewType” = “[shape]” (Sphere, Plane, Skybox)
유니티 에디터에서 보여지는 프리뷰의 형태를 결정합니다..
CanUseSpriteAtlas
“CanUseSpriteAtlas” = “[boolean]”
원본 텍스처 좌표에 의존하므로, 스프라이트 패킹(텍스쳐 아틀라스를 제작)을 할 경우 텍스쳐 좌표가 꼬여 이상해 질 수 있습니다.
따라서 해당 서브쉐이더를 사용하는 스프라이트는 패킹되지 않습니다
Lambert
패스를 배웠으니 써먹어 볼 것 입니다.
1.라이트를 가져와야합니다.
2.노말을 가져와야합니다.
3.끝났네요.
자 하나하나 해봅시다.
라이트는 어디에 있나 하니
RealtimeLights.hlsl에 들어있습니다.
가져옵니다.
컴파일오류를 냅니다
대충 읽어보니 undeclared identifier ‘LerpWhiteTo’ 라고합니다.
저 함수는 무엇일까요?
UnityStandardUtils를 가져오지 못한 것 같습니다.
그런데 저함수만 있으면 되는게 아닌가?
복붙해서 구현합니다.
그다음은 뭐.. IA에서 가져온 오브젝트의 노말 정보를 버텍스 쉐이더에서 빛과 연산한 다음,
Varyings을 통해 버텍스 쉐이더에서 픽셀 쉐이더로 TEXCOORD1을 사용해 이동합니다.
대충 곱합니다.
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
Pass
{
Name "Lambert"
Tags {"LightMode" = "Lambert"}
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
//RealtimeLights.hlsl -> Shadows.hlsl throw Exception : undeclared identifier 'LerpWhiteTo' (UnityStandardUtils)
//therefore. declare LerpWhiteTo (*^^*)
//사실 Lighting.hlsl을 include하면 됩니다
half3 LerpWhiteTo(half3 b, half t)
{
half oneMinusT = 1 - t;
return half3(oneMinusT, oneMinusT, oneMinusT) + b * t;
}
//include
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
//for Get Main Light
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/RealtimeLights.hlsl"
struct Input
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
float3 normal : NORMAL;
};
struct Varyings
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
float diffuse : TEXCOORD1;
};
//properties
TEXTURE2D(_MainTex);
SAMPLER(sampler_MainTex);
//constant buffer
CBUFFER_START(UnityPerMaterial)
float4 _MainTex_ST; //scale.x,scale.y,offset.x,offset.y
CBUFFER_END
Varyings vert(Input v)
{
Varyings o;
o.vertex = TransformObjectToHClip(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
//getLightDirection
Light mainLight = GetMainLight();
float3 worldNormal = TransformObjectToWorldNormal(v.normal);
float nDotl = dot(worldNormal, mainLight.direction);
o.diffuse = saturate(nDotl);
return o;
}
half4 frag(Varyings IN) : SV_Target
{
half4 color = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, IN.uv);
float diffuse = ceil( IN.diffuse * 4 ) * 0.25f;
color *= diffuse;
return color;
}
ENDHLSL
}
텍스처의 색상만 렌더링 했을 때
램버트 라이팅 모델 적용
돌려봄
참조
https://docs.unity3d.com/Manual/SL-PassTags.html
https://docs.unity3d.com/Manual/SL-SubShaderTags.html
https://docs.unity3d.com/2021.2/Documentation/Manual/SL-Properties.html