728x90

보통은 물체마다 '고유한'색이 있다고 생각한다.


하지만 엄밀히 물체는 광원으로부터 빛을 반사할 뿐이고


그 반사된 빛이 적색계열에 민감한 L형, 녹색계열에 민감한 M형, 청색계열에 민감한 S형


원추세포들의 반응에 따라 색을 구분한다. 


그래서 광원의 세기, 색 등에 따라 물체의 색은 달라질수있다.


컴퓨터에서도 원추세포들처럼 R, G, B값들의 조합에 따라 색을 표현한다.



빛을 컴퓨터상에서 표현할때 주로 rasterization과 ray tracing방식을 쓴다.


ray tracing방식은 계산비용이 커서 게임과 같은 실시간 렌더링에서는 쓰지 않는다.

(하드웨어의 발전으로 요새는 차차 쓰인다고 한다.)


그래서 rasterization방식을 이용하여 빛을 그리고 색을 표현해볼 것이다.




빛의 종류


빛은 크게 3가지로 추상화할 수 있다.


Ambient Light (주변광) : 수많은 반사를 거쳐서 광원이 불분명한 빛이다.

                           물체를 덮고 있는 빛이며 일정한 밝기와 색으로 표현된다.


Diffuse Light (분산광) : 물체의 표면에서 분산되어 눈으로 바로 들어오는 빛이다.

                          각도에 따라 밝기가 다르다.


Specular Light (반사광) : 분산광과 달리 한방향으로 완전히 반사되는 빛이다.

                            반사되는 부분은 흰색의 광으로 보인다.




Ambient Light


주변광의 경우 각도나 세기에 상관없이 물체나 배경에 '스며들어'있어 일정하다.


이렇게 생각하면 계산이 쉽다.



final color = material color * ambient light color

                      (반사계수. 즉 물체 색)     (주변광의 세기)



만약 물체의 색이 빨간색이고 주변광의 세기가 0.1이면


최종 물체의 색은 어둑어둑한 붉은색이 될 것이다.



final color = {1, 0, 0} * {0.1, 0.1, 0.1} = {0.1, 0.0, 0.0}




Diffuse Light


분산광의 경우 램버트 코사인 법칙을 이용한다.


먼저 표면 위치 벡터에서 빛 위치 벡터를 빼서 빛에서 표면으로 가는 벡터를 구하고


입사각의 코사인값을 구하기 위해 법선 벡터(Normal Vector)와 빛 벡터의 내적을 이용한다.


light vector = light position - object position
cosine = dot product(object normal, normalize(light vector))
lambert factor = max(cosine, 0)

이때 입사각이 90도가 넘으면 안보이는것 즉 코사인값이 -가 되므로 (0~180 일때)

위 lambert factor의 범위를 0~1로 한다.



한 점에서 빛은 멀어질수록 같은 면적에따른 빛의 세기가 약해진다. (역제곱 법칙)


luminosity = 1 / (distance * distance)


거리가 1보다 작을때를 위해 식을 수정하면


luminosity = 1 / (1 + (distance * distance))


최종적으로 분산광에 의한 물체 색이다.


final color = material color * (light color * lambert factor * luminosity)



램버트 코사인 법칙에 의한 분산광과 주변광에 의한 라이팅을 램버트 조명모델이라고 한다.


final color = material color * (ambient light color + diffuse light color)





Shader


// vertex를 카메라 공간으로

vec3 modelViewVertex = vec3(u_MVMatrix * a_Position);

//법선 벡터를 카메라 공간으로

vec3 modelViewNormal = vec3(u_MVMatrix * vec4(a_Normal, 0.0));

// 감쇠효과에 사용됨.

float distance = length(u_LightPos - modelViewVertex);

// 빛 방향 벡터 얻음.

vec3 lightVector = normalize(u_LightPos - modelViewVertex);

// 입사각의 코사인값 얻음.

float diffuse = max(dot(modelViewNormal, lightVector), 0.1);

