Posts Unlit 쉐이더그래프로 만드는 Custom Lit 쉐이더
Post
Cancel

Unlit 쉐이더그래프로 만드는 Custom Lit 쉐이더

목표


  • URP 쉐이더그래프 중 Unlit 그래프를 이용해 직접 Lit 쉐이더 만들기


1. Diffuse 구현


  • 커스텀 함수를 이용하여 메인라이트의 방향, 색상, 감쇠를 얻어낸다.

Custom_Mainlight.hlsl

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
void MainLight_half(float3 WorldPos, out half3 Direction, out half3 Color, out half DistanceAtten, out half ShadowAtten)
{
    #if SHADERGRAPH_PREVIEW
        Direction = half3(0.5, 0.5, 0);
        Color = 1;
        DistanceAtten = 1;
        ShadowAtten = 1;
    #else
        half4 shadowCoord = TransformWorldToShadowCoord(WorldPos);
        Light mainLight = GetMainLight(shadowCoord);
        Direction = mainLight.direction;
        Color = mainLight.color;
        DistanceAtten = mainLight.distanceAttenuation;

        #if !defined(_MAIN_LIGHT_SHADOWS) || defined(_RECEIVE_SHADOWS_OFF)
            ShadowAtten = 1.0h;
        #endif
            ShadowSamplingData shadowSamplingData = GetMainLightShadowSamplingData();
            half shadowStrength = GetMainLightShadowStrength();
            ShadowAtten = SampleShadowmap(shadowCoord,
                TEXTURE2D_ARGS(_MainLightShadowmapTexture, sampler_MainLightShadowmapTexture),
                shadowSamplingData, shadowStrength, false
            );
    #endif
}


  • 주변광을 얻어와야 하므로, 주변광을 얻기 위한 커스텀 함수와 서브 노드를 이용한다.

  • Sub_AdditionalLights

  • 여기에 들어가는 커스텀 함수 :

Custom_AdditionalLights.hlsl

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void AdditionalLights_half(half3 WorldPos, half3 WorldNormal, half3 WorldView, out half3 Diffuse)
{
    half3 diffuseColor = 0;
    
#ifndef SHADERGRAPH_PREVIEW
    WorldNormal = normalize(WorldNormal);
    WorldView = SafeNormalize(WorldView);
    int pixelLightCount = GetAdditionalLightsCount();

    for (int i = 0; i < pixelLightCount; ++i)
    {
        Light light = GetAdditionalLight(i, WorldPos);
        half3 attenuatedLightColor = light.color * (light.distanceAttenuation * light.shadowAttenuation);
        diffuseColor += LightingLambert(attenuatedLightColor, light.direction, WorldNormal);
    }
#endif

    Diffuse = diffuseColor;
}


  • PBR 라이팅 공식을 이용해 조립한다.


2. Soft Shadow 적용


  • 이대로는 하드 쉐도우만 적용되므로, 키워드를 이용해 소프트 쉐도우를 적용한다.
  • Keyword - Boolean : Shader Feature, Global
    • _MAIN_LIGHT_SHADOWS_CASCADE
    • _SHADOWS_SOFT


3. Fog 적용


  • 여기에 필요한 커스텀 함수 2가지

Custom_ComputeFogFactor.hlsl

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void ComputeFogFactor_float(in float z, out float fogFactor)
{
    float clipZ_01 = UNITY_Z_0_FAR_FROM_CLIPSPACE(z);

#if defined(FOG_LINEAR)
    fogFactor = saturate(clipZ_01 * unity_FogParams.z + unity_FogParams.w);

#elif defined(FOG_EXP) || defined(FOG_EXP2)
    fogFactor = (unity_FogParams.x * clipZ_01);

#else
    fogFactor = 0.0h;

#endif
}

Custom_ComputeFogIntensity.hlsl

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void ComputeFogIntensity_float(in float fogFactor, out float fogIntensity)
{
    fogIntensity = 1;

#if defined(FOG_EXP)
    fogIntensity = saturate(exp2(-fogFactor));

#elif defined(FOG_EXP2)
    fogIntensity = saturate(exp2(-fogFactor * fogFactor));

#elif defined(FOG_LINEAR)
    fogIntensity = fogFactor;

#endif
}

4. Specular, Rim Light 추가


  • 쉐이더그래프의 월드 Normal, View 벡터들은 크기가 1이 아니므로

    반드시 정규화시켜서 사용해야 한다.

  • 블린 퐁 스페큘러와 림라이트까지 적용한 커스텀 릿 쉐이더를 완성하였다.


비교


  • 좌측 : PBR, 우측 : Custom Lit


Reference



Download


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