82
프 프 프 프 프

프 레 임 버 퍼

  • Upload
    giona

  • View
    62

  • Download
    0

Embed Size (px)

DESCRIPTION

프 레 임 버 퍼. 프레임 버퍼. “ 버퍼와 버퍼의 사용 ” “ 프래그먼트의 테스트와 연산 ” “ 누적 버퍼 ”. 버퍼와 버퍼의 사용. OpenGL 시스템은 다음의 버퍼들을 다룸 컬러 버퍼 깊이 버퍼 스텐실 버퍼 누적 버퍼 사용자의 특별한 OpenGL 실행 환경에 따라서 어떤 버퍼가 사용 가능한지 , 픽셀당 얼마나 많은 수의 비트를 각 버퍼들이 가지고 있는지 결정. 각 픽셀의 버퍼 저장을 위한 매개변수 요청. glGetIntegerv() 사용. 컬러 버퍼. - PowerPoint PPT Presentation

Citation preview

Page 1: 프 레 임 버 퍼

프 레 임 버 퍼

Page 2: 프 레 임 버 퍼

20010-2 학기 가상현실 2

프레임 버퍼

“ 버퍼와 버퍼의 사용 ”

“ 프래그먼트의 테스트와 연산 ”

“ 누적 버퍼 ”

Page 3: 프 레 임 버 퍼

20010-2 학기 가상현실 3

버퍼와 버퍼의 사용

OpenGL 시스템은 다음의 버퍼들을 다룸 컬러 버퍼 깊이 버퍼 스텐실 버퍼 누적 버퍼

사용자의 특별한 OpenGL 실행 환경에 따라서 어떤 버퍼가 사용 가능한지 , 픽셀당 얼마나 많은 수의 비트를 각 버퍼들이 가지고 있는지 결정

Page 4: 프 레 임 버 퍼

20010-2 학기 가상현실 4

각 픽셀의 버퍼 저장을 위한 매개변수 요청

glGetIntegerv() 사용

매개변수 설명

GL_RED_BITS, GL_GREEN_BITS, GL_BLUE_BITS, GL_ALPHA_BITS

컬러 버퍼에서 R,G,B,A 구성 요소당 비트의 개수

GL_INDEX_BITS 컬러 버퍼에서 참조당 비트의 개수

GL_DEPTH_BITS 깊이 버퍼에서 픽셀당 비트의 개수

GL_STENCIL_BITS 스텐실 버퍼에서 픽셀당 비트의 개수

GL_ACCUM_RED_BITS,GL_ACCUM_GREEN_BITS,GL_ACCUM_BLUE_BITS,GL_ACCUM_ALPHA_BITS

누적 버퍼에서 R,G,B,A 구성 요소당 비트의 개수

Page 5: 프 레 임 버 퍼

20010-2 학기 가상현실 5

컬러 버퍼

컬러 버퍼는 사용자가 보통 그리기 위해서 사용하는 버퍼컬러 인덱스나 RGB 컬러 자료를 가짐 , 알파값을 가지기도 함

입체적인 시각 정보를 위해 왼쪽과 오른쪽의 입체적 영상을 나타내기 위하여 좌측과 우측의 컬러 버퍼를 가진다 .양 ( 더블 ) 버퍼 시스템은 전위 버퍼와 후위 버퍼를 가지며 , 단일 버퍼 시스템은 전위 버퍼만 가진다 .

선택적이며 표시되지 않는 보조 컬러 버퍼가 제공되는 경우도 있다 .

사용자는 자신의 시스템이 입체 버퍼링인지 양 버퍼링 인지를 알기 위해 GL_STEREO 나 GL_DOUBLEBUFFER 를 사용 입체 버퍼링 양 버퍼링

Page 6: 프 레 임 버 퍼

20010-2 학기 가상현실 6

깊이 버퍼 (Depth Buffer)

깊이버퍼는 각각의 픽셀의 깊이값을 지니고 있다 .

깊이는 눈과의 거리로 측정

큰 값의 깊이 버퍼를 갖는 픽셀들은 작은 값을 갖는 픽셀들에 의해 덧씌워짐

깊이 버퍼는 Z 버퍼로도 불림

Z 값은 화면에 수직인 거리 ( 눈과 화면과의 거리 ) 를 나타냄

Page 7: 프 레 임 버 퍼

20010-2 학기 가상현실 7

스텐실 버퍼 (Stencil Buffer)

스텐실 버퍼의 한 가지 사용법

카드 스텐실이 스프레이 페인트로 매우 정밀한 이미지를 만들 수 있는 것처럼 화면의 특정 부분의 사용을 제한하는 것

예를 들어 사용자가 자동차의 바람막이 유리를 통해서 보이는 형태의 이미지를 그리는 경우

사용자는 바람막이 형태의 이미지를 스텐실 버퍼에 저장한 후 전체 장면을 그림

스텐실 버퍼는 바람막이 유리를 통해 보이지 않는 장면을 제거

Page 8: 프 레 임 버 퍼

20010-2 학기 가상현실 8

누적 버퍼 (Accumulation Buffer)

누적 버퍼는 RGBA 모드에서 컬러 버퍼들이 동작하는 것처럼 RGBA 컬러 자료들을 가지고 있다 .

보통의 이미지들을 혼합된 이미지들로 축적하는데 사용

사용자는 장면 안티앨리어싱과 같은 작업들을 수행할 수 있다 .

사용자는 직접적으로 누적 버퍼에 그리지는 않음

누적 작업은 직사각형의 블록 내에서 수행 , 블록들은 자료를 컬러 버퍼 안으로 또는 컬러 버퍼에서 이동시키는 역할

Page 9: 프 레 임 버 퍼

20010-2 학기 가상현실 9

버퍼 초기화

간단한 그래픽 작업에서 초기화 연산은 그림의 나머지보다 더 많은 시간을 요구

만약 사용자가 컬러 버퍼와 깊이 버퍼 그리고 스텐실 버퍼를 초기화하고자 하면 초기화 연산은 세 배의 시간이 걸림

이 문제를 해결하기 위해 일부 장치들은 한번에 한 개 이상의 버퍼를 초기화하기 위한 하드웨어 가짐

Page 10: 프 레 임 버 퍼

20010-2 학기 가상현실 10

컬러 (RGBA, 컬러인덱스모드 ), 깊이 , 스텐실 , 누적버퍼의 현재 초기화 값들을 명세 , 다음 연산들은 각각의 버퍼들의 초기화 값

void glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);

void glClearIndex(GLfloat iudex); void glClearDepth(GLclampd depth); void glClearStencil(GLint s); void glClearAccum(GLfloat red, GLfloat green, GLfloat

blue, GLfloat of alpha);

GLclampf 와 GLclamd 타입들은 0.0 과 1.0 사이에서 고정 깊이 초기화 기본값은 1.0, 다른 초기화 기본값은 0 이다 .

Page 11: 프 레 임 버 퍼

20010-2 학기 가상현실 11

초기화 값을 결정하고 , 버퍼들을 초기화할 준비되면 glClear() 함수 사용 void glClear(GLbitfield mask);

지정된 버퍼들을 초기화 mask 값은 비트형식의 논리값인 OR 로서

GL_COLOR_BUFFER_BIT, GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT, GL_ACCUM_BUFFER_BIT 의 조합으로 이루어짐

Page 12: 프 레 임 버 퍼

20010-2 학기 가상현실 12

읽기와 쓰기를 위한 컬러 버퍼의 선택

그리기와 읽기 연산은 컬러버퍼에 입력되거나 버퍼로부터 나옴

그리기를 할 때 그림을 그릴 오브젝트로 한 개 이상의 버퍼를 동시에 지정할 수 있다 .

glReadPixels(), glCopyPixels(), glCopyTexImage*(), glCopyTexSubImage*() 의 소스가 될 버퍼를 선택하기 위해 glReadBuffer() 명령 사용

glDrawBuffer() 명령은 입체적 이미지를 나타내거나 , 보조 버퍼에 내용을 표현할 버퍼를 선택하는데 사용

Page 13: 프 레 임 버 퍼

20010-2 학기 가상현실 13

void glDrawBuffer(GLenum mode); 쓰기와 지우기를 위해 버퍼를 활성화 혹은 비활성화시킴 mode 의 값

GL_AUXi 에서 i 는 특정한 보조버퍼를 나타내는 숫자이다 . 디폴트일 때 단일 버퍼의 모드값은 GL_FRONT 로 나타내고

이중 버퍼의 경우에는 GL_BACK 이다 .

GL_FRONT GL_FRONT_LEFT GL_AUXi

GL_BACK GL_FRONT_RIGHT GL_FRONT_AND_BACK

GL_LEFT GL_BACK_LEFT GL_NONE

GL_RIGHT GL_BACK_RIGHT

Page 14: 프 레 임 버 퍼

20010-2 학기 가상현실 14

void glReadBuffer(GLenum mode);

glReadBuffer() 가 적용되는 버퍼들은 glDrawBuffer() 를 표현하는 버퍼들과 동일

glReadPixels(), glCopyPixels(), glCopyTexImage*().. 등 사전 호출을 통하여 활성화된 컬러 버퍼를 선택한다 .

단일버퍼의 디폴트값은 GL_FRONT, 이고 이중 버퍼일 경우에는 GL_BACK

mode 값

GL_FRONT GL_FRONT_LEFT GL_AUXi

GL_BACK GL_FRONT_RIGHT

GL_LEFT GL_BACK_LEFT

GL_RIGHT GL_BACK_RIGHT

Page 15: 프 레 임 버 퍼

20010-2 학기 가상현실 15

버퍼 마스킹하기

활성화된 컬러 , 깊이 , 또는 스텐실 버퍼에 데이터를 입력하기 전에 마스크 연산이 자료들에 적용

void glIndexMask(Gluint mask);void glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean of alpha);void glDepthMask(Glboolean flag);void glStencilMask(Gluint mask);

올바른 버퍼로 입력되도록 제어하기 위해 마스크를 설정glIndexMask() 로 설정된 마스크는 컬러 인덱스 모드에서만 적용 마스크에 1 이 나타나 해당 비트가 입력되고 0 이면 입력되지

않는다 .

Page 16: 프 레 임 버 퍼

20010-2 학기 가상현실 16

glColorMask() 명령은 RGBA 모드에서 그릴 때에만 영향을 미친다 . GL_TRUE 일 때 R, G, B, A 값이 일치하는 구성요소 입력

glDepthMask() 의 표시 문자가 GL_TRUE 일 때 깊이 버퍼 입력 가능

glStencilMask() 의 마스크는 스텐실데이터를 위해 사용됨

Page 17: 프 레 임 버 퍼

20010-2 학기 가상현실 17

프래그먼트의 테스트와 연산

OpenGL 프로그램이 프래그먼트들의 생성 여부와 각각의 컬러를 결정한 후에 프래그먼트들이 픽셀 형태로 프레임버퍼에 그려지는 방법을 제어하기 위한 처리 필요프래그먼트들이 프레임 버퍼에 저장되기 전에 반드시 거쳐야 할 완벽한 테스트들과 프래그먼트들의 입력 등 마지막 단계 연산들에 대해 설명 . 다음의 순서로 진행됨 .

편집 테스트 알파 테스트 스텐실 테스트 깊이 테스트 블렌딩 디더링 논리적 연산

Page 18: 프 레 임 버 퍼

20010-2 학기 가상현실 18

편집 테스트

사용자는 glScissor()커맨드를 이용하여 윈도우의 직사각형 분할 및 그 분할 내에서의 그릴 때의 제한 사항 등을 정의

void glScissor(GLint x, GLint y, GLsizei width, GLsizei height); 편집 사각형의 위치와 크기를 설정 변수는 좌측 아래에 있는 정점 좌표 (x, y) 와 직사각형의 가로 ,

세로 길이로 정의 편집테스트는 GL_SCISSOR_TEST(glEnable(), glDisable())

의 통과 여부로 판별 한 프래그먼트가 직사각형 내부에 존재할 때 편집 테스트를

통과하게 됨 디폴트는 직사각형 크기가 윈도우 크기와 동일하며 편집 테스트

통과는 불가능

Page 19: 프 레 임 버 퍼

20010-2 학기 가상현실 19

알파 테스트RGBA 모드에서 알파 테스트는 알파값에 기초한 프래그먼트의 수용이 가능한지를 알려줌알파 테스트는 GL_ALPHA_TEST(glEnable(), glDisable()) 의 통과 여부에 따라 판별알파 테스트의 가능성을 판정하기 위해 GL_ALPHA_TEST (glIsEnabled()) 와 함께 사용 프래그먼트는 이 비교 결과에 따라 허가되거나 기각된다 .

