[컴퓨터그래픽스] GLSL Introduction

Serun1017·2024년 10월 23일
0

컴퓨터그래픽스

목록 보기
16/31

GLSL

GLSL(OpenGL Shading Language)은 C 언어를 기초로 한, 상위 레벨 셰이덩 언어이다. HLSL과 유사한 이 언어는 어셈블리 언어나 하드웨어에 의존한 언어를 사용하지 않고, 개발자가 그래픽스 파이프라인을 직접 제어할 수 있도록 OpenGL ARB(Architecture Review Board) 가 책정하였다.

GLSL 특징

  1. C 기반의 고수준 언어
    • GLSL은 C 와 유사한 구문 구조를 가지며, 변수, 함수, 조건문, 반복문 등 일반적인 프로그래밍 언어의 기능을 사용할 수 있다.
    • 하지만 GLSL은 GPU에서 실행되기 때문에, CPU와는 다른 병렬 처리를 위한 구조와 GPU의 특성에 맞춘 다양한 내장 함수들을 제공한다.
  2. Programmable Pipeline
    • OpenGL에서 고정 기능 파이프라인에서 벗어나 Programmable Pipeline을 도입하게 되면서, 사용자가 셰이더를 통해 그래픽 파이프라인의 다양한 단계를 제어할 수 있게 되었다.
    • GLSL은 이러한 Programmable Pipeline에서 정점 셰이더(Vertex Shader), 프래그먼트 셰이더(Fragment Sahder), 지오메트리 셰이더(Geometry Shader) 등을 정의할 수 있다.
  3. GPU에서 병렬 처리
    • GLSL로 작성한 셰이더 코드는 GPU에서 병렬로 실행된다. 이는 수많은 vertex나 fragment에 대해 동시에 계산을 수행할 수 있도록 하며, 복잡한 그래픽 처리를 빠르고 효율적으로 처리할 수 있다.
  4. 내장된 벡터 및 행렬 타입
    • GLSL은 그래픽스 연산에 자주 사용되는 벡터와 행렬 타입을 기본으로 제공한다. 예를 들어, 2D, 3D, 4D 벡터(vec2, vec3, vec4)와 행렬(mat2, mat3, mat4)을 지원하며, 좌표 변환이나 조명 계산과 같은 그래픽스 작업을 쉽게 처리할 수 있다.
  5. 플랫폼 독립성
    • GLSL은 OpenGL의 표준 셰이더 언어이므로, OpenGL을 지워하는 다양한 플랫폼에서 동일한 셰이더 코드를 사용할 수 있다. 이로 인해 Windows, macOS, Linux 등 여러 운용 체제에서 같은 셰이더 프로그램을 실행할 수 있다.

GLSL Syntax Overview

GLSL의 기본 구조는 C 와 같으나 몇몇 기능은 지원하지 않는다.

GLSL is like C without

  • Pointers
  • Recursion
  • Dynamic Memory Allocation

GLSL is like C with

  • Built-in vector, matrix and sampler types
  • Constructors
  • A great math library
  • Input and output qualifiers

GLSL has a preprocessor

#version 430

#ifdef FAST_EXACT_METHOD
	FastExact();
#else
	SlowApproximate();
#endif

// ... many others

All Shaders have main()

void main(void) {

}

GLSL Data Types

Scalar Types

  • bool
  • int
  • uint
  • float
  • double

Vector Types

  • bvec2, bvec3, bvec4
  • ivec2, ivec3, ivec4
  • uvec2, uvec3, uvec4
  • vec2, vec3. vec4
  • dvec2, dvec3, dvec4

Matrix Types

  • mat2, mat3, mat4

Texture Sampling

  • sampler1D, sampler2D, sampler3D, samplerCube

C++ Style Constructors

  • vec3 a = vec3(1.0, 2.0, 3.0);

Operators

C의 기본적인 연산 및 논리 연산을 제공하며 추가적으로 행렬과 벡터를 위한 연산 또한 제공한다.

mat4 m;
vec4 a, b, c;

b = a * m;
c = m * a;

Components and Swizzling

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 성분 값으로 바뀜.

Constructors

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);

Vectors

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

Matrices

GLSL에서 matrix는 다음과 같이 사용할 수 있다.

  • Matrices are built-in types
    • Square: mat2, mat3, mat4
    • Rectangular: matmxn (m Columns, n rows), mat2x3, mat3x4, mat4x4
  • Stored [[Column Major]]

Constructors

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

Accessing Elements

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

GLSL Syntax

Vectors and Matrices

벡터와 행렬은 다음의 연산을 수행할 수 있고 연산 속도 또한 빠르다.

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

Qualifiers는 GLSL에서 변수의 속성이나 사용 방법을 정의하는데 사용되는 키워드 이다. Qualifier 는 변수가 어떻게 사용되고, 어디에서 정의되며, 어느 시점에 값을 가지는지 등을 결정한다.

in, out

  • Copy vertex attributes and other variables to/from shaders
  • in vec2 tex_coord;
  • out vec4 color;

Uniform

  • Variable from application
  • uniform float time;
  • uniform vec4 rotation;

GLSL Syntax_in_out_uniform.png

Example

#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);
}

Flow Control

  • if
  • if else
  • expression ? true-expression : false-expression
  • while, do while
  • for

Functions

  • Built in
    • Arithmetic: sqrt, power, abs
    • Trigonometric: sin, asin
    • Graphical: length, reflect
  • User defined

Example

Vertex Shader

#version 330

in vec4 vPosition;
in vec4 vColor;
out vec4 color;

void main() {
	color = vColor;
	gl_Position = vPosition;
}

이 예제에서 vertex shader는 in 을 이용해 vertex data 인 vec4 vPositionvec4 vColor 값들을 받는다. 이때 vPosition, vColor는 상수로서 수정이 불가능하다.

vertex shader는 항상 gl_Position 을 가지는데, 이는 vertex shader에서 반드시 계산되어야 한다.
gl_Position은 정점의 최종 위치를 나타내며, in으로 입력받은 vec4 vPosition 값에 대해 벡터 혹은 행렬 연산을 수행하여 정점의 최종 위치를 수정 및 계산할 수 있다. 이 위치 정보(gl_Position)는 나중에 rasterization 단계에서 사용되어 화면에 그릴 픽셀 위치를 결정한다.

또한 vertex shader에서 out 을 통해 vec4 color 를 fragment shader에 전달한다.

Fragment Shader

#version 330

in vec4 color;
out vec4 fColor;

void main() {
	fColor = color;
}

이 예제에서 fragment shader는 in 을 이용해 vertex shader 로 부터 vec4 color 값을 전달 받는다. 이때 color는 상수로서 수정이 불가능하다.

fragment shader는 항상 vec4out 해야 한다. 이때 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 으로 최종 색상 값을 출력하지 않는 다면 화면 상에 색상 정보가 없는 상태로 출력된다. 즉, 화면상 결과가 출력되지 않는다.

0개의 댓글