본문 바로가기
Computer Science/Computer Graphics

[OpenGL] Lighting, Shading

by Gofo 2021. 5. 31.

Lighting, Shading

OpenGL에서 lighting/shading을 하기 위해서 vertex normal을 설정해줘야 한다.

<pre>glNormal*()</pre>을 이용한다.

 

vertex normal을 어떻게 정해주느냐에 따라 flat shading을 할지 smooth shading을 할지가 달라진다.

 

OpenGL에서는 phong shading은 지원하지 않는다.

  • flat shading
  • gouraud shading

 


Shading

Flat shading

Flat shading을 하기 위해서 각 vertex normal을 그 vertex가 포함된 face normal로 설정해야 한다.

따라서 하나의 vertex는 여러 개의 normal을 가진다.

flat shading

 

Gouraud Shading

각의 vertex normal을 인접한 모든 face normal의 평균으로 지정한다.

하나의 vertex는 하나의 normal을 가진다.

 


Shading

Vertex Normal

OpenGL에서 normal vector는 unit length를 가져야 한다.

Normal을 사용하기 위해서 <pre>glEnableClientState(GL_NORMAL_ARRAY)</pre>를 반드시 해줘야 한다.

 

glNormal*()

<pre>glNormal*()</pre>을 이용해서 vertex normal을 지정한다.

 

변경 전까지 state가 유지된다.

즉, 다시 glNormal을 하기 전까지 선언된 vertex들은 동일한 normal을 가진다.

 

아래에서 #2~#8까지의 vertex는 모두 (0, 0, 1)을 normal로 가진다.

glNormal3f(0, 0, 1)		# v0, v2, v1, v0, v3, v2's normal
glVertex3f(-1,  1,  1)	# v0 position
glVertex3f( 1, -1,  1)	# v2 position
glVertex3f( 1,  1,  1)	# v1 position

glVertex3f(-1,  1,  1)	# v0 position
glVertex3f(-1, -1,  1)	# v3 position
glVertex3f( 1, -1,  1)	# v2 position

 

Vertex Array

Vertex array를 이용해서 vertex normal을 지정할 때에는 각 vertex 마다 normal을 명시해주면 된다.

( 0, 0, 1),	# v0 normal
(-1, 1, 1),	# v0 position

( 0, 0, 1),	# v2 normal
( 1,-1, 1),	# v2 position

( 0, 0, 1),	# v1 normal
( 1, 1, 1),	# v1 position

 

Normal Array

vertex array를 vertex pointer를 통해 지정해준 것 처럼, normal array를 normal pointer로 지정해주면 된다.

 

<pre>glNormalPointer(type, stride, pointer)</pre>

  • normal array의 location, data format을 지정해준다.
  • normal은 항상 3차원 정보이다.
  •  type
    • data type
    • GL_FLOAT, GL_SHORT, LGL_INT, GL_DOBULE
  • stride
    • byte offset to the next vertex
    • 각 쌍 사이의 byte offset
    • 하나의 normal의 x 좌표에서 다음 normal까지의 x 좌표까지 몇 바이트 차이나는가?
  • pointer
    • vertex array의 위치
    • 파이썬에서는 vertex array의 변수명

 

Noraml Vector 계산

Flat shading

  1. cross product를 사용해서 각 face normal을 계산한다.
  2. 해당 face에 속하는 vertex들의 normal로 face normal을 사용한다.

Smooth shading

  1. cross product를 사용해서 각 face normal을 계산한다.
  2. vertex normal은 인접한 face normal들의 평균을 사용한다. (unit vector)

 

Length

OpenGL에서 normal vector는 unit length를 가져야 한다.

 

model view transformation을 한 후에 normal vector의 길이가 변경될 수 있다.

이를 방지하기 위해 다음을 사용해야 한다.

  • <pre>glEnable(GL_NORMALIZE)</pre>
    • 자동으로 normal vector를 model-view transformation을 한 후에 normalize한다.
  • <pre>glEnable(GL_RESCLAE_NORMAL)</pre>
    • 속도가 더 빠르지만, 다음과 같은 한계가 있다.
      • 처음에 normal vector는 반드시 unit vector여야 한다.
      • uniform scling 만 이루어져야 한다.

 


