๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿ˜ธ OpenGL

[Learn OpenGL] Shaders - 1

by HOENDEV 2023. 11. 18.

์‰์ด๋”๋Š” GPU์— ์กด์žฌํ•˜๋Š” ์ž‘์€ ํ”„๋กœ๊ทธ๋žจ๋“ค๋กœ, ๊ทธ๋ž˜ํ”ฝ ํŒŒ์ดํ”„๋ผ์ธ์˜ ํŠน์ • ๋ถ€๋ถ„๋งˆ๋‹ค ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.

 

๊ธฐ๋ณธ์ ์œผ๋กœ, ์‰์ด๋”๋Š” ์ž…๋ ฅ์„ ์ถœ๋ ฅ์œผ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ํ”„๋กœ๊ทธ๋žจ์— ๋ถˆ๊ณผํ•ฉ๋‹ˆ๋‹ค.

 

์‰์ด๋”๋Š” ์„œ๋กœ ํ†ต์‹ ํ•  ์ˆ˜ ์—†๋Š” ๋งค์šฐ ๋…๋ฆฝ์ ์ธ ํ”„๋กœ๊ทธ๋žจ์ด๋ฉฐ, ์ž…๋ ฅ๊ณผ ์ถœ๋ ฅ์„ ํ†ตํ•ด์„œ๋งŒ ํ†ต์‹ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

์ด์ „ ์žฅ์—์„œ ์šฐ๋ฆฌ๋Š” ์‰์ด๋”์™€ ๊ทธ ์‚ฌ์šฉ ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ๊ฐ„๋‹จํžˆ ๋‹ค๋ฃจ์—ˆ์Šต๋‹ˆ๋‹ค. ์ด์ œ ์‰์ด๋”, ํŠนํžˆ OpenGL Shading Language์— ๋Œ€ํ•ด ์ข€ ๋” ์ผ๋ฐ˜์ ์œผ๋กœ ์„ค๋ช…ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

GLSL

์‰์ด๋”๋Š” C์™€ ์œ ์‚ฌํ•œ ์–ธ์–ด์ธ GLSL๋กœ ์ž‘์„ฑ๋ฉ๋‹ˆ๋‹ค. GLSL์€ ๊ทธ๋ž˜ํ”ฝ์šฉ์œผ๋กœ ์ œ์ž‘๋˜์—ˆ์œผ๋ฉฐ ๋ฒกํ„ฐ์™€ ํ–‰๋ ฌ ์กฐ์ž‘์— ํŠนํ™”๋œ ์œ ์šฉํ•œ ๊ธฐ๋Šฅ์„ ํฌํ•จํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

 

์‰์ด๋”๋Š” ํ•ญ์ƒ ๋ฒ„์ „ ์„ ์–ธ์œผ๋กœ ์‹œ์ž‘ํ•œ ํ›„, ์ž…๋ ฅ ๋ฐ ์ถœ๋ ฅ ๋ณ€์ˆ˜, ์œ ๋‹ˆํผ ๋ฐ ๋ฉ”์ธ ํ•จ์ˆ˜์˜ ๋ชฉ๋ก์ด ์ด์–ด์ง‘๋‹ˆ๋‹ค.

 

๊ฐ ์‰์ด๋”์˜ ์ง„์ž…์ ์€ ์ž…๋ ฅ ๋ณ€์ˆ˜๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ณ  ๊ฒฐ๊ณผ๋ฅผ ์ถœ๋ ฅ ๋ณ€์ˆ˜์— ์ถœ๋ ฅํ•˜๋Š” ๋ฉ”์ธ ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค.

 

์œ ๋‹ˆํผ์ด ๋ฌด์—‡์ธ์ง€ ๋ชจ๋ฅด๋”๋ผ๋„ ๊ฑฑ์ •ํ•˜์ง€ ๋งˆ์„ธ์š”. ์šฐ๋ฆฌ๋Š” ๊ณง ๊ทธ๊ฒƒ์— ๋Œ€ํ•ด ์„ค๋ช…ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

 

์‰์ด๋”๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ตฌ์กฐ๋ฅผ ๊ฐ€์ง‘๋‹ˆ๋‹ค.

 