참조값과 비교함수는 glAlphaFunc() 로 설정디폴트는 값이 0 이고 비교함수는 GL_ALWAYS 이며 알파테스트는 불가능

void glAlphaFunc(GLenum func, GLclampf ref); 알파테스트를 위한 참조값과 비교함수를 설정 참조값 ref 는 0 과 1 사이에서 조정됨 func 에 가능한 값 ( 표 10-2)

Page 20: 프 레 임 버 퍼

20010-2 학기 가상현실 20

표 10-2 glAlphaFunc() 매개변수 값

매개변수 설명

GL_NEVER 프래그먼트를 받아들이지 않는다 .

GL_ALWAYS 항상 프래그먼트를 받아들인다 .

GL_LESS 알파 < 참조알파 일 경우 , 프래그먼트를 받아들인다 .

GL_LEQUAL 알파 <= 참조알파 일 경우 , 프래그먼트를 받아들인다 .

GL_EQUAL 알파 = 참조알파 일 경우 , 프래그먼트를 받아들인다 .

GL_GEQUAL 알파 >= 참조알파 일 경우 , 프래그먼트를 받아들인다 .

GL_GREATER 알파 > 참조알파 일 경우 , 프래그먼트를 받아들인다 .

GL_NOTEQUAL 알파 , 참조알파가 같지 않을 경우 , 프래그먼트를 받아들인다 .

Page 21: 프 레 임 버 퍼

20010-2 학기 가상현실 21

스텐실 테스트스텐실 테스트는 스텐실 버퍼가 있을 때에만 사용스텐실은 참조값과 스텐실 버퍼의 픽셀에 저장된 값과의 비교 테스트를 적용테스트의 결과에 의해 스텐실 버퍼 내의 값은 변경사용되는 특정한 비교함수와 참고값과 glStencilFunc(), glStencilOp() 함수로 수행되는 변화값을 선택

void glStencilFunc(GLenum func, GLint ref, GLuint mask); 스텐실 테스트를 사용하기 위해 비교 함수 (func), 참조값 (ref)

그리고 마스크 (mask) 를 설정 비교함수에 의해 스텐실 버퍼 값과 비교 비교함수 : GL_NEVER, GL_ALWAYS, GL_LESS, GL_LEQUAL,

GL_EQUAL, GL_GREATER, GL_NOTEQUAL 예를 들어 , GL_LESS 경우 , 프래그먼트는 ref 값이 스텐실

버퍼의 값보다 작을 때 통과된다 . 디폴트는 func 이 GL_ALWAYS 이며 ref 는 0, 마스크는 1,

스텐실은 불가능

Page 22: 프 레 임 버 퍼

20010-2 학기 가상현실 22

void glStencilOp(GLenum fail, GLenum zfail, GLenum zpass);

프래그먼트가 스텐실 테스트를 통과하거나 디폴트일 때 스텐실 버퍼의 자료가 어떻게 변화하는지 상술

fail, zfail, zpass 는 GL_KEEP, GL_ZERO, GL_REPLACE, GL_INCR, GL_DECR, GL_INVERT 가 될 수 있다 . fail: stencil test 가 실패이면 취하는 동작 zfail: stencil test 가 통과이고 depth test 는 실패인

경우의 동작 zpass: stencil test 와 depth test 가 통과이거나 ,

stencil test 통과 후 depth buffer 나 depth test 가 없는 경우의 동작

디폴트일 때 세 가지 스텐실 연산은 GL_KEEP 이 된다 .

Page 23: 프 레 임 버 퍼

20010-2 학기 가상현실 23

스텐실 질의

질의 함수인 glGetIntegerv() 와 표에 나타난 값들을 이용하여 6가지의 스텐실 관련 변수들의 값을 구할 수 있다 .GL_STENCIL_TEST(glIsEnabled() 와 함께 ) 를 통해 스텐실 테스트의 가능 여부 판정스텐실 테스트를 위한 질의 값

질의값 설명

GL_STENCIL_FUNC 스텐실 함수

GL_STENCIL_REF 스텐실 참조값

GL_STENCIL_VALUE_MASK 스텐실 마스크

GL_STENCIL_FAIL 스텐실 실패 액션

GL_STENCIL_PASS_DEPTH_FAIL 스텐실 패스와 깊이 버퍼 실패 액션

GL_STENCIL_PASS_DEPTH_PASS 스텐실 패스와 깊이 버퍼 패스 액션

Page 24: 프 레 임 버 퍼

20010-2 학기 가상현실 24

스텐실 예제

스텐실 테스트를 사용하는 전형적인 방법 화면의 비정상적인 구역에 그림이 그려지지 않도록 마스크 사용

스텐실 마스크를 0 으로 채운 뒤 원하는 형상을 스텐실 버퍼에 1 이 설정되도록 그린다 .

스텐실 구역을 정의한 후 참조값을 1 로 설정하고 , 참조값이 스텐실 평면의 값과 같을 경우 , 프래그먼트가 통과하는 비교 함수를 설정

Page 25: 프 레 임 버 퍼

20010-2 학기 가상현실 25

예제 10-1 스텐실 테스트의 사용 : stencil.c

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

#define YELLOWMAT 1#define BLUEMAT 2

void init (void) { GLfloat yellow_diffuse[] = { 0.7, 0.7, 0.0, 1.0 }; GLfloat yellow_specular[] = { 1.0, 1.0, 1.0, 1.0 };

GLfloat blue_diffuse[] = { 0.1, 0.1, 0.7, 1.0 }; GLfloat blue_specular[] = { 0.1, 1.0, 1.0, 1.0 };

Page 26: 프 레 임 버 퍼

20010-2 학기 가상현실 26

GLfloat position_one[] = { 1.0, 1.0, 1.0, 0.0 };

glNewList(YELLOWMAT, GL_COMPILE); glMaterialfv(GL_FRONT, GL_DIFFUSE, yellow_diffuse); glMaterialfv(GL_FRONT, GL_SPECULAR, yellow_specular); glMaterialf(GL_FRONT, GL_SHININESS, 64.0); glEndList();

glNewList(BLUEMAT, GL_COMPILE); glMaterialfv(GL_FRONT, GL_DIFFUSE, blue_diffuse); glMaterialfv(GL_FRONT, GL_SPECULAR, blue_specular); glMaterialf(GL_FRONT, GL_SHININESS, 45.0); glEndList();

Page 27: 프 레 임 버 퍼

20010-2 학기 가상현실 27

glLightfv(GL_LIGHT0, GL_POSITION, position_one);

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

glClearStencil(0x0); glEnable(GL_STENCIL_TEST);}

