76
블블블 블블블블블블 , 블블블블 블블블 블블블 블블블

블렌딩 안티앨리어싱 , 안개효과 그리고 폴리곤 오프셋

  • Upload
    dara

  • View
    128

  • Download
    0

Embed Size (px)

DESCRIPTION

블렌딩 안티앨리어싱 , 안개효과 그리고 폴리곤 오프셋. 내용. 블렌딩 물체를 반투명하게 나타내는 기법 안티앨리어싱 가장자리를 부드럽게 처리 안개 효과 화면을 사실적으로 나타내는 기법 폴리곤 오프셋 교차되는 도형을 깔끔하게 나타냄. 블렌딩. 블렌딩이 활성화 되어 있을 경우 알파값은 프레임 버퍼에 저장되어 있는 픽셀의 컬러와 프레그먼트의 픽셀의 컬러값을 결합하는데 사용 - PowerPoint PPT Presentation

Citation preview

Page 1: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

블렌딩 안티앨리어싱 , 안개효과 그리고 폴리곤 오프셋

Page 2: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 2

내용

블렌딩

물체를 반투명하게 나타내는 기법

안티앨리어싱

가장자리를 부드럽게 처리

안개 효과

화면을 사실적으로 나타내는 기법

폴리곤 오프셋

교차되는 도형을 깔끔하게 나타냄

Page 3: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 3

블렌딩

블렌딩이 활성화 되어 있을 경우 알파값은 프레임 버퍼에 저장되어 있는 픽셀의 컬러와

프레그먼트의 픽셀의 컬러값을 결합하는데 사용

블렌딩 연산은 장면이 레스터화되고 , 프레그먼트로 전환된 후 프레임버퍼의 마지막 픽셀이 그려지기 전에 수행

블렌딩을 하지 않으면 새로운 프레그먼트들은 프레임버퍼에 있는 기존의 컬러값을 덮어쓰게 됨

프레그먼트의 RGB 성분은 컬러를 나타내고 , 알파 성분은 투명도를 나타낸다고 생각

Page 4: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 4

입력값 요소와 기존값 요소

블렌딩을 하는 동안 프레그먼트의 컬러값과 현재 저장된 픽셀의 컬러값은 2 단계의 과정을 거쳐 결합

입력값 (source) 요소와 기존값 (destination) 요소의 계산 방식을 설정하고 입력값과 기존값을 서로 대응되는 요소들끼리 곱해줌

입력값과 기존값에 있는 RGBA 값들을 더한다 . (RsSr+RdDr, GsSg+GdDg, BsSb+BdDb,

AsSa+AdDa)

Page 5: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 5

입력값 블렌딩 요소와 기존값 블렌딩 요소가 만들어지는 방법

두 개의 상수를 만들기 위해 glBlendFunc() 사용 두 가지 상수 중 하나는 입력값 요소가 계산되는 방법 결정 다른 하나는 기존값 요소가 계산되는 방법 결정

glEnable(GL_BLEND) 로 활성화 기본값 : GL_ONE( 입력값 ), GL_ZERO( 기존값 ) => 블렌딩

비활성화

void glBlendFunc(GLenum sfactor, GLenum dfacor);

프레그먼트에 있는 컬러값 ( 입력값 ) 과 프레임 버퍼에 있는 컬러값 (기존값 ) 이 결합되는 방식을 설정

sfactor : 입력값의 블렌딩 요소를 계산하는 방법 dfactor : 기존 값의 블렌딩 요소가 계산되는 방법 각 요소들은 [0,1] 사이의 값을 가짐 결합된 입력값과 기존값의 컬러값도 [0, 1] 구간으로 클램프됨

Page 6: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 6

블 렌 딩

입력값 블렌딩 요소와 기존값 블렌딩 요소들

상수 관련 요소 계산된 블렌딩 요소

GL_ZERO 입력값 , 기존값 (0, 0, 0, 0)

GL_ONE 입력값 , 기존값 (1, 1, 1, 1)

GL_DST_COLOR 입력값 (Rd, Gd, Bd, Ad)

GL_SRC_COLOR 기존값 (Rs, Gs, Bs, As)

GL_ONE_MINUS_DST_COLOR

입력값 (1,1,1,1)-(Rd,Gd,Bd,Ad)

GL_ONE_MINUS_SRC_COLOR

기존값 (1,1,1,1)-(Rs,Gs,Bs,As)

GL_SRC_ALPHA 입력값 . 기존값 (As, As, As, As)

Page 7: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 7

블 렌 딩

GL_ONE_MINUS_SRC_ALPHA

입력값 , 기존값 (1,1,1,1)- (As, As, As, As)

GL_DST_ALPHA 입력값 , 기존값 (Ad, Ad, Ad, Ad)

