Home 8. Lambert와 ShaderLab
Post
Cancel

8. Lambert와 ShaderLab

URP Pass tags: LightMode (ShaderTag)


Unity가 주어진 프레임 동안 패스를 실행할지,

프레임 동안 Unity가 패스를 실행하는 시기 및 Unity가 출력으로 수행하는 작업을 결정하는 데

사용하는 미리 정의된 패스 태그입니다.

조명의 모드와는 상관없습니다.

“LightMode” = “[value]” 형식으로 사용하며,

유니티에서 기본적으로 사용하는 태그는 다음과 같습니다.

Untitled

Custom LightMode

이걸 이제 마음대로 설정해서 사용할 수 있습니다.

ShaderLab에서 사용하는 기능이므로 HLSLPROGRAM 정의 전에 설정합니다.

Untitled

그다음 렌더설정을 합니다.

일단 기본렌더링에서 Prop을 제외합니다.

시각적으로 확실한 테스트를 위해서요.

Untitled

그다음 렌더설정을 합니다.

Untitled

그러면 깊이검사가 큰 값들은

Untitled

다음과 같이 CustomPass라고 명명한 태그를 사용한

다른 패스를 사용해서 그릴 수 있음을 확인할 수 있습니다.

ShdaerLab Properties Attribute


대략적인 구성에 대한 내용은 저번주차에서 했으니 넘어가겠습니다.

hlsl Anatomy 2.png

[MainColor]와 [MainTexture]는 무엇일까요? 이런 [어쩌구]를 보통 Attribute라고 일컫습니다.

정리해보면 다음과 같습니다

[Gamma]

float 또는 vector 속성이 sRGB 값을 사용함을 나타냅니다.

즉, 프로젝트의 색상 공간에서 이를 요구하는 경우 다른 sRGB 값과 함께 변환해야 합니다.

[HDR]

텍스처 혹은 색상속성이 HDR을 사용함을 나타냅니다.

텍스처 프로퍼티의 경우 LDR 텍스처가 할당되면 Unity 편집기에 경고가 표시됩니다. 

색상 프로퍼티의 경우 Unity 편집기는 HDR 색상 선택기를 사용하여 이 값을 편집합니다.

[HideInInspector]

말 그대로 인스펙터에서 표시하지 않습니다.

[MainTexture] & [MainColor]

코드나 애니메이터 등에서 머테리얼에 접근하면 몇가지 수정할 수 있는 값들이 있습니다.

바로 Material.mainTextureMateria.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]”

과 같은 형식으로 사용합니다. 강의에는 숫자도 넣을 수 있다고 말씀하셨는데.. 잘 모르겠습니다?

Untitled

아무튼 해당하는queue name은 익숙한 그것들입니다.

Background (1000)

Geometry (2000)

AlphaTest (2450)

여기까지 불투명(2500이하)

Transparent(3000)

Overlay(4000)

즉 “Queue” = “Transparent+5”

이런식으로 선언할 수 있다는 것입니다.

RenderType

“RenderType” = “[renderType]”

어떤방식으로 렌더링 할 것인지를 지정합니다.

대게 Opaque, Transparent를 사용하며, 기타 아래의 것들이 존재합니다.

Untitled

여기부터는 이제 살짝 쓸모없습니다.

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


패스를 배웠으니 써먹어 볼 것 입니다.

Untitled

1.라이트를 가져와야합니다.

2.노말을 가져와야합니다.

3.끝났네요.

자 하나하나 해봅시다.

라이트는 어디에 있나 하니

Untitled

RealtimeLights.hlsl에 들어있습니다.

가져옵니다.

컴파일오류를 냅니다

Untitled

대충 읽어보니 undeclared identifier ‘LerpWhiteTo’ 라고합니다.

저 함수는 무엇일까요?

Untitled

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

https://docs.unity3d.com/Packages/com.unity.render-pipelines.universal@11.0/manual/urp-shaders/urp-shaderlab-pass-tags.html#urp-pass-tags-lightmode

This post is licensed under CC BY 4.0 by the author.
Contents