그래픽스(DirectX)

[DirectX11] Lighting - 빛과 머티리얼, normal vector, Lambert 코사인 법칙

gamzachips 2023. 5. 21.

 

Lighting

3D 물체에 빛이 없으면 그냥 2D처럼 보이게 된다.

실제로 우리가 세상을 보는 모습은 물질(material)과 빛의 상호작용에 의존한다.

따라서 사실성을 위해서 정확한 빛 모델을 사용해야 하지만,

비용이 크기 때문에 속도와 사실성 사이에서 밸런스를 맞추어야 한다. 

 

 

따라서 pixel shader에서 각 정점마다 색상을 그냥 리턴하는 것이 아니라, 머티리얼을 두어서 이들의 상호작용에 기반해 정점의 색상을 계산하는 빛 공식을 적용해야 한다.

머리티얼이라는 것은 물체 표면이 빛과 어떻게 상호작용하는지를 결정하는 특성으로 생각할 수 있다. 

 

 

빛은 다양한 색상이 될 수 있고, 광원으로부터 바깥으로 이동하다가 다른 물체와 충돌하여 일부는 흡수되고 일부는 반사되어 다른 물체를 칠 수 있다. 그러다 일부는 눈에 들어와서 보이게 된다. 

 

lighting models

local illumination models은 각 물체가 광원으로부터 직접적으로 방출되는 빛에 의해서만 비춰지고, 다른 물체와는 독립적인 모델이다.

반면 global illumination models은 광원에서 직접 방출된 빛 뿐만 아니라 물체에서 반사된 간접적인 빛까지 고려하여 물체를 비추는 모델이다. 일반적으로 실시간 게임에 적용하기에는 비용이 엄청 크다. 

 

 

Normal vectors

face normal은 도형이 향하는 방향을 묘사하는 단위 벡터이다. 이는 도형의 모든 점에 수직이다. 

surface normal은 표면에 있는 점에서 접하는 평면에 수직인 단위 벡터이다.

 

(a) face normal,  (b) surface normal

 

삼각형 mesh의 각 표면 위의 점에 대해 surface normal을 알면, mesh 표면에서 빛이 들어오는 지점에서의 각도를 결정할 수 있다. 

 

surface normal을 구하기 위해서 우선 각 정점에서의 normal을 구한다. 이를 vertex normal이라 한다. 

그리고 RS단계에서 vertex normal을 보간하여, 삼각형 mesh 표면의 각 점에 대한 normal을 얻는다. 

이때 정점 사이의 각 픽셀들의 normal은 vertex normal 사이에서 선형적으로 보간된다.

 

이렇게 normal을 보간하고 픽셀마다 빛 연산을 하는 것을 pixel lighting 또는 phong lighting이라 한다. 

PS단계에서 픽셀마다 빛 연산을 하는 것이 아니라 VS단계에서 정점에 대해 normal을 구한 후 PS로 넘어갈 때 보간하는 것은 정확도는 떨어지지만 비용이 적다. 시각적 차이가 크지 않기도 하므로, 성능 최적화를 하는 흔한 방법이다. 

 

 

 

Normal vectors 계산

 

삼각형의 face normal을 구해보자. 

삼각형 ΔP0P1P2에서, 삼각형의 변에 놓인 두 벡터를 구하고, 이를 외적하고 정규화하여 수직한 벡터를 구하면 된다. 

 

 

미분 가능한 표면이라면 미분으로 normal을 계산할 수 있지만, 삼각형 mesh는 미분가능하지않다. 

따라서 vertex normal averaging 라는 기술이 일반적으로 사용된다. 

 

임의의 정점 v에서의 vertex normal을, 이 정점을 공유하는 모든 삼각형의 face normal을 평균하여 구하는 것이다. 

좀더 정교하게 구하기 위해서 가중치를 이용하는 등의 방법들이 이루어질 수도 있다. 예를 들어 다각형의 면적이 넓을수록 더 큰 가중치를 줄 수 있다.

 

 

 

Normal vectors 변환

좌표 변환으로 위치가 달라졌을 때, 변환 행렬을 normal vector에 그대로 곱하면 수직이 되지 않는다. 

변환된 상태에서의 노멀 벡터를 어떻게 다시 구할 수 있을까? 

즉, 변환행렬 A가 주어질 때, 변환 후의 normal을 구하는 변환행렬 B를 구해보자.

 

 

B는 변환행렬 A의 역전치행렬이다.

 

normal vector를 변환한 후에는 다시 정규화해야 한다. 

 

 

 

 

Lambert의 코사인 법칙

비스듬이 비치는 빛보다 정면으로 비치는 빛이 더 강하다. 

 

따라서 light 벡터(L)와 normal 벡터(n)가 이루는 각에 기반하여 서로 다른 세기를 반환하는 함수를 고려할 수 있다. 

여기서 light 벡터는 표면에서 광원으로 가는 방향이다. 

 

L과 n의 방향이 정확히 일치하여 0도가 될 때 빛의 세기가 가장 강하고, 

각도가 커질수록 세기가 서서히 약해진다.

그리고 90도가 넘어가면 표면의 뒤쪽에 비치는 것이므로 세기를 0으로 설정한다.

 

n과 L이 단위 벡터일 때 아래와 같은 함수로 표현할 수 있고, 이것이 Lambert의 코사인 법칙이다. 

 

 

 

 

댓글