WebGL μ °μ΄λ μ λνΌ λΈλ‘ ν¨νΉμ λν μ¬μΈ΅ λΆμ. νμ€, 곡μ , μμΆ λ μ΄μμμ λ€λ£¨λ©°, μ±λ₯ ν₯μμ μν λ©λͺ¨λ¦¬ μ¬μ© μ΅μ ν λ°©λ²μ μκ°ν©λλ€.
WebGL μ °μ΄λ μ λνΌ λΈλ‘ ν¨νΉ μκ³ λ¦¬μ¦: λ©λͺ¨λ¦¬ λ μ΄μμ μ΅μ ν
WebGLμμ μ °μ΄λλ νλ©΄μ κ°μ²΄κ° λ λλ§λλ λ°©μμ μ μνλ λ° νμμ μ λλ€. μ λνΌ λΈλ‘μ μ¬λ¬ μ λνΌ λ³μλ₯Ό ν¨κ» κ·Έλ£Ήννμ¬ CPUμ GPU κ°μ λ°μ΄ν° μ μ‘μ λ³΄λ€ ν¨μ¨μ μΌλ‘ λ§λλλ€. κ·Έλ¬λ μ΄λ¬ν μ λνΌ λΈλ‘μ΄ λ©λͺ¨λ¦¬μ ν¨νΉλλ λ°©μμ μ±λ₯μ μλΉν μν₯μ λ―ΈμΉ μ μμ΅λλ€. μ΄ κΈμμλ WebGL(νΉν μ λνΌ λΈλ‘μ νμν WebGL2)μμ μ¬μ© κ°λ₯ν λ€μν ν¨νΉ μκ³ λ¦¬μ¦μ μμΈν μ΄ν΄λ³΄κ³ λ©λͺ¨λ¦¬ λ μ΄μμ μ΅μ ν κΈ°μ μ μ€μ μ λ‘λλ€.
μ λνΌ λΈλ‘ μ΄ν΄νκΈ°
μ λνΌ λΈλ‘μ OpenGL ES 3.0(λ°λΌμ WebGL2)μμ λμ λ κΈ°λ₯μΌλ‘, κ΄λ ¨ μ λνΌ λ³μλ₯Ό λ¨μΌ λΈλ‘μΌλ‘ κ·Έλ£Ήνν μ μμ΅λλ€. μ΄λ κ°λ³ μ λνΌμ μ€μ νλ κ²λ³΄λ€ API νΈμΆ μλ₯Ό μ€μ΄κ³ λλΌμ΄λ²κ° λ°μ΄ν° μ μ‘μ μ΅μ νν μ μλλ‘ νμ¬ λ ν¨μ¨μ μ λλ€.
λ€μ GLSL μ °μ΄λ μ€λν«μ μ΄ν΄λ³΄μμμ€:
#version 300 es
uniform CameraData {
mat4 projectionMatrix;
mat4 viewMatrix;
vec3 cameraPosition;
float nearPlane;
float farPlane;
};
uniform LightData {
vec3 lightPosition;
vec3 lightColor;
float lightIntensity;
};
in vec3 inPosition;
in vec3 inNormal;
out vec4 fragColor;
void main() {
// ... shader code using the uniform data ...
gl_Position = projectionMatrix * viewMatrix * vec4(inPosition, 1.0);
// ... lighting calculations using LightData ...
fragColor = vec4(1.0, 0.0, 0.0, 1.0); // Example
}
μ΄ μμμμ `CameraData`μ `LightData`λ μ λνΌ λΈλ‘μ λλ€. `projectionMatrix`, `viewMatrix`, `cameraPosition` λ±μ κ°λ³μ μΌλ‘ μ€μ νλ λμ , λ¨μΌ νΈμΆλ‘ μ 체 `CameraData` λ° `LightData` λΈλ‘μ μ λ°μ΄νΈν μ μμ΅λλ€.
λ©λͺ¨λ¦¬ λ μ΄μμ μ΅μ
μ λνΌ λΈλ‘μ λ©λͺ¨λ¦¬ λ μ΄μμμ λΈλ‘ λ΄ λ³μκ° λ©λͺ¨λ¦¬μ μ΄λ»κ² λ°°μΉλλμ§λ₯Ό κ²°μ ν©λλ€. WebGL2λ μΈ κ°μ§ μ£Όμ λ μ΄μμ μ΅μ μ μ 곡ν©λλ€:
- νμ€ λ μ΄μμ: (`std140` λ μ΄μμμΌλ‘λ μλ €μ Έ μμ) μ΄λ κΈ°λ³Έ λ μ΄μμμ΄λ©° μ±λ₯κ³Ό νΈνμ± μ¬μ΄μ κ· νμ μ 곡ν©λλ€. GPUμ ν¨μ¨μ μΈ μ κ·Όμ μν΄ λ°μ΄ν°κ° μ μ νκ² μ λ ¬λλλ‘ νΉμ μ λ ¬ κ·μΉμ λ°λ¦ λλ€.
- 곡μ λ μ΄μμ: νμ€ λ μ΄μμκ³Ό μ μ¬νμ§λ§, μ»΄νμΌλ¬κ° λ μ΄μμμ μ΅μ ννλ λ° λ λ§μ μ μ°μ±μ μ 곡ν©λλ€. κ·Έλ¬λ μ΄λ‘ μΈν΄ λΈλ‘ λ΄ λ³μμ μμΉλ₯Ό κ²°μ νκΈ° μν΄ λͺ μμ μΈ μ€νμ μΏΌλ¦¬κ° νμνλ€λ λ¨μ μ΄ μμ΅λλ€.
- μμΆ λ μ΄μμ: μ΄ λ μ΄μμμ λ³μλ₯Ό κ°λ₯ν ν μ‘°λ°νκ² ν¨νΉνμ¬ λ©λͺ¨λ¦¬ μ¬μ©λμ μ΅μννλ©°, μ μ¬μ μΌλ‘ ν¨λ©μ μ€μΌ μ μμ΅λλ€. κ·Έλ¬λ μ κ·Ό μκ°μ΄ λλ €μ§ μ μκ³ νλμ¨μ΄μ λ°λΌ λ¬λΌμ§ μ μμ΄ μ΄μμ±μ΄ λ¨μ΄μ§λλ€.
νμ€ λ μ΄μμ (`std140`)
`std140` λ μ΄μμμ WebGL2μμ μ λνΌ λΈλ‘μ κ°μ₯ μΌλ°μ μ΄κ³ κΆμ₯λλ μ΅μ μ λλ€. μ΄λ λ€μν νλμ¨μ΄ νλ«νΌμμ μΌκ΄λ λ©λͺ¨λ¦¬ λ μ΄μμμ 보μ₯νμ¬ λμ μ΄μμ±μ μ 곡ν©λλ€. λ μ΄μμ κ·μΉμ 2μ κ±°λμ κ³± μ λ ¬ λ°©μμ κΈ°λ°νλ©°, GPUμ ν¨μ¨μ μΈ μ κ·Όμ μν΄ λ°μ΄ν°κ° μ μ νκ² μ λ ¬λλλ‘ ν©λλ€.
λ€μμ `std140`μ μ λ ¬ κ·μΉ μμ½μ λλ€:
- μ€μΉΌλΌ νμ
(
float
,int
,bool
): 4λ°μ΄νΈλ‘ μ λ ¬λ©λλ€. - λ²‘ν° (
vec2
,ivec2
,bvec2
): 8λ°μ΄νΈλ‘ μ λ ¬λ©λλ€. - λ²‘ν° (
vec3
,ivec3
,bvec3
): 16λ°μ΄νΈλ‘ μ λ ¬λ©λλ€ (곡백μ μ±μ°κΈ° μν ν¨λ©μ΄ νμν©λλ€). - λ²‘ν° (
vec4
,ivec4
,bvec4
): 16λ°μ΄νΈλ‘ μ λ ¬λ©λλ€. - νλ ¬ (
mat2
): κ° μ΄μvec2
λ‘ μ·¨κΈλλ©° 8λ°μ΄νΈλ‘ μ λ ¬λ©λλ€. - νλ ¬ (
mat3
): κ° μ΄μvec3
λ‘ μ·¨κΈλλ©° 16λ°μ΄νΈλ‘ μ λ ¬λ©λλ€ (ν¨λ©μ΄ νμν©λλ€). - νλ ¬ (
mat4
): κ° μ΄μvec4
λ‘ μ·¨κΈλλ©° 16λ°μ΄νΈλ‘ μ λ ¬λ©λλ€. - λ°°μ΄: κ° μμλ κΈ°λ³Έ νμ μ λ°λΌ μ λ ¬λλ©°, λ°°μ΄μ κΈ°λ³Έ μ λ ¬μ μμμ μ λ ¬κ³Ό λμΌν©λλ€. λν λ°°μ΄μ ν¬κΈ°κ° μμμ μ λ ¬ λ°°μκ° λλλ‘ λ°°μ΄ λμ ν¨λ©μ΄ μμ΅λλ€.
- ꡬ쑰체: λ©€λ² μ€ κ°μ₯ ν° μ λ ¬ μꡬ μ¬νμ λ°λΌ μ λ ¬λ©λλ€. λ©€λ²λ ꡬ쑰체 μ μμ λνλλ μμλλ‘ λ°°μΉλλ©°, κ° λ©€λ² λ° κ΅¬μ‘°μ²΄ μ체μ μ λ ¬ μꡬ μ¬νμ μΆ©μ‘±μν€κΈ° μν΄ νμν λ§νΌ ν¨λ©μ΄ μ½μ λ©λλ€.
μμ:
#version 300 es
layout(std140) uniform ExampleBlock {
float scalar;
vec3 vector;
mat4 matrix;
};
μ΄ μμμμ:
- `scalar`λ 4λ°μ΄νΈλ‘ μ λ ¬λ©λλ€.
- `vector`λ 16λ°μ΄νΈλ‘ μ λ ¬λλ©°, `scalar` λ€μ 4λ°μ΄νΈμ ν¨λ©μ΄ νμν©λλ€.
- `matrix`λ 4κ°μ μ΄λ‘ ꡬμ±λλ©°, κ° μ΄μ `vec4`λ‘ μ·¨κΈλκ³ 16λ°μ΄νΈλ‘ μ λ ¬λ©λλ€.
`ExampleBlock`μ μ 체 ν¬κΈ°λ ν¨λ©μΌλ‘ μΈν΄ λ©€λ² ν¬κΈ°μ ν©λ³΄λ€ 컀μ§λλ€.
곡μ λ μ΄μμ
곡μ λ μ΄μμμ λ©λͺ¨λ¦¬ λ μ΄μμ μΈ‘λ©΄μμ μ»΄νμΌλ¬μκ² λ λ§μ μ μ°μ±μ μ 곡ν©λλ€. κΈ°λ³Έμ μΈ μ λ ¬ μꡬ μ¬νμ μ‘΄μ€νμ§λ§, νΉμ λ μ΄μμμ 보μ₯νμ§λ μμ΅λλ€. μ΄λ νΉμ νλμ¨μ΄μμ μ μ¬μ μΌλ‘ λ ν¨μ¨μ μΈ λ©λͺ¨λ¦¬ μ¬μ©κ³Ό λ λμ μ±λ₯μΌλ‘ μ΄μ΄μ§ μ μμ΅λλ€. κ·Έλ¬λ λ¨μ μ WebGL API νΈμΆ(μ: `gl.UNIFORM_OFFSET`κ³Ό ν¨κ» `gl.getActiveUniformBlockParameter`)μ μ¬μ©νμ¬ λΈλ‘ λ΄ λ³μμ μ€νμ μ λͺ μμ μΌλ‘ 쿼리ν΄μΌ νλ€λ κ²μ λλ€.
μμ:
#version 300 es
layout(shared) uniform SharedBlock {
float scalar;
vec3 vector;
mat4 matrix;
};
곡μ λ μ΄μμμμλ `scalar`, `vector`, `matrix`μ μ€νμ μ κ°μ ν μ μμ΅λλ€. WebGL API νΈμΆμ μ¬μ©νμ¬ λ°νμμ 쿼리ν΄μΌ ν©λλ€. μ΄λ JavaScript μ½λμμ μ λνΌ λΈλ‘μ μ λ°μ΄νΈν΄μΌ νλ κ²½μ° μ€μν©λλ€.
μμΆ λ μ΄μμ
μμΆ λ μ΄μμμ λ³μλ₯Ό κ°λ₯ν ν μ‘°λ°νκ² ν¨νΉνμ¬ ν¨λ©μ μ κ±°ν¨μΌλ‘μ¨ λ©λͺ¨λ¦¬ μ¬μ©λμ μ΅μννλ κ²μ λͺ©νλ‘ ν©λλ€. μ΄λ λ©λͺ¨λ¦¬ λμνμ΄ λ³λͺ© νμμΈ μν©μμ μ μ©ν μ μμ΅λλ€. κ·Έλ¬λ GPUκ° λ³μλ₯Ό μ°ΎκΈ° μν΄ λ 볡μ‘ν κ³μ°μ μνν΄μΌ νλ―λ‘ μμΆ λ μ΄μμμ μ κ·Ό μκ°μ΄ λλ €μ§ μ μμ΅λλ€. λν μ νν λ μ΄μμμ νΉμ νλμ¨μ΄ λ° λλΌμ΄λ²μ ν¬κ² μμ‘΄νλ―λ‘ `std140` λ μ΄μμλ³΄λ€ μ΄μμ±μ΄ λ¨μ΄μ§λλ€. λ§μ κ²½μ°, λ°μ΄ν° μ κ·Όμ μΆκ°μ μΈ λ³΅μ‘μ±μΌλ‘ μΈν΄ μ€μ λ‘ μμΆ λ μ΄μμμ μ¬μ©νλ κ²μ΄ λ λΉ λ₯΄μ§λ μμ΅λλ€.
μμ:
#version 300 es
layout(packed) uniform PackedBlock {
float scalar;
vec3 vector;
mat4 matrix;
};
μμΆ λ μ΄μμμμλ λ³μκ° κ°λ₯ν ν μ‘°λ°νκ² ν¨νΉλ©λλ€. κ·Έλ¬λ μ νν λ μ΄μμμ΄ λ³΄μ₯λμ§ μμΌλ―λ‘ λ°νμμ μ€νμ μ 쿼리ν΄μΌ ν©λλ€. μ΄ λ μ΄μμμ λ©λͺ¨λ¦¬ μ¬μ©μ μ΅μνν΄μΌ νλ νΉλ³ν νμκ° μκ³ μ±λ₯ μ΄μ μ μ 곡νλ€λ κ²μ μ ν리μΌμ΄μ μ νλ‘νμΌλ§νμ¬ νμΈν κ²½μ°κ° μλλΌλ©΄ μΌλ°μ μΌλ‘ κΆμ₯λμ§ μμ΅λλ€.
μ λνΌ λΈλ‘ λ©λͺ¨λ¦¬ λ μ΄μμ μ΅μ ν
μ λνΌ λΈλ‘ λ©λͺ¨λ¦¬ λ μ΄μμμ μ΅μ ννλ κ²μ ν¨λ©μ μ΅μννκ³ ν¨μ¨μ μΈ μ κ·Όμ μν΄ λ°μ΄ν°κ° μ λ ¬λλλ‘ νλ κ²μ ν¬ν¨ν©λλ€. λ€μμ λͺ κ°μ§ μ λ΅μ λλ€:
- λ³μ μ¬μ λ ¬: μ λνΌ λΈλ‘ λ΄ λ³μλ₯Ό ν¬κΈ° λ° μ λ ¬ μꡬ μ¬νμ λ°λΌ λ°°μ΄ν©λλ€. ν¨λ©μ μ€μ΄κΈ° μν΄ λ ν° λ³μ(μ: νλ ¬)λ₯Ό λ μμ λ³μ(μ: μ€μΉΌλΌ) μμ λ°°μΉν©λλ€.
- μ μ¬ν νμ κ·Έλ£Ήν: λμΌν νμ μ λ³μλ₯Ό ν¨κ» κ·Έλ£Ήνν©λλ€. μ΄λ ν¨λ©μ μ΅μννκ³ μΊμ μ§μμ±μ κ°μ νλ λ° λμμ΄ λ μ μμ΅λλ€.
- ꡬ쑰체λ₯Ό νλͺ νκ² μ¬μ©: ꡬ쑰체λ₯Ό μ¬μ©νμ¬ κ΄λ ¨ λ³μλ₯Ό ν¨κ» κ·Έλ£Ήνν μ μμ§λ§, ꡬ쑰체 λ©€λ²μ μ λ ¬ μꡬ μ¬νμ μ μν΄μΌ ν©λλ€. ν¨λ©μ μ€μ΄λ λ° λμμ΄ λλ€λ©΄ νλμ ν° κ΅¬μ‘°μ²΄ λμ μ¬λ¬ κ°μ μμ ꡬ쑰체λ₯Ό μ¬μ©νλ κ²μ κ³ λ €νμμμ€.
- λΆνμν ν¨λ© νΌνκΈ°: `std140` λ μ΄μμμΌλ‘ μΈν΄ λμ λλ ν¨λ©μ μΈμ§νκ³ μ΄λ₯Ό μ΅μννλλ‘ λ Έλ ₯νμμμ€. μλ₯Ό λ€μ΄, `vec3`κ° μλ€λ©΄ 4λ°μ΄νΈ ν¨λ©μ νΌνκΈ° μν΄ `vec4`λ₯Ό λμ μ¬μ©νλ κ²μ κ³ λ €νμμμ€. κ·Έλ¬λ μ΄λ λ©λͺ¨λ¦¬ μ¬μ©λ μ¦κ°λΌλ λ¨μ μ΄ μμ΅λλ€. μ΅μ μ μ κ·Ό λ°©μμ κ²°μ νλ €λ©΄ λ²€μΉλ§νΉμ ν΄μΌ ν©λλ€.
- `std430` μ¬μ© κ³ λ €: WebGL2 μ체μ λ μ΄μμ νμ μλ‘ μ§μ λ ΈμΆλμ§λ μμ§λ§, OpenGL 4.3 μ΄μ(λ° OpenGL ES 3.1 μ΄μ)μμ μμλ `std430` λ μ΄μμμ νλμ¨μ΄ μ’ μμ±μ΄ λνκ³ λ°νμ μ€νμ μΏΌλ¦¬κ° νμ μλ "μμΆ" λ μ΄μμμ λ κ°κΉμ΄ μ μ¬μ²΄μ λλ€. κΈ°λ³Έμ μΌλ‘ λ©€λ²λ₯Ό μ΅λ 16λ°μ΄νΈκΉμ§ μμ° ν¬κΈ°λ‘ μ λ ¬ν©λλ€. λ°λΌμ `float`λ 4λ°μ΄νΈ, `vec3`λ 12λ°μ΄νΈ λ±μ λλ€. μ΄ λ μ΄μμμ νΉμ WebGL νμ₯ νλ‘κ·Έλ¨μμ λ΄λΆμ μΌλ‘ μ¬μ©λ©λλ€. `std430`μ μ§μ *μ§μ *ν μλ μμ§λ§, λ©€λ² λ³μλ₯Ό ν¨νΉνλ κ²κ³Ό κ°λ μ μΌλ‘ μ μ¬νλ€λ μ§μμ ꡬ쑰체λ₯Ό μλμΌλ‘ λ°°μΉνλ λ° μ’ μ’ μ μ©ν©λλ€.
μμ: μ΅μ νλ₯Ό μν λ³μ μ¬μ λ ¬
λ€μ μ λνΌ λΈλ‘μ κ³ λ €ν΄λ³΄μμμ€:
#version 300 es
layout(std140) uniform BadBlock {
float a;
vec3 b;
float c;
vec3 d;
};
μ΄ κ²½μ°, `vec3` λ³μμ μ λ ¬ μꡬ μ¬νμΌλ‘ μΈν΄ μλΉν ν¨λ©μ΄ λ°μν©λλ€. λ©λͺ¨λ¦¬ λ μ΄μμμ λ€μκ³Ό κ°μ΅λλ€:
- `a`: 4 bytes
- Padding: 12 bytes
- `b`: 12 bytes
- Padding: 4 bytes
- `c`: 4 bytes
- Padding: 12 bytes
- `d`: 12 bytes
- Padding: 4 bytes
`BadBlock`μ μ΄ ν¬κΈ°λ 64λ°μ΄νΈμ λλ€.
μ΄μ λ³μλ₯Ό μ¬μ λ ¬ν΄ λ΄ μλ€:
#version 300 es
layout(std140) uniform GoodBlock {
vec3 b;
vec3 d;
float a;
float c;
};
λ©λͺ¨λ¦¬ λ μ΄μμμ μ΄μ λ€μκ³Ό κ°μ΅λλ€:
- `b`: 12 bytes
- Padding: 4 bytes
- `d`: 12 bytes
- Padding: 4 bytes
- `a`: 4 bytes
- Padding: 4 bytes
- `c`: 4 bytes
- Padding: 4 bytes
`GoodBlock`μ μ΄ ν¬κΈ°λ μ¬μ ν 32λ°μ΄νΈμ΄μ§λ§, floatμ μ κ·Όνλ κ²μ΄ μ½κ° λλ €μ§ μ μμ΅λλ€ (νμ§λ§ μλ§λ λμ λμ§ μμ κ²μ λλ€). λ€λ₯Έ κ²μ μλν΄ λ΄ μλ€:
#version 300 es
layout(std140) uniform BestBlock {
vec3 b;
vec3 d;
vec2 ac;
};
λ©λͺ¨λ¦¬ λ μ΄μμμ μ΄μ λ€μκ³Ό κ°μ΅λλ€:
- `b`: 12 bytes
- Padding: 4 bytes
- `d`: 12 bytes
- Padding: 4 bytes
- `ac`: 8 bytes
- Padding: 8 bytes
`BestBlock`μ μ΄ ν¬κΈ°λ 48λ°μ΄νΈμ λλ€. λ λ²μ§Έ μμλ³΄λ€ ν¬μ§λ§, `a`μ `c` μ¬μ΄μ ν¨λ©μ μ κ±°νμΌλ©°, λ¨μΌ `vec2` κ°μΌλ‘ λ ν¨μ¨μ μΌλ‘ μ κ·Όν μ μμ΅λλ€.
μ€μ©μ μΈ ν΅μ°°: νΉν μ±λ₯μ΄ μ€μν μ ν리μΌμ΄μ μμλ μ λνΌ λΈλ‘μ λ μ΄μμμ μ κΈ°μ μΌλ‘ κ²ν νκ³ μ΅μ ννμμμ€. μ½λ νλ‘νμΌλ§μ ν΅ν΄ μ μ¬μ μΈ λ³λͺ© νμμ μλ³νκ³ λ€μν λ μ΄μμμ μ€ννμ¬ μ΅μ μ ꡬμ±μ μ°ΎμΌμμμ€.
JavaScriptμμ μ λνΌ λΈλ‘ λ°μ΄ν° μ κ·ΌνκΈ°
JavaScript μ½λμμ μ λνΌ λΈλ‘ λ΄μ λ°μ΄ν°λ₯Ό μ λ°μ΄νΈνλ €λ©΄ λ€μ λ¨κ³λ₯Ό μνν΄μΌ ν©λλ€:
- μ λνΌ λΈλ‘ μΈλ±μ€ κ°μ Έμ€κΈ°: `gl.getUniformBlockIndex`λ₯Ό μ¬μ©νμ¬ μ °μ΄λ νλ‘κ·Έλ¨ λ΄ μ λνΌ λΈλ‘μ μΈλ±μ€λ₯Ό κ²μν©λλ€.
- μ λνΌ λΈλ‘ ν¬κΈ° κ°μ Έμ€κΈ°: `gl.UNIFORM_BLOCK_DATA_SIZE`μ ν¨κ» `gl.getActiveUniformBlockParameter`λ₯Ό μ¬μ©νμ¬ μ λνΌ λΈλ‘μ λ°μ΄νΈ ν¬κΈ°λ₯Ό κ²°μ ν©λλ€.
- λ²νΌ μμ±: μ λνΌ λΈλ‘ λ°μ΄ν°λ₯Ό λ΄μ μ¬λ°λ₯Έ ν¬κΈ°μ `Float32Array` (λλ λ€λ₯Έ μ μ ν νμ λ°°μ΄)λ₯Ό μμ±ν©λλ€.
- λ²νΌ μ±μ°κΈ°: μ λνΌ λΈλ‘μ κ° λ³μμ λν΄ μ μ ν κ°μΌλ‘ λ²νΌλ₯Ό μ±μλλ€. λ©λͺ¨λ¦¬ λ μ΄μμ(νΉν 곡μ λλ μμΆ λ μ΄μμμ κ²½μ°)μ μ μνκ³ μ¬λ°λ₯Έ μ€νμ μ μ¬μ©νμμμ€.
- λ²νΌ κ°μ²΄ μμ±: `gl.createBuffer`λ₯Ό μ¬μ©νμ¬ WebGL λ²νΌ κ°μ²΄λ₯Ό μμ±ν©λλ€.
- λ²νΌ λ°μΈλ©: `gl.bindBuffer`λ₯Ό μ¬μ©νμ¬ λ²νΌ κ°μ²΄λ₯Ό `gl.UNIFORM_BUFFER` λμμΌλ‘ λ°μΈλ©ν©λλ€.
- λ°μ΄ν° μ λ‘λ: `gl.bufferData`λ₯Ό μ¬μ©νμ¬ νμ λ°°μ΄μ λ°μ΄ν°λ₯Ό λ²νΌ κ°μ²΄λ‘ μ λ‘λν©λλ€.
- μ λνΌ λΈλ‘μ λ°μΈλ© ν¬μΈνΈμ λ°μΈλ©: μ λνΌ λ²νΌ λ°μΈλ© ν¬μΈνΈ(μ: 0, 1, 2)λ₯Ό μ νν©λλ€. `gl.bindBufferBase` λλ `gl.bindBufferRange`λ₯Ό μ¬μ©νμ¬ λ²νΌ κ°μ²΄λ₯Ό μ νλ λ°μΈλ© ν¬μΈνΈμ λ°μΈλ©ν©λλ€.
- μ λνΌ λΈλ‘μ λ°μΈλ© ν¬μΈνΈμ μ°κ²°: `gl.uniformBlockBinding`μ μ¬μ©νμ¬ μ °μ΄λμ μ λνΌ λΈλ‘μ μ νλ λ°μΈλ© ν¬μΈνΈμ μ°κ²°ν©λλ€.
μμ: JavaScriptμμ μ λνΌ λΈλ‘ μ λ°μ΄νΈνκΈ°
// Assuming you have a WebGL context (gl) and a shader program (program)
// 1. Get the uniform block index
const blockIndex = gl.getUniformBlockIndex(program, "MyBlock");
// 2. Get the size of the uniform block
const blockSize = gl.getActiveUniformBlockParameter(program, blockIndex, gl.UNIFORM_BLOCK_DATA_SIZE);
// 3. Create a buffer
const bufferData = new Float32Array(blockSize / 4); // Assuming floats
// 4. Populate the buffer (example values)
// Note: You need to know the offsets of the variables within the block
// For std140, you can calculate them based on the alignment rules
// For shared or packed, you need to query them using gl.getActiveUniform
bufferData[0] = 1.0; // myFloat
bufferData[4] = 2.0; // myVec3.x (offset needs to be calculated correctly)
bufferData[5] = 3.0; // myVec3.y
bufferData[6] = 4.0; // myVec3.z
// 5. Create a buffer object
const buffer = gl.createBuffer();
// 6. Bind the buffer
gl.bindBuffer(gl.UNIFORM_BUFFER, buffer);
// 7. Upload the data
gl.bufferData(gl.UNIFORM_BUFFER, bufferData, gl.DYNAMIC_DRAW);
// 8. Bind the uniform block to a binding point
const bindingPoint = 0;
gl.bindBufferBase(gl.UNIFORM_BUFFER, bindingPoint, buffer);
// 9. Link the uniform block to the binding point
gl.uniformBlockBinding(program, blockIndex, bindingPoint);
μ±λ₯ κ³ λ € μ¬ν
μ λνΌ λΈλ‘ λ μ΄μμμ μ νκ³Ό λ©λͺ¨λ¦¬ λ μ΄μμμ μ΅μ νλ νΉν λ§μ μ λνΌ μ λ°μ΄νΈκ° μλ 볡μ‘ν μ₯λ©΄μμ μ±λ₯μ μλΉν μν₯μ λ―ΈμΉ μ μμ΅λλ€. λ€μμ λͺ κ°μ§ μ±λ₯ κ³ λ € μ¬νμ λλ€:
- λ©λͺ¨λ¦¬ λμν: λ©λͺ¨λ¦¬ μ¬μ©λμ μ΅μννλ©΄ CPUμ GPU κ°μ μ μ‘λμ΄μΌ νλ λ°μ΄ν° μμ μ€μ¬ μ±λ₯μ ν₯μμν¬ μ μμ΅λλ€.
- μΊμ μ§μμ±: μΊμ μ§μμ±μ κ°μ νλ λ°©μμΌλ‘ λ³μλ₯Ό λ°°μ΄νλ©΄ μΊμ λ―Έμ€ μλ₯Ό μ€μ¬ λ λΉ λ₯Έ μ κ·Ό μκ°μ μ»μ μ μμ΅λλ€.
- μ λ ¬: μ μ ν μ λ ¬μ GPUκ° λ°μ΄ν°λ₯Ό ν¨μ¨μ μΌλ‘ μ κ·Όν μ μλλ‘ λ³΄μ₯ν©λλ€. μλͺ» μ λ ¬λ λ°μ΄ν°λ μ±λ₯ μ νλ‘ μ΄μ΄μ§ μ μμ΅λλ€.
- λλΌμ΄λ² μ΅μ ν: λ€μν κ·Έλν½ λλΌμ΄λ²λ μ λνΌ λΈλ‘ μ κ·Όμ λ€μν λ°©μμΌλ‘ μ΅μ νν μ μμ΅λλ€. λμ νλμ¨μ΄μ κ°μ₯ μ ν©ν ꡬμ±μ μ°ΎκΈ° μν΄ λ€μν λ μ΄μμμ μ€νν΄ λ³΄μμμ€.
- μ λνΌ μ λ°μ΄νΈ μ: μ λνΌ μ λ°μ΄νΈ μλ₯Ό μ€μ΄λ©΄ μ±λ₯μ ν¬κ² ν₯μμν¬ μ μμ΅λλ€. μ λνΌ λΈλ‘μ μ¬μ©νμ¬ κ΄λ ¨ μ λνΌμ κ·Έλ£Ήννκ³ λ¨μΌ νΈμΆλ‘ μ λ°μ΄νΈνμμμ€.
κ²°λ‘
μ λνΌ λΈλ‘ ν¨νΉ μκ³ λ¦¬μ¦μ μ΄ν΄νκ³ λ©λͺ¨λ¦¬ λ μ΄μμμ μ΅μ ννλ κ²μ WebGL μ ν리μΌμ΄μ μμ μ΅μ μ μ±λ₯μ λ¬μ±νλ λ° μ€μν©λλ€. `std140` λ μ΄μμμ μ±λ₯κ³Ό νΈνμ± μ¬μ΄μ μ’μ κ· νμ μ 곡νλ©°, 곡μ λ° μμΆ λ μ΄μμμ λ λ§μ μ μ°μ±μ μ 곡νμ§λ§ νλμ¨μ΄ μ’ μμ± λ° λ°νμ μ€νμ 쿼리μ λν μ μ€ν κ³ λ €κ° νμν©λλ€. λ³μλ₯Ό μ¬μ λ ¬νκ³ , μ μ¬ν μ νμ κ·Έλ£Ήννλ©°, λΆνμν ν¨λ©μ μ΅μνν¨μΌλ‘μ¨ λ©λͺ¨λ¦¬ μ¬μ©λμ ν¬κ² μ€μ΄κ³ μ±λ₯μ ν₯μμν¬ μ μμ΅λλ€.
μ½λ νλ‘νμΌλ§μ μννκ³ λ€μν λ μ΄μμμ μ€ννμ¬ νΉμ μ ν리μΌμ΄μ λ° λμ νλμ¨μ΄μ μ΅μ μ ꡬμ±μ μ°ΎμΌμμμ€. μ °μ΄λκ° λ°μ νκ³ λ 볡μ‘ν΄μ§μ λ°λΌ μ λνΌ λΈλ‘ λ μ΄μμμ μ κΈ°μ μΌλ‘ κ²ν νκ³ μ΅μ ννμμμ€.
μΆκ° μλ£
μ΄ ν¬κ΄μ μΈ κ°μ΄λλ WebGL μ °μ΄λ μ λνΌ λΈλ‘ ν¨νΉ μκ³ λ¦¬μ¦μ μ΄ν΄νκ³ μ΅μ ννλ λ° νμν νκ³ ν κΈ°λ°μ μ 곡ν κ²μ λλ€. νμ΄μ λΉλ©°, μ¦κ±°μ΄ λ λλ§ λμΈμ!