본문 바로가기
공허의 유산/표현의 자유

[opengl].[#2.GLSL] 05. gl_Position 끄적거리기

by 바른생활머시마 2023. 1. 8.
728x90
반응형

앞에서 gl_Color의 특성에 대해서 알아보았습니다.

https://learn-and-give.tistory.com/28

 

[opengl].[#2.GLSL] 04. gl_Color 끄적거리기

지난 글에서 Shader가 interpolation을 통해서 여러가지 벡터를 보간하고, 그것으로 멋진 효과를 만들어 낸다는, 지극히 주관적인 잔소리를 좀 했었어요. https://learn-and-give.tistory.com/27 [opengl].[#2.GLSL] 03.

learn-and-give.tistory.com

이번에는 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] 06. gl_Position 끄적거리기(2)

지난 시간에는 Shader 밖에서 설정 된 Vertex 좌표가 gl_Position에 전달되는지 확인 해 봤습니다. 코드 상에서는 glRotate를 했지만 이것은 Model View Matrix에 영향을 미쳤고, glVertex로 입력 된 좌표가 그대

learn-and-give.tistory.com

 

728x90
반응형

댓글