GL_ONE_MINUS_DST_ALPHA

입력값 , 기존값 (1,1,1,1)- (Ad, Ad, Ad, Ad)

GL_SRC_ALPHA_SATURATE

입력값 (f, f, f, 1); f=min(As,1-Ad)

GL_CONSTANT_COLOR 입력값 , 기존값 (Rc, Gc, Bc, Ac)

GL_ONE_MINUS_CONSTANT_COLOR

입력값 , 기존값 (1,1,1,1)-(Rc,Gc,Bc,Ac)

GL_CONSTANT_ALPHA 입력값 , 기존값 (Ac, Ac,Ac,Ac)

GL_ONE_MINUS_CONSTANT_ALPHA

입력값 , 기존값 (1,1,1,1)-(Ac,Ac,Ac,Ac)

Page 8: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 8

블 렌 딩블렌딩을 사용한 샘플들

입력값 요소와 기존값 요소의 모든 조합을 사용할 수 있는 건 아님

대부분 응용 프로그램에서는 몇 가지 조합만 사용

하나의 이미지와 또 다른 이미지를 절반씩 그릴 때 ( 두 이미지를 동등한 비율로 혼합하여 그릴 때 )

입력값 요소를 GL_ONE 으로 , 기존값 요소를 GL_ZERO 로 놓고 첫번째 그림을 그린 후 ,

입력값 요소를 GL_SRC_ALPHA 로 설정 , 기존값 요소를 GL_ONE_MINUS_SRC_ALPHA 로 설정 , 알파값을 0.5 로 놓고 두 번째 그림을 그림

첫 번째 그림을 0.75, 두 번째 그림을 0.25 정도의 비율로 섞고 싶을 경우에는 , 첫 번째 그림은 위와 동일하게 , 두 번째 그림은 알파값을 0.25 로 설정하여 그림

Page 9: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 9

3 개의 서로 다른 그림을 균일하게 섞고 싶은 경우 기존값 요소를 GL_ONE 으로 설정 , 입력값 요소를

GL_SRC_ALPHA 로 설정 후 그림의 알파값을 0.3333333으로 똑같이 놓고 그림

현재 이미지에 관계 없이 브러쉬로 칠할 때 마다 색이 덧입혀지도록 만들고 싶은 경우

10% 의 알파값과 GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA 이용 , 브러쉬 이미지를 표현

블렌딩 함수의 입력값 요소로 GL_DST_COLOR 또는 GL_ONE_MINUS_DST_COLOR 를 사용 , 기존값 요소로 GL_SRC_COLOR 또는 GL_ONE_MINUS_SRC_COLOR 를 사용 하면 각 컬러 요소들을 개별적으로 조절 가능

Page 10: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 10

3 개의 반투명한 면으로 구성된 그림을 그릴 때 몇몇 오브젝트들이 다른 오브젝트들을 가리고 있고 , 모든 오브젝트들이 솔리드 배경 위에 놓여 있는 경우

가장 멀리 있는 면은 배경 컬러의 80%, 그 다음이 40%, 가장 가까운 면이 90% 컬러를 전달하려면

입력값 요소와 기존값 요소를 기본값으로 설정 블렌딩 요소의 입력값은 GL_SRC_ALPHA, 기존값은

GL_ONE_MINUS_SRC_ALPHA 로 바꿈 알파값은 차례로 0.2, 0.6, 0.1 로 설정

투명하게 처리해서 보이지 않게 만들려는 프레그먼트에 대해서는 알파값을 0 으로주고 , 불투명한 프레그먼트에 대해서는 알파값을 1.0 으로 준다 .

이런 식으로 이미지에 있는 개별적인 프레그먼트에 서로 다른 알파값을 할당하면 직사각형이 아닌 래스터 이미지 효과를 낼 수 있다 .

Page 11: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 11

예제 6-1 블렌딩 예제 : alpha.c

서로 겹쳐진 두 개의 컬러 삼각형

include <GL/glut.h>#include <stdlib.h>

static int leftFirst = GL_TRUE;

/* 알파 블렌딩 함수 초기화 */static void init(void){ glEnable (GL_BLEND); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glShadeModel (GL_FLAT); glClearColor (0.0, 0.0, 0.0, 0.0);}

Page 12: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 12

