눈팅하는 게임개발자 블로그
OpenGL Advanced Lighting 6-1 Advanced Lighting 본문
원문 사이트
learnopengl.com/Advanced-Lighting/Advanced-Lighting
번역 사이트
gyutts.tistory.com/165?category=755809
Advanced Lighting
조명 강좌에서 Phong 조명 모델을 간략하게 짚어보았었다.
Phong 조명 모델은 보기에 나쁘지 않지만, 이번 강좌에서 다른 모델들도 다루어본다.
Blin-Phong
퐁 조명은 조명의 훌륭한 근사이지만, 특정 조건에서는 특히 반사율이 낮아서 반사 영역이 거친 경우
반사 현상이 발생한다.
아래 이미지는 평평한 텍스처면에서 1.0의 반사광 지수를 사용할 때 어떤 일이 일어나는지 보여준다.
가장자리에서 반사 영역이 즉시 끊어지는 것을 볼 수 있다.
그 이유는 뷰 벡터와 반사 벡터 사이의 각도가 90도 이상으로 올라가지 않도록 하기 위함이다.
각도가 90도 이상이면 결과 내적이 음수가 되고 반사 지수가 0.0이 된다.
실제로는 90도 이상의 각도로도 빛을 얻어야 하기 때문에 이는 문제가 될 수 있다.
여기서 틀린 점은 일반 광원과 광원 사이의 90도 이상인 각도가 광원이 조명된 표면 아래에 있으므로
광원의 확산 기여도가 0.0이어야 한다는 것을 의미한다.
그러나 광원과 법선 사이의 각도를 측정하지 않고, 뷰와 반사 방향 벡터 사이의 각도를 측정한다.
다음 두 이미지를 살펴보자.
여기서 문제가 분명해진다. 왼쪽 이미지는 θ가 90도 미만인 Phong 반사를 보여준다.
오른쪽 이미지에서 뷰와 반사 방향 사이의 각도 θ가 90도보다 크다는 것을 알 수 있으며,
결과적으로 반사 기여도를 무효화할 수 있다.
뷰 방향은 반사 방향과는 거리가 멀기 때문에 일반적으로 문제가 되지 않지만,
낮은 반사 지수를 사용하면 반사 반경은 이러한 조건에서 공헌할 만큼 충분히 크다.
이 경우 첫번째 이미지에서 확인할 수 있듯이 90도 이상의 각도에서 이 기여를 무효화한다.
1977년 Blinn-Phong 쉐이딩 모델은 James F Blinn에 의해 그 이전까지 사용해왔던 Phong 쉐이딩의 확장으로 소개되었다.
Blinn-Phong 모델은 대체로 유사하지만 결과적으로 해당 문제를 극복하는 약간 다른 specular 모델에 접근한다.
반사 벡터를 사용하는 대신 뷰 방향과 조명 방향 중간의 단위 벡터인 소위 중간 벡터를 사용한다.
이 중간 벡터가 srfuace의 법선 벡터에 가까울수록 반사도가 높아진다.
뷰 방향이 (현재 가상의) 반사 벡터와 완벽하게 정렬되면 중간 벡터는 법선 벡터와 완벽하게 정렬된다.
따라서 viewer가 원래의 반사 방향으로 가까이 갈수록 반사의 밝은 부분이 강해진다.
여기서 viewer가 바라는 방향이 무엇이든 간에 중간 벡터와 표면 법선 사이의 각도는 절대적으로 90도를 초과하지 않는다.
이는 Phong 방향과 비교해 약간 다른 결과를 생성하지만, 대개 낮은 반사 지수로 인해 시각적으로 약간 더 보기가 쉽다.
Blinn-Phong 쉐이딩 모델은 OpenGL의 이전 고정 함수 파이프라인에서 사용된 정확한 쉐이딩 모델이기도 하다.
중간 벡터를 얻는 것은 어렵지 않다. 빛의 방향 벡터와 view 벡터를 함게 추가하고 결과를 정규화하면 된다.
이는 다음과 같은 GLSL 코드로 변환된다.
vec3 lightDir = normalize(lightPos - FragPos);
vec3 viewDir = normalize(viewPos - FragPos);
vec3 halfwayDir = normalize(lightDir + viewDir);
그 다음 specular term의 실제 계산은 기본적으로 표면 법선과 중간 벡터 사이의 클램프된 내적이 되어서
반사된 shininess 지수로 다시 발생시키는 코사인 각도를 얻는다.
float spec = pow(max(dot(normal, halfwayDir), 0.0), shininess);
vec3 specular = lightColor * spec;
Blinn-Phong은 방금 설명한 것이 전부이다.
Blinn-Phong과 Phong의 정반사와의 유일한 차이점은 뷰 방향과 반사 벡터 사이의 각도와 비교해 법선 벡터와 중간 벡터
사이의 각도를 측정한다는 점 뿐이다.
specular 하이라이트를 계산하기 위한 중간 벡터가 도입됨에 따라 더이상 Phong shader에서의 specular cutoff 문제가 없어야 한다.
아래 이미지는 specular 지수가 0.5인 두 가지 방법의 반사 영역을 보여준다.
Phong과 Blinn-Phong 쉐이딩의 또 다른 미묘한 차이점은 중간 벡터와 표면 법선 사이의 각도가
뷰와 반사 벡터 사이의 각도보다 짧다는 것이다.
결과적으로 Phong 쉐이딩과 비슷한 결과를 얻으려면 반사광 지수를 약간 높게 설정해야 한다.
일반적으로 Phong shininess 지수의 2~4배로 설정한다.
다음은 Phong 지수가 8.0이고, Blinn-Phong 구성 요소가 32.0으로 설정된 두 반사 모델 사이의 비교이다.
Blinn-Phong 대수 지수가 Phong에 비해 조금 더 선명하다는 것을 알 수 있다.
이전에 Phong 음영으로 설정한 것과 비슷한 결과를 얻으려면 약간의 조정이 필요하지만 Blinn-Phong 음영은
기본 Phong 음영에 비해 일반적으로 약간 더 정확한 결과를 제공한다.
여기서는 일반적인 Phong 반사와 Blinn-Phong 반사를 전환하는 간단한 프래그먼트 쉐이더를 사용하였다.
void main()
{
[...]
float spec = 0.0;
if(blinn)
{
vec3 halfwayDir = normalize(lightDir + viewDir);
spec = pow(max(dot(normal, halfwayDir), 0.0), 16.0);
}
else
{
vec3 reflectDir = reflect(-lightDir, normal);
spec = pow(max(dot(viewDir, reflectDir), 0.0), 8.0);
}
}
'공부한거 > OpenGL' 카테고리의 다른 글
OpenGL Advanced Lighting 6-3-1 Shadow Mapping (0) | 2020.12.13 |
---|---|
OpenGL Advanced Lighting 6-2 Gamma Correction (0) | 2020.12.13 |
OpenGL Advanced 5-11 Anti aliasing (0) | 2020.12.12 |
OpenGL Advanced 5-10 Instancing (0) | 2020.12.12 |
OpenGL Advanced 5-9 Geometry Shader (0) | 2020.12.11 |