Advanced Lighting
lighting tutorials에서, 우리는 간단하게 우리의 scene에 기본적인 현실성을 가져오기 위해 Phong lighting model을 도입했다. 그 Phong model은 꽤 좋아보이지만, 우리가 이 튜토리얼에서 집중할 몇 가지 뉘앙스들을 가지고 있다.
Blinn-Phong
Phong lighting은 lighting에 있어서 훌륭하고 매우 효율적인 근사이다. 하지만, 그것의 specular reflections은 어떤 조건에서는 깨진다. 특정하게, shininness property가 낮을 때 큰 (대강의) specular area를 만들면서. 아래의 이미지는 우리가 평평한 텍스쳐 입힌 평면에서 1.0의 specular shininess exponent를 사용할 때 발생하는 것을 보여준다.
너는 edges에서 specular area가 즉시 단절되는 것을 볼 수 있다. 이것이 발생하는 이유는 view vector와 reflection vector 사이의 각이 90도 이상 넘어가는 것이 허용되지 않기 때문이다. 만약 그 각이 90도 이상이라면, 그 최종 내적은 음의 값이되고, 이것은 specular exponents를 0.0으로 만든다. 너는 아마도 이것이 문제가 아닐 것이라고 생각할 것이다. 왜냐하면 우리는 90도 이상의 각을 가진 어떠한 빛도 가지지 않을 것이기 때문이다. 그런가?
아니다, 이것은 오직 diffuse component에만 적용된다. 거기에서 법선과 light source 사이의 90도 이상의 한 각은 light source가 비춰지는 표면의 아래에 있다는 것을 의미하고, 따라서 light의 diffuse contribution은 0.0이 되어야 한다. 그러나 specular lighting으로, 우리는 light source와 normal사이의 각이 아닌, view와 reflection direction vector 사이의 각을 측정하고 있다. 다음의 두 이미지를 보아라:
여기에서 문제는 명백해 질 것이다. 왼쪽의 이미지는 theta 각이 90도 이하로 친숙한 Phong reflections을 보여준다. 오른쪽 이미지에서, 우리는 view와 reflection direction사이의 각 theta가 90도 이상이고 결과적으로 specular contribution을 무효하게 만드는 것을 볼 수 있다. 이것은 일반적으로 문제가 아니다. 왜냐하면 view direction은 reflection direction가 멀기 때문이다. 그러나 만약 우리가 낮은 specular exponent를 사용한다면, specular radius는 이러한 조건하에서 contribution을 가질만큼 충분히 크다. 그러한 경우에 우리는 90도 이상의 각에서 이 contribution을 무효화 할 것이다. (첫 번째 이미지에서 보여지듯이)
1977년에, Blinn-Phong shading model이 James F.Blinn에 의해 우리가 이제까지 사용한 Phong shading의 확장으로서 도입되었다. Blinn-Phong model은 크게 유사하지만, 결과적으로 우리의 문제를 극복하는 specualr model를 조금 다르게 접근한다. reflection vector 대신에, 우리는 view direction과 light direction 사이의 정확히 절반인 단위 벡터인 halfway vector라고 불리는 것을 사용할 것이다. 이 half way vector가 표면의 법선 벡터와 정렬될수록, 그 specular contribution은 높아진다.
그 view direction이 완벽히 (이제 상상의) reflection vector와 정렬될 때, 그 halfway vector는 완벽히 normal vector와 일치한다. 따라서 그 viewer가 원래 reflection direction으로 바라볼수록, 그 specular highlight는 더 강해진다.
여기에서 너는 viewer가 무슨 방향을 보든 halfway vector와 surface normal사이의 각이 90도를 결코 초과하지 않는 것을 볼 수 있다. (만약 그 light가 물론 표면아래에 있지 않다면) 이것은 Phong reflections와 비교해서 다소 다른 결과를 만든다. 그러나 대개 다소 좀 더 시각적으로 그럴듯해 보인다. 특히 낮은 specular exponents와. Blinn-Phong Shading model은 또한 OpenGL의 이전의 fixed function pipeline에서 사용된 정확한 shading model이다.
halfway vector를 얻는 것은 쉽다. 우리는 light의 방향벡터와 view vector를 함꼐 더하여 그 결과를 표준화한다:
이것은 GLSL 코드로 다음과 같이 바뀐다:
// World coordinates lighting vec3 lightDir = normalize(lightPos - world_FragPos); vec3 viewDir = normalize(viewPos - world_FragPos); vec3 halfwayDir = normalize(lightDir + viewDir); // View coordinates lighting vec3 lightDir = normalize(lightPos - view_FragPos); vec3 viewDir = normalize(-view_FragPos); vec3 halfwayDir = normalize(lightDir + viewDir);
그러고나서 specular term의 실제 계산은 기본적으로 surface normal과 halfway vector사이의 calmped된 내적이 된다. 이것은 우리가 다시 specular shininess exponent를 지수승할 것들 사이의 cosine 각도를 얻기위해서이다:
float spec = pow(max(dot(normal, halfwayDir), 0.0), shininess); vec3 specular = lightColor * spec;
그리고 우리가 묘사했던 것 보다 Blinn-Phong에 해야할 더이상의 것은 없다. Blinn-Phong과 Phong specular reflection의 유일한 차이는 우리는 이제 view direction과 reflection vector 사이의 각과 비교해서, normal과 halfway vector사이의 각을 측정한다는 것이다.
specular highlights를 계산하는데 halfway vector의 도입과함께, 우리는 더 이상 Phong shading의 specular cutoff 문제를 갖지 않을 것이다. 아래의 이미지는 0.5의 specular exponent를 가진 두 방식의 specular area를 보여준다.
Phong과 Blinn- Phong shading사이의 또 다른 미묘한 차이는 halfway vector와 surface normal사이의 각이 종종 view와 reflection vector사이의 각보다 더 짧다는 것이다. 결과적으로 Phong shading과 비슷한 결과를 얻기위해, specular shininess exponent는 좀 더 높게 설정되어야만 한다. 일반적인 경험은 그것을 Phong shininess exponent의 2와 4사이의 배수로 설정하라는 것이다.
Phong exponent는 8.0으로 설정되고, Blinn-Phong component는 32.0으로 설정된 두 specular reflection models 사이의 비교가 아래에 있다:
너는 Blinn-Phong specular exponent가 Phong과 비교해서 좀 더 날카롭다는 것을 알 수 있다. 그것은 보통 너가 Phong shading으로 이전에 설정한 것과 유사한 결과를 얻기위해서 조금 수정해보는 것을 요구한다. 그러나 Blinn-Phong shading은 일반적으로 기본 Phong shading과 비교해서 좀 더 그럴듯한 결과를 준다.
여기에서 우리는 일반적인 Phong reflections와 Blinn-Phong reflections사이를 스위치하는 간단한 fragment shader를 사용했따:
너는 간단한 데모를 위한 source code를 여기에서 볼 수 있고. b키를 눌러서 그 데모는 Phong과 Blinn-Phong 라이팅을 바꾼다.
========================================
일반적으로 Blinn-Phong shading이 더 그럴듯한 결과를 준다하니 모두 Blinn-Phong으로 바꾸자.
댓글 없음:
댓글 쓰기