static void drawLeftTriangle(void){ // draw a yellow triangle glBegin (GL_TRIANGLES); glColor4f(1.0, 1.0, 0.0, 0.75); glVertex3f(0.1, 0.9, 0.0); glVertex3f(0.1, 0.1, 0.0); glVertex3f(0.7, 0.5, 0.0); glEnd();}

static void drawRightTriangle(void){ // draw a cyan triangle glBegin (GL_TRIANGLES); glColor4f(0.0, 1.0, 1.0, 0.75); glVertex3f(0.9, 0.9, 0.0); glVertex3f(0.3, 0.5, 0.0); glVertex3f(0.9, 0.1, 0.0); glEnd();}

Page 13: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 13

void display(void){ glClear(GL_COLOR_BUFFER_BIT);

if (leftFirst) { drawLeftTriangle(); drawRightTriangle(); } else { drawRightTriangle(); drawLeftTriangle(); }

glFlush();}

Page 14: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 14

void reshape(int w, int h){ glViewport(0, 0, (GLsizei) w, (GLsizei) h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if (w <= h) gluOrtho2D (0.0, 1.0, 0.0, 1.0*(GLfloat)h/(GLfloat)w); else gluOrtho2D (0.0, 1.0*(GLfloat)w/(GLfloat)h, 0.0, 1.0);}

Page 15: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 15

void keyboard(unsigned char key, int x, int y){ switch (key) { case 't': case 'T': leftFirst = !leftFirst; glutPostRedisplay(); break; case 27: /* Escape key */ exit(0); break; default: break; }}

Page 16: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 16

int main(int argc, char** argv){ glutInit(&argc, argv); glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB); glutInitWindowSize (200, 200); glutCreateWindow (argv[0]); init(); glutReshapeFunc (reshape); glutKeyboardFunc (keyboard); glutDisplayFunc (display); glutMainLoop(); return 0;}

Page 17: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 17

Page 18: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 18

깊이 버퍼를 이용한 3 차원 블렌딩 폴리곤이 그려지는 순서는 블렌딩의 결과에 많은 영향을 미침

3 차원의 반투명한 물체를 그릴 때는 앞에서부터 뒤로 그릴 것인지 , 뒤에서부터 앞으로 그릴 것인지에 따라 다른 결과를 얻을 수 있음 .

깊이버퍼에는 스크린의 윈도우상의 물체 중에서 주어진 픽셀이 차지하고 있는 부분과 시점 사이의 거리가 기록

한 화면에 불투명 오브젝트와 반투명 오브젝트 모두를 그릴 때는 불투명한 오브젝트의 뒤에 가려진 부분이 그려지지 않도록 깊이버퍼를 사용

Page 19: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 19

반투명한 오브젝트가 가까이 있는 경우에는 불투명한 오브젝트의 컬러와 블렌딩한다 .

반투명한 오브젝트를 그리는 동안 깊이 버퍼를 활성화시키되 읽기 전용 상태로 둔다 .

glDepthMask() 함수 이용 인자로 GL_FALSE 를 주면 버퍼는 읽기 전용 ,

GL_TRUE 면 쓰기 가능 그리는 방법

먼저 깊이 버퍼를 사용하여 불투명한 오브젝트를 그린 후 깊이 버퍼를 읽기 전용 상태로 만들고 , 반투명한 물체를

그리면서 불투명한 오브젝트의 깊이버퍼값과 비교함 .

Page 20: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 20

예제 6-2 3 차원 블렌딩 : alpha3D.c

#include <GL/glut.h>#include <stdlib.h>#include <stdio.h>

#define MAXZ 8.0#define MINZ -8.0#define ZINC 0.4

static float solidZ = MAXZ;static float transparentZ = MINZ;static GLuint sphereList, cubeList;

static void init(void){ GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 0.15 }; GLfloat mat_shininess[] = { 100.0 }; GLfloat position[] = { 0.5, 0.5, 1.0, 0.0 };

Page 21: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 21

glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess); glLightfv(GL_LIGHT0, GL_POSITION, position);

glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_DEPTH_TEST);

sphereList = glGenLists(1); glNewList(sphereList, GL_COMPILE); glutSolidSphere (0.4, 16, 16); glEndList();

cubeList = glGenLists(1); glNewList(cubeList, GL_COMPILE); glutSolidCube (0.6); glEndList();}

Page 22: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 22

void display(void){ GLfloat mat_solid[] = { 0.75, 0.75, 0.0, 1.0 }; GLfloat mat_zero[] = { 0.0, 0.0, 0.0, 1.0 }; GLfloat mat_transparent[] = { 0.0, 0.8, 0.8, 0.6 }; GLfloat mat_emission[] = { 0.0, 0.3, 0.3, 0.6 };

glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glPushMatrix (); glTranslatef (-0.15, -0.15, solidZ); glMaterialfv(GL_FRONT, GL_EMISSION, mat_zero); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_solid); glCallList (sphereList); glPopMatrix ();

Page 23: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 23

