WebGL ๋ณด์ผ๋ฌํ๋ ์ดํธ(HTML/JS)๋ ์ด๋ฏธ ๊ตฌ์ฑ๋์ด ์๋ค๋ ๊ฐ์ ํ์, ์
ฐ์ด๋ ์ฝ๋(vert.glsl, frag.glsl) ์์ฒด์์ ์์์ผ ํ๋ ๋ฌธ๋ฒ๊ณผ ๊ฐ๋
๋ง ๋ค๋ฃน๋๋ค. ๊ธฐ์ค ๋ฒ์ ์ WebGL2์์ ์ฌ์ฉํ๋ GLSL ES 3.00(#version 300 es)์
๋๋ค.
1. ์ ฐ์ด๋ ํ์ดํ๋ผ์ธ ๊ธฐ๋ณธ ๊ตฌ์กฐ
GPU ํ์ดํ๋ผ์ธ์์ ๋ฒํ
์ค ์
ฐ์ด๋๋ ์ ์ ๋จ์๋ก, ํ๋๊ทธ๋จผํธ ์
ฐ์ด๋๋ ํฝ์
๋จ์๋ก ๋์์ ์คํ๋ฉ๋๋ค. ๋ฒํ
์ค ์
ฐ์ด๋๊ฐ out์ผ๋ก ๋ด๋ณด๋ธ ๊ฐ์ ๋์คํฐํ ๊ณผ์ ์์ ๋ณด๊ฐ๋์ด ํ๋๊ทธ๋จผํธ ์
ฐ์ด๋์ in์ผ๋ก ๋ค์ด์ต๋๋ค.
vert.glsl (๋ฒํ ์ค ์ ฐ์ด๋)
#version 300 es
// [ํ์ ๊ฐ๋
1: in / out]
// in: ๋ณด์ผ๋ฌํ๋ ์ดํธ(JS)์์ ๋ฒํผ๋ก ๋๊ฒจ์ค ๋ฐ์ดํฐ๋ฅผ ๋ฐ๋ ํค์๋ (๊ตฌ๋ฒ์ ์ attribute)
in vec2 a_position;
// [ํ์ ๊ฐ๋
2: varying ๋์ฒด]
// ๋ฒํ
์ค ์
ฐ์ด๋์์ ํ๋๊ทธ๋จผํธ ์
ฐ์ด๋๋ก ๋ฐ์ดํฐ๋ฅผ ๋๊ธธ ๋ out์ ์ฌ์ฉํฉ๋๋ค.
out vec2 v_uv;
void main() {
// [ํ์ ๊ฐ๋
3: gl_Position]
// ๋ฒํ
์ค ์
ฐ์ด๋๋ ๋ฐ๋์ ์ด ๋ด์ฅ ๋ณ์์ ์ขํ๋ฅผ ํ ๋นํด์ผ ํฉ๋๋ค.
// a_position์ ๋ณดํต -1.0 ~ 1.0 ๋ฒ์์
๋๋ค.
gl_Position = vec4(a_position, 0.0, 1.0);
// [ํ์ ๊ฐ๋
4: ๋ฒกํฐ ์ฐ์ฐ๊ณผ ์ค์์ฆ๋ง(Swizzling)]
// -1~1 ๋ฒ์๋ฅผ 0~1 ๋ฒ์๋ก ๋ณํํ์ฌ ํ๋๊ทธ๋จผํธ ์
ฐ์ด๋๋ก ๋๊น๋๋ค.
// xy, xyz ๋ฑ ์ํ๋ ์ถ์ ๋ฝ์๋ด๋ ๋ฌธ๋ฒ์ ์ค์์ฆ๋ง์ด๋ผ๊ณ ํฉ๋๋ค.
v_uv = a_position * 0.5 + 0.5;
}
frag.glsl (ํ๋๊ทธ๋จผํธ ์ ฐ์ด๋)
#version 300 es
// [ํ์ ๊ฐ๋
5: ์ ๋ฐ๋ ์ค์ ]
// WebGL์ ๋ชจ๋ฐ์ผ ํ๊ฒฝ์ ๊ณ ๋ คํด ์ ๋ฐ๋๋ฅผ ๋ช
์์ ์ผ๋ก ์ง์ ํด์ผ ํฉ๋๋ค.
precision highp float;
// [ํ์ ๊ฐ๋
6: uniform]
// JS์์ ํ๋ ์๋ง๋ค ์
ฐ์ด๋ ์ ์ฒด์ ๋์ผํ๊ฒ ์ ๋ฌํ๋ ์ ์ญ ๊ฐ์
๋๋ค.
uniform float u_time;
uniform vec2 u_resolution;
// ๋ฒํ
์ค ์
ฐ์ด๋์์ ๋์ด์จ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์ต๋๋ค. (๊ตฌ๋ฒ์ ์ varying)
in vec2 v_uv;
// [ํ์ ๊ฐ๋
7: out ๋ณ์]
// GLSL ES 3.00๋ถํฐ๋ gl_FragColor ๋์ ์ง์ out ๋ณ์๋ฅผ ์ ์ธํฉ๋๋ค.
out vec4 fragColor;
void main() {
// 1. ์ข
ํก๋น(Aspect Ratio) ๋ณด์
vec2 uv = v_uv;
uv.x *= u_resolution.x / u_resolution.y;
// 2. ์ค์ฌ์ ๊ณ์ฐ
vec2 center = vec2(u_resolution.x / u_resolution.y * 0.5, 0.5);
// [ํ์ ๊ฐ๋
8: ๋ด์ฅ ์ํ ํจ์]
// distance(A, B): ๋ ์ ์ฌ์ด์ ๊ฑฐ๋ฆฌ
float dist = distance(uv, center);
// sin()์ -1.0 ~ 1.0์ ๋ฐํํ๋ฏ๋ก * 0.5 + 0.5๋ก 0.0 ~ 1.0 ๋ฒ์๋ก ์ ๊ทํํฉ๋๋ค.
float wave = sin(dist * 15.0 - u_time * 3.0) * 0.5 + 0.5;
// [ํ์ ๊ฐ๋
9: vec3 ์์ ํํ]
// RGB ๊ฐ ์ฑ๋์ 0.0(์ด๋ ) ~ 1.0(๋ฐ์) ์ค์๋ก ํํํฉ๋๋ค.
vec3 color1 = vec3(0.1, 0.5, 1.0);
vec3 color2 = vec3(1.0, 0.2, 0.4);
// mix(A, B, t): t๊ฐ 0.0์ด๋ฉด A, 1.0์ด๋ฉด B, ์ค๊ฐ๊ฐ์ด๋ฉด ๋ณด๊ฐ๋ ์์ ๋ฐํํฉ๋๋ค.
vec3 finalColor = mix(color1, color2, wave);
// [ํ์ ๊ฐ๋
10: ์ต์ข
์ถ๋ ฅ]
// vec4(R, G, B, Alpha) ํํ๋ก ์ถ๋ ฅํฉ๋๋ค.
fragColor = vec4(finalColor, 1.0);
}
2. ๋ฐ์ดํฐ ํ์
-
float: ์์ ํ์ ์ ๋๋ค. GLSL์์๋ ์ ์ ๋ฆฌํฐ๋ด์ ๊ฑฐ์ ์ฌ์ฉํ์ง ์์ผ๋ฉฐ,1์ด ์๋๋ผ1.0์ฒ๋ผ ์์์ ์ ๋ช ์ํด์ผ ํ์ ๋ถ์ผ์น ์๋ฌ๋ฅผ ํผํ ์ ์์ต๋๋ค. -
int,uint: ์ ์ ํ์ ์ ๋๋ค. ๋ฐ๋ณต๋ฌธ ์ธ๋ฑ์ค๋ ๋นํธ ์ฐ์ฐ์ ์ฌ์ฉ๋๋ฉฐ,float๊ณผ ์๋ ํ๋ณํ๋์ง ์์ผ๋ฏ๋กfloat(i)์ฒ๋ผ ๋ช ์์ ์บ์คํ ์ด ํ์ํฉ๋๋ค. -
bool: ๋ ผ๋ฆฌ ํ์ ์ ๋๋ค.if์กฐ๊ฑด์ด๋step()๊ฐ์ ํจ์์ ๋ฐํ๊ณผ ํธํ๋ฉ๋๋ค. -
vec2,vec3,vec4:float์ฌ๋ฌ ๊ฐ๋ฅผ ๋ฌถ์ ๋ฒกํฐ ํ์ ์ ๋๋ค. ์์น, ์์, UV ์ขํ ๋ฑ์ ์ฌ์ฉ๋ฉ๋๋ค. -
mat2,mat3,mat4: ํ๋ ฌ ํ์ ์ ๋๋ค. ์ด๋, ํ์ , ํฌ์ ๋ณํ์ ์ฌ์ฉ๋ฉ๋๋ค. -
sampler2D: ํ ์ค์ฒ ์ ๋์ ์ฐธ์กฐํ๋ ํธ๋ค ํ์ ์ ๋๋ค. ๋ณ์ ์์ฒด์ ๋ฐ์ดํฐ๊ฐ ๋ค์ด์์ง ์๊ณ ,texture()ํจ์์ ํจ๊ป ์ฌ์ฉํฉ๋๋ค.
3. ๋ณ์ ํ์ ์ (Qualifier)
-
in: ์ธ๋ถ(JS ๋๋ ์ด์ ์คํ ์ด์ง)๋ก๋ถํฐ ๋ฐ์ดํฐ๋ฅผ ๋ฐ๋ ํ์ ์์ ๋๋ค. -
out: ๋ค์ ์คํ ์ด์ง(ํ๋๊ทธ๋จผํธ ์ ฐ์ด๋ ๋๋ ํ๋ ์๋ฒํผ)๋ก ๋ฐ์ดํฐ๋ฅผ ๋ด๋ณด๋ด๋ ํ์ ์์ ๋๋ค. -
uniform: JS์์ ์ ฐ์ด๋ ์ ์ฒด์ ๋์ผํ๊ฒ ์ ๋ฌํ๋ ์ ์ญ ๋ณ์์ ๋๋ค. ์ ์ /ํฝ์ ๋ง๋ค ๊ฐ์ด ๋ฐ๋์ง ์์ต๋๋ค. -
const: ์ปดํ์ผ ํ์ ์์์ ๋๋ค. ๋ฐ๋ณต๋ฌธ์ ์ํ๊ฐ์ฒ๋ผ GPU๊ฐ ๋ฏธ๋ฆฌ ์์์ผ ํ๋ ๊ฐ์ ์ฌ์ฉ๋ฉ๋๋ค. -
flat: ๋ณด๊ฐ ์์ด ๊ฐ์ ์ ๋ฌํ๋ ํ์ ์์ ๋๋ค. ๋ณดํต ์ ์ํout/in๋ณ์์ ํ์๋ก ๋ถ์ฌ์ผ ํฉ๋๋ค(์ ์๋ ๋ณด๊ฐ์ด ์ ์๋์ง ์๊ธฐ ๋๋ฌธ์ ๋๋ค).
4. ์์ฃผ ์ฐ๋ ๋ด์ฅ ํจ์
| ํจ์ | ์ค๋ช |
|---|---|
mix(a, b, t) |
์ ํ ๋ณด๊ฐ. ์์์ด๋ ๊ฐ์ ๋ถ๋๋ฝ๊ฒ ์์ ๋ ๊ฐ์ฅ ๋ง์ด ์ฌ์ฉ๋ฉ๋๋ค. |
clamp(x, min, max) |
x๋ฅผ min~max ๋ฒ์๋ก ์ ํํฉ๋๋ค. |
smoothstep(edge0, edge1, x) |
๋ถ๋๋ฌ์ด S์ ๋ณด๊ฐ. ๋ง์คํน์ด๋ ๊ฒฝ๊ณ๋ฅผ ๋ถ๋๋ฝ๊ฒ ์ฒ๋ฆฌํ ๋ ์ฌ์ฉ๋ฉ๋๋ค. |
step(edge, x) |
x๊ฐ edge๋ณด๋ค ์์ผ๋ฉด 0.0, ํฌ๊ฑฐ๋ ๊ฐ์ผ๋ฉด 1.0์ ๋ฐํํ๋ ๊ณ๋จ ํจ์์ ๋๋ค. |
length(v) |
๋ฒกํฐ์ ๊ธธ์ด(ํฌ๊ธฐ)๋ฅผ ๋ฐํํฉ๋๋ค. |
distance(a, b) |
๋ ์ ์ฌ์ด์ ๊ฑฐ๋ฆฌ๋ฅผ ๋ฐํํฉ๋๋ค. |
normalize(v) |
๋ฒกํฐ๋ฅผ ๊ธธ์ด 1์ธ ๋จ์ ๋ฒกํฐ๋ก ๋ณํํฉ๋๋ค. |
dot(a, b) |
๋ด์ ์ ๋๋ค. ๋ ๋ฒกํฐ์ ๋ฐฉํฅ ์ ์ฌ๋๋ ์กฐ๋ช ๊ณ์ฐ์ ์ฌ์ฉ๋ฉ๋๋ค. |
cross(a, b) |
์ธ์ ์ ๋๋ค. ๋ฒ์ ๋ฒกํฐ ๊ณ์ฐ ๋ฑ์ ์ฌ์ฉ๋ฉ๋๋ค. |
reflect(I, N), refract(I, N, eta)
|
๋ฐ์ฌ/๊ตด์ ๋ฒกํฐ ๊ณ์ฐ์ ์ฌ์ฉ๋ฉ๋๋ค. |
pow(x, y), exp(x), log(x)
|
์ง์/๋ก๊ทธ ์ฐ์ฐ์ ๋๋ค. |
floor(x), ceil(x), fract(x)
|
๋ด๋ฆผ, ์ฌ๋ฆผ, ์์๋ถ ์ถ์ถ์ ๋๋ค. ๊ทธ๋ฆฌ๋ ํจํด์ด๋ ๋ฐ๋ณต ํจํด์ ๋ง๋ค ๋ ์์ฃผ ์ฌ์ฉ๋ฉ๋๋ค. |
mod(x, y) |
๋๋จธ์ง ์ฐ์ฐ์ ๋๋ค. ๋ฐ๋ณต(ํ์ผ๋ง) ํจํด์ ์ฌ์ฉ๋ฉ๋๋ค. |
abs(x), sin(x), cos(x)
|
์ ๋๊ฐ, ์ผ๊ฐํจ์์ ๋๋ค. |
GLSL ES์๋ Perlin/Simplex ๋ ธ์ด์ฆ ๊ฐ์ ๋ ธ์ด์ฆ ํจ์๊ฐ ๋ด์ฅ๋์ด ์์ง ์์ต๋๋ค. ๋ ธ์ด์ฆ๊ฐ ํ์ํ ๊ฒฝ์ฐ ํด์ ํจ์ ๊ธฐ๋ฐ์ ์ปค์คํ ๊ตฌํ์ ์ ฐ์ด๋ ์ฝ๋์ ์ง์ ํฌํจ์์ผ์ผ ํฉ๋๋ค.
5. ์ค์์ฆ๋ง (Swizzling)
๋ฒกํฐ ์ปดํฌ๋ํธ๋ฅผ ์์ ๋กญ๊ฒ ์กฐํฉํด์ ์ถ์ถํ๋ ๋ฌธ๋ฒ์
๋๋ค.
vec3 v = vec3(1.0, 2.0, 3.0);
v.x; // 1.0 (์์น ํ๊ธฐ: xyzw)
v.r; // 1.0 (์์ ํ๊ธฐ: rgba, ์๋ฏธ๋ ๋์ผ)
v.xy; // vec2(1.0, 2.0)
v.xyy; // vec3(1.0, 2.0, 2.0) โ ์์ ์กฐํฉ ๋ฐ ์ค๋ณต ๊ฐ๋ฅ
v.xy = vec2(5.0, 6.0); // ์ผ๋ถ ์ปดํฌ๋ํธ๋ง ๋์
(write-swizzle)๋ ๊ฐ๋ฅ
6. ํ ์ค์ฒ ์ํ๋ง
GLSL ES 3.00๋ถํฐ ํ
์ค์ฒ๋ฅผ ์ฝ๋ ํจ์๋ texture()๋ก ํต์ผ๋์์ต๋๋ค. ๊ตฌ๋ฒ์ ์ texture2D()๋ ์ฌ์ฉํ์ง ์์ต๋๋ค.
uniform sampler2D u_texture;
in vec2 v_uv;
out vec4 fragColor;
void main() {
vec4 texColor = texture(u_texture, v_uv);
fragColor = texColor;
}
7. ๋ถ๊ธฐ์ ๋ฐ๋ณต๋ฌธ
if/else, for, while์ ๋ชจ๋ ์ฌ์ฉํ ์ ์์ง๋ง, GPU๋ SIMD ๋ฐฉ์์ผ๋ก ํฝ์
์ ๋ฌถ์ด์ ์ฒ๋ฆฌํ๊ธฐ ๋๋ฌธ์ ๋ถ๊ธฐ ๋น์ฉ์ด CPU๋ณด๋ค ํฝ๋๋ค. ๊ฐ์ ๊ทธ๋ฃน ๋ด ํฝ์
๋ค์ด ๋ค๋ฅธ ๋ถ๊ธฐ๋ฅผ ํ๋ฉด ์์ชฝ ๋ถ๊ธฐ๋ฅผ ๋ชจ๋ ๊ณ์ฐํ๊ณ ๊ฒฐ๊ณผ๋ง ์ ํํ๋ ๋ฐฉ์์ผ๋ก ๋์ํ ์ ์์ต๋๋ค.
for (int i = 0; i < 8; i++) {
// const ๋๋ ์ปดํ์ผ ํ์์ ์ ์ ์๋ ์ํ๊ฐ์ ๊ถ์ฅํฉ๋๋ค.
}
๊ฐ๋ฅํ๋ฉด if/else ๋์ step(), mix(), smoothstep() ๊ฐ์ ํจ์๋ก ๋ถ๊ธฐ๋ฅผ ๋์ฒดํ๋ ๊ฒ์ด ์ผ๋ฐ์ ์ธ ์ต์ ํ ํจํด์
๋๋ค.
8. ๋ฐฐ์ด๊ณผ ๊ตฌ์กฐ์ฒด
// ๋ฐฐ์ด
float values[4] = float[4](0.1, 0.3, 0.6, 1.0);
// ๊ตฌ์กฐ์ฒด
struct Light {
vec3 position;
vec3 color;
};
Light light;
light.position = vec3(0.0, 1.0, 0.0);
9. ์ฌ์ฉ์ ์ ์ ํจ์์ ๋งค๊ฐ๋ณ์ ํ์ ์
ํจ์ ๋งค๊ฐ๋ณ์์๋ in(๊ธฐ๋ณธ๊ฐ, ์ฝ๊ธฐ ์ ์ฉ), out(ํจ์ ๋ด๋ถ์์ ๊ฐ์ ์ฑ์ ๋ฐํ), inout(์ฝ๊ณ ์ฐ๊ธฐ ๋ชจ๋ ๊ฐ๋ฅ) ํ์ ์๋ฅผ ๋ถ์ผ ์ ์์ต๋๋ค.
float square(in float x) {
return x * x;
}
void getMinMax(in float a, in float b, out float minV, out float maxV) {
minV = min(a, b);
maxV = max(a, b);
}
10. discard์ ์ํ ํด๋ฆฌํ
ํ๋๊ทธ๋จผํธ ์
ฐ์ด๋ ๋ด์์ ํน์ ํฝ์
์ ์ถ๋ ฅ์ ์์ ํ ๋ฒ๋ฆด ๋ ์ฌ์ฉํฉ๋๋ค.
void main() {
float alpha = texture(u_texture, v_uv).a;
if (alpha < 0.1) {
discard;
}
fragColor = vec4(1.0, 1.0, 1.0, alpha);
}
11. ์ ๋ฐ๋(precision) ํ์ ์
lowp, mediump, highp ์ธ ๋จ๊ณ๊ฐ ์์ผ๋ฉฐ, ํ๋๊ทธ๋จผํธ ์
ฐ์ด๋๋ ๊ธฐ๋ณธ ์ ๋ฐ๋๊ฐ ์ ์๋์ด ์์ง ์์ precision ์ง์์ด๋ฅผ ์ง์ ์ ์ธํด์ผ ์ปดํ์ผ ์๋ฌ๋ฅผ ํผํ ์ ์์ต๋๋ค. ๋ฒํ
์ค ์
ฐ์ด๋๋ highp๊ฐ ๊ธฐ๋ณธ๊ฐ์ผ๋ก ์กํ ์๋ ๊ฒฝ์ฐ๊ฐ ๋ง์ง๋ง, ๋ช
์์ ์ผ๋ก ์ ์ธํ๋ ๊ฒ์ด ์์ ํฉ๋๋ค.
precision highp float;
precision highp int;
๋ชจ๋ฐ์ผ GPU์์๋ mediump๋ง ์ฌ์ฉํด๋ ์ถฉ๋ถํ ๊ฒฝ์ฐ๊ฐ ๋ง๊ณ , ์ฑ๋ฅ ์ต์ ํ ์ ์ ๋ฐ๋๋ฅผ ๋ฎ์ถ๋ ๊ฒ๋ ๊ณ ๋ ค ๋์์ด ๋ฉ๋๋ค.
12. Multiple Render Targets์ layout(location = ...)
์ฌ๋ฌ ๊ฐ์ out ๋ณ์๋ฅผ ๋์์ ๋ค๋ฅธ ํ๋ ์๋ฒํผ ์ดํ์น๋จผํธ๋ก ์ถ๋ ฅํ ๋๋ layout(location = N)์ผ๋ก ์ธ๋ฑ์ค๋ฅผ ๋ช
์ํฉ๋๋ค.
layout(location = 0) out vec4 fragColor;
layout(location = 1) out vec4 fragNormal;
๊ฐ์ ๋ฐฉ์์ผ๋ก ๋ฒํ
์ค ์
ฐ์ด๋์ in ๋ณ์์๋ layout(location = 0) in vec2 a_position;์ฒ๋ผ attribute ์์น๋ฅผ ๋ช
์์ ์ผ๋ก ๊ณ ์ ํ ์ ์์ต๋๋ค.
13. ์์ฃผ ์ฐ๋ ๋ด์ฅ ๋ณ์
-
gl_Position(๋ฒํ ์ค ์ ฐ์ด๋, ํ์): ํด๋ฆฝ ๊ณต๊ฐ ์ขํ์ ๋๋ค. -
gl_PointSize(๋ฒํ ์ค ์ ฐ์ด๋):gl.POINTS๋ก ๊ทธ๋ฆด ๋ ์ ์ ํฝ์ ํฌ๊ธฐ๋ฅผ ์ง์ ํฉ๋๋ค. -
gl_FragCoord(ํ๋๊ทธ๋จผํธ ์ ฐ์ด๋): ํ์ฌ ํฝ์ ์ ํ๋ฉด ์ขํ(xy)์ ๊น์ด(z)๋ฅผ ๋ด๊ณ ์์ต๋๋ค.u_resolution์ ๋๊ธฐ์ง ์๊ณ ํ๋ฉด ์ขํ ๊ธฐ๋ฐ ํจ๊ณผ๋ฅผ ๋ง๋ค ๋ ์ฌ์ฉ๋ฉ๋๋ค. -
gl_FragDepth(ํ๋๊ทธ๋จผํธ ์ ฐ์ด๋): ๊น์ด ๊ฐ์ ์ง์ ๋ฎ์ด์ธ ๋ ์ฌ์ฉํฉ๋๋ค.
14. ์ฐธ๊ณ : ๊ตฌ๋ฒ์ (GLSL ES 1.00) ๋ฌธ๋ฒ๊ณผ์ ์ฐจ์ด
| GLSL ES 1.00 (WebGL1) | GLSL ES 3.00 (WebGL2) |
|---|---|
attribute |
in (๋ฒํ
์ค ์
ฐ์ด๋) |
varying |
๋ฒํ
์ค: out / ํ๋๊ทธ๋จผํธ: in
|
texture2D(), textureCube()
|
texture() |
gl_FragColor |
์ง์ ์ ์ธํ out vec4 ๋ณ์ |
๋ฒ์ ์ง์์ด ์์ ๋๋ #version 100
|
#version 300 es |
๊ธฐ์กด WebGL1 ์์ ์ฝ๋๋ฅผ ์ฐธ๊ณ ํ ๋๋ ์ด ํ๋ฅผ ๊ธฐ์ค์ผ๋ก ์นํํ๋ฉด ๋๋ถ๋ถ ํธํ๋ฉ๋๋ค.
Top comments (0)