Reflection of Light
Reflection of Light
- 빛은 object에 의해 흡수(absorbed), 발산(emitted), 산란(scattered), 반사(reflected), 굴절(refracted)된다
→ scattered: 대부분의 물체가 특정 색깔로 보이는 이유는, 산란 할 때 특정 파장은 흡수하고 특정 파장 반사하기 때문
→ reflected: 아주 매끄러운 물체에서 반사되면 그 물체는 거울처럼 보임
→ emitted: 달궈진 쇠공, 형광등
- Scattering이랑 reflection은 물체의 비주얼적인 특성을 결정하는 가장 핵심적인 요소
→ surface color, surface highlight 같은 특성..
- 컴퓨터 그래픽스에서는 scattering과 refletion을 합쳐서 reflection이라고 표현한다.
reflection은 크게 2가지로 나눠진다. diffuse reflection이랑 specular reflection
<Type of reflection>
1) Diffuse reflection
Specular reflection
→ 2) Ideal specular reflection
→ 3) Non-ideal specular reflection (gloomy reflection)
컴퓨터 그래픽스에선 위의 1), 2), 3) 3가지를 component로 modeling을 하는 경우가 가장 많다.
1) Diffuse Reflection
- 산란(scattering)에 해당하는 reflection
- 특정 빛의 파장을 모든 방향으로 고르게 scattering 한다.
→ 이걸로 물체의 suface color가 결정
- 모든 방향으로 고르게 빛을 반사하기 때문에(난반사) 어디서 보느냐와 상관이 없다. (View-independent)
![](https://blog.kakaocdn.net/dn/mOBLP/btrWfRM8xYv/0q1pA5cTpbsBz68NYsoCP1/img.png)
Diffuse Reflection - Lambert's Cosine Law
Diffuse Reflection은 램버트의 코사인 법칙이라는 Law를 따른다.
→ small surface area에서 반사되는 에너지는 incident light direction과 sufrace의 normal 이루는 각도의 cos 값에 비례한다
![](https://blog.kakaocdn.net/dn/FaUmY/btrWkv3Cs7Y/g8c1RKPskqATyMONCG1Eg1/img.png)
![](https://blog.kakaocdn.net/dn/1zlQi/btrWghEU1iw/Ge1YtTofU6ED496Jy1txkK/img.png)
2) Ideal Specular Reflection
- 거울과 같이 매우 잘 연마된 표면에서 일어나는 반사.
→ mirrored images 를 생성해낸다. (즉, 물체 표면에 거울처럼 비친 이미지를 만들어낸다는거)
- 한 방향으로 반사되므로 View-dependent
![](https://blog.kakaocdn.net/dn/bkqWAs/btrWdIcaVVP/kgWRwVdKNE0KS4KBA99Dnk/img.png)
Ideal Specular Reflection - Laws of Reflection
Ideal Specular Reflection은 Laws of Reflection(반사의 법칙)을 따른다.
![](https://blog.kakaocdn.net/dn/DInvO/btrWeeaPiIE/94ZtmXNoanU5bkEdTdW7e0/img.png)
3) Non-Ideal Specular Reflection (a.k.a. Glossy Reflection)
- 거울만큼 매끄럽진 않은 shiny & glossy surface에서 일어나는 반사 (전반사라고도 부름)
- suface의 거친 정도에 따라 반사되는 빛이 퍼져나간다.
→ 이가 highlight를 생성시킨다.
- 내가 움직이면 highlight 위치가 변함. 즉, View-dependent 하다.
Reflection of General Materials
- 대부분의 물체의 suface에서는 diffuse reflection과 specular reflection이 같이 일어난다.
![](https://blog.kakaocdn.net/dn/Zfgbc/btrWghdRBAK/XHf0Wu33HfAlQDb5JrUpuK/img.png)
Quiz #1
![](https://blog.kakaocdn.net/dn/bxO3C8/btrWeHD0SK0/lNqtWQ9IkokuhfFkwwL8Fk/img.png)
Phong Illumination Model
Lighting (or Illumination) → 컴퓨터 그래픽스에서 두 용어는 같은 의미임
- Lighting(or Illumination) : 빛의 효과를 계산하는 과정을 이야기한다.
→ 즉, surface color와 highlights of object 를 계산하는거
- 빛의 효과를 계산하기 위해(Lighting을 위해) 세우는 모델
→ Lighting Model 또는 Illumination Model 이라고 부른다.
Phong Illumination Model
- 가장 흔하게 쓰이는 Illumination Model 중 하나
- classical illumination model 이다.
→ 실험적으로 결정된 모델이라는 말이다. 물리적인 법칙을 충분히 재현한게 아님
(요즘은, physically based rendering 기법들이 사용되기도 하는데 일단 Phong Illumination Model은 아님)
- 3가지 component를 가진다.
1) Ambient
→ 사실 물체는 광원에게만 영향(direct lighting)을 받는게 아니다. 물체의 표면 사이에도 빛을 주고받는다.(indirect lighting)
→ 이걸 일일히 계산하는건 매우 힘드므로 물체 전체에 아주 약한 reflect ray가 있다고 가정해버린거.
(Crudest(대충의) approximation for indirect lighting)
→ 물체의 법선벡터 이런거 신경안쓰고 물체의 모든부분에서 동일한 Intensity로 빛이 나온다고 생각하고 아주 약하게 색을 입힘
2) Diffuse
→ 우리가 앞서 배웠던 diffuse와 같은 의미임
→ Lambert's model에 근거해 색깔을 입힌거
→ 근데 view-independent 면 ambient처럼 색 고르게 입혀야하는거 아닌가? 그게 아님. 광원과 물체가 고정되어있을 때
특정 point의 색깔은 우리가 시선을 옮겨도 안변한다는거지. 물체 전체의 색이 같다는게 아님
3) Specular
→ Hightlight만 다룬다.
→ glossy reflection 에 근접하기 위해 를 사용한다.
n 이 커지면 알파값이 커지면 전체 value가 훅훅 줄어든다. 즉 좁게 퍼지는거 (매끄러움)
n 이 작아지면 알파값이 커져도 전체 value가 훅훅 안줄어든다. 즉 넓게 퍼지는거 (거칠다)
![](https://blog.kakaocdn.net/dn/2MeWn/btrWlkOpaLe/x8Z0YmehMO4KCPv8m0sY40/img.png)
Ambient Light
![](https://blog.kakaocdn.net/dn/dBDxOm/btrWc1Xs8WI/RYFshy7uPvefQJpBHYvw70/img.png)
- : ambient light(주위 빛)의 intensity (이건 색깔 정하는 느낌)
😀 light color와 martial color 를 곱한 값임
- : ambient reflection coefficient (이건 얼마나 밝게 할지 정하는 느낌)
→ 사실 이거 3개의 식임 가 사실 ( (red), (green), (blue)) 로 나누어짐.
→ 두 요소를 조절하면서 마음에 드는 값으로 디자이너가 튜닝하면 된다.
→ 는 물체 surface의 임의의 지점에 대해 계산된다.
![](https://blog.kakaocdn.net/dn/tXN2C/btrWdgmEAXQ/oatSpkXNp0Z1S7UR00yH4k/img.png)
→ Ambient light으로 렌더링한 결과. 아주 약하게 color를 입혔다.
→ 빛의 color는 모두 동일하지만 material color가 모두 달라서 물체마다 색이 다르게 입혀짐
Diffuse Light
![](https://blog.kakaocdn.net/dn/LIKSP/btrWmlTXLB4/VvfKYDF7Dt6fxUldQSEFBk/img.png)
- : intensity of light source (ambient light와 마찬가지로 red, green, blue에 대한 3개의 식임) (색깔 정하는 느낌)
😀 light color와 material color를 곱한 값임
- : diffuse reflection coefficient (얼마나 밝게 할지 정하는 느낌)
- . : normal vector와 light direction vector가 이루는 각도
→ 는 물체 surface의 임의의 지점에 대해 계산된다.
→ Diffuse Light는 우리가 배웠던 diffuse임. 즉, Lambert's Cosine Law를 따라야한다. 이때문에 식에 cos(theta)가 있음.
![](https://blog.kakaocdn.net/dn/bSDuFB/btrWdokCpmj/I2MdwfNwzp4PRwWruyKqUk/img.png)
→ Ambient Light를 적용한 결과에 Diffuse Light를 적용한 결과를 합친거
→ 아직 Specular Light 의 결과를 적용하지 않아서 매트한 무광재질로 보인다.
Specular Light
![](https://blog.kakaocdn.net/dn/cKRYG3/btrWdnF2jGH/qAW7ECBRzy5CwWnZjbmgj1/img.png)
- : intensity of light source (이것도 사실 3개의 식임)
😀 이건 light color (material color 반영되지 않은 값)
- : specular reflection coefficient
- : reflected vector (R)과 eye (E) 사이의 각도 (그치, reflect vector에서 멀어질수록 덜 하얗게 보이는게 맞지)
- : shininess coefficient (n이 클수록 매끄러운 surface, n이 작을수록 거칠거칠한 surface)
![](https://blog.kakaocdn.net/dn/bsMumR/btrWdHxBguF/eO24KISCJ3SiNh1i6I78D1/img.png)
→ Ambient Light와 Diffuse Light를 적용한 결과에 Specular Light까지 적용한 결과
→ n 이 커질수록 덜퍼진다. (한방향에 가까워지는거. 거울이 한방향으로 반사되니까 n 이 커질수록 매끄러운거)
Quiz #2
![](https://blog.kakaocdn.net/dn/cZFHop/btrWccSEzpP/meK8vRpOCKrhsWLFSkjVh1/img.png)
Shading
Shading - General Meaning
빛에 strongly 하게 affected 되는 물체에 생기는 색깔의 변화를 의미한다.
Shading - Meaning in Computer Graphics
<컴퓨터 그래픽스에서 shading의 의미는 더 협소하다>
😀illumination model에 근거해 polygon 안의 각 픽셀의 color를 결정하는 과정을 shading이라고 한다.
![](https://blog.kakaocdn.net/dn/qo0fv/btrWeYlh7uJ/oKvNTgMMdKEOihkIYlkwB0/img.png)
→ 셋은 모두 같은 mesh 모델을 사용했다.
→ wireframe이 왼쪽과 같이 있을때 2번째와 3번째는 서로 다른 shading model을 사용했다.
→ shading 모델에 따라 2번째처럼 각져보일수도 있고 3번째처럼 둥글게 보일수도 있다.
→ illumination 모델은 빛의 direction vector와 normal vector를 사용해서 색깔을 정하는 모델이였음.
Shading 모델에서는 surface 상에서 normal vector를 어떻게 설정하는지 명시한다.
Surface Normal
- Shading을 이야기 하기 위해서는 surface normal 이야기가 반드시 나와야한다.
- normal vector는 shading 과 illumination model 상에서 모두 중요한 역할을 한다.
(diffuse reflection 이랑 specular reflection 할 때 모두 사용되었음)
Face Normal
- 하나의 polygon surface의 Normal
- 삼각형 <p1, p2, p3>의 normal은 v1 X v2를 해서 쉽게 구할 수 있다.
![](https://blog.kakaocdn.net/dn/bSOIny/btrWfQgm4nQ/LxWyX4kJUIqqjzBb4rSKsK/img.png)
→ face normal의 방향을 face의 outside로 취급하기 때문에 우리가 vertex ordering을 할 때 couterclockwise로 한 거임
Flat Shading
- 하나의 polygon 당 하나의 face normal 사용
→ 실제로 normal vector 한 surface에서 같긴하지만 illumination model에서 Normal vector랑 빛의 방향 vector
사용해서 계산을 하는데 이 두 벡터가 동일하니까 한 polygon 상에서 픽셀 색상이 모두 동일한거임
- polygon의 center에서 color 계산해서 polygon 전체에 적용.
- 빠르지만 curved shape에 적용하기 바람직하지 않다.
![](https://blog.kakaocdn.net/dn/tMCBc/btrWdokCpzk/1ww46zxhPU6KXeXuaRHNAk/img.png)
→ 오른쪽처럼 curved shape 에선 각져보여서 바람직하지 않음.
→ polygon 수를 늘리면 조금은 자연스러워지긴 하지만 여전히 어색하다.
→ 참고로 한 vertex가 여러개 normal vector 가지는건 우리 배우는 것중엔 flat shading 뿐. Gouraurd와 Phong shading 모두 한 vertex 당 1개
Smooth Shading
- flat shading을 할 경우 curved shapes에서 각져보이기 때문에 curved shape의 경우 smooth shading을 한다.
- Smooth Shading은 2개의 인접한 polygons 사이에 color transition(그라데이션)이 이루어진다.
- face마다 face normal을 하나로 다루지 않고 vertex마다 vertex normal을 사용한다.
→ vertex normal이 어딨냐? → 이렇게 구한다.
→ 인접한 polygon의 face normal의 평균을 vertex normal로 정한다.
- Smooth shading에는 2가지 방법이 있음.
1) Gouraud shading
2) Phong shading
Smooth shading -1) Gouraud Shading
- 각 vertex마다 vertex normal을 계산해서 각 vertex에서의 색깔을 구한다.
- 계산된 vertex color를 사용해서 polygon 안에서 Interpolate한다.
→ 이때 하는 interpolation을 Barycentric interpolation이라고 부른다.
![](https://blog.kakaocdn.net/dn/3mSwR/btrWc2296yF/et97gfzyw4kvxLY3KpTTUK/img.jpg)
→ 같은 Mesh model을 사용했음. Gouraud Shading의 결과를 보면, Flat shading보다 훨씬 부드러워보임.
→ 근데 아주 부드러운 것도 아님. highlight를 적용하면 좀 이상해보임.
Gouraud shading problem
specular highlight가 왜곡되거나 주변이랑 평균이 되면서 사라질 수 있음
Smooth shading - 2) Phong Shading
- 각 vertex 마다 normal vector 하나씩만 사용한다. (Gouraud shading과 같은 점)
- 근데 polygon 안에 있는 모든 픽셀에 대해 Barycentric interpolation을 사용해 normal vetor를 계산해서 픽셀의 color를 각각 구한다.
(즉, Gouraud shading처럼 color를 interpolation 하는게 아니라 normal vector를 interpolation 하는거)
- Gouraud shading의 경우 삼각형일때 normal vector 3개만 구하면 되는데 phong shading에선 Polygon 안에 있는 픽셀 수 만큼 계산해야함
→ 계산량 많아지지만 괜찮다. 요즘 GPU에선 큰 문제 없음(실시간 렌더링 가능).
하지만 legacy OpenGL을 쓸 당시의 GPU에선 실시간으로 렌더링 불가.
그래서 legacy OpenGL에서는 Phong Shading을 지원하지 않는다.
- highlights가 훨씬 자연스럽다.
→ 왜? Interpolated 된 normal vector가 실제 normal vector의 꽤 휼륭한 approximation이기 때문에.
Lighting & Shading in OpenGL
To do Lighting & Shading in OpenGL
- 일단, OpenGL에서 vertex normal을 set 해줘야한다
- 앞에 수업 시간에서 vertex는 4개의 attribute를 갖는다고 했었음.
→ vertex coordinate, vertex color, normal vector, texture coordinate 이 4개 중 Noraml vector를 지정
Shading in OpenGL
- Flat shading
→ 한 polygon를 형성하는 vertex의 normal vector를 모두 동일하게 지정.
→ 만약 여러 polygon에 속하는 vertex라면 이 polygon을 지정할 땐 이 normal vector로 지정하고
저 polygon을 지정할 땐 저 normal vector로 지정하고~~(즉, 한 vertex가 여러개의 normal vector를 가지는셈)
![](https://blog.kakaocdn.net/dn/bnG3hl/btrWcbzmT9n/h5nilyeODXZfvbHdKjaEU1/img.png)
→ legacy OpenGL에서는 Gouraud shading 에서처럼 vertex color를 interpolated 시키는게 디폴트임
(Gouraud shading이 디폴트는 아니고 vertex color들을 interpolated 시키는게 디폴트)
즉 vertex 색깔에 따라 한 polygon 안에서 그라데이션을 하는데
여기서는 한 polygon의 vertex normal vector가 같으니까 illumination model에 의해 vertex 색깔이 같아짐.
같은 색깔끼리 그라데이션 해봤자 단색이니까 Flat shading에서는 한 polygon의 색깔은 단색
- Gouraud shading
→ OpenGL에서 Gouraud shading의 결과를 이끌어내려면 각 vertex의 normal을 주변 face normal의 average로 set 하면 된다.
→ 각 vertex는 normal vector 하나씩만 가진다.
![](https://blog.kakaocdn.net/dn/bstnB2/btrWjmeDK5E/IXro6STJNfrLKJMbCkkkLk/img.png)
- Phong shading
→ legacy OpenGL에서 불가.
→ polygon의 vertex normal vector 정해줬을때 polygon 내부의 모든 픽셀에 대해서 normal vector를 정해주는 기능 제공 X
Setting Vertex Normals in OpenGL
Setting Vertex Normals in OpenGL
- 앞에처럼 normal을 hare-coding 하거나 vertex position을 기준으로 normal을 계산할 수 있음. (삼각형의 경우 v1 X v2)
- 근데 가장 많이 사용하는 방법은 .obj files 으로부터 normal vector를 읽어오는거!
블렌더같은 프로그램에서 obj 파일을 저장할때 normal vector도 같이 저장되므로 그 정보들을 읽어오면 된다.
Lighting(= Illumination) in OpenGL
- legacy OpenGL에서 Lighting은 매우 제약적이다.
→ Blinn-Phoing illumination Model 밖에 못쓴다. (Phong illumination model 에서 계산량을 좀 줄이도록 개선된 모델)
- glEnable(GL_LIGHTING)
→ enable lighting. 이거 해줘야한다.
- glEnable(GL_LIGHT0) (GL_LIGHT0 ~ GL_LIGHT7)
→ 위에 glEnable(GL_LIGHTING) 하고 이거도 또 해주는거임
→ legacy OpenGL에서 8가지의 Light source를 사용할 수 있다. glEnable를 하면서 무슨 light source를 쓸지 말해줘야한다.
glLightfv()
- light property를 주는 함수이다.
- glLightfv(light, pname, parma)
→ light: assign 하려는 light의 종류. (GL_LIGHT0~GL_LIGHT7)
→ pname: parameter name (GL_AMBIENT, GL_DIFFUSE, GL_SPECULAR, GL_POSITION)
(사실 빛에 ambient color, diffuse color, specular color 왜 있어야하는지 잘모르겠지만...
polygon color는 ambient, diffuse, specular component들의 합으로 결정되는데
이거 구할때 빛의 color랑 물체 color 곱한값을 씀
그때 곱할려고 각각의 요소에 대응되는 color를 만들어준다고 이해해야할것 같다.)
→ param: parameter value
![](https://blog.kakaocdn.net/dn/s5UP5/btrWc3udnew/QogJLH2E14FY6qEYPadmlK/img.png)
glMaterialfv()
- 물체 표면 결정 결정하는 함수이다.
- glMaterialfv(face, pname, param)
→ face: 이 함수를 통해 설정할 face (GL_FRONT, GL_BACK, GL_FRONT_AND_BACK)
앞면 설정할건지, 뒷면 설정할건지, 아님 둘다 설정할건지
→ pname: parameter name
GL_AMBIENT, GL_DIFFUSE, GL_SPECUAR
GL_AMBIENT_AND_DIFFUSE (물체의 ambient color와 diffuse color를 보통 같게 주다보니 이런 parameter name 생김)
GL_SHINESS: glLightfv()에서 없었던거. 물체의 매끄러운 정도를 의미하는데 광원이 매끄러운 정도를 지정하는건 이상
I = C_s k_s cos^n(alpha) 식에서 n을 지정하는거임 (0~128)의 숫자로 shininess coefficient를 지정한다.
Good Setting for glLightfv() & glMaterialfv()
보통 추천되는 방식은 아래와 같다.
- glLightfv()
GL_DIFFUSE, GL_SPECULAR: light source의 색깔로 결정하기
GL_AMBIENT: 같은 color로 하되, 훨씬 작은 intensity로 하기 (about 10%)
(gl_Materialfv에선 GL_DIFFUSE, GL_AMBIENT를 같은 색, intensity로 하니까 AMBIENT 어두워야하는걸 glLightfv에서 조절)
- glMaterialfv()
GL_DIFFUSE & GL_AMBIENT: Color of Object
GL_SPECULAR: White(1, 1, 1)
→ GL_SPECULAR을 (1, 1, 1)로 세팅해야 highlight의 색깔이 광원의 색깔로 그대로 나온다.
- Final color는 ambient, diffuse, specular component의 합으로 나온다. 이 각각의 component는
glMaterial color와 glLight color의 곱으로 형성된다.
Normals with Lighting
- OpenGL에서 normal vectors는 항상 unit length를 가져야한다.
- Normal vecotrs는 GL_MODELVIEW matrix에 의해 형성되는데
modeview transformation 과정에서 normal vector의 길이 바뀔수 있음
별도의 처리를 하지 않으면 unit length 가지지 않아서 scaling 작업이 필요하다.
- renormalize를 하기 위해선 아래의 2가지 중 하나를 해야한다.
glEnable(GL_NORMALIZE) : 이거 하면 modelview transform 한 다음에 길이 1 되도록 normalize를 한다.
glEnable(GL_RESCALE_NORMAL) : 이거 하면 더 빠르다. 근데 처음에 주어진 normal vector가 unit vector여야하고
uniform scaling에 대해서만 제대로 작동한다는 제약조건이 있음
→ 그냥 glEnable(GL_NORMALIZE) 써라!!
[Practice] OpenGL Lighting
![](https://blog.kakaocdn.net/dn/kYV7H/btrWdox9sqy/Fny39INMmGcaCcXegMy8MK/img.png)
![](https://blog.kakaocdn.net/dn/cUA3cA/btrWdn0j0cb/8iPdtphhZOFoBBS3dsIPuk/img.png)
glNormalPointer()
![](https://blog.kakaocdn.net/dn/Dh5ok/btrWdn0j0su/K16bEDkL93mdZzUrf3kIUK/img.png)
Uploaded by N2T