OpenGL Shader – 19

GLSL 예제 – Flatten Shader(납작 쉐이더? =_=;)
원문 : http://www.lighthouse3d.com/opengl/glsl/index.php?flatten

쉐이더 프로그래밍은 3차원 장면에 새로운 효과를 넣는데 매우 유용하다. 이 작은 예는 버텍스가 기묘한 방법으로 가공되는 것을 보여준다.

먼저 3D 모델을 납작하게 렌더링시키기 위해, 모델뷰 변환을 적용하기 전에 z 좌표의 값을 0으로 설정한다. 아래의 버텍스 쉐이더가 이 연산을 수행한다.

void main(void)
{
    vec4 v = vec4(gl_Vertex);
    v.z = 0.0;

    gl_Position = gl_ModelViewProjectionMatrix * v;
}

위의 코드를 보면, 먼저 지역변수(v)에 gl_Vertex를 복사하고 있다. gl_Vertex는 GLSL에서 제공하는 Attribute 변수이며, 버텍스 쉐이더가 수행되는 동안에는 읽기전용으로 사용할 수 있는 변수이다. 읽기전용이기 때문에 지역변수에 복사하여 값을 변환시킨것이다.

프레그먼트 쉐이더는 단지 색상만을 지정하므로, 이전 섹션(Hello World 예제)에서 제공한 코드와 동일하다.

이 쉐이더는 각 버텍스의 z 좌표를 0으로 지정한다. 주전자 3D 모델에 적용을 해보면, 아래의 그림처럼 납작해진 것으로 표현된다.

됐다. 이제 여기서 좀 응용을 해보자. 버텍스의 z값을 sin함수와 sin함수의 변수는 버텍스의 x좌표로 해면 주전자 모델이 너울거리는 것처럼 표시된다.

void main(void)
{
    vec4 v = vec4(gl_Vertex);
    v.z = sin(5.0 * v.x) * 0.25;

    gl_Position = gl_ModelViewProjectionMatrix * v;
}

이제 이 간단한 예제에 마지막으로 버텍스 에니메이션 효과를 적용해보자. 이 효과를 위해서, 시간을 추적하거나 프레임 카운터를 위한 변수가 필요하다. A vertex shader can’t keep track of values between vertices, let alone between frames. 그래서 OpenGL 어플리케이션에 변수를 하나 정의하고, 이 변수를 Uniform 변수로 쉐이더에 넘겨야 한다. OpenGL 어플리케이션에 “time”이라는 이름의 변수가 있는데, 이변수는 프레임을 카운터하고, 같은 이름의 Uniform 변수가 쉐이더 안에 있다.

버텍스 쉐이더에 대한 코드는 다음과 같다.

uniform float time;

void main(void)
{
    vec4 v = vec4(gl_Vertex);

    v.z = sin(5.0*v.x + time*0.01)*0.25;

    gl_Position = gl_ModelViewProjectionMatrix * v;
}

Uniform 변수를 설명한 섹션에서 언급했듯, OpenGL 어플리케이션에서는 다음 두단계가 필요하다.

  • setup : Uniform 변수의 위치를 얻는다.
  • render : Uniform 변수를 갱신한다.

setup 부분은 다음 코드와 같다.

loc = glGetUniformLocationARB(p, "time");

위의 코드에서 인자 p는 쉐이더 프로그램의 헨들이고, time은 버텍스 쉐이더에서 정의한 Uniform 변수의 이름이다. loc 변수는 GLint 형이며 render 함수에서 접근할 수 있는 위치에 정의되어야 한다.

render 함수는 아래와 같다.

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

    glLoadIdentity();
    gluLootAt(0, 0, 5, 0, 0, 0, 0, 1, 0);

    glUniform1fARB(loc, time);

    glutSolidTeaport(1);
    time += 0.1;

    glutSwapBuffers();
}

time 변수는 초기화부분에서 임의값으로 초기화되었을 것이고 매 프레임마다 증가된다.

여기까지의 예제 코드에 대한 전체 코드는 아래를 통해 다운로드 받길 바란다.

1167513658.zip1017013023.zip

“OpenGL Shader – 19”에 대한 3개의 댓글

  1. 요즘 opengl 에 재미를 붙여서 보고 있는데 정말 좋은 강좌를 알게 되어 기쁩니다.
    한가지 궁금한것은.. 첫번째 예제에서 버텍스의 z 값을 0으로 하면 위의 그림처럼 나와야 할것 같은데, 실제로 돌려보면 y축에 대해 0으로 변형한 형태(호떡 눌러놓은 것)처럼 되는데, 영문을 모르겠습니다. 행여 이 글 보시면 알려주세요 ^^;
    건승하세요!

    1. 주전자에 대한 모델이 구성될때의 좌표축이 그리되어 있어서 그럴듯합니다. 주전자 모델을 y축으로 세울 것인지.. z축으로 세울 것인지는.. 모델의 구성하는 제작자 마음이니까요..

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다