/* 토러스에서 윈도우 중앙의 다이아몬드 모양의 부분에 구를 그림 */

Page 28: 프 레 임 버 퍼

20010-2 학기 가상현실 28

void display(void){ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

/* 스텐실이 1 인 부분에서는 청색 구를 그림 */ glStencilFunc (GL_EQUAL, 0x1, 0x1); glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP); glCallList (BLUEMAT); glutSolidSphere (0.5, 15, 15);

(fail, zfail, zpass)

(func, ref, mask)

Page 29: 프 레 임 버 퍼

20010-2 학기 가상현실 29

/* 스텐실이 1 이 아닌 부분에서는 토러스를 그림 */ glStencilFunc (GL_NOTEQUAL, 0x1, 0x1); glPushMatrix(); glRotatef (45.0, 0.0, 0.0, 1.0); glRotatef (45.0, 0.0, 1.0, 0.0); glCallList (YELLOWMAT); glutSolidTorus (0.275, 0.85, 15, 15); glPushMatrix(); glRotatef (90.0, 1.0, 0.0, 0.0); glutSolidTorus (0.275, 0.85, 15, 15); glPopMatrix(); glPopMatrix();}

Page 30: 프 레 임 버 퍼

20010-2 학기 가상현실 30

/* 윈도우가 다시 그려질 때마다 좌표계를 다시 정의하고 , 스텐실 영역을 다시 그림 */

