WebGL ์ ๋ํผ ๋ฒํผ ๊ฐ์ฒด(UBO) ์ ๋ ฌ ์๊ตฌ ์ฌํญ๊ณผ ๋ค์ํ ํ๋ซํผ์์ ์ ฐ์ด๋ ์ฑ๋ฅ์ ๊ทน๋ํํ๊ธฐ ์ํ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ์ฌ์ธต ๋ถ์ํฉ๋๋ค.
WebGL ์ ฐ์ด๋ ์ ๋ํผ ๋ฒํผ ์ ๋ ฌ: ์ฑ๋ฅ์ ์ํ ๋ฉ๋ชจ๋ฆฌ ๋ ์ด์์ ์ต์ ํ
WebGL์์ ์ ๋ํผ ๋ฒํผ ๊ฐ์ฒด(UBO)๋ ๋๋์ ๋ฐ์ดํฐ๋ฅผ ์ ฐ์ด๋์ ํจ์จ์ ์ผ๋ก ์ ๋ฌํ๋ ๊ฐ๋ ฅํ ๋ฉ์ปค๋์ฆ์ ๋๋ค. ๊ทธ๋ฌ๋ ๋ค์ํ ํ๋์จ์ด ๋ฐ ๋ธ๋ผ์ฐ์ ๊ตฌํ์์ ํธํ์ฑ๊ณผ ์ต์ ์ ์ฑ๋ฅ์ ๋ณด์ฅํ๋ ค๋ฉด UBO ๋ฐ์ดํฐ๋ฅผ ๊ตฌ์ฑํ ๋ ํน์ ์ ๋ ฌ ์๊ตฌ ์ฌํญ์ ์ดํดํ๊ณ ์ค์ํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค. ์ด๋ฌํ ์ ๋ ฌ ๊ท์น์ ๋ฌด์ํ๋ฉด ์๊ธฐ์น ์์ ๋์, ๋ ๋๋ง ์ค๋ฅ ๋ฐ ์ฌ๊ฐํ ์ฑ๋ฅ ์ ํ๋ก ์ด์ด์ง ์ ์์ต๋๋ค.
์ ๋ํผ ๋ฒํผ์ ์ ๋ ฌ ์ดํดํ๊ธฐ
์ ๋ํผ ๋ฒํผ๋ GPU ๋ฉ๋ชจ๋ฆฌ์ ์์ฃผํ๋ฉฐ ์ ฐ์ด๋์์ ์ ๊ทผํ ์ ์๋ ๋ฉ๋ชจ๋ฆฌ ๋ธ๋ก์ ๋๋ค. ํนํ ๋ณํ ํ๋ ฌ, ์ฌ์ง ์์ฑ ๋๋ ์กฐ๋ช ๋งค๊ฐ๋ณ์์ ๊ฐ์ ๋๊ท๋ชจ ๋ฐ์ดํฐ ์ธํธ๋ฅผ ์ฒ๋ฆฌํ ๋ ๊ฐ๋ณ ์ ๋ํผ ๋ณ์๋ณด๋ค ๋ ํจ์จ์ ์ธ ๋์์ ์ ๊ณตํฉ๋๋ค. UBO ํจ์จ์ฑ์ ํต์ฌ์ ๋จ์ผ ๋จ์๋ก ์ ๋ฐ์ดํธํ ์ ์๋ ๋ฅ๋ ฅ์ ์์ผ๋ฉฐ, ์ด๋ ๊ฐ๋ณ ์ ๋ํผ ์ ๋ฐ์ดํธ์ ์ค๋ฒํค๋๋ฅผ ์ค์ฌ์ค๋๋ค.
์ ๋ ฌ์ด๋ ๋ฐ์ดํฐ ์ ํ์ด ์ ์ฅ๋์ด์ผ ํ๋ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๋ฅผ ์๋ฏธํฉ๋๋ค. ๋ฐ์ดํฐ ์ ํ๋ง๋ค ๋ค๋ฅธ ์ ๋ ฌ์ด ํ์ํ๋ฉฐ, ์ด๋ฅผ ํตํด GPU๊ฐ ๋ฐ์ดํฐ์ ํจ์จ์ ์ผ๋ก ์ ๊ทผํ ์ ์์ต๋๋ค. WebGL์ OpenGL ES๋ก๋ถํฐ ์ ๋ ฌ ์๊ตฌ ์ฌํญ์ ์์๋ฐ์ผ๋ฉฐ, ์ด๋ ๋ค์ ๊ธฐ๋ณธ ํ๋์จ์ด ๋ฐ ์ด์ ์ฒด์ ๊ด๋ก์์ ๋น๋กฏ๋ฉ๋๋ค. ์ด๋ฌํ ์๊ตฌ ์ฌํญ์ ์ข ์ข ๋ฐ์ดํฐ ์ ํ์ ํฌ๊ธฐ์ ๋ฐ๋ผ ๊ฒฐ์ ๋ฉ๋๋ค.
์ ๋ ฌ์ด ์ค์ํ ์ด์
์๋ชป๋ ์ ๋ ฌ์ ์ฌ๋ฌ ๊ฐ์ง ๋ฌธ์ ๋ก ์ด์ด์ง ์ ์์ต๋๋ค:
- ์ ์๋์ง ์์ ๋์: GPU๊ฐ ์ ๋ํผ ๋ณ์์ ๋ฒ์๋ฅผ ๋ฒ์ด๋ ๋ฉ๋ชจ๋ฆฌ์ ์ ๊ทผํ์ฌ ์์ธกํ ์ ์๋ ๋์์ ์ผ์ผํค๊ณ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ถฉ๋์ํฌ ์ ์์ต๋๋ค.
- ์ฑ๋ฅ ์ ํ: ์ ๋ ฌ๋์ง ์์ ๋ฐ์ดํฐ ์ ๊ทผ์ GPU๊ฐ ์ฌ๋ฐ๋ฅธ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๊ธฐ ์ํด ์ถ๊ฐ์ ์ธ ๋ฉ๋ชจ๋ฆฌ ์ฐ์ฐ์ ์ํํ๊ฒ ๋ง๋ค์ด ๋ ๋๋ง ์ฑ๋ฅ์ ์๋นํ ์ํฅ์ ๋ฏธ์น ์ ์์ต๋๋ค. ์ด๋ GPU์ ๋ฉ๋ชจ๋ฆฌ ์ปจํธ๋กค๋ฌ๊ฐ ํน์ ๋ฉ๋ชจ๋ฆฌ ๊ฒฝ๊ณ์์ ๋ฐ์ดํฐ๋ฅผ ์ ๊ทผํ๋ ๋ฐ ์ต์ ํ๋์ด ์๊ธฐ ๋๋ฌธ์ ๋๋ค.
- ํธํ์ฑ ๋ฌธ์ : ํ๋์จ์ด ๊ณต๊ธ์ ์ฒด์ ๋๋ผ์ด๋ฒ ๊ตฌํ๋ง๋ค ์ ๋ ฌ๋์ง ์์ ๋ฐ์ดํฐ๋ฅผ ๋ค๋ฅด๊ฒ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค. ํ ๊ธฐ๊ธฐ์์ ์ฌ๋ฐ๋ฅด๊ฒ ์๋ํ๋ ์ ฐ์ด๋๊ฐ ๋ฏธ๋ฌํ ์ ๋ ฌ ์ฐจ์ด๋ก ์ธํด ๋ค๋ฅธ ๊ธฐ๊ธฐ์์๋ ์คํจํ ์ ์์ต๋๋ค.
WebGL ์ ๋ ฌ ๊ท์น
WebGL์ UBO ๋ด์ ๋ฐ์ดํฐ ์ ํ์ ๋ํ ํน์ ์ ๋ ฌ ๊ท์น์ ์๋ฌดํํฉ๋๋ค. ์ด๋ฌํ ๊ท์น์ ์ผ๋ฐ์ ์ผ๋ก ๋ฐ์ดํธ ๋จ์๋ก ํํ๋๋ฉฐ ํธํ์ฑ๊ณผ ์ฑ๋ฅ์ ๋ณด์ฅํ๋ ๋ฐ ๋งค์ฐ ์ค์ํฉ๋๋ค. ๊ฐ์ฅ ์ผ๋ฐ์ ์ธ ๋ฐ์ดํฐ ์ ํ๊ณผ ํ์ํ ์ ๋ ฌ์ ๋ํ ๋ถ์์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
float,int,uint,bool: 4๋ฐ์ดํธ ์ ๋ ฌvec2,ivec2,uvec2,bvec2: 8๋ฐ์ดํธ ์ ๋ ฌvec3,ivec3,uvec3,bvec3: 16๋ฐ์ดํธ ์ ๋ ฌ (์ค์: 12๋ฐ์ดํธ์ ๋ฐ์ดํฐ๋ง ํฌํจํ์ง๋ง vec3/ivec3/uvec3/bvec3๋ 16๋ฐ์ดํธ ์ ๋ ฌ์ด ํ์ํฉ๋๋ค. ์ด๋ ํํ ํผ๋์ ์ผ์ผํค๋ ์์ธ์ ๋๋ค.)vec4,ivec4,uvec4,bvec4: 16๋ฐ์ดํธ ์ ๋ ฌ- ํ๋ ฌ (
mat2,mat3,mat4): ์ด ์ฐ์ ์์(Column-major order)์ด๋ฉฐ, ๊ฐ ์ด์vec4๋ก ์ ๋ ฌ๋ฉ๋๋ค. ๋ฐ๋ผ์mat2๋ 32๋ฐ์ดํธ(2์ด * 16๋ฐ์ดํธ),mat3๋ 48๋ฐ์ดํธ(3์ด * 16๋ฐ์ดํธ),mat4๋ 64๋ฐ์ดํธ(4์ด * 16๋ฐ์ดํธ)๋ฅผ ์ฐจ์งํฉ๋๋ค. - ๋ฐฐ์ด: ๋ฐฐ์ด์ ๊ฐ ์์๋ ํด๋น ๋ฐ์ดํฐ ์ ํ์ ์ ๋ ฌ ๊ท์น์ ๋ฐ๋ฆ ๋๋ค. ๊ธฐ๋ณธ ์ ํ ์ ๋ ฌ์ ๋ฐ๋ผ ์์ ์ฌ์ด์ ํจ๋ฉ์ด ์์ ์ ์์ต๋๋ค.
- ๊ตฌ์กฐ์ฒด: ๊ตฌ์กฐ์ฒด๋ ํ์ค ๋ ์ด์์ ๊ท์น์ ๋ฐ๋ผ ์ ๋ ฌ๋๋ฉฐ, ๊ฐ ๋ฉค๋ฒ๋ ์์ฐ์ค๋ฌ์ด ์ ๋ ฌ์ ๋ง์ถฐ์ง๋๋ค. ๋ํ ๊ตฌ์กฐ์ฒด์ ํฌ๊ธฐ๊ฐ ๊ฐ์ฅ ํฐ ๋ฉค๋ฒ์ ์ ๋ ฌ ๋ฐฐ์๊ฐ ๋๋๋ก ๊ตฌ์กฐ์ฒด ๋์ ํจ๋ฉ์ด ์ถ๊ฐ๋ ์ ์์ต๋๋ค.
ํ์ค ๋ ์ด์์ vs. ๊ณต์ ๋ ์ด์์
OpenGL(๊ทธ๋ฆฌ๊ณ ํ์ฅํ์ฌ WebGL)์ ์ ๋ํผ ๋ฒํผ์ ๋ํด ํ์ค ๋ ์ด์์(standard layout)๊ณผ ๊ณต์ ๋ ์ด์์(shared layout)์ด๋ผ๋ ๋ ๊ฐ์ง ์ฃผ์ ๋ ์ด์์์ ์ ์ํฉ๋๋ค. WebGL์ ์ผ๋ฐ์ ์ผ๋ก ๊ธฐ๋ณธ์ ์ผ๋ก ํ์ค ๋ ์ด์์์ ์ฌ์ฉํฉ๋๋ค. ๊ณต์ ๋ ์ด์์์ ํ์ฅ์ ํตํด ์ฌ์ฉํ ์ ์์ง๋ง ์ง์์ด ์ ํ์ ์ด์ด์ WebGL์์๋ ๋๋ฆฌ ์ฌ์ฉ๋์ง ์์ต๋๋ค. ํ์ค ๋ ์ด์์์ ๋ค์ํ ํ๋ซํผ์์ ์ด์ ๊ฐ๋ฅํ๊ณ ์ ์ ์๋ ๋ฉ๋ชจ๋ฆฌ ๋ ์ด์์์ ์ ๊ณตํ๋ ๋ฐ๋ฉด, ๊ณต์ ๋ ์ด์์์ ๋ ์์ถ๋ ํจํน์ ํ์ฉํ์ง๋ง ์ด์์ฑ์ด ๋จ์ด์ง๋๋ค. ์ต๋์ ํธํ์ฑ์ ์ํด ํ์ค ๋ ์ด์์์ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
์ค์ฉ์ ์ธ ์์ ๋ฐ ์ฝ๋ ์์ฐ
์ด๋ฌํ ์ ๋ ฌ ๊ท์น์ ์ค์ฉ์ ์ธ ์์ ์ ์ฝ๋ ์ค๋ํซ์ผ๋ก ์ค๋ช ํด ๋ณด๊ฒ ์ต๋๋ค. ์ ๋ํผ ๋ธ๋ก์ ์ ์ํ๊ธฐ ์ํด GLSL(OpenGL Shading Language)์ ์ฌ์ฉํ๊ณ , UBO ๋ฐ์ดํฐ๋ฅผ ์ค์ ํ๊ธฐ ์ํด JavaScript๋ฅผ ์ฌ์ฉํ๊ฒ ์ต๋๋ค.
์์ 1: ๊ธฐ๋ณธ ์ ๋ ฌ
GLSL (์ ฐ์ด๋ ์ฝ๋):
layout(std140) uniform ExampleBlock {
float value1;
vec3 value2;
float value3;
};
JavaScript (UBO ๋ฐ์ดํฐ ์ค์ ):
const gl = canvas.getContext('webgl');
const buffer = gl.createBuffer();
gL.bindBuffer(gl.UNIFORM_BUFFER, buffer);
// ์ ๋ํผ ๋ฒํผ์ ํฌ๊ธฐ ๊ณ์ฐ
const bufferSize = 4 + 16 + 4; // float (4) + vec3 (16) + float (4)
gl.bufferData(gl.UNIFORM_BUFFER, bufferSize, gl.DYNAMIC_DRAW);
// ๋ฐ์ดํฐ๋ฅผ ๋ด์ Float32Array ์์ฑ
const data = new Float32Array(bufferSize / 4); // ๊ฐ float๋ 4๋ฐ์ดํธ
// ๋ฐ์ดํฐ ์ค์
data[0] = 1.0; // value1
// ์ฌ๊ธฐ์ ํจ๋ฉ์ด ํ์ํฉ๋๋ค. value2๋ ์คํ์
4์์ ์์ํ์ง๋ง 16๋ฐ์ดํธ๋ก ์ ๋ ฌ๋์ด์ผ ํฉ๋๋ค.
// ์ด๋ ํจ๋ฉ์ ๊ณ ๋ คํ์ฌ ๋ฐฐ์ด์ ์์๋ฅผ ๋ช
์์ ์ผ๋ก ์ค์ ํด์ผ ํจ์ ์๋ฏธํฉ๋๋ค.
data[4] = 2.0; // value2.x (์คํ์
16, ์ธ๋ฑ์ค 4)
data[5] = 3.0; // value2.y (์คํ์
20, ์ธ๋ฑ์ค 5)
data[6] = 4.0; // value2.z (์คํ์
24, ์ธ๋ฑ์ค 6)
data[7] = 5.0; // value3 (์คํ์
32, ์ธ๋ฑ์ค 8)
gl.bindBuffer(gl.UNIFORM_BUFFER, buffer);
gl.bufferSubData(gl.UNIFORM_BUFFER, 0, data);
์ค๋ช :
์ด ์์ ์์ `value1`์ `float`(4๋ฐ์ดํธ, 4๋ฐ์ดํธ ์ ๋ ฌ), `value2`๋ `vec3`(12๋ฐ์ดํธ ๋ฐ์ดํฐ, 16๋ฐ์ดํธ ์ ๋ ฌ), `value3`์ ๋ ๋ค๋ฅธ `float`(4๋ฐ์ดํธ, 4๋ฐ์ดํธ ์ ๋ ฌ)์ ๋๋ค. `value2`๊ฐ 12๋ฐ์ดํธ๋ง ํฌํจํ๋๋ผ๋ 16๋ฐ์ดํธ๋ก ์ ๋ ฌ๋ฉ๋๋ค. ๋ฐ๋ผ์ ์ ๋ํผ ๋ธ๋ก์ ์ด ํฌ๊ธฐ๋ 4 + 16 + 4 = 24๋ฐ์ดํธ์ ๋๋ค. `value2`๋ฅผ 16๋ฐ์ดํธ ๊ฒฝ๊ณ์ ์ฌ๋ฐ๋ฅด๊ฒ ์ ๋ ฌํ๋ ค๋ฉด `value1` ๋ค์ ํจ๋ฉ์ ์ถ๊ฐํ๋ ๊ฒ์ด ๋งค์ฐ ์ค์ํฉ๋๋ค. JavaScript ๋ฐฐ์ด์ด ์์ฑ๋๊ณ ํจ๋ฉ์ ๊ณ ๋ คํ์ฌ ์ธ๋ฑ์ฑ์ด ์ํ๋๋ ๋ฐฉ์์ ์ฃผ๋ชฉํ์ธ์. ์ฌ๋ฐ๋ฅธ ํจ๋ฉ์ด ์์ผ๋ฉด ์๋ชป๋ ๋ฐ์ดํฐ๋ฅผ ์ฝ๊ฒ ๋ฉ๋๋ค.
์์ 2: ํ๋ ฌ ์์
GLSL (์ ฐ์ด๋ ์ฝ๋):
layout(std140) uniform MatrixBlock {
mat4 modelMatrix;
mat4 viewMatrix;
};
JavaScript (UBO ๋ฐ์ดํฐ ์ค์ ):
const gl = canvas.getContext('webgl');
const buffer = gl.createBuffer();
gl.bindBuffer(gl.UNIFORM_BUFFER, buffer);
// ์ ๋ํผ ๋ฒํผ์ ํฌ๊ธฐ ๊ณ์ฐ
const bufferSize = 64 + 64; // mat4 (64) + mat4 (64)
gl.bufferData(gl.UNIFORM_BUFFER, bufferSize, gl.DYNAMIC_DRAW);
// ํ๋ ฌ ๋ฐ์ดํฐ๋ฅผ ๋ด์ Float32Array ์์ฑ
const data = new Float32Array(bufferSize / 4); // ๊ฐ float๋ 4๋ฐ์ดํธ
// ์ํ ํ๋ ฌ ์์ฑ (์ด ์ฐ์ ์์)
const modelMatrix = new Float32Array([
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1
]);
const viewMatrix = new Float32Array([
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1
]);
// ๋ชจ๋ธ ํ๋ ฌ ๋ฐ์ดํฐ ์ค์
for (let i = 0; i < 16; ++i) {
data[i] = modelMatrix[i];
}
// ๋ทฐ ํ๋ ฌ ๋ฐ์ดํฐ ์ค์ (16๊ฐ float ๋๋ 64๋ฐ์ดํธ ์คํ์
)
for (let i = 0; i < 16; ++i) {
data[i + 16] = viewMatrix[i];
}
gl.bindBuffer(gl.UNIFORM_BUFFER, buffer);
gl.bufferSubData(gl.UNIFORM_BUFFER, 0, data);
์ค๋ช :
๊ฐ `mat4` ํ๋ ฌ์ 4๊ฐ์ `vec4` ์ด๋ก ๊ตฌ์ฑ๋๋ฏ๋ก 64๋ฐ์ดํธ๋ฅผ ์ฐจ์งํฉ๋๋ค. `modelMatrix`๋ ์คํ์ 0์์ ์์ํ๊ณ , `viewMatrix`๋ ์คํ์ 64์์ ์์ํฉ๋๋ค. ํ๋ ฌ์ OpenGL๊ณผ WebGL์ ํ์ค์ธ ์ด ์ฐ์ ์์(column-major order)๋ก ์ ์ฅ๋ฉ๋๋ค. ํญ์ JavaScript ๋ฐฐ์ด์ ์์ฑํ ๋ค์ ๊ฐ์ ํ ๋นํ๋ ๊ฒ์ ๊ธฐ์ตํ์ธ์. ์ด๋ ๊ฒ ํ๋ฉด ๋ฐ์ดํฐ ์ ํ์ด Float32๋ก ์ ์ง๋์ด `bufferSubData`๊ฐ ์ ๋๋ก ์๋ํ ์ ์์ต๋๋ค.
์์ 3: UBO์ ๋ฐฐ์ด
GLSL (์ ฐ์ด๋ ์ฝ๋):
layout(std140) uniform LightBlock {
vec4 lightColors[3];
};
JavaScript (UBO ๋ฐ์ดํฐ ์ค์ ):
const gl = canvas.getContext('webgl');
const buffer = gl.createBuffer();
gl.bindBuffer(gl.UNIFORM_BUFFER, buffer);
// ์ ๋ํผ ๋ฒํผ์ ํฌ๊ธฐ ๊ณ์ฐ
const bufferSize = 16 * 3; // vec4 * 3
gl.bufferData(gl.UNIFORM_BUFFER, bufferSize, gl.DYNAMIC_DRAW);
// ๋ฐฐ์ด ๋ฐ์ดํฐ๋ฅผ ๋ด์ Float32Array ์์ฑ
const data = new Float32Array(bufferSize / 4);
// ์กฐ๋ช
์์
const lightColors = [
[1.0, 0.0, 0.0, 1.0],
[0.0, 1.0, 0.0, 1.0],
[0.0, 0.0, 1.0, 1.0],
];
for (let i = 0; i < lightColors.length; ++i) {
data[i * 4 + 0] = lightColors[i][0];
data[i * 4 + 1] = lightColors[i][1];
data[i * 4 + 2] = lightColors[i][2];
data[i * 4 + 3] = lightColors[i][3];
}
gl.bindBuffer(gl.UNIFORM_BUFFER, buffer);
gl.bufferSubData(gl.UNIFORM_BUFFER, 0, data);
์ค๋ช :
`lightColors` ๋ฐฐ์ด์ ๊ฐ `vec4` ์์๋ 16๋ฐ์ดํธ๋ฅผ ์ฐจ์งํฉ๋๋ค. ์ ๋ํผ ๋ธ๋ก์ ์ด ํฌ๊ธฐ๋ 16 * 3 = 48๋ฐ์ดํธ์ ๋๋ค. ๋ฐฐ์ด ์์๋ ๊ฐ๊ฐ์ ๊ธฐ๋ณธ ์ ํ ์ ๋ ฌ์ ๋ง์ถฐ์ ธ ๋นฝ๋นฝํ๊ฒ ์ฑ์์ง๋๋ค. JavaScript ๋ฐฐ์ด์ ์กฐ๋ช ์์ ๋ฐ์ดํฐ์ ๋ฐ๋ผ ์ฑ์์ง๋๋ค. ์ ฐ์ด๋์ `lightColors` ๋ฐฐ์ด์ ๊ฐ ์์๋ `vec4`๋ก ์ทจ๊ธ๋๋ฉฐ JavaScript์์๋ ๋ง์ฐฌ๊ฐ์ง๋ก ์์ ํ ์ฑ์์ ธ์ผ ํ๋ค๋ ์ ์ ๊ธฐ์ตํ์ธ์.
์ ๋ ฌ ๋ฌธ์ ๋๋ฒ๊น ์ ์ํ ๋๊ตฌ ๋ฐ ๊ธฐ์
์ ๋ ฌ ๋ฌธ์ ๋ฅผ ๊ฐ์งํ๋ ๊ฒ์ ์ด๋ ค์ธ ์ ์์ต๋๋ค. ๋ค์์ ๋ช ๊ฐ์ง ์ ์ฉํ ๋๊ตฌ์ ๊ธฐ์ ์ ๋๋ค:
- WebGL Inspector: Spector.js์ ๊ฐ์ ๋๊ตฌ๋ฅผ ์ฌ์ฉํ๋ฉด ์ ๋ํผ ๋ฒํผ์ ๋ด์ฉ์ ๊ฒ์ฌํ๊ณ ๋ฉ๋ชจ๋ฆฌ ๋ ์ด์์์ ์๊ฐํํ ์ ์์ต๋๋ค.
- ์ฝ์ ๋ก๊น : ์ ฐ์ด๋์์ ์ ๋ํผ ๋ณ์์ ๊ฐ์ ์ถ๋ ฅํ๊ณ JavaScript์์ ์ ๋ฌํ๋ ๋ฐ์ดํฐ์ ๋น๊ตํ์ธ์. ๋ถ์ผ์น๋ ์ ๋ ฌ ๋ฌธ์ ๋ฅผ ๋ํ๋ผ ์ ์์ต๋๋ค.
- GPU ๋๋ฒ๊ฑฐ: RenderDoc๊ณผ ๊ฐ์ ๊ทธ๋ํฝ ๋๋ฒ๊ฑฐ๋ GPU ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ ๋ฐ ์ ฐ์ด๋ ์คํ์ ๋ํ ์์ธํ ํต์ฐฐ๋ ฅ์ ์ ๊ณตํ ์ ์์ต๋๋ค.
- ๋ฐ์ด๋๋ฆฌ ๊ฒ์ฌ: ๊ณ ๊ธ ๋๋ฒ๊น ์ ์ํด UBO ๋ฐ์ดํฐ๋ฅผ ๋ฐ์ด๋๋ฆฌ ํ์ผ๋ก ์ ์ฅํ๊ณ ํฅ์ค ํธ์ง๊ธฐ๋ฅผ ์ฌ์ฉํ์ฌ ๊ฒ์ฌํ์ฌ ์ ํํ ๋ฉ๋ชจ๋ฆฌ ๋ ์ด์์์ ํ์ธํ ์ ์์ต๋๋ค. ์ด๋ฅผ ํตํด ํจ๋ฉ ์์น์ ์ ๋ ฌ์ ์๊ฐ์ ์ผ๋ก ํ์ธํ ์ ์์ต๋๋ค.
- ์ ๋ต์ ํจ๋ฉ: ํ์คํ์ง ์์ ๋๋ ๊ตฌ์กฐ์ฒด์ ๋ช ์์ ์ผ๋ก ํจ๋ฉ์ ์ถ๊ฐํ์ฌ ์ฌ๋ฐ๋ฅธ ์ ๋ ฌ์ ๋ณด์ฅํ์ธ์. ์ด๋ ๊ฒ ํ๋ฉด UBO ํฌ๊ธฐ๊ฐ ์ฝ๊ฐ ์ฆ๊ฐํ ์ ์์ง๋ง, ๋ฏธ๋ฌํ๊ณ ๋๋ฒ๊น ํ๊ธฐ ์ด๋ ค์ด ๋ฌธ์ ๋ฅผ ์๋ฐฉํ ์ ์์ต๋๋ค.
- GLSL Offsetof: GLSL์ `offsetof` ํจ์(GLSL ๋ฒ์ 4.50 ์ด์ ํ์, ์ผ๋ถ WebGL ํ์ฅ ๊ธฐ๋ฅ์์ ์ง์)๋ฅผ ์ฌ์ฉํ์ฌ ์ ๋ํผ ๋ธ๋ก ๋ด ๋ฉค๋ฒ์ ๋ฐ์ดํธ ์คํ์ ์ ๋์ ์ผ๋ก ๊ฒฐ์ ํ ์ ์์ต๋๋ค. ์ด๋ ๋ ์ด์์์ ๋ํ ์ดํด๋ฅผ ๊ฒ์ฆํ๋ ๋ฐ ๋งค์ฐ ์ ์ฉํ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ๋ธ๋ผ์ฐ์ ๋ฐ ํ๋์จ์ด ์ง์์ ๋ฐ๋ผ ์ฌ์ฉ ๊ฐ๋ฅ ์ฌ๋ถ๊ฐ ์ ํ๋ ์ ์์ต๋๋ค.
UBO ์ฑ๋ฅ ์ต์ ํ๋ฅผ ์ํ ๋ชจ๋ฒ ์ฌ๋ก
์ ๋ ฌ ์ธ์๋ UBO ์ฑ๋ฅ์ ๊ทน๋ํํ๊ธฐ ์ํด ๋ค์๊ณผ ๊ฐ์ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ๊ณ ๋ คํ์ธ์:
- ๊ด๋ จ ๋ฐ์ดํฐ ๊ทธ๋ฃนํ: ์์ฃผ ์ฌ์ฉํ๋ ์ ๋ํผ ๋ณ์๋ฅผ ๋์ผํ UBO์ ๋ฐฐ์นํ์ฌ ๋ฒํผ ๋ฐ์ธ๋ฉ ์๋ฅผ ์ต์ํํ์ธ์.
- UBO ์ ๋ฐ์ดํธ ์ต์ํ: ํ์ํ ๋๋ง UBO๋ฅผ ์ ๋ฐ์ดํธํ์ธ์. ์ฆ์ UBO ์ ๋ฐ์ดํธ๋ ์ฌ๊ฐํ ์ฑ๋ฅ ๋ณ๋ชฉ ํ์์ ์ ๋ฐํ ์ ์์ต๋๋ค.
- ์ฌ์ง๋น ๋จ์ผ UBO ์ฌ์ฉ: ๊ฐ๋ฅํ๋ค๋ฉด ๋ชจ๋ ์ฌ์ง ์์ฑ์ ๋จ์ผ UBO๋ก ๊ทธ๋ฃนํํ์ธ์.
- ๋ฐ์ดํฐ ์ง์ญ์ฑ ๊ณ ๋ ค: ์ ฐ์ด๋์์ ์ฌ์ฉ๋๋ ๋ฐฉ์์ ๋ฐ์ํ๋ ์์๋ก UBO ๋ฉค๋ฒ๋ฅผ ์ ๋ ฌํ์ธ์. ์ด๋ ์บ์ ํํธ์จ์ ํฅ์์ํฌ ์ ์์ต๋๋ค.
- ํ๋กํ์ผ๋ง ๋ฐ ๋ฒค์น๋งํน: ํ๋กํ์ผ๋ง ๋๊ตฌ๋ฅผ ์ฌ์ฉํ์ฌ UBO ์ฌ์ฉ๊ณผ ๊ด๋ จ๋ ์ฑ๋ฅ ๋ณ๋ชฉ ํ์์ ์๋ณํ์ธ์.
๊ณ ๊ธ ๊ธฐ์ : ์ธํฐ๋ฆฌ๋ธ ๋ฐ์ดํฐ
์ผ๋ถ ์๋๋ฆฌ์ค, ํนํ ํํฐํด ์์คํ ์ด๋ ๋ณต์กํ ์๋ฎฌ๋ ์ด์ ์ ๋ค๋ฃฐ ๋, UBO ๋ด์ ๋ฐ์ดํฐ๋ฅผ ์ธํฐ๋ฆฌ๋ธ(interleave)ํ๋ฉด ์ฑ๋ฅ์ ํฅ์์ํฌ ์ ์์ต๋๋ค. ์ด๋ ๋ฉ๋ชจ๋ฆฌ ์ ๊ทผ ํจํด์ ์ต์ ํํ๋ ๋ฐฉ์์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ๋ฐฐ์ดํ๋ ๊ฒ์ ํฌํจํฉ๋๋ค. ์๋ฅผ ๋ค์ด, ๋ชจ๋ `x` ์ขํ๋ฅผ ํจ๊ป ์ ์ฅํ๊ณ ๊ทธ ๋ค์ ๋ชจ๋ `y` ์ขํ๋ฅผ ์ ์ฅํ๋ ๋์ , `x1, y1, z1, x2, y2, z2...`์ ๊ฐ์ด ์ธํฐ๋ฆฌ๋ธํ ์ ์์ต๋๋ค. ์ด๋ ์ ฐ์ด๋๊ฐ ํํฐํด์ `x`, `y`, `z` ๊ตฌ์ฑ ์์๋ฅผ ๋์์ ์ ๊ทผํด์ผ ํ ๋ ์บ์ ์ผ๊ด์ฑ์ ํฅ์์ํฌ ์ ์์ต๋๋ค.
๊ทธ๋ฌ๋ ์ธํฐ๋ฆฌ๋ธ ๋ฐ์ดํฐ๋ ์ ๋ ฌ ๊ณ ๋ ค ์ฌํญ์ ๋ณต์กํ๊ฒ ๋ง๋ค ์ ์์ต๋๋ค. ๊ฐ ์ธํฐ๋ฆฌ๋ธ๋ ์์๊ฐ ์ ์ ํ ์ ๋ ฌ ๊ท์น์ ์ค์ํ๋์ง ํ์ธํด์ผ ํฉ๋๋ค.
์ฌ๋ก ์ฐ๊ตฌ: ์ ๋ ฌ์ด ์ฑ๋ฅ์ ๋ฏธ์น๋ ์ํฅ
์ ๋ ฌ์ด ์ฑ๋ฅ์ ๋ฏธ์น๋ ์ํฅ์ ์ค๋ช ํ๊ธฐ ์ํด ๊ฐ์ ์๋๋ฆฌ์ค๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค. ๊ฐ๊ฐ ๋ณํ ํ๋ ฌ์ด ํ์ํ ์๋ง์ ๊ฐ์ฒด๊ฐ ์๋ ์ฅ๋ฉด์ ์๊ฐํด๋ณด์ธ์. ๋ณํ ํ๋ ฌ์ด UBO ๋ด์์ ์ ๋๋ก ์ ๋ ฌ๋์ง ์์ผ๋ฉด GPU๋ ๊ฐ ๊ฐ์ฒด์ ํ๋ ฌ ๋ฐ์ดํฐ๋ฅผ ๊ฒ์ํ๊ธฐ ์ํด ์ฌ๋ฌ ๋ฒ์ ๋ฉ๋ชจ๋ฆฌ ์ ๊ทผ์ ์ํํด์ผ ํ ์ ์์ต๋๋ค. ์ด๋ ํนํ ๋ฉ๋ชจ๋ฆฌ ๋์ญํญ์ด ์ ํ๋ ๋ชจ๋ฐ์ผ ๊ธฐ๊ธฐ์์ ์๋นํ ์ฑ๋ฅ ์ ํ๋ก ์ด์ด์ง ์ ์์ต๋๋ค.
๋ฐ๋๋ก ํ๋ ฌ์ด ์ฌ๋ฐ๋ฅด๊ฒ ์ ๋ ฌ๋๋ฉด GPU๋ ๋จ์ผ ๋ฉ๋ชจ๋ฆฌ ์ ๊ทผ์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ํจ์จ์ ์ผ๋ก ๊ฐ์ ธ์ฌ ์ ์์ด ์ค๋ฒํค๋๋ฅผ ์ค์ด๊ณ ๋ ๋๋ง ์ฑ๋ฅ์ ํฅ์์ํต๋๋ค.
๋ ๋ค๋ฅธ ์ฌ๋ก๋ ์๋ฎฌ๋ ์ด์ ์ ๋๋ค. ๋ง์ ์๋ฎฌ๋ ์ด์ ์ ์๋ง์ ์ ์์ ์์น์ ์๋๋ฅผ ์ ์ฅํด์ผ ํฉ๋๋ค. UBO๋ฅผ ์ฌ์ฉํ๋ฉด ์ด๋ฌํ ๋ณ์๋ฅผ ํจ์จ์ ์ผ๋ก ์ ๋ฐ์ดํธํ๊ณ ์ ์๋ฅผ ๋ ๋๋งํ๋ ์ ฐ์ด๋๋ก ๋ณด๋ผ ์ ์์ต๋๋ค. ์ด๋ฌํ ์ํฉ์์ ์ฌ๋ฐ๋ฅธ ์ ๋ ฌ์ ๋งค์ฐ ์ค์ํฉ๋๋ค.
์ ์ญ์ ๊ณ ๋ ค ์ฌํญ: ํ๋์จ์ด ๋ฐ ๋๋ผ์ด๋ฒ ๋ณํ
WebGL์ ๋ค์ํ ํ๋ซํผ์์ ์ผ๊ด๋ API๋ฅผ ์ ๊ณตํ๋ ๊ฒ์ ๋ชฉํ๋ก ํ์ง๋ง, UBO ์ ๋ ฌ์ ์ํฅ์ ๋ฏธ์น๋ ํ๋์จ์ด ๋ฐ ๋๋ผ์ด๋ฒ ๊ตฌํ์๋ ๋ฏธ๋ฌํ ์ฐจ์ด๊ฐ ์์ ์ ์์ต๋๋ค. ํธํ์ฑ์ ๋ณด์ฅํ๊ธฐ ์ํด ๋ค์ํ ๊ธฐ๊ธฐ์ ๋ธ๋ผ์ฐ์ ์์ ์ ฐ์ด๋๋ฅผ ํ ์คํธํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค.
์๋ฅผ ๋ค์ด, ๋ชจ๋ฐ์ผ ๊ธฐ๊ธฐ๋ ๋ฐ์คํฌํฑ ์์คํ ๋ณด๋ค ๋ฉ๋ชจ๋ฆฌ ์ ์ฝ์ด ๋ ์๊ฒฉํ ์ ์์ด ์ ๋ ฌ์ด ๋์ฑ ์ค์ํด์ง๋๋ค. ๋ง์ฐฌ๊ฐ์ง๋ก, GPU ๊ณต๊ธ์ ์ฒด๋ง๋ค ์ ๋ ฌ ์๊ตฌ ์ฌํญ์ด ์ฝ๊ฐ ๋ค๋ฅผ ์ ์์ต๋๋ค.
๋ฏธ๋ ๋ํฅ: WebGPU์ ๊ทธ ์ด์
์น ๊ทธ๋ํฝ์ ๋ฏธ๋๋ WebGPU์ ๋๋ค. ์ด๋ WebGL์ ํ๊ณ๋ฅผ ํด๊ฒฐํ๊ณ ์ต์ GPU ํ๋์จ์ด์ ๋ ๊ฐ๊น๊ฒ ์ ๊ทผํ ์ ์๋๋ก ์ค๊ณ๋ ์๋ก์ด API์ ๋๋ค. WebGPU๋ ๋ฉ๋ชจ๋ฆฌ ๋ ์ด์์ ๋ฐ ์ ๋ ฌ์ ๋ํ ๋ ๋ช ์์ ์ธ ์ ์ด๋ฅผ ์ ๊ณตํ์ฌ ๊ฐ๋ฐ์๊ฐ ์ฑ๋ฅ์ ๋์ฑ ์ต์ ํํ ์ ์๋๋ก ํฉ๋๋ค. WebGL์ UBO ์ ๋ ฌ์ ์ดํดํ๋ ๊ฒ์ WebGPU๋ก ์ ํํ๊ณ ๊ทธ ๊ณ ๊ธ ๊ธฐ๋ฅ์ ํ์ฉํ๊ธฐ ์ํ ๊ฒฌ๊ณ ํ ๊ธฐ๋ฐ์ ์ ๊ณตํฉ๋๋ค.
WebGPU๋ ์ ฐ์ด๋์ ์ ๋ฌ๋๋ ๋ฐ์ดํฐ ๊ตฌ์กฐ์ ๋ฉ๋ชจ๋ฆฌ ๋ ์ด์์์ ๋ช ์์ ์ผ๋ก ์ ์ดํ ์ ์์ต๋๋ค. ์ด๋ ๊ตฌ์กฐ์ฒด์ `[[offset]]` ์์ฑ์ ์ฌ์ฉํ์ฌ ๋ฌ์ฑ๋ฉ๋๋ค. `[[offset]]` ์์ฑ์ ๊ตฌ์กฐ์ฒด ๋ด ๋ฉค๋ฒ์ ๋ฐ์ดํธ ์คํ์ ์ ์ง์ ํฉ๋๋ค. WebGPU๋ ๋ํ ํ๋ ฌ์ ๋ํ `layout(row_major)` ๋๋ `layout(column_major)`์ ๊ฐ์ด ๊ตฌ์กฐ์ฒด์ ์ ์ฒด ๋ ์ด์์์ ์ง์ ํ๋ ์ต์ ๋ ์ ๊ณตํฉ๋๋ค. ์ด๋ฌํ ๊ธฐ๋ฅ์ ๊ฐ๋ฐ์์๊ฒ ๋ฉ๋ชจ๋ฆฌ ์ ๋ ฌ ๋ฐ ํจํน์ ๋ํ ํจ์ฌ ๋ ์ธ๋ฐํ ์ ์ด๊ถ์ ๋ถ์ฌํฉ๋๋ค.
๊ฒฐ๋ก
WebGL UBO ์ ๋ ฌ ๊ท์น์ ์ดํดํ๊ณ ์ค์ํ๋ ๊ฒ์ ์ต์ ์ ์ ฐ์ด๋ ์ฑ๋ฅ์ ๋ฌ์ฑํ๊ณ ๋ค์ํ ํ๋ซํผ์์ ํธํ์ฑ์ ๋ณด์ฅํ๋ ๋ฐ ํ์์ ์ ๋๋ค. UBO ๋ฐ์ดํฐ๋ฅผ ์ ์คํ๊ฒ ๊ตฌ์ฑํ๊ณ ์ด ๊ธ์์ ์ค๋ช ํ ๋๋ฒ๊น ๊ธฐ์ ์ ์ฌ์ฉํ๋ฉด ์ผ๋ฐ์ ์ธ ํจ์ ์ ํผํ๊ณ WebGL์ ๋ชจ๋ ์ ์ฌ๋ ฅ์ ๋ฐํํ ์ ์์ต๋๋ค.
์ ๋ ฌ ๊ด๋ จ ๋ฌธ์ ๋ฅผ ์๋ณํ๊ณ ํด๊ฒฐํ๊ธฐ ์ํด ํญ์ ๋ค์ํ ๊ธฐ๊ธฐ์ ๋ธ๋ผ์ฐ์ ์์ ์ ฐ์ด๋๋ฅผ ํ ์คํธํ๋ ๊ฒ์ ์ฐ์ ์ํด์ผ ํฉ๋๋ค. ์น ๊ทธ๋ํฝ ๊ธฐ์ ์ด WebGPU๋ก ๋ฐ์ ํจ์ ๋ฐ๋ผ, ์ด๋ฌํ ํต์ฌ ์์น์ ๋ํ ํ์คํ ์ดํด๋ ๊ณ ์ฑ๋ฅ์ ์๊ฐ์ ์ผ๋ก ๋ฉ์ง ์น ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ๋ ๋ฐ ๊ณ์ํด์ ์ค์ํ ๊ฒ์ ๋๋ค.