glPushMatrix (); glTranslatef (0.15, 0.15, transparentZ); glRotatef (15.0, 1.0, 1.0, 0.0); glRotatef (30.0, 0.0, 1.0, 0.0); glMaterialfv(GL_FRONT, GL_EMISSION, mat_emission); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_transparent); glEnable (GL_BLEND); glDepthMask (GL_FALSE); // Depth 버퍼가 읽기전용 상태로 됨 glBlendFunc (GL_SRC_ALPHA, GL_ONE); glCallList (cubeList); glDepthMask (GL_TRUE); // Depth 버퍼가 쓰기전용 상태로 됨 glDisable (GL_BLEND); glPopMatrix ();

glutSwapBuffers();}

Page 24: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 24

void reshape(int w, int h){ glViewport(0, 0, (GLint) w, (GLint) h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if (w <= h) glOrtho (-1.5, 1.5, -1.5*(GLfloat)h/(GLfloat)w, 1.5*(GLfloat)h/(GLfloat)w, -10.0, 10.0); else glOrtho (-1.5*(GLfloat)w/(GLfloat)h, 1.5*(GLfloat)w/(GLfloat)h, -1.5, 1.5, -10.0, 10.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity();}

Page 25: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 25

void animate(void){ if (solidZ <= MINZ || transparentZ >= MAXZ) glutIdleFunc(NULL); else { solidZ -= ZINC; transparentZ += ZINC; glutPostRedisplay(); }}

Page 26: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 26

void keyboard(unsigned char key, int x, int y){ switch (key) { case 'a': case 'A': solidZ = MAXZ; transparentZ = MINZ; glutIdleFunc(animate); break; case 'r': case 'R': solidZ = MAXZ; transparentZ = MINZ; glutPostRedisplay(); break; case 27: exit(0); }}

Page 27: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 27

int main(int argc, char** argv){ glutInit(&argc, argv); glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB |

GLUT_DEPTH); glutInitWindowSize(500, 500); glutCreateWindow(argv[0]); init(); glutReshapeFunc(reshape); glutKeyboardFunc(keyboard); glutDisplayFunc(display); glutMainLoop(); return 0;}

Page 28: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 28

실행결과

Page 29: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 29

안티앨리어싱 수평이나 수직에 가까운 선들이 울퉁불퉁하게 보이는 것을

앨리어싱이라 함 안티앨리어싱 : 앨리어싱을 줄이는 방법 그림의 조각이 덮고 있는 픽셀 조각에 기초하여 각 프레그먼트에

대한 적용범위 (Coverage) 를 계산한다 . RGBA 모드에서는 프레그먼트의 알파값과 적용범위값을

곱한다 . 컬러인덱스모드에서는 프레그먼트 적용범위에 기초해서

컬러 인덱스의 하위 4비트를 설정한다 . 0000: 적용범위 없음 1111: 적용범위가 전체

Page 30: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 30

void glHint(GLenum target, GLenum hint)

이 함수는 OpenGL 의 특정한 동작을 제어 적용범위의 계산은 복잡하고 OpenGL 구현마다 달라질 수

있으므로 glHint() 를 사용하여 제어 target : 제어할 동작을 나타냄 hint :

효율적으로 동작하도록 설정할 때 GL_FASTEST 지정 최고의 품질로 이미지 생성 때 GL_NICEST 를 지정 별도로 지정하고 싶지 않을 때 GL_DONT_CARE 선택

Page 31: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 31

glHint() 에서 사용하는 값들 : target 인자값

매개변수 설명

GL_POINT_SMOOTH_HINT, GL_LINE_SMOOTH_HINT, GL_POLYGON_SMOOTH_HINT

안티앨리어싱 작업에서 점이나 선 , 또는 다각형의 샘플링 품질을 설정

GL__FOG_HINT 안개 효과 계산이 픽셀마다 이루어지는지(GL_NICEST), 정점마다 이루어지는지(GL_FASTEST) 여부를 설정

GL_PERSPECTIVE_CORRECTION_HINT

컬러와 텍스처 좌표 보간의 품질을 설정

Page 32: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 32

점과 선에 대한 안티앨리어싱

점이나 선을 안티앨리어싱 하려면 먼저 glEnable() 함수로 안티앨리어싱 모드를 활성화

GL_POINT_SMOOTH 나 GL_LINE_SMOOTH 의 값을 선택함 glHInt() 를 이용하여 , 품질에 대한 힌트를 줄 수 있음

점의 크기나 선의 너비 , 선의 모양 등 결정

RGBA 모드에서의 안티앨리어싱

RGBA 모드에서는 블렌딩을 활성화 시켜야 함 입력값에 GL_SRC_ALPHA 를 기존값에 GL_ONE_MUNUS_SRC_ALPHA 를 사용 . 선분이 조금 밝아지는 효과를 주기 위해서 기존값을

GL_ONE 으로 설정 가능

Page 33: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 33

예제 6-3 안티앨리어싱 선분 : aargb.c 안티앨리어싱 된 선분 [ 6 – 3 ]#include <GL/glut.h>#include <stdlib.h>#include <stdio.h>

static float rotAngle = 0.;

/* 알파 블렌딩 , 힌트 , 선분의 너비를 포함 , RGBA 모드를 위한 * 안티앨리어싱 초기화 , 선분의 너비입상 (line width granularity) 과 * 너비에 관해서 OpenGL 의 구현에 따라 달라지는 내용 출력 */void init(void){ GLfloat values[2]; glGetFloatv (GL_LINE_WIDTH_GRANULARITY, values); printf ("GL_LINE_WIDTH_GRANULARITY value is %3.1f\n",

values[0]);

Page 34: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 34

glGetFloatv (GL_LINE_WIDTH_RANGE, values); printf ("GL_LINE_WIDTH_RANGE values are %3.1f %3.1f\n", values[0], values[1]);

glEnable (GL_LINE_SMOOTH); glEnable (GL_BLEND); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glHint (GL_LINE_SMOOTH_HINT, GL_DONT_CARE); glLineWidth (1.5);

glClearColor(0.0, 0.0, 0.0, 0.0);}

Page 35: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 35

void display(void){ glClear(GL_COLOR_BUFFER_BIT);

glColor3f (0.0, 1.0, 0.0); glPushMatrix(); glRotatef(-rotAngle, 0.0, 0.0, 0.1); glBegin (GL_LINES); glVertex2f (-0.5, 0.5); glVertex2f (0.5, -0.5); glEnd (); glPopMatrix();

Page 36: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 36

glColor3f (0.0, 0.0, 1.0); glPushMatrix(); glRotatef(rotAngle, 0.0, 0.0, 0.1); glBegin (GL_LINES); glVertex2f (0.5, 0.5); glVertex2f (-0.5, -0.5); glEnd (); glPopMatrix();

glFlush();}

Page 37: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 37

void reshape(int w, int h){ glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if (w <= h) gluOrtho2D (-1.0, 1.0, -1.0*(GLfloat)h/(GLfloat)w, 1.0*(GLfloat)h/(GLfloat)w); else gluOrtho2D (-1.0*(GLfloat)w/(GLfloat)h, 1.0*(GLfloat)w/(GLfloat)h, -1.0, 1.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity();}

Page 38: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 38

void keyboard(unsigned char key, int x, int y){ switch (key) { case 'r': case 'R': rotAngle += 20.; if (rotAngle >= 360.) rotAngle = 0.; glutPostRedisplay(); break; case 27: /* Escape Key */ exit(0); break; default: break; }}

Page 39: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 39

int main(int argc, char** argv){ glutInit(&argc, argv); glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB); glutInitWindowSize (200, 200); glutCreateWindow (argv[0]); init(); glutReshapeFunc (reshape); glutKeyboardFunc (keyboard); glutDisplayFunc (display); glutMainLoop(); return 0;}

Page 40: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 40

Page 41: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 41

컬러 인덱스 모드에서의 안티앨리어싱

컬러 인덱스 모드에서 안티 앨리어싱을 적용할 때 가장 까다로운 부분은 컬러 맵을 읽어오고 사용하는 부분

컬러 인덱스의 마지막 4비트가 적용 범위값을 나타내기 때문에 배경 컬러에서 오브젝트 컬러까지 16 개의 인덱스를 컬러 램프에 읽어 와야 함

램프에 있는 처음 16 컬러로 컬러 버퍼를 초기화 한 다음 , 이 램프에 있는 컬러를 사용하여 점과 선을 그림

Page 42: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 42

안티앨리어싱을 적용한 폴리곤

내부가 채워진 폴리곤을 안티앨리어싱 하는 원리는 점이나 선을 안티앨리어싱 하는 것과 비슷

폴리곤들 모서리가 서로 중첩될 때는 컬러 값을 적절하게 블렌딩

RGBA 모드에서 안티앨리어싱을 하기 위해서는 폴리곤 가장자리의 적용 범위값을 알파값으로 사용 .

폴리곤에 대해 안티앨리어싱을 적용하려면 glEnable() 의 인자로 GL_POLYGON_SMOOTH 를 넘겨줌

Page 43: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 43

안 개 효 과

이미지가 너무 날카롭거나 부자연스럽게 보이는 경우를 보완 안티앨리어싱으로 오브젝트의 모서리를 부드럽게 다듬어

오브젝트가 좀더 사실적으로 보이도록 만들기 가능 안개 효과 함께 이용 , 전반적인 이미지를 더욱 자연스럽게 표현

안개효과가 활성화 되면 시점으로부터 멀리 떨어져 있는 물체는 안개효과 컬러로 서서히 흐려짐

안개 효과는 행렬변환 , 라이팅 , 텍스처매핑이 끝난 뒤에 적용됨

점과 선을 포함한 모든 종류의 기하 프리미티브에 적용될 수 있다 . 점과 선에 안개효과를 적용한 것을 Depth-cuing 이라고 부름

Page 44: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 44

안개 효과 사용하기

glEnable() 인자로 GL_FOG 넘겨줌 glFog() 를 이용 , 안개의 컬러와 밀도를 결정할 방정식을 선택

예 )glFogi(GL_FOG_MODE, GL_LINEAR);

