Advanced GLSL
카테고리: OpenGL
태그: Graphics
Main Reference
- Learn OpenGL
- Rinthel Kwon - OpenGL Lecture
GLSL Built-In Variable
GLSL에는 여러가지 내장 변수(타입)들이 존재한다. 예를 들어 vertex shader에서 출력에 사용되는 gl_position
은 clip space 상에서의 위치를 나타내는 변수이다. 이번 포스팅에서는 gl_position
외에 GLSL의 몇 가지 다른 내장 변수들을 알아보자.
gl_PointSize
// Render()...
glEnable(GL_PROGRAM_POINT_SIZE);
glDrawElements(GL_POINTS, m_indexBuffer->GetCount(), GL_UNSIGNED_INT, 0);
// vertex shader
void main()
{
gl_Position = projection * view * model * vec4(aPos, 1.0);
gl_PointSize = gl_Position.z;
}
gl_VertexID
gl_VertexID
는 현재 vertex shader에서 처리 중인 vertex의 index이다. 어디에 사용되는지는 잘 모르겠지만, 이전에 회사에서 compute shader로 ML모델을 다룰 때 매우 중요하게 사용되었다.
gl_FragCoord
// fragment shader
void main()
{
if(gl_FragCoord.x < 400)
FragColor = vec4(1.0, 0.0, 0.0, 1.0);
else
FragColor = vec4(0.0, 1.0, 0.0, 1.0);
}
gl_FragCoord
의 z값은 해당 픽셀의 깊이를 0~1의 값으로 표현해주기 때문에 여기저기 유용하게 사용됨- x,y 좌표는 window-space 상에서의 x,y좌표를 나타냄
gl_FrontFacing
#version 330 core
out vec4 FragColor;
in vec2 TexCoords;
uniform sampler2D frontTexture;
uniform sampler2D backTexture;
void main()
{
if(gl_FrontFacing)
FragColor = texture(frontTexture, TexCoords);
else
FragColor = texture(backTexture, TexCoords);
}
gl_FrontFacing
: 해당 픽셀이 앞면인지, 뒷면인지 bool값을 리턴- 앞면/뒷면에 따라 다른 재질을 입히거나 할 때 등 사용
gl_FragDepth
// fragment shader
#version 420 core // note the GLSL version!
out vec4 FragColor;
layout (depth_greater) out float gl_FragDepth;
void main()
{
FragColor = vec4(1.0);
gl_FragDepth = gl_FragCoord.z + 0.1;
}
gl_FragCoord의 z값을 이용해면 fragment의 depth값을 불러올 수 있다. 하지만 gl_FragCoord는 read_only 데이터이기 때문에 이를 이용해 fragment의 depth값을 수정할 수는 없다. 이때 gl_FragDepth
데이터를 이용하면 해당 fragment의 depth값을 직접 지정할 수 있다. 하지만 gl_FragDepth
을 이용할 때 성능적인 패널티를 고려해야 한다. 뒤에서 배울 Deferred Shading의 경우 fragment shader 실행 이전에 depth-test(early depth-test)가 실행되는데, fragment shader에서 depth값을 변경한다면 해당 옵션을 사용할 수 없기 때문이다. 하지만 OpenGL4.2 버전부터 이러한 오버헤드를 적절히 조절할 수 있는 기능이 추가되었다.
layout (depth_<condition>) out float gl_FragDepth;
Condition | Description |
---|---|
any | 기본값. Early depth testing이 비활성화되고 대부분의 성능을 잃게됨 |
greater | gl_FragCoord.z 값보다 큰 depth 값만을 작성할 수 있음 |
less | gl_FragCoord.z 값보다 작은 depth 값만을 작성할 수 있음 |
unchanged | gl_FragDepth를 작성하면 정확히 gl_FragCoord.z의 값을 작성 |
댓글 남기기