GLSL(OpenGL Shading Language)은 C 언어를 기초로 한, 상위 레벨 셰이덩 언어이다. HLSL과 유사한 이 언어는 어셈블리 언어나 하드웨어에 의존한 언어를 사용하지 않고, 개발자가 그래픽스 파이프라인을 직접 제어할 수 있도록 OpenGL ARB(Architecture Review Board) 가 책정하였다.
vec2, vec3, vec4
)와 행렬(mat2, mat3, mat4
)을 지원하며, 좌표 변환이나 조명 계산과 같은 그래픽스 작업을 쉽게 처리할 수 있다.GLSL의 기본 구조는 C 와 같으나 몇몇 기능은 지원하지 않는다.
#version 430
#ifdef FAST_EXACT_METHOD
FastExact();
#else
SlowApproximate();
#endif
// ... many others
void main(void) {
}
bool
int
uint
float
double
bvec2, bvec3, bvec4
ivec2, ivec3, ivec4
uvec2, uvec3, uvec4
vec2, vec3. vec4
dvec2, dvec3, dvec4
mat2, mat3, mat4
sampler1D, sampler2D, sampler3D, samplerCube
vec3 a = vec3(1.0, 2.0, 3.0);
C의 기본적인 연산 및 논리 연산을 제공하며 추가적으로 행렬과 벡터를 위한 연산 또한 제공한다.
mat4 m;
vec4 a, b, c;
b = a * m;
c = m * a;
GLSL에서 벡터의 값에 접근을 할 때 [], xyzw, rgba, stpq
를 사용하여 접근할 수 있다.
vec3 v;
v[1], v.y, v.g, v.t; // all refer to the same element
또한 Swizzling을 사용하여 두 개 이상의 벡터 요소에 한번에 접근할 수 있다.
vec3 a, b;
a.xy = b.yx; // a의 x, y 성분 값이 b의 y, x 성분 값으로 바뀜.
GLSL에서 벡터, 행렬에 대해 생성자를 이용해 초기 값을 전달할 수 있다.
vec3 xyz = vec3(1.0, 2.0, 3.0);
vec3 xyz = vec3(1.0); // [1.0, 1.0, 1.0]
vec3 xyz = vec3(vec2(1.0, 2.0), 3.0);
// ERROR
vec3 xyz (1.0, 2.0, 3.0);
GLSL에서 vector는 다음과 같이 사용할 수 있다.
vec4 c = vec4(0.5, 1.0, 0.8, 1.0);
vec3 rgb = c.rgb; // [0.5, 1.0, 0.8]
vec3 bgr = c.bgr; // [0.8, 1.0, 0.5]
vec3 rrr = c.rrr; // [0.5, 0.5, 0.5]
c.a = 0.5; // [0.5, 1.0, 0.8, 0.5]
c.rb = 0.0; // [0.0, 1.0, 0.0, 0.5]
float g = rgb[1]; // 0.5, indexing, not swizzling
GLSL에서 matrix는 다음과 같이 사용할 수 있다.
mat2, mat3, mat4
matmxn
(m
Columns, n
rows), mat2x3, mat3x4, mat4x4
mat3 i = mat3(1.0); // 3x3 Identity Matrix
mat2 m = mat2(1.0, 2.0, // [1.0, 3.0]
3.0, 4.0); // [2.0, 4.0] // Column Major
float f = m[column][row];
// Threat matrix as array of column vectors
float x = m[0].x; // x component of first column
// Can Swizzle too!
vec2 yz = m[1].yz; //yz components of second column
벡터와 행렬은 다음의 연산을 수행할 수 있고 연산 속도 또한 빠르다.
vec3 xyz = // ...
vec3 v0 = 2.0 * xyz; // scale
vec3 v1 = v0 + xyz; // Component-wise
vec3 v2 = v0 * xyz; // Component-wise
mat3 m = // ...
mat3 t = // ...
mat3 mt = t * m; // matrix * matrix
vec3 xyz2 = mt * xyz; // matrix * vector
vec3 xyz3 = xyz * mt; // vector * matrix ( = transposed_matrix * vector)
Qualifiers는 GLSL에서 변수의 속성이나 사용 방법을 정의하는데 사용되는 키워드 이다. Qualifier 는 변수가 어떻게 사용되고, 어디에서 정의되며, 어느 시점에 값을 가지는지 등을 결정한다.
in vec2 tex_coord;
out vec4 color;
uniform float time;
uniform vec4 rotation;
#version 430
// uniform: shader input constant accross glDraw
uniform mat4 u_ModelView;
// in: shader input varies per vertex attribute
in vec3 Position;
in vec3 Color;
// out: shader output
out vec3 fs_Color;
void main(void) {
fs_Color = Color;
gl_Position = u_ModelView * vec4(Position, 1.0);
}
if
if else
expression ? true-expression : false-expression
while, do while
for
sqrt, power, abs
sin, asin
length, reflect
#version 330
in vec4 vPosition;
in vec4 vColor;
out vec4 color;
void main() {
color = vColor;
gl_Position = vPosition;
}
이 예제에서 vertex shader는 in
을 이용해 vertex data 인 vec4 vPosition
과 vec4 vColor
값들을 받는다. 이때 vPosition, vColor
는 상수로서 수정이 불가능하다.
vertex shader는 항상 gl_Position
을 가지는데, 이는 vertex shader에서 반드시 계산되어야 한다.
gl_Position
은 정점의 최종 위치를 나타내며, in
으로 입력받은 vec4 vPosition
값에 대해 벡터 혹은 행렬 연산을 수행하여 정점의 최종 위치를 수정 및 계산할 수 있다. 이 위치 정보(gl_Position
)는 나중에 rasterization 단계에서 사용되어 화면에 그릴 픽셀 위치를 결정한다.
또한 vertex shader에서 out
을 통해 vec4 color
를 fragment shader에 전달한다.
#version 330
in vec4 color;
out vec4 fColor;
void main() {
fColor = color;
}
이 예제에서 fragment shader는 in 을 이용해 vertex shader 로 부터 vec4 color
값을 전달 받는다. 이때 color
는 상수로서 수정이 불가능하다.
fragment shader는 항상 vec4
를 out
해야 한다. 이때 out
하는 값은 최종 색상 값으로 예제에서는 vec4 fColor
값을 out
한다. 또한 fColor
는 CPU에서 vertex data 로 만든 color
값이 vertex shader -> fragment shader 순서로 전달되어 in
으로 vertex shader 로 부터 전달 받은 값이다.
out
으로 출력하는 최종 값인 vec4
는 최종 색상 값으로 RGBA
의 값으로 구성되어 있다. 여기서 R
은 RED, G
는 GREEN, B
는 BLUE 값을 나타내며 A
는 Alpha로 투명도를 의미한다.
만약 out
으로 최종 색상 값을 출력하지 않는 다면 화면 상에 색상 정보가 없는 상태로 출력된다. 즉, 화면상 결과가 출력되지 않는다.