void reshape(int w, int h){ glViewport(0, 0, (GLsizei) w, (GLsizei) h);

/* 다이아몬드 모양의 스텐실 영역을 생성 */

glMatrixMode(GL_PROJECTION); glLoadIdentity();

Page 31: 프 레 임 버 퍼

20010-2 학기 가상현실 31

if (w <= h) gluOrtho2D(-3.0, 3.0, -3.0*(GLfloat)h/(GLfloat)w, 3.0*(GLfloat)h/(GLfloat)w); else gluOrtho2D(-3.0*(GLfloat)w/(GLfloat)h, 3.0*(GLfloat)w/(GLfloat)h, -3.0, 3.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity();

glClear(GL_STENCIL_BUFFER_BIT); glStencilFunc (GL_ALWAYS, 0x1, 0x1); glStencilOp (GL_REPLACE, GL_REPLACE, GL_REPLACE);

Page 32: 프 레 임 버 퍼

20010-2 학기 가상현실 32

glBegin(GL_QUADS); glVertex2f (-1.0, 0.0); glVertex2f (0.0, 1.0); glVertex2f (1.0, 0.0); glVertex2f (0.0, -1.0); glEnd();

glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0, (GLfloat) w/(GLfloat) h, 3.0, 7.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(0.0, 0.0, -5.0);}

Page 33: 프 레 임 버 퍼

20010-2 학기 가상현실 33

void keyboard(unsigned char key, int x, int y){ switch (key) { case 27: exit(0); break; }}

Page 34: 프 레 임 버 퍼

20010-2 학기 가상현실 34

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

Page 35: 프 레 임 버 퍼

20010-2 학기 가상현실 35

샐행결과

Page 36: 프 레 임 버 퍼

20010-2 학기 가상현실 36

스텐실 테스트의 사용

캐핑 (capping) 여러 개 폴리곤의 닫힌 볼록 폴리곤에서 , 평면이 볼록 폴리곤을

만날 때 몇 개의 표면들로 그 폴리곤을 덮으려고 하는 경우 스텐실 버퍼를 0 으로 초기화한 후 , 스텐실이 가능하고

스텐실 비교함수가 항상 프래그먼트를 수용하도록 그림반투명 폴리곤의 겹침 각각의 프래그먼트가 투명 면의 하나의 부분으로 덮힐 수 있도록

스텐실 평면을 사용 스텐실 평면을 0 으로 초기화한 후 스텐실 평면이 0 일 때만

그리고 스텐실 평면의 값을 그리는 중에 증가시킨다 .스티플링 한 이미지를 점으로만 표현하려고 할 때

스티플 방식을 스텐실 버퍼에 입력하고 스텐실 버퍼의 배부 조건에 따라 그린다 .

Page 37: 프 레 임 버 퍼

20010-2 학기 가상현실 37

깊이 테스트

화면의 각각의 픽셀에 대해 깊이 버퍼는 시점과 오브젝트에 포함된 각 픽셀 사이의 거리 정보를 유지깊이 버퍼는 은면 ( 숨어있는 표면 ) 제거에 주로 사용어떤 픽셀에 표현될 새로운 컬러가 나타나면 이 컬러가 기존의 컬러보다 가까울 경우에만 그려짐처음에 깊이 버퍼의 초기값은 시점으로부터 가능한 먼 거리였으며 , 따라서 어떠한 픽셀들이라도 초기값보다 가까운 거리를 가짐

void glDepthfunc(Glenum func); 깊이 테스트에서 비교하는 함수 설정 func : GL_NEVER, GL_ALWAYS, GL_LESS, GL_LEQUAL,

GL_EQUAL, GL_GEQUAL, GL_GREATER, GL_NOTEQUAL 기본값은 GL_LESS: 입력된 프래그먼트가 z- 값이 깊이 버퍼

값보다 작다면 테스트를 지나감

Page 38: 프 레 임 버 퍼

20010-2 학기 가상현실 38

블렌딩 디더링 , 논리적 연산블렌딩

블렌딩은 입력된 프래그먼트의 R, G, B, A 와 알파값이 이미 그 위치에 저장된 픽셀들의 값과 함께 결합하는 것

디더링

시스템에서 적은 수의 컬러 비트평면을 사용하여 이미지에서 컬러를 디더링 함으로써 공간적인 해상도를 향상

디더링은 신문의 하프톤과 같은 것 다양한 회색 음영 효과를 내기 위해 흑색과 백색 점의 패턴과

밀도가 변화되는 처리 과정을 통한다 . 디더링은 하드웨어 의존적

OpenGL 은 사용자가 디더링을 켜고 끄는 것만 할 수 있도록 함 . 기본값은 활성화 상태 .

디더링은 RGBA 와 컬러 인덱스 모드 둘 다 적용

Page 39: 프 레 임 버 퍼

20010-2 학기 가상현실 39

논리적인 연산들

프래그먼트의 마지막 연산은 OR, XOR, INVERT 와 같은 논리적인 연산

들어오는 컬러버퍼 또는 프래그먼트 값에 적용 프래그먼트 연산들은 특히 비트 - 블록 이동 - 형식의 기계에 유용 GL_INDEX_LOGIC_OP, GL_COLOR_LOGIC_OP 를

glEnable(), glDisable() 로 넘김으로써 컬러 인덱스 모드나 RGBA 모드에서 논리적 연산의 활성화 , 비활성화 함

glLogicOp() 를 이용 , 반드시 16 가지의 연산들 가운데 선택

Page 40: 프 레 임 버 퍼

20010-2 학기 가상현실 40

void glLogicOp(Glenum opcode);

프래그먼트와 컬러 버퍼에 저장되어 있는 픽셀에 의해 주어진 연산 중에서 수행하고 논리적인 연산을 선택

매개변수 연산 매개변수 연산

GL_CLEAR 0 GL_AND s ^ d

GL_COPY s GL_OR s v d

GL_NOOP d GL_NAND -(s ^ d)

GL_SET 1 GL_NOR -(s v d)

GL_COPY_INVERTED -s GL_XOR s XOR d

GL_INVERT -d GL_EQUIV -(S XOR d)

GL_AND_REVERSE S ^ -d GL_AND_INVERTED -s ^ d

GL_OR_REVERSE S v -d GL_OR_INVERTED -s v d

Page 41: 프 레 임 버 퍼

20010-2 학기 가상현실 41

누적 버퍼

장면 안티앨리어싱이나 모션 블러 , 어떤 필드의 사진적인 깊이에 대한 시뮬레이팅 , 복합적인 빛으로 인해 생기는 작은 그림자의 계산 등에 사용마치 사진작가가 복합 노출을 위해 필름을 이용하는 것과 같은 방법으로 누적 버퍼를 이용할 수 있다 . 사진작가는 복합 노출을 필름의 교체없이 같은 장면을 계속 찍어서 표현

void glAccum(GLenum op, GLfloat value);

누적 버퍼를 제어하는 커맨드이다 . op 변수는 연산 선택 value 는 연산에서 사용되는 숫자 가능한 연산에는 GL_ACCUM, GL_LOAD, GL_RETURN,

GL_ADD 그리고 GL_MULT 가 있다 .

Page 42: 프 레 임 버 퍼

20010-2 학기 가상현실 42

장면 안티앨리어싱

장면 안티앨리어싱을 수행하기 위해서 우선 누적 버퍼를 초기화 , 프론트 버퍼의 입력과 사용이

가능해야 한다 . n 회 동안 지터를 수행하고 이미지를 그리는 코드를 반복

glAccum(GL_ACCUM, 1.0/n); 로 자료를 누적하고 glAccum(GL_RETURN, 1.0) 을 호출한다 .

각각의 부가적인 조각들이 누적되는 것처럼 이미지의 변화하는 단계를 보여줌이미지가 원하는 형태가 되었을 때 과정을 멈추게 할 수 있는 사용자 인터페이스를 제공glAccum() 커맨드 사용 (GL_RETURN 을 매개변수로 )

Page 43: 프 레 임 버 퍼

20010-2 학기 가상현실 43

예제 10-2, 3 뷰잉볼륨저장 , 장면 안티앨리어싱 : accpersp.c#include <GL/glut.h>#include <stdlib.h>#include <math.h>#include "jitter.h"

#define PI_ 3.14159265358979323846void accFrustum(GLdouble left, GLdouble right, GLdouble

bottom, GLdouble top, GLdouble zNear, GLdouble zFar, GLdouble pixdx, GLdouble pixdy, GLdouble eyedx, GLdouble eyedy, GLdouble

focus){ GLdouble xwsize, ywsize; GLdouble dx, dy; GLint viewport[4];

Page 44: 프 레 임 버 퍼

20010-2 학기 가상현실 44

glGetIntegerv (GL_VIEWPORT, viewport); xwsize = right - left; ywsize = top - bottom; dx = -(pixdx*xwsize/(GLdouble) viewport[2] +

eyedx*zNear/focus); dy = -(pixdy*ywsize/(GLdouble) viewport[3] +

eyedy*zNear/focus); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glFrustum (left + dx, right + dx, bottom + dy, top + dy,

zNear, zFar); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef (-eyedx, -eyedy, 0.0);}

Page 45: 프 레 임 버 퍼

20010-2 학기 가상현실 45

void accPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar, GLdouble pixdx, GLdouble

pixdy, GLdouble eyedx, GLdouble eyedy, GLdouble focus){ GLdouble fov2,left,right,bottom,top;

fov2 = ((fovy*PI_) / 180.0) / 2.0; top = zNear / (cos(fov2) / sin(fov2)); bottom = -top; right = top * aspect; left = -right;

accFrustum (left, right, bottom, top, zNear, zFar, pixdx, pixdy, eyedx, eyedy, focus);}

Page 46: 프 레 임 버 퍼

20010-2 학기 가상현실 46

void init(void){ GLfloat mat_ambient[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat light_position[] = { 0.0, 0.0, 10.0, 1.0 }; GLfloat lm_ambient[] = { 0.2, 0.2, 0.2, 1.0 };

glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient); glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); glMaterialf(GL_FRONT, GL_SHININESS, 50.0); glLightfv(GL_LIGHT0, GL_POSITION, light_position); glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lm_ambient);

Page 47: 프 레 임 버 퍼

20010-2 학기 가상현실 47

glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_DEPTH_TEST); glShadeModel (GL_FLAT);