#version version_number
in type in_variable_name;
in type in_variable_name;

out type out_variable_name;
  
uniform type uniform_name;
  
void main()
{
  // ์ž…๋ ฅ ์ฒ˜๋ฆฌ ๋ฐ ์ผ๋ถ€ ๊ทธ๋ž˜ํ”ฝ ์ž‘์—… ์ˆ˜ํ–‰
  ...
  // ์ฒ˜๋ฆฌ๋œ ๋‚ด์šฉ์„ ์ถœ๋ ฅ ๋ณ€์ˆ˜์— ์ถœ๋ ฅ
  out_variable_name = weird_stuff_we_processed;
}

 

์ •์  ์‰์ด๋”์— ๊ด€ํ•ด์„œ๋Š”, ๊ฐ ์ž…๋ ฅ ๋ณ€์ˆ˜๋ฅผ ์ •์  ์†์„ฑ์ด๋ผ๊ณ ๋„ ํ•ฉ๋‹ˆ๋‹ค.

 

ํ•˜๋“œ์›จ์–ด์— ์˜ํ•ด ์ œํ•œ๋˜๋Š” ์ •์  ์†์„ฑ์˜ ์ตœ๋Œ€ ๊ฐœ์ˆ˜๊ฐ€ ์žˆ์œผ๋ฉฐ, OpenGL์€ ํ•ญ์ƒ ์ตœ์†Œ 16๊ฐœ์˜ 4-์ปดํฌ๋„ŒํŠธ ์ •์  ์†์„ฑ์„ ๋ณด์žฅํ•ฉ๋‹ˆ๋‹ค.

 

ํ•˜์ง€๋งŒ ์ผ๋ถ€ ํ•˜๋“œ์›จ์–ด์—์„œ๋Š” ๋” ๋งŽ์€ ๊ฒƒ์„ ํ—ˆ์šฉํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, GL_MAX_VERTEX_ATTRIBS๋ฅผ ์กฐํšŒํ•˜์—ฌ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

int nrAttributes;
glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &nrAttributes);
std::cout << "Maximum nr of vertex attributes supported: " << nrAttributes << std::endl;

 

Types

GLSL์€ ๋‹ค๋ฅธ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด์ฒ˜๋Ÿผ, ์šฐ๋ฆฌ๊ฐ€ ์ž‘์—…ํ•˜๊ณ ์ž ํ•˜๋Š” ๋ณ€์ˆ˜์˜ ์ข…๋ฅ˜๋ฅผ ์ง€์ •ํ•˜๊ธฐ ์œ„ํ•œ ๋ฐ์ดํ„ฐ ํƒ€์ž…์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

 

GLSL์—๋Š” C ์–ธ์–ด์™€ ๊ฐ™์€ ์–ธ์–ด์—์„œ ์•Œ๊ณ  ์žˆ๋Š” ๋Œ€๋ถ€๋ถ„์˜ ๊ธฐ๋ณธ ๊ธฐ๋ณธ ํƒ€์ž…์ด ์žˆ์Šต๋‹ˆ๋‹ค.

 

int, float, double, uint, bool. ๋˜ํ•œ GLSL์—๋Š” ๋ฒกํ„ฐ์™€ ํ–‰๋ ฌ ๋‘ ๊ฐ€์ง€ ์ปจํ…Œ์ด๋„ˆ ํƒ€์ž…์ด ์žˆ์œผ๋ฉฐ, ์ด๋“ค์€ ์ž์ฃผ ์‚ฌ์šฉ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

 

ํ–‰๋ ฌ์— ๋Œ€ํ•ด์„œ๋Š” ๋‚˜์ค‘์— ๋‹ค๋ฃฐ ์˜ˆ์ •์ž…๋‹ˆ๋‹ค.

 

Vectors

GLSL์˜ ๋ฒกํ„ฐ๋Š” ๋ฐฉ๊ธˆ ์–ธ๊ธ‰ํ•œ ๊ธฐ๋ณธ ํƒ€์ž…์˜ 2, 3, ๋˜๋Š” 4๊ฐœ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๊ฐ€์ง„ ์ปจํ…Œ์ด๋„ˆ์ž…๋‹ˆ๋‹ค.

 

