
사용법은 엄청 간단함
#version 330 core
layout (points) in;
layout (line_strip, max_vertices = 2) out;
void main() {
gl_Position = gl_in[0].gl_Position + vec4(-0.1, 0.0, 0.0, 0.0);
EmitVertex();
gl_Position = gl_in[0].gl_Position + vec4( 0.1, 0.0, 0.0, 0.0);
EmitVertex();
EndPrimitive();
}
이게 거의 전부라고 봐도 됨
in 입력 옵션은 어떤 형식의 도형으로 입력이 주어지는지 알려주는거임
| 옵션 | glDrawArrays 그리기 옵션 | 필요 정점 수 |
|---|---|---|
points | GL_POINTS 원시를 그릴 때 | (1개) |
lines | GL_LINES 또는 GL_LINE_STRIP을 그릴 때 | (2개) |
lines_adjacency | GL_LINES_ADJACENCY 또는 GL_LINE_STRIP_ADJACENCY | (4개) |
triangles | GL_TRIANGLES, GL_TRIANGLE_STRIP 또는 GL_TRIANGLE_FAN | (3개) |
triangles_adjacency | GL_TRIANGLES_ADJACENCY 또는 GL_TRIANGLE_STRIP_ADJACENCY | (6개) |
우리가 만약 glDrawArrays에서 GL_TRIANGLE을 그리고자 한다면
옵션을 triangle로 맞춰줘야함
그리려고하는 도형과 출력할 정점의 최대 개수를 제공해주면 됨
| 도형 | 옵션 |
|---|---|
| 점 | points |
| 선 | line_strip |
| 삼각형 | triangle_strip |
이렇게 그리려는 도형을 제공해주고
예를들어 삼각형 2개로 사각형을 그린다고 했을때
필요한 최대 정점 개수는 4개이므로
layout(triangle_strip, max_vertices = 4) out;
이렇게 제공해주면 됨
triangle_strip의 삼각형 그려지는 순서제공되는 정점이 7개이면 7-2개의 삼각형이 만들어짐
그리고 만들어지는 삼각형은 (1,2,3) (2,3,4) (3,4,5) (4,5,6) (5,6,7)의 정점 순서로 만들어짐
먼저 glsl에서는
in gl_Vertex
{
vec4 gl_Position;
float gl_PointSize;
float gl_ClipDistance[];
} gl_in[];
이런 인터페이스를 제공함
이 인터페이스는 이전단계의 쉐이더에서 넘겨진 데이터들임
따라서 Geometry Shader에서 직접 gl_Position에 뭔가를 제공하고싶으면
gl_Position = gl_in[0].glPosition;
이런식으로 제공해주면 됨
그리고 인터페이스가 배열형식으로 제공되는 이유는 정점이 여러개라서 그럼
그럼
EmitVertex가 뭐겠음?
Geometry shader에서 바꾼/만든 정점 적용하는거임
그럼
EndPrimitive는?
Geometry Shader에서 모든게 끝났으니 이제 마무리 짓는거임
float points[] =
{
-0.5f, 0.5f, // top-left
0.5f, 0.5f, // top-right
0.5f, -0.5f, // bottom-right
-0.5f, -0.5f // bottom-left
};
이렇게 4개의 정점이 있음
#version 330 core
layout (points) in;
layout (triangle_strip, max_vertices = 5) out;
void build_house(vec4 position)
{
gl_Position = position + vec4(-0.2, -0.2, 0.0, 0.0); // 1:bottom-left
EmitVertex();
gl_Position = position + vec4( 0.2, -0.2, 0.0, 0.0); // 2:bottom-right
EmitVertex();
gl_Position = position + vec4(-0.2, 0.2, 0.0, 0.0); // 3:top-left
EmitVertex();
gl_Position = position + vec4( 0.2, 0.2, 0.0, 0.0); // 4:top-right
EmitVertex();
gl_Position = position + vec4( 0.0, 0.4, 0.0, 0.0); // 5:top
EmitVertex();
EndPrimitive();
}
void main() {
build_house(gl_in[0].gl_Position);
}
그리고 이런 Geometry shader를 만들음
출력할 도형은 점인데,
쉐이더에서 삼각형으로 변환하는거임
각 정점에 대해 특정 vector값을 더해준다음 그걸로 삼각형을 그릴거임
그리고 출력해줌
glDrawArrays(GL_POINTS, 0, 2);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glDrawArrays(GL_POINTS, 2, 2);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
그럼 아래처럼 나옴

딱 3개의 삼각형으로 그려진거 확인가능~
그럼 여기에 색상을 입혀보자
Geometry Shader에 in을 통해 변수를 받아야하는데...
일단 먼저 points를 약간 수정
float points[] = {
-0.5f, 0.5f, 1.0f, 0.0f, 0.0f, // top-left
0.5f, 0.5f, 0.0f, 1.0f, 0.0f, // top-right
0.5f, -0.5f, 0.0f, 0.0f, 1.0f, // bottom-right
-0.5f, -0.5f, 1.0f, 1.0f, 0.0f // bottom-left
};
vertex shader를 약간 수정
#version 330 core
layout (location = 0) in vec2 aPos;
layout (location = 1) in vec3 aColor;
out VS_OUT
{
vec3 color;
}vs_out;
void main()
{
gl_Position = vec4(aPos.x, aPos.y, 0.0, 1.0);
vs_out.color = aColor;
}
이전 챕터에서 공부한 인터페이스 블록 사용함
그리고 geometry에서 받아주면 되는데...
#version 330 core
layout (points) in;
layout (triangle_strip, max_vertices = 5) out;
in VS_OUT
{
vec3 color;
}gs_in[];
out vec3 fColor;
void build_house(vec4 position)
{
fColor = gs_in[0].color;
gl_Position = position + vec4(-0.2, -0.2, 0.0, 0.0); // 1:bottom-left
EmitVertex();
gl_Position = position + vec4( 0.2, -0.2, 0.0, 0.0); // 2:bottom-right
EmitVertex();
gl_Position = position + vec4(-0.2, 0.2, 0.0, 0.0); // 3:top-left
EmitVertex();
gl_Position = position + vec4( 0.2, 0.2, 0.0, 0.0); // 4:top-right
EmitVertex();
gl_Position = position + vec4( 0.0, 0.4, 0.0, 0.0); // 5:top
//additional
fColor = vec3(1.0, 1.0, 1.0);
EmitVertex();
EndPrimitive();
}
void main()
{
build_house(gl_in[0].gl_Position);
}
이렇게 사용함
geometry shader는 입력이 정점들의 집합이므로 무조건 배열형식으로 in을 받아주면 됨
in vec3 outColor[];도 가능
쉐이더는 간단하게 vertex - geometry - fragment로 이어짐
따라서 geometry shader를 만든 이상, fragment로 색상을 넘겨줘야하니 이렇게 하는거 ㅇㅇ
그리고 fragment shader는 그냥 in받으면

이런 화면이 출력됨~~~
코드를 놓쳤다면
LearnOpenGL - geometry_shader_houses.cpp 이걸 참고!
cpu에서 정점 할당하고 gpu로 넘겨서 사용하는것보다
간단한 도형(e.g 잔디, 나뭇잎 등)은 gpu에 특정 정점만 주어지고,
그 정점을 토대로 gpu에서 정점을 만들어 특정 도형을 만드는게 더 빠르고 간단함
즉 gpu의 속도에서 바로바로 만들어내기때문에 속도가 어마어마하게 빠르게 동작하는거임