glClearColor(0.0, 0.0, 0.0, 0.0); glClearAccum(0.0, 0.0, 0.0, 0.0);}void displayObjects(void) { GLfloat torus_diffuse[] = { 0.7, 0.7, 0.0, 1.0 }; GLfloat cube_diffuse[] = { 0.0, 0.7, 0.7, 1.0 }; GLfloat sphere_diffuse[] = { 0.7, 0.0, 0.7, 1.0 }; GLfloat octa_diffuse[] = { 0.7, 0.4, 0.4, 1.0 };

Page 48: 프 레 임 버 퍼

20010-2 학기 가상현실 48

glPushMatrix (); glTranslatef (0.0, 0.0, -5.0); glRotatef (30.0, 1.0, 0.0, 0.0); glPushMatrix (); glTranslatef (-0.80, 0.35, 0.0); glRotatef (100.0, 1.0, 0.0, 0.0); glMaterialfv(GL_FRONT, GL_DIFFUSE, torus_diffuse); glutSolidTorus (0.275, 0.85, 16, 16); glPopMatrix ();

glPushMatrix (); glTranslatef (-0.75, -0.50, 0.0); glRotatef (45.0, 0.0, 0.0, 1.0);

Page 49: 프 레 임 버 퍼

20010-2 학기 가상현실 49

glRotatef (45.0, 1.0, 0.0, 0.0); glMaterialfv(GL_FRONT, GL_DIFFUSE, cube_diffuse); glutSolidCube (1.5); glPopMatrix ();

glPushMatrix (); glTranslatef (0.75, 0.60, 0.0); glRotatef (30.0, 1.0, 0.0, 0.0); glMaterialfv(GL_FRONT, GL_DIFFUSE, sphere_diffuse); glutSolidSphere (1.0, 16, 16); glPopMatrix ();

glPushMatrix (); glTranslatef (0.70, -0.90, 0.25); glMaterialfv(GL_FRONT, GL_DIFFUSE, octa_diffuse);

Page 50: 프 레 임 버 퍼

20010-2 학기 가상현실 50

glutSolidOctahedron (); glPopMatrix ();

glPopMatrix ();}

#define ACSIZE 8

void display(void){ GLint viewport[4]; int jitter;

glGetIntegerv (GL_VIEWPORT, viewport);

Page 51: 프 레 임 버 퍼

20010-2 학기 가상현실 51

glClear(GL_ACCUM_BUFFER_BIT); for (jitter = 0; jitter < ACSIZE; jitter++) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); accPerspective (50.0, (GLdouble) viewport[2]/(GLdouble) viewport[3], 1.0, 15.0, j8[jitter].x, j8[jitter].y, 0.0, 0.0, 1.0); displayObjects (); glAccum(GL_ACCUM, 1.0/ACSIZE); } glAccum (GL_RETURN, 1.0); glFlush();}

Page 52: 프 레 임 버 퍼

20010-2 학기 가상현실 52

void reshape(int w, int h){ glViewport(0, 0, (GLsizei) w, (GLsizei) h);}

void keyboard(unsigned char key, int x, int y){ switch (key) { case 27: exit(0); break; }}

Page 53: 프 레 임 버 퍼

20010-2 학기 가상현실 53

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

Page 54: 프 레 임 버 퍼

20010-2 학기 가상현실 54

Page 55: 프 레 임 버 퍼

20010-2 학기 가상현실 55

예제 10-4 정사영으로 지터링 하기 : accanti.c

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

void init(void){ GLfloat mat_ambient[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat light_position[] = { 0.0, 0.0, 10.0, 1.0 }; GLfloat lm_ambient[] = { 0.2, 0.2, 0.2, 1.0 };

Page 56: 프 레 임 버 퍼

20010-2 학기 가상현실 56

glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient); glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); glMaterialf(GL_FRONT, GL_SHININESS, 50.0); glLightfv(GL_LIGHT0, GL_POSITION, light_position); glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lm_ambient); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_DEPTH_TEST); glShadeModel (GL_FLAT); glClearColor(0.0, 0.0, 0.0, 0.0); glClearAccum(0.0, 0.0, 0.0, 0.0);}

Page 57: 프 레 임 버 퍼

20010-2 학기 가상현실 57

void displayObjects(void) { GLfloat torus_diffuse[] = { 0.7, 0.7, 0.0, 1.0 }; GLfloat cube_diffuse[] = { 0.0, 0.7, 0.7, 1.0 }; GLfloat sphere_diffuse[] = { 0.7, 0.0, 0.7, 1.0 }; GLfloat octa_diffuse[] = { 0.7, 0.4, 0.4, 1.0 }; glPushMatrix (); glRotatef (30.0, 1.0, 0.0, 0.0);

glPushMatrix (); glTranslatef (-0.80, 0.35, 0.0); glRotatef (100.0, 1.0, 0.0, 0.0);

Page 58: 프 레 임 버 퍼

20010-2 학기 가상현실 58

glMaterialfv(GL_FRONT, GL_DIFFUSE, torus_diffuse); glutSolidTorus (0.275, 0.85, 16, 16); glPopMatrix ();

glPushMatrix (); glTranslatef (-0.75, -0.50, 0.0); glRotatef (45.0, 0.0, 0.0, 1.0); glRotatef (45.0, 1.0, 0.0, 0.0); glMaterialfv(GL_FRONT, GL_DIFFUSE, cube_diffuse); glutSolidCube (1.5); glPopMatrix ();

Page 59: 프 레 임 버 퍼

20010-2 학기 가상현실 59

glPushMatrix (); glTranslatef (0.75, 0.60, 0.0); glRotatef (30.0, 1.0, 0.0, 0.0); glMaterialfv(GL_FRONT, GL_DIFFUSE, sphere_diffuse); glutSolidSphere (1.0, 16, 16); glPopMatrix ();

glPushMatrix (); glTranslatef (0.70, -0.90, 0.25); glMaterialfv(GL_FRONT, GL_DIFFUSE, octa_diffuse); glutSolidOctahedron (); glPopMatrix ();

Page 60: 프 레 임 버 퍼

20010-2 학기 가상현실 60

glPopMatrix ();}#define ACSIZE 8