필요에 따라 glHint() 로 GL_FOG_HINT 의 값을 설정할 수도 있다 .

Page 45: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 45

예제 6-5 RGBA 에서 안개 효과를 적용하여 그린 다섯 개의 구 : fog.c

#include <GL/glut.h>#include <math.h>#include <stdlib.h>#include <stdio.h>

static GLint fogMode;

static void init(void){ GLfloat position[] = { 0.5, 0.5, 3.0, 0.0 };

glEnable(GL_DEPTH_TEST);

glLightfv(GL_LIGHT0, GL_POSITION, position); glEnable(GL_LIGHTING);

Page 46: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 46

glEnable(GL_LIGHT0); { GLfloat mat[3] = {0.1745, 0.01175, 0.01175}; glMaterialfv (GL_FRONT, GL_AMBIENT, mat); mat[0] = 0.61424; mat[1] = 0.04136; mat[2] = 0.04136;

glMaterialfv (GL_FRONT, GL_DIFFUSE, mat); mat[0] = 0.727811; mat[1] = 0.626959; mat[2] =

0.626959; glMaterialfv (GL_FRONT, GL_SPECULAR, mat); glMaterialf (GL_FRONT, GL_SHININESS, 0.6*128.0); }

Page 47: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 47

glEnable(GL_FOG); { GLfloat fogColor[4] = {0.5, 0.5, 0.5, 1.0};

fogMode = GL_EXP; glFogi (GL_FOG_MODE, fogMode); glFogfv (GL_FOG_COLOR, fogColor); glFogf (GL_FOG_DENSITY, 0.35); glHint (GL_FOG_HINT, GL_DONT_CARE); glFogf (GL_FOG_START, 1.0); glFogf (GL_FOG_END, 5.0); } glClearColor(0.5, 0.5, 0.5, 1.0); /* fog color */}

