GLSL

Date:     Updated:

카테고리:

태그:

Main Reference
- Learn OpenGL
- Rinthel Kwon - OpenGL Lecture


Shader Format

#version version_number

in type in_variable_name;
in type in_variable_name;

out type out_variable_name;

uniform type uniform_name;

void main() {
  // process input(s) and do some weird graphics stuff ...
  // output processed stuff to output variable
  out_variable_name = weird_stuff_we_processed;
}
  • in / out : 파이프라인에서 shader들의 입/출력
    • ex) vertex shader에서 out으로 지정한 output을 fragment shader에서 in으로 받아옴
    • program에서 shader들 link할 때 in/out 변수의 타입, 이름을 검사
  • Vertex Shader의 경우 VAO로 부터 데이터를 받아와야 하므로 input 받는 방식이 약간 다름
    • layout (location = 0) in vec3 aPos
  • uniform : 병렬로 수행되는 shader thread들이 동일한 값을 사용해야 하는 경우 사용하는 global variable
    • ex) 모든 vertex에서 동일한 color 값을 사용할 경우, cpu에서 해당 값만 넘겨주면 됨
    • ex) color값이 time에 따라 변하는 경우 cpu에서 time 변수 넘겨줄 때
    • 사용법은 아래에서 다시 설명
  • 모든 shader는 main 함수를 가져야 함


Uniform Variable

// context.cpp

// ...
auto loc = glGetUniformLocation(m_program->Get(), "color");
m_program->Use();
glUniform4f(loc, 1.0f, 1.0f, 0.0f, 1.0f);

// ...
  • glGetUniformLocation()함수를 이용해 program object로 부터 uniform handler 얻기
    • “color”라는 변수 명을 이용해 location 찾음
  • glUniformXXXX 함수를 이용해 값 전달
    • 4f : float 4개
    • glUniform4fv 포인터 타입으로 값을 넘겨줄 경우 끝에 v가 붙음


GLSL Data Type

Type

  • X : 2, 3, 4
    • vecX : float형 벡터
    • bvecX : bool형 벡터
    • ivecX : int형 벡터
    • uvecX : uint형 벡터
    • dvecX : double형 벡터
  • 마찬가지로
    • matX, bmatX, …, dmatX 존재


Initialize

vec2 vect = vec2(0.5, 0.7);
vec4 result = vec4(vect, 0.0, 0.0);
vec4 otherResult = vec4(result.xyz, 1.0);
  • 벡터의 초기값은 생성자를 이용해 선언
  • 다른 벡터를 섞어서 사용도 가능


Vector Index

vec2 someVec;
vec4 differentVec = someVec.xyxx;
vec3 anotherVec = differentVec.zyw;
vec4 otherVec = someVec.xxxx + anotherVec.yxzy;
  • 벡터의 인덱스는 xyzw, rgba 등으로 접근 가능
  • 얻고 싶은 인덱스를 순서에 상관없이 사용할 수 있음


Example

// context.cpp
float vertices[] = {
0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, // top right, red
0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, // bottom right, green
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, // bottom left, blue
-0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 0.0f, // top left, yellow
};

uint32_t indices[] = { // note that we start from 0!
    0, 1, 3, // first triangle
    1, 2, 3, // second triangle
};

m_vertexLayout = VertexLayout::Create();

m_vertexBuffer = Buffer::CreateWithData(GL_ARRAY_BUFFER, GL_STATIC_DRAW, vertices, sizeof(float) * 24);

m_vertexLayout->SetAttrib(0, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 6, 0);
m_vertexLayout->SetAttrib(1, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 6, sizeof(float) * 3);

m_indexBuffer = Buffer::CreateWithData(GL_ELEMENT_ARRAY_BUFFER, GL_STATIC_DRAW, indices, sizeof(uint32_t) * 6);

ShaderPtr vertShader = Shader::CreateFromFile("./shader/per_vertex_color.vs", GL_VERTEX_SHADER);
ShaderPtr fragShader = Shader::CreateFromFile("./shader/per_vertex_color.fs", GL_FRAGMENT_SHADER);
  • 이번에는 vertex마다 color값을 다르게 지정
  • position에 관한 VBO, color에 관한 VBO를 각각 생성 후 바인딩


// vertex shader
#version 330 core

layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor;

out vec4 vertexColor;

void main() {
    gl_Position = vec4(aPos, 1.0);
    vertexColor = vec4(aColor, 1.0);
}
  • vertex shader에서는 layout-location을 이용해 position, color값 받아온 후
  • 해당 color값을 fragment shader로 전달(output)


#version 330 core

in vec4 vertexColor;

out vec4 fragColor;

void main() {
    fragColor = vertexColor;
}
  • fragment shader에서는 넘겨받은 color를 칠하기만 하면 되는데
  • 주의할 점은 rasterization이 끝난 후 (interpolation된) 픽셀들이 넘어온다는 점


image



맨 위로 이동하기

OpenGL 카테고리 내 다른 글 보러가기

댓글 남기기