๋‹ค์Œ๊ณผ ๊ฐ™์€ ํ˜•ํƒœ๋ฅผ ์ทจํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(n์€ ๊ตฌ์„ฑ ์š”์†Œ์˜ ์ˆ˜๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค)

 

vecn: n๊ฐœ์˜ float๋กœ ๊ตฌ์„ฑ๋œ ๊ธฐ๋ณธ ๋ฒกํ„ฐ.

bvecn: n๊ฐœ์˜ boolean์œผ๋กœ ๊ตฌ์„ฑ๋œ ๋ฒกํ„ฐ.

ivecn: n๊ฐœ์˜ integer๋กœ ๊ตฌ์„ฑ๋œ ๋ฒกํ„ฐ.

uvecn: n๊ฐœ์˜ unsigned integer๋กœ ๊ตฌ์„ฑ๋œ ๋ฒกํ„ฐ.

dvecn: n๊ฐœ์˜ double ๊ตฌ์„ฑ ์š”์†Œ๋กœ ๊ตฌ์„ฑ๋œ ๋ฒกํ„ฐ.

 

๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ, float์ด๋ฉด ์ถฉ๋ถ„ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ธฐ๋ณธ์ ์ธ vecn์„ ์‚ฌ์šฉํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

 

๋ฒกํ„ฐ์˜ ๊ตฌ์„ฑ ์š”์†Œ๋Š” vec.x์™€ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์—ฌ๊ธฐ์„œ x๋Š” ๋ฒกํ„ฐ์˜ ์ฒซ ๋ฒˆ์งธ ๊ตฌ์„ฑ ์š”์†Œ์ž…๋‹ˆ๋‹ค.

 

.x, .y, .z, .w๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ๊ฐ ์ฒซ ๋ฒˆ์งธ, ๋‘ ๋ฒˆ์งธ, ์„ธ ๋ฒˆ์งธ, ๋„ค ๋ฒˆ์งธ ๊ตฌ์„ฑ ์š”์†Œ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

GLSL์€ ์ƒ‰์ƒ์— ๋Œ€ํ•ด rgba๋‚˜ ํ…์Šค์ฒ˜ ์ขŒํ‘œ์— ๋Œ€ํ•ด stpq๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋™์ผํ•œ ๊ตฌ์„ฑ ์š”์†Œ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋„๋ก ํ—ˆ์šฉํ•ฉ๋‹ˆ๋‹ค.

 

 

๋ฒกํ„ฐ ๋ฐ์ดํ„ฐ ํƒ€์ž…์€ ์Šค์œ„์ฆ๋ง์ด๋ผ๊ณ  ๋ถˆ๋ฆฌ๋Š” ํฅ๋ฏธ๋กญ๊ณ  ์œ ์—ฐํ•œ ๊ตฌ์„ฑ ์š”์†Œ ์„ ํƒ์„ ํ—ˆ์šฉํ•ฉ๋‹ˆ๋‹ค.

 

์Šค์œ„์ฆ๋ง์„ ์‚ฌ์šฉํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฌธ๋ฒ•์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

vec2 someVec;
vec4 differentVec = someVec.xyxx;
vec3 anotherVec = differentVec.zyw;
vec4 otherVec = someVec.xxxx + anotherVec.yxzy;

 

์ตœ๋Œ€ 4๊ฐœ์˜ ๋ฌธ์ž๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ƒˆ๋กœ์šด ๋ฒกํ„ฐ(๋™์ผํ•œ ํƒ€์ž…)๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์›๋ž˜ ๋ฒกํ„ฐ๊ฐ€ ํ•ด๋‹น ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ํ•œ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค;

 

์˜ˆ๋ฅผ ๋“ค์–ด, vec2์˜ .z ๊ตฌ์„ฑ ์š”์†Œ์— ์ ‘๊ทผํ•˜๋Š” ๊ฒƒ์€ ํ—ˆ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

 

