조명의 세 가지 종류
조명으로부터 멀어지면 점점 어두워지는 것을 어떻게 구현?
정확한 물리 계산을 하면 너무 느림
falloffStart falloffEnd 이 두 가지를 이용한다.
Spot Lights
중심에서 멀 수록 빛이 약해야 한다. 중심에 가까울수록 빛이 강해야 한다.
vec3 ComputeSpotLight(Light L, Material mat, vec3 pos, vec3 normal,
vec3 toEye) {
vec3 lightVec = L.position - pos;
// 쉐이딩할 지점부터 조명까지의 거리 계산
float d = length(lightVec);
// 너무 멀면 조명이 적용되지 않음
if (d > L.fallOffEnd)
return vec3(0.0f);
lightVec /= d;
float ndotl = glm::max(dot(lightVec, normal), 0.0f);
vec3 lightStrength = L.strength * ndotl;
float att = CalcAttenuation(d, L.fallOffStart, L.fallOffEnd);
lightStrength *= att;
float spotFactor = glm::pow(glm::max(dot(-lightVec, L.direction), 0.0f), L.spotPower);
lightStrength *= spotFactor;
return BlinnPhong(lightStrength, lightVec, normal, toEye, mat);
}
Point Light
vec3 ComputePointLight(Light L, Material mat, vec3 pos, vec3 normal,
vec3 toEye) {
vec3 lightVec = L.position - pos;
// 쉐이딩할 지점부터 조명까지의 거리 계산
float d = length(lightVec);
// 너무 멀면 조명이 적용되지 않음
if (d > L.fallOffEnd)
return vec3(0.0f);
lightVec /= d; // 유닛 벡터로 만듦.
float ndotl = glm::max(dot(lightVec, normal), 0.0f);
vec3 lightStrength = L.strength * ndotl;
float att = CalcAttenuation(d, L.fallOffStart, L.fallOffEnd);
lightStrength *= att;
return BlinnPhong(lightStrength, lightVec, normal, toEye, mat);
}
Directional Light
vec3 ComputeDirectionalLight(Light L, Material mat, vec3 normal, vec3 toEye) {
vec3 lightVec = -L.direction;
float ndotl = glm::max(dot(lightVec, normal), 0.0f);
vec3 lightStrength = L.strength * ndotl;
// Luna DX12 책에서는 Specular 계산에도
// Lambert's law가 적용된 lightStrength를 사용합니다.
return BlinnPhong(lightStrength, lightVec, normal, toEye, mat);
}