Lighting

OpenGL에서의 lighting 사용은 Blinn-Phong illumination model 만 사용 가능하다.

Blinn-Phong illumination은 phong illumination에서 계산량을 줄인 한정된 방법이다.

 

<pre>glEnable(GL_LIGHTING)</pre>와 <pre>glEnable(GL_LIGHT*)</pre>를 사용해서 lighting을 사용한다.

  • <pre>glEnable(GL_LIGHTING)</pre>
    • lighting을 enable 한다.
  • <pre>glEnable(GL_LIGHT*)</pre>
    • glEnable(GL_LIGHT0), glEnable(GL_LIGHT1) ... glEnable(GL_LIGHT7)
    • * 번째 light를 enable 한다.
    • 총 8개의 light를 사용할 수 있다.

 

Light와 material의 속성은 다음을 이용한다.

  • glLightfv() : 광원을 설정한다.
  • glMaterialfv() : 물체의 표면을 결정한다.

 

glLightfv()

glLightfv(light, pname, param)

  • light
    • 설정할 light
    • GL_LIGHT0 ~ GL_LIGHT7
  • pname, param
    • pname : 설정할 light property
    • param : 각 color channel(R, G, B)의 light intensity and alpha 값
pname param 의미
GL_AMBIENT (0.0, 0.0, 0.0, 0.0) ambient intensity
GL_DIFFUSE (1.0, 1.0, 1.0, 1.0) diffuse intensity
GL_SPECULAR (1.0, 1.0, 1.0, 1.0) specular intensity
GL_POSITION (0.0, 0.0, 1.0, 0.0)
(0.0, 0.0, 1.0, 1.0)
position of light
w = 0 : directional light : 물체가 멀리있다고 생각하고 방향만 지정해줌
w = 1 : point light : homogeneous coordinate, 광원의 위치를 지정

 

보통 diffuse와 specular는 광원의 색으로 설정한다.

ambient는 같은 색상으로 하되, intensity를 10%로 한다.

 

glMaterialfv()

glMaterialfv(face, pname, param)

  • face
    • 어디에 설정을 할 것인지 (앞/뒤)
    • GL_FRONT, GL_BACK, GL_FRONT_AND_BACK
  • pname, param
    • GL_AMBIENT, GL_DIFFUSE, GL_SPECULAR
    • GL_AMBIENT_AND_DIFFUSE : 보통 물체의 ambient와 diffuse color는 같게 설정함
    • GL_SHININESS : shiniess coefficient (커질수록 highlight가 작아짐)

보통 diffuse와 ambient는 물체의 색으로 한다.

specular는 white(1, 1, 1, 1)로 한다.

specular가 white이면 광원의 색이 highlight로 나온다.

 


참고

본 포스트는 한양대학교 이윤상 교수님의 수업을 정리한 내용입니다.

출처: 한양대학교 이윤상 교수님 컴퓨터그래픽스 강의 강의자료 - https://cgrhyu.github.io/courses/2022-spring-cg.html

 

CGR LAB

Computer Graphics - 2022 Spring Instructor: Yoonsang Lee Teaching Assistant: Chaejun Sohn Undergraduate Mentor: Bokyoung Jang Time / Location: Mon 09:00-11:00 / Online (originally 207 IT.BT Building) - Lab Wed 09:00-11:00 / 508 IT.BT Building - Lecture Cou

cgrhyu.github.io

 

 

'Computer Science > Computer Graphics' 카테고리의 다른 글

Hierarchical Modeling  (0) 2021.05.31
Affine Transformation Matrix, Transformation의 해석  (0) 2021.05.31
Shading  (0) 2021.05.31
Lighting  (0) 2021.05.31
Mesh, OBJ File  (0) 2021.04.08

댓글