๋˜ํ•œ ๋ฒกํ„ฐ๋ฅผ ๋‹ค๋ฅธ ๋ฒกํ„ฐ ์ƒ์„ฑ์ž ํ˜ธ์ถœ์˜ ์ธ์ˆ˜๋กœ ์ „๋‹ฌํ•˜์—ฌ ํ•„์š”ํ•œ ์ธ์ˆ˜์˜ ์ˆ˜๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

vec2 vect = vec2(0.5, 0.7);
vec4 result = vec4(vect, 0.0, 0.0);
vec4 otherResult = vec4(result.xyz, 1.0);

 

๋”ฐ๋ผ์„œ ๋ฒกํ„ฐ๋Š” ์ž…๋ ฅ๊ณผ ์ถœ๋ ฅ์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์œ ์—ฐํ•œ ๋ฐ์ดํ„ฐ ํƒ€์ž…์ž…๋‹ˆ๋‹ค.

 

์ด ์ฑ…์„ ํ†ตํ•ด ๋ฒกํ„ฐ๋ฅผ ์ฐฝ์˜์ ์œผ๋กœ ๊ด€๋ฆฌํ•˜๋Š” ๋‹ค์–‘ํ•œ ์˜ˆ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

 

Ins and outs

์‰์ด๋”๋Š” ์ž์ฒด์ ์œผ๋กœ ๋ฉ‹์ง„ ์ž‘์€ ํ”„๋กœ๊ทธ๋žจ์ด์ง€๋งŒ, ์ „์ฒด์˜ ์ผ๋ถ€๋กœ ๋™์ž‘ํ•˜๊ธฐ ๋•Œ๋ฌธ๋ฐ

 

๊ฐœ๋ณ„ ์‰์ด๋”์— ์ž…๋ ฅ๊ณผ ์ถœ๋ ฅ์ด ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ์ด๋™์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

GLSL์€ ์ด ๋ชฉ์ ์„ ์œ„ํ•ด in๊ณผ out ํ‚ค์›Œ๋“œ๋ฅผ ์ •์˜ํ–ˆ์Šต๋‹ˆ๋‹ค.

 

์ถœ๋ ฅ ๋ณ€์ˆ˜๊ฐ€ ๋‹ค์Œ ์‰์ด๋” ๋‹จ๊ณ„์˜ ์ž…๋ ฅ ๋ณ€์ˆ˜์™€ ์ผ์น˜ํ•  ๊ฒฝ์šฐ ์ „๋‹ฌ๋ฉ๋‹ˆ๋‹ค.

 

 

vertex shader๋Š” ์–ด๋–ค ํ˜•ํƒœ์˜ ์ž…๋ ฅ์„ ๋ฐ›์•„์•ผ ํ•˜๋ฉฐ, ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ๊ต‰์žฅํžˆ ๋น„ํšจ์œจ์ ์ด๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

 

์ •์  ์‰์ด๋”๋Š” ์ž…๋ ฅ์„ ์ •์  ๋ฐ์ดํ„ฐ๋กœ ๋ถ€ํ„ฐ ์ง์ ‘ ๋ฐ›๋Š”๋‹ค๋Š” ์ ์—์„œ ๋‹ค๋ฆ…๋‹ˆ๋‹ค.

 

์ •์  ๋ฐ์ดํ„ฐ์˜ ๊ตฌ์„ฑ์„ ์ •์˜ํ•˜๊ธฐ ์œ„ํ•ด ์œ„์น˜ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ์™€ ํ•จ๊ป˜ ์ž…๋ ฅ ๋ณ€์ˆ˜๋ฅผ ์ง€์ •ํ•˜์—ฌ CPU์—์„œ ์ •์  ์†์„ฑ์„ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

์ด์ „ ์žฅ์—์„œ laouy(location = 0) ์œผ๋กœ ์ด๋ฅผ ๋ณด์•˜์Šต๋‹ˆ๋‹ค.

 

๋”ฐ๋ผ์„œ ์ •์  ์‰์ด๋”๋Š” ์ •์  ๋ฐ์ดํ„ฐ์™€ ์—ฐ๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ์ž…๋ ฅ์— ๋Œ€ํ•œ ์ถ”๊ฐ€ ๋ ˆ์ด์•„์›ƒ ์‚ฌ์–‘์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

 

 