Page 48: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 48

static void renderSphere (GLfloat x, GLfloat y, GLfloat z){ glPushMatrix(); glTranslatef (x, y, z); glutSolidSphere(0.4, 16, 16); glPopMatrix();}void display(void){ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); renderSphere (-2., -0.5, -1.0); renderSphere (-1., -0.5, -2.0); renderSphere (0., -0.5, -3.0); renderSphere (1., -0.5, -4.0); renderSphere (2., -0.5, -5.0); glFlush();}

Page 49: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 49

void reshape(int w, int h){ glViewport(0, 0, (GLsizei) w, (GLsizei) h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if (w <= h) glOrtho (-2.5, 2.5, -2.5*(GLfloat)h/(GLfloat)w, 2.5*(GLfloat)h/(GLfloat)w, -10.0, 10.0); else glOrtho (-2.5*(GLfloat)w/(GLfloat)h, 2.5*(GLfloat)w/(GLfloat)h, -2.5, 2.5, -10.0, 10.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity ();}

Page 50: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 50

void keyboard(unsigned char key, int x, int y){ switch (key) { case 'f': case 'F': if (fogMode == GL_EXP) {

fogMode = GL_EXP2; printf ("Fog mode is GL_EXP2\n");

} else if (fogMode == GL_EXP2) { fogMode = GL_LINEAR; printf ("Fog mode is GL_LINEAR\n"); }

Page 51: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 51

else if (fogMode == GL_LINEAR) { fogMode = GL_EXP; printf ("Fog mode is GL_EXP\n"); } glFogi (GL_FOG_MODE, fogMode); glutPostRedisplay(); break; case 27: exit(0); break; default: break; }}

Page 52: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 52

int main(int argc, char** argv){ glutInit(&argc, argv); glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB|

GLUT_DEPTH); glutInitWindowSize(500, 500); glutCreateWindow(argv[0]); init(); glutReshapeFunc (reshape); glutKeyboardFunc (keyboard); glutDisplayFunc (display); glutMainLoop(); return 0;}

Page 53: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 53

실행결과

Page 54: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 54

안개 효과 방정식

void glFog{if}(Glenum pname, TYPE param); void glFog{if}v(Glenum pname, TYPE *params);

이 함수들은 안개 효과를 계산하기 위한 매개변수 방정식 설정

pname 을 GL_FOG_MODE 로 설정할 경우 param 은 GL_EXP, GL_EXP2, GL_LINEAR 중에서 설정

Page 55: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 55

RGBA 모드에서 안개 효과

RGBA 모드에서는 안개 효과 요소 f를 다음과 같이 최종적인 안개 효과의 컬러를 결정하는 데 사용

C = fCi + (1 – f)Cf

f: 안개효과 요소 Ci : 입력된 프레그먼트의 RGBA 값을 나타냄 Cf : GL_FOG_COLOR 로 설정된 안개 효과 컬러값을

나타냄

Page 56: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 56

컬러 인덱스 모드에서의 안개 효과

컬러 인덱스 모드에서의 최종적인 안개 효과는 컬러는 다음과 같은 공식으로 계산

I = Ii + (1 – f) If

Ii : 는 입력된 프레그먼트의 컬러 인덱스를 나타냄 If : GL_FOG_INDEX 설정된 안개 효과의 컬러 인덱스를

나타냄

컬러 인덱스 모드에서 안개 효과를 사용하려면 컬러 램프에 적절한 값을 넣어야 한다 .

Page 57: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 57

폴리곤 오프셋

솔리드 오브젝트의 모서리를 하이라이트 처리하려면 오브젝트를 GL_FILL 모드로 그린 후 다른 컬러로 GL_LINE

모드에서 다시 한 번 그려주어야 함

선분과 폴리곤은 정확히 동일한 방식으로 래스터화 되지 않음 . 그래서 선분의 깊이값과 폴리곤 모서리 깊이값이 서로 다름 이 때문에 선분이 도형의 위에서 사라졌다 나타났다 하는 현상이 발생 ( 스티칭 현상 )

이러한 어색한 효과를 없애주기 위해서 폴리곤 오프셋 이용 모서리를 하이라이트 선분과 깨끗하게 분리

Page 58: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 58

오프셋은 폴리곤을 래스터하는 3 가지 방법에 따라 활성화

GL_FILL, GL_LINE, GL_POINT

glEnableI() 의 인자로 GL_POLYGON_OFFSET_FILL, GL_POLYGON_OFFSET, GL_POLYGON_OFFSET_POINT 으로 모드를 활성화

void glPolygonOffset(GLfloat factor, GLfoat units); 폴리곤 오프셋이 활성화되어 있을 때 각각 프레그먼트의

깊이값을 계산된 오프셋값에 더한다 .

Page 59: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 59

계산된 오프셋값 o = m*factor + r*units

m: 다각형의 최대 깊이 경사값 (maximum depth slope) r: OpenGL 구현에 따라 다름

깊이경사값 폴리곤을 가로지르는 선분의 z 값의 변화량을 x 와 y 값의 변화량으로

나눈 값을 말한다 . 깊이값은 윈도우 좌표계의 값으로 계산되고 [0, 1] 구간으로

클램프된다 . near 클리핑 평면과 far 클리핑 평면에 평행한 폴리곤은 깊이 경사가

0 이된다 . 깊이 경사가 0 에 가까운 폴리곤들은 작은 상수 오프셋으로 충분하며 ,

glPolygonOffset() 의 인자로 factor=0.0, unit=1.0 으로 전달 클리핑 평면에 대해 큰 각도를 갖는 도형 ( 깊이 경사값이 0 보다 큰

도형 ) 은 큰 오프셋이 필요 0 이 아닌 작은 값 , 즉 0.75 나 1.0 같은 값들을 이용

Page 60: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 60

예제 : glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_POLYGON_OFFSET_FILL); glPolygonOffset(1.0, 1.0); glCallList(list); glDisable(GL_POLYGON_OFFSET_FILL); glDisable(GL_LIGHTING); glDisable(GL_LIGHT0); glColor3f(1.0, 1.0, 1.0); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glCallList(list); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

