조명효과(Pong Model)

상태
담당자

목표

레이 트레이싱으로 만든 구체에 조명효과를 입혀보자.
 

Pong Reflection Model

 
notion image
notion image

Ambiant

물체의 색 별 달리 계산할 것이 없음.
 

Diffuse

which is a diffuse reflection constant, the ratio of reflection of the diffuse term of incoming light (Lambertian reflectance)
 
notion image
notion image
→ 요약 하자면, 벡터 N과 L의 닷 프로덕트를 하면, cos a가 나오고 이 cos a는 밝기를 뜻한다.
const vec3 dirToLight = glm::normalize(light.pos - hit.point); const float diff = glm::max( glm::dot(hit.normal, dirToLight),0.0f);
light.pos는 빛의 위치를 나타내며, 충돌지점을 뺀 후 정규화 하면, 충돌지점으로 향하는 빛의 방향 벡터(벡터 L)을 구할 수 있다.
 
그걸, 정규화된 충돌지점 벡터 N과 닷프로덕트 한 다음 0.0f와 max 비교를 통해 더 높은 값을 추출하는데 그 이유를 설명해보자면 아래와 같다.
notion image
cos a의 각도가 0 일 때 가장 세기가 크고 90도에 가까우면 빛이 아예 들어오지 않는다. 즉 90도 이후
부터는 0으로 맞춰주면 되고 이를 표현 한 것이. max 0.0f라 보면된다.
 

결과

notion image

Specular

반짝이 효과.
notion image
notion image
스펙큘러를 구하기 전 reflection을 구해야 한다. 식은 맨 밑에 나와 있는대로 해석하자면.
reflection = 2*(빛의 방향벡터 닷 충돌지점의 법선)*충돌지점의 법선 - 빛의 방향
const vec3 reflectDir = 2 * glm::dot(hit.normal, dirToLight) * hit.normal - dirToLight;
식으로 표현하자면 위와 같다. 빛의 방향벡터는 이미 diffuse를 구현할 때 구해 놨으니 쉽게 구할 수 있었다.
notion image
이렇게 구한 reflectDir과 V를 닷 프로덕트 하란다. V는 바라보는 방향이며 이는 코드로
const float specular = glm::max(glm::dot(-ray.dir, reflectDir), 0.0f);
위와 같이 표현이 가능하다.
 

결과

notion image
하지만 우리가 원하는 스펙큘러는 뭔가 반짝이는 듯한 느낌이었으나. 그렇지 못하다.
notion image
강렬하게 빛을 모으는 변수가 더 있는데. 퐁 모델에서는 제곱을 해버리면 된다.
 
const float specular = glm::pow( glm::max(glm::dot(-ray.dir, reflectDir), 0.0f),sphere->alpha);
코드로 보면 pow를 하고 alpha를 통해 강도를 정해주면 된다.
notion image
좀 더 빛이 한 점에 모여 있는 것을 볼 수 있다.

결론

return sphere->amb + sphere->diff * diff + sphere->spec * specular * sphere->ks;
결론적으로 ambiant와 diffuse, specular을 모두 더해주면.
notion image
요런식으로 조명효과를 받는 구체를 만들 수 있다.