앞에서 gl_Color의 특성에 대해서 알아보았습니다.
https://learn-and-give.tistory.com/28
이번에는 Color와 함께 가장 대표적인 Vertex의 속성인 position에 대해서 알아보겠습니다.
좌표 변환을 해야 하니, 알아보기 쉽게 좀 정리를 하겠습니다.
왼쪽 아래 Vertex부터 반시계 방향으로 RGB 색상을 부여하였습니다.
void display()
{
//Clear
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//Draw
glBegin(GL_TRIANGLES);
glColor3f(1.f, 0.f, 0.f);
glVertex3f(-0.5, -0.5, 0.0);
glColor3f(0.f, 1.f, 0.f);
glVertex3f(0.5, -0.5, 0.0);
glColor3f(0.f, 0.f, 1.f);
glVertex3f(0.0, 0.5, 0.0);
glEnd();
glFlush();
glutSwapBuffers();
//rotate_angle = rotate_angle + 0.1f;
//if (rotate_angle > 360.f) rotate_angle -= 360.f;
}
좌표계는 기본 좌표계 설정 그대로 가로가 X, 세로가 Y입니다. (기본 Clipping Volume인 -1~1범위)
Vertex Shader에서 좌표를 다룰 예정이라, gl_Vertex로 전달 받은 값을 처리하는 로직이 보이는 형태로 아래와 같이 수정하였습니다. 결과는 앞에서 사용한 코드의 결과와 같습니다.
void main()
{
gl_FrontColor = gl_Color;
vec4 newPos = vec4(gl_Vertex);
gl_Position = gl_ModelViewProjectionMatrix * newPos;
}
이제, 대조군으로써 노란색 삼각형을 y방향으로 0.1 올라간 위치, 그리고 앞에 보이도록 z좌표도 0.1로 하여 그려보겠습니다.
//Draw
glBegin(GL_TRIANGLES);
glColor3f(1.f, 0.f, 0.f);
glVertex3f(-0.5, -0.5, 0.0);
glColor3f(0.f, 1.f, 0.f);
glVertex3f(0.5, -0.5, 0.0);
glColor3f(0.f, 0.f, 1.f);
glVertex3f(0.0, 0.5, 0.0);
glEnd();
glColor3f(1.f, 1.f, 0.f);
glBegin(GL_TRIANGLES);
glVertex3f(-0.5, -0.5 + 0.1, 0.1);
glVertex3f(0.5, -0.5 + 0.1, 0.1);
glVertex3f(0.0, 0.5 + 0.1, 0.1);
glEnd();
glFlush();
이 상태에서, 노란 삼각형의 랜더링 코드 앞에 회전 코드를 넣으면 당연한 이야기지만 노란색 삼각형만 회전할 것입니다.
Z축에 대해서 90도 회전 시키도록 하겠습니다.
//Draw
glBegin(GL_TRIANGLES);
glColor3f(1.f, 0.f, 0.f);
glVertex3f(-0.5, -0.5, 0.0);
glColor3f(0.f, 1.f, 0.f);
glVertex3f(0.5, -0.5, 0.0);
glColor3f(0.f, 0.f, 1.f);
glVertex3f(0.0, 0.5, 0.0);
glEnd();
glPushMatrix();
glRotatef(90.f, 0.f, 0.f, 1.f);
glColor3f(1.f, 1.f, 0.f);
glBegin(GL_TRIANGLES);
glVertex3f(-0.5, -0.5 + 0.1, 0.1);
glVertex3f(0.5, -0.5 + 0.1, 0.1);
glVertex3f(0.0, 0.5 + 0.1, 0.1);
glEnd();
glPopMatrix();
당연한 듯 노란색 삼각형이 회전 되었습니다.
자~, 그럼 여기서 생각 해 볼 이슈로, Vertex Shader에서 vertex의 y좌표를 증가시키면 어떻게 될까요?
RGB삼각형은 당연히 위로 갈 것 같은데, 노란색 삼각형은 위로 갈까요? 아니면 노란 삼각형이 그려지는 좌표계에서 Y축 방향인 왼쪽으로 갈까요?
테스트를 위해서 Vertex Shader를 아래와 같이 수정합니다.
void main()
{
gl_FrontColor = gl_Color;
vec4 newPos = vec4(gl_Vertex);
newPos.y = newPos.y + 0.5;
gl_Position = gl_ModelViewProjectionMatrix * newPos;
}
결과는~~~
이 결과를 보면, Vertex Shader에서의 연산은, 입력되는 Vertex 좌표 자체를 변경 시키는 것이고, 랜더링 된 결과에서 처리되는 것이 아닙니다. 사실, 이것은 Rendering Pipeline에서 Vertex Shader가 어느 위치에서 사용되는지를 생각해보면 예상 할 수 있는 것이기도 합니다.
Shader Code를 보면, 더 잘 드러납니다.
vec4 newPos = vec4(gl_Vertex);
newPos.y = newPos.y + 0.5;
gl_Position = gl_ModelViewProjectionMatrix * newPos;
Vertex 좌표는 gl_Vertex로 넘겨왔고, 밖에서 적용한 회전은 gl_ModelVeiwProjectionMatrix에 적용된 것입니다.
어찌보면 당연한 이야기인데, 이렇게 장황하게 설명하는 이유는, 아주 골치아픈 경험 때문인데요, 예전에 GLSL 관련 된 글을 쓸 때 주전자 샘플을 썼고, Vertex Shader에서 y좌표를 반대로 했음에도 주전자가 똑같이 그려지는 일이 있었습니다. 디버깅을 위해 좌표축도 함께 그려봤는데, 좌표축은 상하 반전이 되는데, 주전자만 되지 않았습니다.
엉뚱하게도 z값을 조정하니 반전과 이동 등 의도한 변화가 생겼습니다.
정리해 보면, 주전자를 그려주는 코드 내부에서는 주전자 위쪽이 Y축이 아니라 Z축인 상태로 그려졌었던 것입니다. 지금 글을 쓰면서 똑같은 테스트를 해 보니, 지금은 또 Y축이 위쪽으로 모델링 된 주전자인 것 같습니다. 주전자를 그려주는 라이브러리 코드가 표준화 되어 있지 않아서 라이브러리마다 다르게 구현 되어 있는 것 같아요.
이런 골치아픈 문제를 겪으면서 Vertex Shader의 위치 입출력에 대해서 조금 더 깊은 이해를 할 수 있었습니다.
이런 내용을 바탕으로 해서, 다음 시간에는 조금 더 재미있는(?) 실험을 해보겠습니다.
https://learn-and-give.tistory.com/31
'공허의 유산 > 표현의 자유' 카테고리의 다른 글
[opengl].[#2.GLSL] 07. Vertex Shader에서 간단한 애니메이션 구현 (0) | 2023.01.11 |
---|---|
[opengl].[#2.GLSL] 06. gl_Position 끄적거리기(2) (0) | 2023.01.09 |
[opengl].[#2.GLSL] 04. gl_Color 끄적거리기 (0) | 2023.01.07 |
[opengl].[#2.GLSL] 03. Shader, 이걸 누가 설명 해 줬더라면... (0) | 2023.01.05 |
[아빠의 Roblox 숙제]#2. 물체를 밀어서 이동시키기(1) (0) | 2021.01.30 |
댓글