void display(void){ GLint viewport[4]; int jitter;

glGetIntegerv (GL_VIEWPORT, viewport);

glClear(GL_ACCUM_BUFFER_BIT); for (jitter = 0; jitter < ACSIZE; jitter++) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix ();

Page 61: 프 레 임 버 퍼

20010-2 학기 가상현실 61

glTranslatef (j8[jitter].x*4.5/viewport[2], j8[jitter].y*4.5/viewport[3], 0.0); displayObjects (); glPopMatrix (); glAccum(GL_ACCUM, 1.0/ACSIZE); } glAccum (GL_RETURN, 1.0); glFlush();}void reshape(int w, int h){ glViewport(0, 0, (GLsizei) w, (GLsizei) h); glMatrixMode(GL_PROJECTION); glLoadIdentity();

Page 62: 프 레 임 버 퍼

20010-2 학기 가상현실 62

if (w <= h) glOrtho (-2.25, 2.25, -2.25*h/w, 2.25*h/w, -10.0, 10.0); else glOrtho (-2.25*w/h, 2.25*w/h, -2.25, 2.25, -10.0, 10.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity();}

void keyboard(unsigned char key, int x, int y){ switch (key) { case 27: exit(0); break; }}

Page 63: 프 레 임 버 퍼

20010-2 학기 가상현실 63

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

| GLUT_ACCUM | GLUT_DEPTH); glutInitWindowSize (250, 250); glutInitWindowPosition (100, 100); glutCreateWindow (argv[0]); init(); glutReshapeFunc(reshape); glutDisplayFunc(display); glutKeyboardFunc(keyboard); glutMainLoop(); return 0; }

Page 64: 프 레 임 버 퍼

20010-2 학기 가상현실 64

실행결과

Page 65: 프 레 임 버 퍼

20010-2 학기 가상현실 65

모션 블러

장면에 정지 그리고 운동하고 있는 오브젝트가 있을 때 잔상이 보이는 이미지 만든다 .

누적버퍼를 설정 , 이미지를 공간적으로 지터링 하는 대신에 일시적으로 지터링

전체 장면은 장면이 누적 버퍼에 그려질 때 glAccum(GL_MULT, decayFactor); 를 호출하여 성공적으로 만들 수 있다 . decayFactor 는 0.0 ~1.0 사이의 수

decayFactor 가 작을수록 오브젝트는 빨리 움직이는 것처럼 보인다 .

Page 66: 프 레 임 버 퍼

20010-2 학기 가상현실 66

필드의 깊이 (DOF, Depth of Field)

카메라의 필드 깊이는 커버할 수 있는 범위 안에 초점에서 벗어난 물체들이 위치하는 완벽한 초점 평면에 대한 영역

일반적인 환경에서 OpenGL 로 그리는 모든 그림들은 초점이 맞는다 . 누적버퍼에 의해 물체가 초점과의 거리가 멀어지면서 더 흐리게 보이는 실제 사진과 같은 효과를 낼 수 있다 .

다른 인수들의 값을 가지는 glFrustum() 을 호출하여 장면을 반복적으로 그린다 .

현재 시점의 위치가 실제의 위치에 근접한 값을 가지도록 해서 각각의 절두체 (frustum) 가 완벽한 초점의 평면에 놓여진 공통의 직사각형을 공유할 수 있도록 인수 선택

Page 67: 프 레 임 버 퍼

20010-2 학기 가상현실 67

예제 10-5 필드 깊이 효과 : dof.c#include <GL/glut.h>#include <stdlib.h>#include <math.h>#include "jitter.h"#define PI_ 3.14159265358979323846GLuint teapotList;void accFrustum(GLdouble left, GLdouble right, GLdouble

bottom, GLdouble top, GLdouble zNear, GLdouble zFar, GLdouble

pixdx, GLdouble pixdy, GLdouble eyedx, GLdouble eyedy,

GLdouble focus){ GLdouble xwsize, ywsize;

Page 68: 프 레 임 버 퍼

20010-2 학기 가상현실 68

GLdouble dx, dy; GLint viewport[4]; glGetIntegerv (GL_VIEWPORT, viewport);

xwsize = right - left; ywsize = top - bottom;

dx = -(pixdx*xwsize/(GLdouble) viewport[2] + eyedx*zNear/focus);

dy = -(pixdy*ywsize/(GLdouble) viewport[3] + eyedy*zNear/focus);

glMatrixMode(GL_PROJECTION); glLoadIdentity(); glFrustum (left + dx, right + dx, bottom + dy, top + dy,

zNear, zFar);

Page 69: 프 레 임 버 퍼

20010-2 학기 가상현실 69

glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef (-eyedx, -eyedy, 0.0);}

void accPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar, GLdouble pixdx, GLdouble

pixdy, GLdouble eyedx, GLdouble eyedy, GLdouble focus){ GLdouble fov2,left,right,bottom,top;

fov2 = ((fovy*PI_) / 180.0) / 2.0;

Page 70: 프 레 임 버 퍼

20010-2 학기 가상현실 70

top = zNear / (cos(fov2) / sin(fov2)); bottom = -top;

right = top * aspect; left = -right;

accFrustum (left, right, bottom, top, zNear, zFar, pixdx, pixdy, eyedx, eyedy, focus);}void init(void){ GLfloat ambient[] = { 0.0, 0.0, 0.0, 1.0 }; GLfloat diffuse[] = { 1.0, 1.0, 1.0, 1.0 };

Page 71: 프 레 임 버 퍼

20010-2 학기 가상현실 71

GLfloat specular[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat position[] = { 0.0, 3.0, 3.0, 0.0 }; GLfloat lmodel_ambient[] = { 0.2, 0.2, 0.2, 1.0 }; GLfloat local_view[] = { 0.0 };

glLightfv(GL_LIGHT0, GL_AMBIENT, ambient); glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse); glLightfv(GL_LIGHT0, GL_POSITION, position); glLightModelfv(GL_LIGHT_MODEL_AMBIENT,

lmodel_ambient); glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER,

local_view);

Page 72: 프 레 임 버 퍼

20010-2 학기 가상현실 72

glFrontFace (GL_CW); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_AUTO_NORMAL); glEnable(GL_NORMALIZE); glEnable(GL_DEPTH_TEST);

glClearColor(0.0, 0.0, 0.0, 0.0); glClearAccum(0.0, 0.0, 0.0, 0.0); teapotList = glGenLists(1); glNewList (teapotList, GL_COMPILE); glutSolidTeapot (0.5); glEndList ();}

Page 73: 프 레 임 버 퍼

20010-2 학기 가상현실 73

