GLSL
- GLSL : Shader 프로그래밍을 위한 C 기반의 언어
#version version_number // Open GL 버전
in type in_variable_name;
in type in_variable_name; // 셰이더에 들어오는 입력 변수
out type out_variable_name; // 셰이더가 처리한 뒤 내보내는 출력 변수
uniform type uniform_name; // 모든 vertex에 대해 동일하게 사용되는 전역 변수
void main() {
out_variable_name = weird_stuff_we_processed;
}
GLSL data types
대부분의 C 데이터 타입 + Vector, matrix 데이터 타입 지원
- Vectors
- 2,3,4개의 구성요소를 지니는 컨테이너
- vecn : n개의 실수(float) 성분을 지니는 기본 벡터
- bvecn : n개의 bool 성분을 지니는 벡터
- ivecn : n개의 정수 성분을 지니는 벡터
- uvecn : n개의 unsigned int 성분을 지니는 벡터
- dvecn : n개의 double 성분을 지니는 벡터
- 2,3,4개의 구성요소를 지니는 컨테이너
Combination of Components
- Swizzling : 벡터의 성분(component)을 조합
vec2 someVec; //someVec : (x,y)
vec4 differentVec = someVec.xyxx; //(x,y,x,x)
vec3 anotherVec = differentVec.zyw; //(x,y,x)
vec4 otherVec = someVec.xxxx + anotherVec.yxzy; //(x,x,x,x) + (y,x,x,y)
Shader Inputs and Outputs
- in : 입력 변수
- out : 출력 변수
Vertex shader은 초기 데이터를 외부에서 입력받아야됨
- Vertex shader의 입력 변수 구분
layout (location = 0) in vec3 aPos; //입력변수 위치
layout (location = 1) in vec3 aColor;
glVertexAttribPointer(0, ..... );
glEnableVertexAttribArray(0); //구분번호 0을 layout에 넘긴다 ⇒ 해당 VAO 바인딩
glVertexAttribPointer 첫 번째 매개변수 : 어떤 버텍스 속성을 지정할 것인지를 나타내는 인덱스
Sending Data between Shaders
- Vertex shader
#version 330 core
layout (location = 0) in vec3 aPos;
out vec4 vertexColor;
void main()
{
gl_Position = vec4(aPos, 1.0);
vectorColor = vec4(0.5, 0.0, 0.0, 1.0);
}
- Fragment shader
#version 330 core
out vec4 FragColor;
in vec4 vertexColor; //이전 스테이지에서의 출력형식, 이름과 동일
void main()
{
FragColor = vertexColor;
}
vertex shader처럼 초기 데이터를 외부로부터 받는게 아니라면, 이전 셰이더의 출력 변수가 그 다음 스테이지 셰이더의 입력 변수로 그대로 들어간다
Uniform 변수
- 모든 vertex에 동일한 변수값을 전달할 때 사용
- 전역변수 속성. 모든 스테이지의 shader에서 접근 가능
#version 330 core
out vec4 FragColor;
uniform vec4 ourColor;
void main() {
FragColor = ourColor; //출력값을 uniform 전역변수 ourColor로부터
}
Uniform 변수값 전달
- int glGetUniformLocation(shaderProgram, uniform 변수 이름)
셰이더 프로그램내에서의 uniform 변수 위치를 int형으로 리턴
Uniform 변수값 지정. int, float 등에 따라 uniform vector, matrix 값 지정할 수 있다
glUniformf() // float(실수값) 설정
glUniformi() // int(정수값) 설정
glUniformui() // unsigned int 설정
glUniform3f() // float 3개 값 설정
glUniform4f() // float 4개 값 설정
glUniformfv() // float vector/array 값 설정
while (!glfwWindowShouldClose(pWindow)) {
processInput(pWindow);
glClearColor(0.2f, 0.3f, 0.3f, 1.0f); //background color
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shaderProgram);
float timeValue = glfwGetTime();
float greenValue = sin(timeValue) / 2.0f + 0.5f;
int vertexColorLocation = glGetUniformLocation(shaderProgram, "ourColor");
// glUniform4f(uniform변수 위치값, 실수값1, 실수값2, 실수값3, 실수값4)
// 시간에 따라서 녹색이 바뀌도록 색상을 4차원 float 벡터로 shader에 전달
glUniform4f(vertexColorLocation, 0.0f, greenValue, 0.0f, 1.0f);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
glfwSwapBuffers(pWindow);
glfwPollEvents();
#version 330 core
out vec4 FragColor;
uniform vec4 ourColor;
void main()
{
FragColor = ourColor;
}
Using Shader Class
지금까지는 main.cpp안에 shader program을 하드코딩해서 사용
외부 소스코드에서 코딩하고, 그 소스코드를 include하는 방식으로
#include <Shader.h>
int main(int argc, char** argv){
:
//vertex shader 파일이름, fragment shader 파일이름
Shader ourShader("3.3.shader.vs", "3.3.shader.fs");
while (!glfwWindowShouldClose(pWindow)) {
:
ourShader.use(); //glUseProgram(shaderProgram); glUseProgram(..) 대체
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
:
}
'강의 > HCI' 카테고리의 다른 글
[HCI] Graphics & OpenGL 4 (0) | 2025.04.22 |
---|---|
[HCI] Graphics & OpenGL 2 (0) | 2025.04.02 |
[HCI] Graphics & OpenGL 1 (1) | 2025.03.26 |