Page 61: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 61

예제 6-7 눈에 띄는 결함을 없애는 다각형 오프셋 : polyoff.c

#include <GL/glut.h>#include <stdio.h>#include <stdlib.h>

#ifdef GL_VERSION_1_1GLuint list;GLint spinx = 0;GLint spiny = 0;GLfloat tdist = 0.0;GLfloat polyfactor = 1.0;GLfloat polyunits = 1.0;

Page 62: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 62

void display (void){ GLfloat mat_ambient[] = { 0.8, 0.8, 0.8, 1.0 }; GLfloat mat_diffuse[] = { 1.0, 0.0, 0.5, 1.0 }; GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat gray[] = { 0.8, 0.8, 0.8, 1.0 }; GLfloat black[] = { 0.0, 0.0, 0.0, 1.0 };

glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix (); glTranslatef (0.0, 0.0, tdist); glRotatef ((GLfloat) spinx, 1.0, 0.0, 0.0); glRotatef ((GLfloat) spiny, 0.0, 1.0, 0.0);

Page 63: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 63

glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, gray); glMaterialfv(GL_FRONT, GL_SPECULAR, black); glMaterialf(GL_FRONT, GL_SHININESS, 0.0); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_POLYGON_OFFSET_FILL); glPolygonOffset(polyfactor, polyunits); glCallList (list); glDisable(GL_POLYGON_OFFSET_FILL);

