티스토리 뷰

Unity/Shader

Lighting Introduction

연홍 2021. 1. 22. 14:06
728x90

built-in 파이프 라인에서 lighting/shadow가 필요한 커스텀 셰이더는 일반적으로 surface 셰이더에 의해 처리되었습니다. physically-based Standard 및 StandardSpecular 또는 Lambert (확산) 및 BlinnPhong (스페큘러) 모델 중에서 사용할 조명 모델을 선택할 수있는 옵션이 있습니다. 예를 들어 툰 음영 결과를 생성하려는 경우 사용할 수있는 커스텀 조명 모델을 작성할 수도 있습니다.

 

Universal RP는 surface 셰이더를 지원하지 않지만 ShaderLibrary는 많은 조명 계산을 처리하는 데 도움이되는 함수를 제공합니다. 이는 Lighting.hlsl에 포함되어 있습니다 (자동으로 포함되지 않음)

 

lighting 파일에는 다음 섹션에서 설명 할 UniversalFragmentPBR을 포함하여 조명을 완전히 처리 할 수있는 함수가 있습니다. 지금은 main directional light에 대해서만 훨씬 더 간단한 조명과 그림자를 살펴 보겠습니다. (좀 더 복잡한 PBR 조명 모델을 좀 더 쉽게 이해할 수있는 예입니다.)

 

Lighting.hlsl에는 셰이더 그래프의 커스텀 조명에 익숙하다면 이미 알고있을 수있는 GetMainLight 함수가 있습니다. 이를 사용하기 위해 먼저 Lighting.hlsl파일을 포함하고 HLSLPROGRAM의 맨 위에있는 동안 그림자를받는 데 필요한 키워드를 제공하는 일부 multi_compile 지시문도 추가합니다.

#pragma multi_compile _ _MAIN_LIGHT_SHADOWS
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS_CASCADE
#pragma multi_compile _ _SHADOWS_SOFT
 
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"

다음으로 shading/lighting을 처리하기 위해 버텍스 노멀이 필요하므로이를 Attributes 및 Varyings 구조체에 추가하고 버텍스 셰이더를 업데이트합니다. 여기에서는 이전 섹션에서 만든 Unlit 셰이더를 기반으로 추가 된 코드 만 보여줍니다.

struct Attributes {
    ...
    float4 normalOS     : NORMAL;
};
 
struct Varyings {
    ...
    float3 normalWS     : NORMAL;
    float3 positionWS   : TEXCOORD2;
};
...
Varyings vert(Attributes IN) {
    Varyings OUT;
    VertexPositionInputs positionInputs = GetVertexPositionInputs(IN.positionOS.xyz);
    ...
    OUT.positionWS = positionInputs.positionWS;
 
    VertexNormalInputs normalInputs = GetVertexNormalInputs(IN.normalOS.xyz);
    OUT.normalWS = normalInputs.normalWS;
 
    return OUT;
}

프래그먼트 셰이더에서 이제 월드 스페이스 노멀을 취하고 월드 스페이스 위치를 사용하여 그림자 좌표를 계산할 수 있습니다. (기술적으로는 정점 셰이더에서 그림자 좌표를 계산하여 통과시킬 수도 있지만 shadow cascades 키워드가 비활성화 된 경우에만 통과 할 수 있습니다. 지금은 간단하게 유지하고 싶지만 다음 예제에 포함됩니다. 다음 섹션).

half4 frag(Varyings IN) : SV_Target {
    half4 baseMap = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, IN.uv);
    half4 color = baseMap * _BaseColor * IN.color;
 
    float4 shadowCoord = TransformWorldToShadowCoord(IN.positionWS.xyz);
    Light light = GetMainLight(shadowCoord);
 
    half3 diffuse = LightingLambert(light.color, light.direction, IN.normalWS);
 
    return half4(color.rgb * diffuse * light.shadowAttenuation, color.a);
}

현재 셰이더는 다른 셰이더의 그림자를 받지만 ShadowCaster 패스가 없으므로 자신 또는 다른 개체에 그림자를 드리우지 않습니다. ShadowCaster 섹션을 참조하십시오.

그림자를 원하지만 오브젝트에 디퓨즈 셰이딩이없는 경우에는 디퓨즈 셰이딩 계산을 제거하고 light.shadowAttenuation 만 사용할 수도 있습니다.

ambient/bakedGI 및 추가 조명을 포함하도록이 값을 추가로 확장하려면 "Lighting.hlsl"의 UniversalFragmentBlinnPhong 메서드를 예로 보거나 자체적으로 조명을 처리하도록합니다. 다음 섹션에서 설명하는 PBR 예제에서도 사용되는 InputData 구조체를 사용합니다.

 

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

ShadowCaster & DepthOnly Passes  (0) 2021.01.25
PBR Lighting  (0) 2021.01.25
Keywords & Shader Variants  (0) 2021.01.22
Fragment Shader  (0) 2021.01.21
Vertex Shader  (0) 2021.01.21
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/05   »
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