GLSL & Shaders Tutorial

출처

[GLSL & Shaders Tutorial - Understanding The Syntax And The Idea Behind The Vertex & Fragment Shaders](https://www.youtube.com/watch?v=xZM8UJqN1eY&t=13s)

 


 

GLSL definition

- Open**GL** **S**hading **L**anguage 의 약자
- 브라우저에 2D를 3D로 표시하기 위해 웹 응용 프로그램이 그래픽 카드와 통신할 수 있는 프로그래밍 언어

 

 


 

Variables and constants + Basic types

  • 데이터 타입 지정하여 선언해야 함.
    • int
    • float
    • bool
  • 변수에 데이터 타입을 지정하면 다른 타입의 값을 설정할 수 없다.
int a = 20.0; -> X 
float b = 4; -> X

 

  • 변환 함수를 사용하여 데이터 타입을 변경할 수 있다.
// c = 1;
int c = int(true);

// d = 2.0;
float d = float(2);

// e = 0.0;
float e = float(false);

 


Vectors

  • Vec
    • vec2
    • vec3
    • vec4
  • ivec
    • ivec2
    • ivec3
    • ivec4
  • bvec
    • bvec2
    • bvec3
    • bvec4
vec2 vectA = vec2(1.0, 6.0);

bvec4 vectB = bvec4(true, true, false, false);

// Same as : vec3 vectC = vec3(0.0, 0.0, 0.0);
vec3 vectC = vec3(0.0);

// vectD value : vec2(0.0, 0.0);
vec2 vecD = vec2(vectC);

// vecE value : vec4(0.0, 0.0, 1.0, 6.0);
vec4 vectE = vec4(vectC, vectA);

Vector 요소

  • 꼭짓점 위치를 다루는 경우
    • x ,y, z
  • 색상 작업을 하는 경우
    • r, g, b
  • 텍스처 작업 하는 경우
    • s, t, p
vec4 vect = vec4(1.0, 2.0, 3.0, 4.0);

// a1 == a2 == a3 == 1.0
float a1 = vect.x;
float a2 = vect.r;
float a3 = vect.s;

// b1 == b2 == b3 == 2.0
float b1 = vect.y;
float b2 = vect.g;
float b3 = vect.t;

// c1 == c2 == c3 == 3.0
float c1 = vect.z;
float c1 = vect.b;
float c1 = vect.p;

// d1 == d2 == d3 == 4.0
float d1 = vect.w;
float d2 = vect.a;
float d3 = vect.q;
  • 동시에 두 개 이상의 구성 요소에 접근 가능하다.
vec3 vectA = vec3(1.0, 2.0, 3.0);

// vectB value: vec2(1.0, 3.0);
vec2 vecB = vectA.xz;

 

  • 다른 순서로 값을 반복하고 가져올 수 있다.
// vectC value : vec3(1.0, 1.0, 1.0);
vec3 vectC = vectA.rrr;

// vectD value : vec2(3.0, 1.0);
vec2 vectD = vectA.br; // 1, 3번

 


Matrices

Matrices

  • 2, 3, 4 차원 행렬 자료형 지원한다.

  • 벡터와 다르게 동시에 다른 유형의 값을 가질 수 있다.
// matA value : mat2(1.0, 1.0, 0.0, 0.0);
mat2 matA = mat2(1, 1, false, false);

 

  • 행렬 생성 예시 코드

 

  • 행렬 접근 예시
// vectC1 value : vec3(7.0, 4.0, 5.0);
vec3 vectC1 = matB[0];

// Replaces 7.0 by 100.0
matB[2][2] = 100.0;

// f value : 4.0
// Same as matB[0][1]
float f = matB[0]y;

 

 

Samplers

  • 이미지 데이터를 저장하는 변수 유형이다.
    • sampler2D: 이미지, 그림 같은 2차원 텍스처 다룰 때 사용
    • samplerCube: Cube Map 텍스처를 위한 데이터 타입, 6개의 2차원 이미지로 구성
      • 주로 reflections, environment mapping 에 사용

Arrays

  • 사전에 데이터 타입과 개수를 지정한다.
  •  
float arrayA[7]; // 배열 생성을 위한 데이터 컬렉션 저장, 사전에 데이터 타입과 개수를 지정해야함.
// 7개의 float 타입 요소를 가지는 배열 선언 O , 배열을 7로 초기화 X

// 첫번째 요소 값 설정
arrayA[0] = 20.0;

// 7번째 요소 값 가져오기 
float a = arrayA[6];

 

 

structures

  • struct 키워드를 사용하여 정의
    • 변수를 생성하기 위한 뼈대
struct myType
{
	int c1;
	vect3 c2;
}

myType a; // 정의된 구조체 사용하기 위한 인스턴스

// Sets the value of c1
a.c1 = 10;

// Gets the value of c2
vect3 vect = a.c2;

 

제어문

if - else
for , while

 

functions

함수와 데이터 타입

  • 함수 또한 데이터 타입을 가져야 한다.
    • 함수 타입은 return 값과 동일한 타입이어야 함.’
    • return 값이 없다면 Void
float funcA(int a, vec2 b) {
	return 1.0;
}

void funcB(vec3 vect){
	// No return
}

 

 

  • 함수를 생성하고 호출하려면 함수의 매개변수 유형도 지정해야 함.
    • 함수 먼저 생성해야 함.
vec2 funcC() // 맞는 예시
{
	return vec2(1.0, 2.0);
}
vec2 vect = funcC();
---------------------------------------------------- 
~~vec2 vect = funcD(); // 틀린 예
vec2 funcD()
{
	return vec2(1.0, 2.0);
}~~

 

  • 함수 먼저 생성하지 않으려면 prototype 을 지정한다.
vec2 funcE(float x, float y);
vec2 vect = funcE(1.0, 1.0);

vec2 funcE(float x, float y)
{
	return vec2(1.0, 2.0);
}

 

 

GLSL 내장 함수

https://shaderific.com/glsl/common_functions.html

 

Shaderific for OpenGL

COMMON FUNCTIONS Absolute value float abs(float x) vec2 abs(vec2 x) vec3 abs(vec3 x) vec4 abs(vec4 x) The abs function returns the absolute value of x, i.e. x when x is positive or zero and -x for negative x. The input parameter can be a floating scalar or

shaderific.com

 

 

Storage qualifiers

저장 한정자

  • 변수의 저장 위치와 수명 정의하는데 사용된다.
    • const
    • attribute
    • uniform
    • varying
  • attribute와 uniform은 JavaScript 쪽에서 값을 전달 받는다.

 

 

  • attribute: 정점 데이터를 셰이더에 전달하기 위해 사용, Vertex Shader에서만 사용
  • uniform: 셰이더 프로그램 전체에서 동일한 값을 유지하는 변수, 프레임마다 또는 드로우콜마다 변경되지 않는 데이터를 전달. Vertex, Fragment 둘 다 사용 가능.
  • varying: 다양한 데이터 전달하는데 사용

 

 

 

Precision qualifiers 정밀도

  • lowp
    • 성능이 중요한 경우에 사용, 색상 값 등 상대적으로 정밀도가 낮아도 되는 계산에 사용.
  • mediump
    • 정밀도 + 성능의 균형 맞출 때 사용, 텍스처 좌표, 중간 수준의 색상 계산.
  • highp
    • 좌표, 변환 행렬 등 정확한 계산이 필요할 때 사

Vertex shader

  • 점, 텍스트, 모양, 3D 모델 등을 구성하는 모든 정점의 위치 관리
  • main 함수 내에 입력되어야 함
    • 메쉬를 구성하는 정점 수만큼 실행됨
      - gl_position
      - 각 정점 좌표가 저장됨.
void main() 
{
	gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
								투영 변환 x 모델 변환 x 초기 좌표
}

 

Fragment shader

  • Vertex Shader에 의해 배치된 후 메쉬에서 정점을 색상화하는 Shader.
  • Vertex Shader에 의해 배치된 정점에서 생성된 메쉬를 작은 조각으로 분해 → 색상화
  • 특수 내장 변수 사용: gl_FragColor
void main()
{
	gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); // R G B A(Opacity)
}