fragment shader๋Š” vec4 ์ƒ‰์ƒ ์ถœ๋ ฅ ๋ณ€์ˆ˜๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

 

์ƒ‰์ƒ ์ถœ๋ ฅ์„ ์ง€์ •ํ•˜์ง€ ์•Š์œผ๋ฉด ์ผ๋ฐ˜์ ์œผ๋กœ OpenGL์€ ์ด๋ฅผ ๊ฒ€์€์ƒ‰์ด๋‚˜ ํฐ์ƒ‰์œผ๋กœ ๋ Œ๋”๋ง ํ•ฉ๋‹ˆ๋‹ค.

 

 

ํƒ€์ž…๊ณผ ์ด๋ฆ„์ด ์–‘์ชฝ ์‰์ด๋”์—์„œ ๋™์ผํ•˜๋ฉด OpenGL์€ ์ด๋Ÿฌํ•œ ๋ณ€์ˆ˜๋ฅผ ์—ฐ๊ฒฐํ•˜๊ณ  ํ”„๋กœ๊ทธ๋žจ ๊ฐ์ฒด๋ฅผ ์—ฐ๊ฒฐํ•  ๋•Œ

 

์‰์ด๋” ๊ฐ„์— ๋ฐ์ดํ„ฐ๋ฅผ ๋ณด๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

 

Vertex Shader

#version 330 core
layout (location = 0) in vec3 aPos; // the position variable has attribute position 0
  
out vec4 vertexColor; // specify a color output to the fragment shader

void main()
{
    gl_Position = vec4(aPos, 1.0); // see how we directly give a vec3 to vec4's constructor
    vertexColor = vec4(0.5, 0.0, 0.0, 1.0); // set the output variable to a dark-red color
}

 

Fragment Shader

#version 330 core
out vec4 FragColor;
  
in vec4 vertexColor; // the input variable from the vertex shader (same name and same type)  

void main()
{
    FragColor = vertexColor;
}

 

์œ„์—์„œ ์ •์  ์‰์ด๋”์— vec4 ์ถœ๋ ฅ์œผ๋กœ vertexColor ๋ณ€์ˆ˜๋ฅผ ์„ ์–ธํ•˜๊ณ  ์„ค์ •ํ•˜๊ณ ,

 

fragment shader์—์„œ vertexColor๋ฅผ ์ž…๋ ฅ์œผ๋กœ ์„ ์–ธํ•˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

๋‘ ๋ณ€์ˆ˜ ๋ชจ๋‘ ๊ฐ™์€ ํƒ€์ž…๊ณผ ์ด๋ฆ„์„ ๊ฐ€์ง€๋ฏ€๋กœ, ์กฐ๊ฐ ์‰์ด๋”์˜ vertexColor๋Š” ์ •์  ์‰์ด๋”์˜ vertexColor์™€ ์—ฐ๊ฒฐ๋ฉ๋‹ˆ๋‹ค.

 

์ •์  ์‰์ด๋”์—์„œ ์ƒ‰์ƒ์„ ์–ด๋‘์šด ๋นจ๊ฐ„์ƒ‰์œผ๋กœ ์„ค์ •ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์—, ๊ฒฐ๊ณผ์ ์œผ๋กœ ์ƒ์„ฑ๋˜๋Š” ์กฐ๊ฐ๋“ค๋„ ์–ด๋‘์šด ๋นจ๊ฐ„์ƒ‰์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ ์ด๋ฏธ์ง€๋Š” ์ถœ๋ ฅ ๊ฒฐ๊ณผ๋ฅผ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

 

'๐Ÿ˜ธ OpenGL' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

[Learn OpenGL] Shaders - 3  (0) 2023.11.18
[Learn OpenGL] Shaders - 2  (0) 2023.11.18
[Learn OpenGL] Hello Triangle - 4  (0) 2023.11.18
[Learn OpenGL] Hello Triangle - 3  (0) 2023.11.17
[Learn OpenGL] Hello Triangle - 2  (0) 2023.11.17