Page 64: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 64

glDisable(GL_LIGHTING); glDisable(GL_LIGHT0); glColor3f (1.0, 1.0, 1.0); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glCallList (list); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

glPopMatrix (); glFlush ();}

Page 65: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 65

void gfxinit (void){ GLfloat light_ambient[] = { 0.0, 0.0, 0.0, 1.0 }; GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };

GLfloat global_ambient[] = { 0.2, 0.2, 0.2, 1.0 };

glClearColor (0.0, 0.0, 0.0, 1.0);

list = glGenLists(1); glNewList (list, GL_COMPILE); glutSolidSphere(1.0, 20, 12); glEndList ();

Page 66: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 66

glEnable(GL_DEPTH_TEST);

glLightfv (GL_LIGHT0, GL_AMBIENT, light_ambient); glLightfv (GL_LIGHT0, GL_DIFFUSE, light_diffuse); glLightfv (GL_LIGHT0, GL_SPECULAR, light_specular); glLightfv (GL_LIGHT0, GL_POSITION, light_position); glLightModelfv (GL_LIGHT_MODEL_AMBIENT,

global_ambient);}

Page 67: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 67

void reshape(int width, int height){ glViewport (0, 0, width, height); glMatrixMode (GL_PROJECTION); glLoadIdentity (); gluPerspective(45.0, (GLdouble)width/(GLdouble)height,

1.0, 10.0); glMatrixMode (GL_MODELVIEW); glLoadIdentity (); gluLookAt (0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);}

Page 68: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 68

void mouse(int button, int state, int x, int y) { switch (button) {

case GLUT_LEFT_BUTTON: switch (state) {

case GLUT_DOWN: spinx = (spinx + 5) % 360;

glutPostRedisplay(); break;default: break;

} break;

Page 69: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 69

case GLUT_MIDDLE_BUTTON: switch (state) {

case GLUT_DOWN: spiny = (spiny + 5) % 360;

glutPostRedisplay(); break;default: break;

} break;

Page 70: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 70

case GLUT_RIGHT_BUTTON: switch (state) {

case GLUT_UP: exit(0); break;default: break;

} break; default: break; }}

Page 71: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 71

void keyboard (unsigned char key, int x, int y){ switch (key) { case 't': if (tdist < 4.0) { tdist = (tdist + 0.5); glutPostRedisplay(); } break; case 'T': if (tdist > -5.0) { tdist = (tdist - 0.5); glutPostRedisplay(); } break;

Page 72: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 72

case 'F': polyfactor = polyfactor + 0.1;

printf ("polyfactor is %f\n", polyfactor); glutPostRedisplay(); break; case 'f': polyfactor = polyfactor - 0.1;

printf ("polyfactor is %f\n", polyfactor); glutPostRedisplay(); break;

Page 73: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 73

case 'U': polyunits = polyunits + 1.0;

printf ("polyunits is %f\n", polyunits); glutPostRedisplay(); break; case 'u': polyunits = polyunits - 1.0;

printf ("polyunits is %f\n", polyunits); glutPostRedisplay(); break; default: break; }}

Page 74: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 74

int main(int argc, char** argv){ glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB |

GLUT_DEPTH); glutCreateWindow(argv[0]); glutReshapeFunc(reshape); glutDisplayFunc(display); glutMouseFunc(mouse); glutKeyboardFunc(keyboard); gfxinit(); glutMainLoop(); return 0;}

Page 75: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 75

#elseint main(int argc, char** argv){ fprintf (stderr, "This program demonstrates a feature which

is not in OpenGL Version 1.0.\n"); fprintf (stderr, "If your implementation of OpenGL Version

1.0 has the right extensions,\n"); fprintf (stderr, "you may be able to modify this program to

make it run.\n"); return 0;}#endif

Page 76: 블렌딩 안티앨리어싱 ,  안개효과                       그리고 폴리곤 오프셋

2009-2 학기 가상현실 76

실행 결과