Direct3D 12 graphics Pipeline

지난 포스팅에서는 pixel shader가 하는 일 중 texturing과 관련해서 texel과 pixel의 해상도 차이로 인한 확대,축소 문제를 어떻게 해결하는지 살펴봤다. 오늘 다룰 내용은 Lighting이다. 전통적인 phong 모델부터 per-pixel lighting, blinn-phong model까지 살펴볼 예정이다. 

 

 

 

 

 

Phong Lighting Model

◇  Diffuse / Specular / Ambiend / Emissive 4가지를 섞어 그럴듯하게 빛을 표현하자

  • 가장 유명하고 전통적인 방식이다.
  • approximation을 어떻게 잘 하는지가 중요하다. 

 

 

 

Light Sources

◇ Point light

  • 하나의 point로부터 전방향으로 빛을 뿜어낸다. 
  • point로부터 거리에 따라 intensity가 결정된다

Directional light

  • scene으로부터 멀리 떨어진 곳에서 보내는 빛  ex) 태양
  • scene 전체에서 one direction이다.
  • 내가 어디에 존재하든 일정한 direction과 크기를 가진다 

◇ Spotlight

  • cone shaped light
  • 거리와 각도에 따라 intensity가 달라진다.
  • ex) 형광등, 백열등

◇ Ambient

  • 은은하게 밝혀주는 간접광
  • 반사되어 떠도는 빛을 계산하기 어렵기 때문에 constant value로 뭉개서 계산한다.

 

 

 

Diffuse (난반사광)

물체 표면에 빛이 반사되었을 때 전방향으로 uniform하게 퍼지는 것을 modeling한다.

  • Lambert's law를 따른다  = 입사각이 작을 수록 밝게 보인다.
    • Diffuse 조명은 표면의 밝기가 빛의 입사각 cos(θ)에 비례한다. 
    • θ: 빛의 방향과 표면 법선 벡터(normal) 사이의 각도
    • 관찰자의 위치와 밝기는 무관하다. 

  • Diffuse computation

  • n : surface normal (표면 법선 벡터)
  • l : light direction (빛 방향 벡터)
  • n · l : 두 벡터의 내적
  • max(n·l, 0) : 음수 제거
  • s_d : light color (빛 색)
  • m_d : material diffuse color (물체 색)

 

white light (1,1,1)이 들어올 때, 물체가 노란색이면 R,G값은 반사하고 B는 흡수한다.

 

 

 

Specular (정반사광)

 

 물체 표면에 빛이 닿을 때, 특정 방향으로 강하게 반사되는 조명 효과

  • 표면 특정 부분에 highlight 효과를 줄 수 있다. 
  • 관찰자의 방향에 따라 밝기가 달라진다.
    •  : view vector
    •  : reflection vector
    •  : shininess (클수록 날카롭고 작은 하이라이트)
    •  : light source의 gray-scale value
    •  : highlight on the surface

 

 

Ambient (간접광)

주변에 퍼져있는 일관된 빛 

  • 씬 내의 다양한 물체에 반사된 빛
  • 표면에 도달한 주변 조명은 모든 방향에서 동일한 강도로 산란된다.

 

 

Emissive 

표면 자체에서 방출되는 빛

emissive 적용 전(좌), emissive 적용 후(우)

 

 

 

Phong Lighting Model

 

◇  Diffuse / Specular / Ambiend / Emissive 4가지 term을 합쳐서 표현한다.

 

 

 

Per-pixel Lighting

◇  각 픽셀 단위에서 조명을 계산하는 방식

  • per-vertex 방식에 비해 high quality
  • per-vertex 방식은 정점만 밝기 계산을 하고, 그 사이 픽셀은 선형 보간해서 부드럽지 않은 부분이 생긴다.

per-vertex(좌), per-pixel(우)

 

◇  pixel shader에서 per-pixel 조명 계산을 위해 필요한 벡터

  • l : light vector
  • n : normal
  • v : view vector
  • r : reflection vector  ( r = 2n(n·l) - l )
  • (이때 l은 directional light로 모든 surface에서 동일 / n,r,v는 픽셀마다 다름)
  • 중요한 점은 l이 world space 기준이기 때문에 n,v도 world space 기준 좌표가 필요하다!
  • n과 v는 vertex shader에서 pixel shader로 넘겨주는 값이고, r은 직접 계산이 가능하기 때문에 파라메터를 하나 줄일 수 있다. 

◇  Normal이 pixel마다 생기는 과정

  • vertex shader : vertex normal을 world space로 변환
  • rasterizer : vertex normal을 보간  

◇  View vector가 pixel마다 생기는 과정

  • vertex shader : v = cameraPos - vertexPos (world space 좌표임)
  • rasterizer : vector 보간

◇   최종 pixel 별 Phong lighting 계산

  • n,v,l이 준비되었기 때문에 r은 계산을 통해서 구할 수 있다.
  • 다음 최종적으로 pixel마다 phong lighting을 계산하면 per-pixel을 구현할 수 있게 된다.

 

 

 

 

 

Blinn-Phong Reflection Model

◇  Phong model의 modified(수정된) version

  • Phong은 lighting approximation에 효율적이다.
  • 그러나 specular term에서 가끔 unrealistic한 결과를 낸다.

 

  • dot project는 cos 계산이기 때문에 90도를 넘기면 음수를 반환하고, 그대로 max()를 통과하면 0이 된다.
  • 이런 급격한 cut off 때문에 경계(boundray)가 생긴다.

 

 

◇  Blinn-Phong reflection model - specular term

  • reflection vector(r) 대신에 halfway vector(h)를 이용한다.
  • h :  (view vector) 와  (light vector)을 이등분(bisects)하는 벡터
  • blinn phong의 장점
    • r과 v의 차이가 90도가 넘더라도, h와 n 사이 각도는 90도가 넘지 않기 때문에 이전의 문제점이 해결된다! 
    • 추가로 r을 구하기 위해서 내부적으로 내적을 했었는데, 이 과정이 없어지고 단순한 덧셈 연산으로 중간 벡터를 구하기 때문에 처리도 빨라진다. 

 

  • 적용 결과
    • specular term을 개선한 것이기 때문에, 바다에 반사되는 햇빛이나 젖은 땅에 멀리 떨어진 가로등이 반사되는 등 평면에 대한 반사를 표현할 때 훨씬 현실적인 표현이 가능해진다고 한다. 

 

 

 

 

 

 

Reference KHU 강형엽 교수님 강의를 수강하며 정리한 내용입니다.

'그래픽스' 카테고리의 다른 글

[DirectX12] 5. Output Merger  (1) 2026.04.10
[DirectX12] 3. Pixel Shader - Texturing  (0) 2026.03.13
[DirectX12] 2. Rasterizer  (1) 2026.03.13
[DirectX12] 1. Input Assembler, Vertex Shader  (0) 2026.03.12

+ Recent posts