새소식

인기 검색어

게임 개발/그래픽스

[그래픽스] Phong Relfection Model 구와 조명 효과

  • -

https://en.wikipedia.org/wiki/Phong_reflection_model

 

Phong reflection model - Wikipedia

From Wikipedia, the free encyclopedia Shading algorithm in computer graphics The Phong reflection model (also called Phong illumination or Phong lighting) is an empirical model of the local illumination of points on a surface designed by the computer graph

en.wikipedia.org

  • Ambient -> 색 그 자체
  • Diffuse -> 물체의 표면이 거칠어서 빛이 난반사된다고 가정
  • Specular -> 반짝반짝한 질감, 매끈한 표면
  • alpha
  • ks

Ambient

그냥 색 그 자체 그대로.

Diffuse (view independent)

표면상의 한 지점이 얼마나 많은 빛을 받는가?

-> normal vector 와의 각도가 작을수록 빛을 더 많이 받는다. (해가 중천에 떳을때 가장 빛이 센걸 생각해보면 됨)

-> 즉, normal vector와 빛의 들어오는 벡터와의 각도에 따라 빛의 양을 조절하면 됨.

-> 각도가 0일때 가장 값이 크고, 각도가 커질때 값이 작아지는 함수 사용하면 되겠다!

-> cosθ! -> 그런데 코사인은 컴퓨터에서 계산할때 느려짐 -> 식 유도 과정에서 코사인이 사라짐

-> 90도가 넘으면 값이 0이 되어야 함

-> max(cosθ, 0.0f)

-> 둘 다 유닛 벡터이면 다음이 성립함 -> cosθ  = n dot l

-> max(n dot l, 0.0f)

// Diffuse
// const vec3 dirToLight = ...
const vec3 dirToLight = glm::normalize(light.pos - hit.point);
// 빛이 90도가 넘어가면 빛이 음수가 되지 않도록 clamp
const float diff = glm::max(glm::dot(hit.normal, dirToLight), 0.0f);

 

Specular (view dependent)

정반사 되는 벡터를 구한다.

정반사(완전반사)

보는 사람의 각도도 고려해야 한다.

물체에서 보는 사람의 시선쪽으로의 벡터와, 반사된 빛의 벡터의 각도에 코사인을 씌우면

  • 세타가  0일때 => 가장 강한 빛
  • 세타가 90일때 => 가장 약한 빛
  • max함수를 씌워서 음수일때는 0이게 하면 됨

그런데, Diffuse 때 했던것과 마찬가지로, 두 벡터가 모두 normalize된 벡터라면, 둘을 dot product하면 코사인 값을 구할 수 있음.

const vec3 reflectDir = glm::normalize(2.0f * glm::dot(hit.normal, dirToLight) * hit.normal - dirToLight);
const float specular = glm::max(glm::dot(-ray.dir, reflectDir), 0.0f);

위 코드의 실행결과

그런데 우리가 원했던 Specular는 빛이 강렬하게 반짝거리는 느낌(마치 눈알에 하이라이트 들어가듯이)인데 우리가 만든 구체는 흐리멍텅한 느낌임. -> 더 강렬하게 빛이 모이게 만들 요소가 필요하다.

https://www.scratchapixel.com/lessons/3d-basic-rendering/phong-shader-BRDF/phong-illumination-models-brdf.html

 

The Phong Model, Introduction to the Concepts of Shader, Reflection Models and BRDF

The glossy reflection of a light source is dimmer than the reflection of that same light source by a mirror-like surface (we assume here that the viewer looks at the reflection of a light source along the light rays' reflection direction as shown in figure

www.scratchapixel.com

n만큼 제곱을 해 주면 된다.

보통 phong 모델의 specular에 몇 제곱을 할 것인가(그림에서 n)는 alpha라는 수로 표현함

 

const vec3 reflectDir = glm::normalize(2.0f * glm::dot(hit.normal, dirToLight) * hit.normal - dirToLight);
const float specular = glm::pow(glm::max(glm::dot(-ray.dir, reflectDir), 0.0f), sphere->alpha);

이런식으로 빛이 더 잘 모여 보임

Ambient + Diffuse + Specular

Ambient + Diffuse + Specular

 

Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.