Quick Syntax
hlsl
float3 N = normalize(input.normalWS);
float3 L = normalize(-light.directionWS);
float diffuse = saturate(dot(N, L));
float3 color = albedo * (ambient + light.color * diffuse);Normal과 light direction은 반드시 같은 coordinate space에 있어야 합니다. Directional light의 저장 방향이 빛이 향하는 쪽인지 표면에서 빛으로 향하는 쪽인지 renderer 계약으로 고정합니다.
Light 종류
Ambient는 방향 없는 최소 밝기 근사이고 directional light는 위치와 무관한 일정한 방향을 사용합니다. Point light는 lightPosition - worldPosition으로 방향과 거리를 만들고 range attenuation을 적용합니다.
hlsl
float3 toLight = point.positionWS - input.positionWS;
float distance = length(toLight);
float3 L = toLight / max(distance, 1e-5);
float attenuation = saturate(1.0 - distance / max(point.range, 1e-5));실제 물리 기반 attenuation과 color space 처리는 renderer 목표에 따라 달라집니다. 최소 예제의 단순 선형 감쇠를 물리적으로 정확한 규칙으로 일반화하지 않습니다.
자주 틀리는 점
- Non-uniform scale이 있는 normal에 world matrix를 그대로 곱하지 않습니다.
- Albedo texture를 sRGB decode 없이 조명 계산에 쓰지 않습니다.
- Normal을 보간한 뒤 normalize하지 않은 채 dot을 계산하지 않습니다.
- Point light의 range가 0인 경우를 나누지 않습니다.
참고 링크
1 sources