티스토리 뷰
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