void renderTeapot (GLfloat x, GLfloat y, GLfloat z, GLfloat ambr, GLfloat ambg, GLfloat ambb, GLfloat difr, GLfloat difg, GLfloat difb, GLfloat specr, GLfloat specg, GLfloat specb, GLfloat shine){ GLfloat mat[4];

glPushMatrix(); glTranslatef (x, y, z);mat[0] = ambr; mat[1] = ambg; mat[2] = ambb; mat[3] =

1.0; glMaterialfv (GL_FRONT, GL_AMBIENT, mat); mat[0] = difr; mat[1] = difg; mat[2] = difb;

Page 74: 프 레 임 버 퍼

20010-2 학기 가상현실 74

glMaterialfv (GL_FRONT, GL_DIFFUSE, mat); mat[0] = specr; mat[1] = specg; mat[2] = specb; glMaterialfv (GL_FRONT, GL_SPECULAR, mat); glMaterialf (GL_FRONT, GL_SHININESS, shine*128.0); glCallList(teapotList); glPopMatrix();}void display(void){ int jitter; GLint viewport[4];

glGetIntegerv (GL_VIEWPORT, viewport); glClear(GL_ACCUM_BUFFER_BIT);

Page 75: 프 레 임 버 퍼

20010-2 학기 가상현실 75

for (jitter = 0; jitter < 8; jitter++) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); accPerspective (45.0, (GLdouble) viewport[2]/(GLdouble) viewport[3], 1.0, 15.0, 0.0, 0.0, 0.33*j8[jitter].x, 0.33*j8[jitter].y, 5.0);

renderTeapot (-1.1, -0.5, -4.5, 0.1745, 0.01175, 0.01175, 0.61424, 0.04136, 0.04136, 0.727811, 0.626959, 0.626959, 0.6);

Page 76: 프 레 임 버 퍼

20010-2 학기 가상현실 76

renderTeapot (-0.5, -0.5, -5.0, 0.24725, 0.1995, 0.0745, 0.75164, 0.60648, 0.22648, 0.628281, 0.555802, 0.366065, 0.4); renderTeapot (0.2, -0.5, -5.5, 0.19225, 0.19225, 0.19225, 0.50754, 0.50754, 0.50754, 0.508273, 0.508273, 0.508273, 0.4); renderTeapot (1.0, -0.5, -6.0, 0.0215, 0.1745, 0.0215, 0.07568, 0.61424, 0.07568, 0.633, 0.727811, 0.633, 0.6); renderTeapot (1.8, -0.5, -6.5, 0.0, 0.1, 0.06, 0.0, 0.50980392, 0.50980392, 0.50196078, 0.50196078, 0.50196078, .25);

Page 77: 프 레 임 버 퍼

20010-2 학기 가상현실 77

glAccum (GL_ACCUM, 0.125); } glAccum (GL_RETURN, 1.0); glFlush();}

void reshape(int w, int h){ glViewport(0, 0, (GLsizei) w, (GLsizei) h);}void keyboard(unsigned char key, int x, int y){ switch (key) { case 27: exit(0); break; }}

Page 78: 프 레 임 버 퍼

20010-2 학기 가상현실 78

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

| GLUT_ACCUM | GLUT_DEPTH); glutInitWindowSize (400, 400); glutInitWindowPosition (100, 100); glutCreateWindow (argv[0]); init(); glutReshapeFunc(reshape); glutDisplayFunc(display); glutKeyboardFunc(keyboard); glutMainLoop(); return 0;}

Page 79: 프 레 임 버 퍼

20010-2 학기 가상현실 79

실행결과

Page 80: 프 레 임 버 퍼

20010-2 학기 가상현실 80

부드러운 그림자

다중 조명 소스로부터 얻어지는 부드러운 그림자들을 누적하기 위해서 동시에 켜진 상태인 조명을 가지고 그림자를 렌더링하고 , 그것들을 함께 누적한다 .

지터링

이미지를 안티앨리어스 하기 위해 9개나 16 개의 샘플이 필요할 경우 , 픽셀을 가로지르는 동일 간격의 격자 형태가 가장 적절한 위치

실제로는 가끔씩 근접한 픽셀들에 있는 위치를 구하거나 , 픽셀의 중심으로 모여지는 ( 클러스터링된 ) 균일 분포나 정규 분포를 선택할 수도 있다 .

다음 표는 몇 가지의 선택된 샘플 카운트에 대한 지터링 값 대부분 픽셀 안에서 균일 분포이며 모두 픽셀 안에 놓인다 .

Page 81: 프 레 임 버 퍼

20010-2 학기 가상현실 81

Count

2 {0.25, 0.75},{0.75, 0.75}

3 {0.5033922635, 0.8317967229}, {0.7806016275,0.2504380877}, {0.2261828938,0.4131553612}

4 {0.375,0.25}, {0.125,0.75}, {0.875,0.25}, {0.625,0.75}

5 {0.5,0.5}, {0.3,0.1}, {0.7,0.9}, {0.9,0.3}, {0.1,0.7}

6 {0.4646464646,0.4646464646}, {0.1313131313,0.7979797979}, {0.5353535353,0.8686868686}, {0.8686868686 ,0.5353535353}{0.7979797979,0.1313131313}, {0.2020202020,0.2020202020},

8 {0.5625,0.4375}, {0.0625,0.9375}, {0.3125,0.6875}, {0.6875,0.8125}, {0.8125,0.1875}, {0.9375,0.5625}, {0.4375,0.0625}, {0.1875,0.3125}

Page 82: 프 레 임 버 퍼

20010-2 학기 가상현실 82

Count 값

9 {0.5,0.5}, {0.1666666666,0.9444444444}, {0.5,0.1666666666}, {0.5,0.8333333333}, {0.1666666666,0.2777777777}, {0.8333333333,0.3888888888}, {0.1666666666,0.6111111111}, {0.8333333333,0.7222222222}, {0.8333333333,0.0555555555},

12 {0.4166666666,0.625}, {0.9166666666,0.875}, {0.25,0.375}, {0.4166666666,0.125}, {0.75,0.125}, {0.833333333,0.125}, {0.75,0.625}, {0.25,0.875}, {0.5833333333,0.375}, {0.9166666666,0.375}, {0.833333333,0.625}, {0.5833333333,0.875},

16 {0.375,0.4375}, {0.625,0.0625}, {0.875,0.1875}, {0.125,0.0625}, {0.375,0.6875}, {0.875,0.4375}, {0.625,0.5625}, {0.375,0.9375}, {0.625,0.3125}, {0.125,0.5625}, {0.125,0.8125}, {0.375,0.1875}, {0.875,0.9375}, {0.875,0.6875}, {0.125,0.3125}, {0.625,0.8125},