// 거리에 따른 감쇠효과 적용 (0.08은 감쇠를 작게 하기 위함).

diffuse = diffuse * (1.0 / (1.0 + (0.08 * distance * distance)));

// 주변광 세기

float ambient = 0.05;

// fragmentShader에 넘길 색상값(최종색상).

v_Color = a_Color * (ambient + diffuse);

// 최종 위치

gl_Position = u_MVPMatrix * a_Position;




빛 적용 전



적용 후



--------------------------------------------------------------------------------------------------------------------

소스 및 참고 자료

728x90

'프로그래밍 > opengl' 카테고리의 다른 글

그래픽 파이프라인 모식도  (0) 2016.01.31
glLight* 함수  (0) 2015.02.20
glOrtho 함수  (0) 2015.02.17
typedef관련  (0) 2015.02.13
728x90


출처

728x90

'프로그래밍 > opengl' 카테고리의 다른 글

Ambient and Diffuse Lighting  (0) 2016.02.06
glLight* 함수  (0) 2015.02.20
glOrtho 함수  (0) 2015.02.17
typedef관련  (0) 2015.02.13
728x90

glLightfv(GL_LIGHT0, GL_POSITION, fLightPosMirror);



파라미터1 : 최소 GL_LIGHT0 ~ GL_LIGHT8 까지 8개의 광원을 개별적으로 정의&제어 할 수                   있음


파라미터2 : 특성 파라미터 아래 표 참고



파라미터3 : 광원의 색 (RGBA)

                 ex) GLfloat myLightColor[] = { 1.0, 0.0, 0.0, 1.0 };

728x90

'프로그래밍 > opengl' 카테고리의 다른 글

Ambient and Diffuse Lighting  (0) 2016.02.06
그래픽 파이프라인 모식도  (0) 2016.01.31
glOrtho 함수  (0) 2015.02.17
typedef관련  (0) 2015.02.13
728x90

glOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top,                                                              GLdouble nearVal, GLdouble farVal);


종횡비를 맞추어주는 함수.





가로 500 세로 500 이던 화면에서 가로를 늘려서


가로 1000 세로 500 인 화면일때


만약 정사각형 하나가 그려졌다면 정사각형은 가로로 2배 늘어난 정사각형이 되었을 것이다.


-))) vertex는 -1.0~1.0의 좌표를 사용하는데 변형 전 가로 0.1이 25이던것이

                                                         변형 후 가로 0.1이 50이 되기때문이다.


따라서 glOrtho 함수로 종횡비를 맞추어 주어야 한다.


glOrtho(-1,1,-1,1,1,-1) 이었다면

가로2배가 늘어났으므로

glOrtho(-2,2,-1,1,1,-1) 로 하면 된다.

728x90

'프로그래밍 > opengl' 카테고리의 다른 글

Ambient and Diffuse Lighting  (0) 2016.02.06
그래픽 파이프라인 모식도  (0) 2016.01.31
glLight* 함수  (0) 2015.02.20
typedef관련  (0) 2015.02.13
728x90




typedef GLfloat GLTVector4[4];



위 같이 쓰게되면


GLTVector4 a[4];


GLfloat v = a;


이렇게 쓰는게 아니라







GLfloat a[4];


GLTVector4 v = a;


이렇게 써야한다.





typedef 특성상 형식이 먼저 오고 그 다음 변환할 형식이 오는데..


ex> typedef unsigned int _Uint


형식의 배열을 해야 할 경우


typedef unsigned int[4] _U4int 로 해야겠지만


이렇게 안되게 되어있어서 어쩔 수 없이 


typedef unsigned int _U4int[4]




이런식으로 써야 한다.

728x90

'프로그래밍 > opengl' 카테고리의 다른 글

Ambient and Diffuse Lighting  (0) 2016.02.06
그래픽 파이프라인 모식도  (0) 2016.01.31
glLight* 함수  (0) 2015.02.20
glOrtho 함수  (0) 2015.02.17

+ Recent posts