πŸ—οΈ WebGL2의 λ©”μ„œλ“œμ™€ μƒμˆ˜

BamgasiJMΒ·2026λ…„ 6μ›” 26일

WebGL

λͺ©λ‘ 보기
6/14
post-thumbnail

gl.clear(), gl.createBuffer(), gl.bindBuffer()와 같이 gl. 뒀에 μ˜€λŠ” 이름듀은 WebGL2 APIκ°€ μ œκ³΅ν•˜λŠ” ν‘œμ€€ λ©”μ„œλ“œ(Methods)와 μƒμˆ˜(Constants)μž…λ‹ˆλ‹€. WebGL ν”„λ‘œκ·Έλž˜λ°μ„ 처음 μ ‘ν•˜λ©΄ ν•¨μˆ˜μ™€ μƒμˆ˜κ°€ λ’€μ„žμ—¬ 보이기 μ‰½μ§€λ§Œ, 이 λ‘˜μ˜ 역할을 κ΅¬λΆ„ν•˜λ©΄ WebGL의 μƒνƒœ 기반(State Machine) ꡬ쑰λ₯Ό 훨씬 μ‰½κ²Œ 이해할 수 μžˆμŠ΅λ‹ˆλ‹€.


1. λ©”μ„œλ“œ (Methods): GPUμ—κ²Œ λͺ…령을 μ „λ‹¬ν•˜λŠ” ν•¨μˆ˜

gl.clear(), gl.drawArrays()처럼 μ†Œλ¬Έμžλ‘œ μ‹œμž‘ν•˜λ©° κ΄„ν˜Έ ()κ°€ λΆ™λŠ” 것듀은 WebGL μ»¨ν…μŠ€νŠΈκ°€ μˆ˜ν–‰ν•  λ™μž‘μ„ λ‚˜νƒ€λ‚΄λŠ” λ©”μ„œλ“œμž…λ‹ˆλ‹€.

λ©”μ„œλ“œλŠ” CPUμ—μ„œ GPU둜 μ „λ‹¬λ˜λŠ” λͺ…λ Ή(Command)이라고 λ³Ό 수 μžˆμŠ΅λ‹ˆλ‹€.

νŠΉμ§•

  • μ†Œλ¬Έμžλ‘œ μ‹œμž‘ν•œλ‹€.
  • κ΄„ν˜Έ ()λ₯Ό κ°€μ§„λ‹€.
  • GPU μƒνƒœλ₯Ό λ³€κ²½ν•˜κ±°λ‚˜ μž‘μ—…μ„ μˆ˜ν–‰ν•œλ‹€.
  • λ°˜ν™˜κ°’μ„ κ°€μ§ˆ μˆ˜λ„ μžˆλ‹€.

μ˜ˆμ‹œ

gl.clear(...);
gl.useProgram(...);
gl.bindBuffer(...);
gl.drawArrays(...);

μ£Όμš” λ©”μ„œλ“œ

λ©”μ„œλ“œμ—­ν• 
gl.clear()버퍼 μ΄ˆκΈ°ν™”
gl.viewport()λ Œλ”λ§ μ˜μ—­ μ„€μ •
gl.createBuffer()버퍼 객체 생성
gl.bindBuffer()버퍼 바인딩
gl.bufferData()버퍼 데이터 μ—…λ‘œλ“œ
gl.createShader()셰이더 객체 생성
gl.shaderSource()셰이더 μ†ŒμŠ€ μ§€μ •
gl.compileShader()셰이더 컴파일
gl.createProgram()ν”„λ‘œκ·Έλž¨ 객체 생성
gl.linkProgram()ν”„λ‘œκ·Έλž¨ 링크
gl.useProgram()ν”„λ‘œκ·Έλž¨ ν™œμ„±ν™”
gl.enableVertexAttribArray()정점 속성 ν™œμ„±ν™”
gl.vertexAttribPointer()정점 데이터 ν˜•μ‹ μ§€μ •
gl.drawArrays()정점 데이터 λ Œλ”λ§
gl.drawElements()인덱슀 기반 λ Œλ”λ§

2. μƒμˆ˜ (Constants): 미리 μ •μ˜λœ μ‹λ³„μž

gl.COLOR_BUFFER_BIT, gl.ARRAY_BUFFER, gl.STATIC_DRAW처럼 λͺ¨λ‘ λŒ€λ¬Έμžλ‘œ μž‘μ„±λœ 값듀은 WebGL이 미리 μ •μ˜ν•œ μƒμˆ˜μž…λ‹ˆλ‹€.

μƒμˆ˜λŠ” μˆ«μžκ°’μ΄μ§€λ§Œ, ν”„λ‘œκ·Έλž˜λ¨Έκ°€ μ΄ν•΄ν•˜κΈ° 쉽도둝 이름이 λΆ™μ–΄ μžˆμŠ΅λ‹ˆλ‹€.

예λ₯Ό λ“€μ–΄:

console.log(gl.COLOR_BUFFER_BIT);

μ‹€μ œλ‘œλŠ” λ‹€μŒκ³Ό 같은 μˆ«μžκ°€ 좜λ ₯λ©λ‹ˆλ‹€.

16384

κ·ΈλŸ¬λ‚˜ μ½”λ“œμ—μ„œ 숫자λ₯Ό 직접 μ‚¬μš©ν•˜λŠ” λŒ€μ‹  의미 μžˆλŠ” 이름을 μ‚¬μš©ν•˜λŠ” 것이 가독성과 μœ μ§€λ³΄μˆ˜μ„± μΈ‘λ©΄μ—μ„œ 훨씬 μœ λ¦¬ν•©λ‹ˆλ‹€.


3. μ™œ 항상 gl.을 λΆ™μ΄λŠ”κ°€?

const gl = canvas.getContext("webgl2");

gl은 WebGL2 λ Œλ”λ§ μ»¨ν…μŠ€νŠΈ κ°μ²΄μž…λ‹ˆλ‹€.

이 객체 λ‚΄λΆ€μ—λŠ” 수백 개의 λ©”μ„œλ“œμ™€ μƒμˆ˜κ°€ ν¬ν•¨λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€.

gl.clear(...)
gl.drawArrays(...)
gl.COLOR_BUFFER_BIT

μ΄λŠ” λͺ¨λ‘ gl 객체 내뢀에 μ†ν•œ λ©€λ²„μž…λ‹ˆλ‹€.

객체 μ§€ν–₯ κ΄€μ μ—μ„œ 보면 λ‹€μŒκ³Ό 같이 이해할 수 μžˆμŠ΅λ‹ˆλ‹€.

  • gl : WebGL2 μ‹œμŠ€ν…œ
  • clear() : μ‹œμŠ€ν…œμ΄ μˆ˜ν–‰ν•  κΈ°λŠ₯
  • COLOR_BUFFER_BIT : μ‹œμŠ€ν…œμ΄ μ œκ³΅ν•˜λŠ” μ„€μ •κ°’

즉,

"WebGL μ‹œμŠ€ν…œ(gl) μ•ˆμ˜ clear κΈ°λŠ₯을 ν˜ΈμΆœν•œλ‹€."

λΌλŠ” μ˜λ―Έμž…λ‹ˆλ‹€.


자주 μ‚¬μš©ν•˜λŠ” WebGL2 λ©”μ„œλ“œ

ν™”λ©΄ μ œμ–΄

gl.clearColor()

화면을 μ§€μšΈ λ•Œ μ‚¬μš©ν•  배경색을 μ§€μ •ν•©λ‹ˆλ‹€.

gl.clearColor(0.0, 0.0, 0.0, 1.0);

gl.clear()

버퍼λ₯Ό μ΄ˆκΈ°ν™”ν•©λ‹ˆλ‹€.

gl.clear(gl.COLOR_BUFFER_BIT);

gl.viewport()

λ Œλ”λ§ μ˜μ—­μ„ μ§€μ •ν•©λ‹ˆλ‹€.

gl.viewport(0, 0, canvas.width, canvas.height);

버퍼 κ΄€λ ¨ λ©”μ„œλ“œ

gl.createBuffer()

GPU 버퍼 객체λ₯Ό μƒμ„±ν•©λ‹ˆλ‹€.

const buffer = gl.createBuffer();

gl.bindBuffer()

ν˜„μž¬ μž‘μ—…ν•  버퍼λ₯Ό μ„ νƒν•©λ‹ˆλ‹€.

gl.bindBuffer(gl.ARRAY_BUFFER, buffer);

gl.bufferData()

버퍼에 데이터λ₯Ό μ—…λ‘œλ“œν•©λ‹ˆλ‹€.

gl.bufferData(
    gl.ARRAY_BUFFER,
    vertices,
    gl.STATIC_DRAW
);

셰이더 κ΄€λ ¨ λ©”μ„œλ“œ

gl.createShader()

셰이더 객체λ₯Ό μƒμ„±ν•©λ‹ˆλ‹€.

const shader = gl.createShader(gl.VERTEX_SHADER);

gl.shaderSource()

GLSL μ½”λ“œλ₯Ό μ „λ‹¬ν•©λ‹ˆλ‹€.

gl.shaderSource(shader, source);

gl.compileShader()

셰이더λ₯Ό μ»΄νŒŒμΌν•©λ‹ˆλ‹€.

gl.compileShader(shader);

ν”„λ‘œκ·Έλž¨ κ΄€λ ¨ λ©”μ„œλ“œ

gl.createProgram()

셰이더 ν”„λ‘œκ·Έλž¨μ„ μƒμ„±ν•©λ‹ˆλ‹€.

const program = gl.createProgram();

gl.attachShader()

셰이더λ₯Ό ν”„λ‘œκ·Έλž¨μ— μ—°κ²°ν•©λ‹ˆλ‹€.

gl.attachShader(program, vertexShader);

gl.linkProgram()

셰이더듀을 ν•˜λ‚˜μ˜ ν”„λ‘œκ·Έλž¨μœΌλ‘œ λ§ν¬ν•©λ‹ˆλ‹€.

gl.linkProgram(program);

gl.useProgram()

ν˜„μž¬ μ‚¬μš©ν•  ν”„λ‘œκ·Έλž¨μ„ μ§€μ •ν•©λ‹ˆλ‹€.

gl.useProgram(program);

정점 속성 κ΄€λ ¨ λ©”μ„œλ“œ

gl.getAttribLocation()

정점 μ†μ„±μ˜ μœ„μΉ˜λ₯Ό κ°€μ Έμ˜΅λ‹ˆλ‹€.

const positionLoc =
    gl.getAttribLocation(program, "aPosition");

gl.enableVertexAttribArray()

정점 속성을 ν™œμ„±ν™”ν•©λ‹ˆλ‹€.

gl.enableVertexAttribArray(positionLoc);

gl.vertexAttribPointer()

버퍼 λ°μ΄ν„°μ˜ ꡬ쑰λ₯Ό μ •μ˜ν•©λ‹ˆλ‹€.

gl.vertexAttribPointer(
    positionLoc,
    3,
    gl.FLOAT,
    false,
    0,
    0
);

λ Œλ”λ§ λ©”μ„œλ“œ

gl.drawArrays()

순차적으둜 정점을 κ·Έλ¦½λ‹ˆλ‹€.

gl.drawArrays(gl.TRIANGLES, 0, 3);

gl.drawElements()

인덱슀 버퍼λ₯Ό μ‚¬μš©ν•˜μ—¬ κ·Έλ¦½λ‹ˆλ‹€.

gl.drawElements(
    gl.TRIANGLES,
    indexCount,
    gl.UNSIGNED_SHORT,
    0
);

자주 μ‚¬μš©ν•˜λŠ” μƒμˆ˜

버퍼 μ’…λ₯˜

μƒμˆ˜μ˜λ―Έ
gl.ARRAY_BUFFER정점 버퍼
gl.ELEMENT_ARRAY_BUFFER인덱슀 버퍼
gl.UNIFORM_BUFFERUniform 버퍼
gl.TRANSFORM_FEEDBACK_BUFFERTransform Feedback 버퍼

버퍼 μ‚¬μš© νŒ¨ν„΄

μƒμˆ˜μ˜λ―Έ
gl.STATIC_DRAWν•œ 번 μ—…λ‘œλ“œ ν›„ μ—¬λŸ¬ 번 μ‚¬μš©
gl.DYNAMIC_DRAW자주 λ³€κ²½
gl.STREAM_DRAWλ§€ ν”„λ ˆμž„ λ³€κ²½

셰이더 μ’…λ₯˜

μƒμˆ˜μ˜λ―Έ
gl.VERTEX_SHADERλ²„ν…μŠ€ 셰이더
gl.FRAGMENT_SHADERν”„λž˜κ·Έλ¨ΌνŠΈ 셰이더

데이터 νƒ€μž…

μƒμˆ˜μ˜λ―Έ
gl.FLOAT32λΉ„νŠΈ μ‹€μˆ˜
gl.INTμ •μˆ˜
gl.UNSIGNED_SHORT16λΉ„νŠΈ λΆ€ν˜Έ μ—†λŠ” μ •μˆ˜
gl.UNSIGNED_INT32λΉ„νŠΈ λΆ€ν˜Έ μ—†λŠ” μ •μˆ˜

ν”„λ¦¬λ―Έν‹°λΈŒ νƒ€μž…

μƒμˆ˜μ˜λ―Έ
gl.POINTS점
gl.LINESμ„ 
gl.LINE_STRIPμ—°κ²°λœ μ„ 
gl.TRIANGLESμ‚Όκ°ν˜•
gl.TRIANGLE_STRIPμ‚Όκ°ν˜• 슀트립
gl.TRIANGLE_FANμ‚Όκ°ν˜• 팬

버퍼 μ΄ˆκΈ°ν™”

μƒμˆ˜μ˜λ―Έ
gl.COLOR_BUFFER_BIT색상 버퍼
gl.DEPTH_BUFFER_BIT깊이 버퍼
gl.STENCIL_BUFFER_BITμŠ€ν…μ‹€ 버퍼

μ—¬λŸ¬ 개λ₯Ό λ™μ‹œμ— μ‚¬μš©ν•  μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€.

gl.clear(
    gl.COLOR_BUFFER_BIT |
    gl.DEPTH_BUFFER_BIT
);

WebGL2μ—μ„œ μΆ”κ°€λœ λŒ€ν‘œμ μΈ μƒμˆ˜

μƒμˆ˜μ˜λ―Έ
gl.TEXTURE_3D3차원 ν…μŠ€μ²˜
gl.TEXTURE_2D_ARRAYν…μŠ€μ²˜ λ°°μ—΄
gl.RGBA32F32λΉ„νŠΈ λΆ€λ™μ†Œμˆ˜μ  ν…μŠ€μ²˜
gl.SAMPLER_2Dν…μŠ€μ²˜ μƒ˜ν”ŒλŸ¬
gl.UNIFORM_BUFFERUniform Buffer Object
gl.TRANSFORM_FEEDBACKTransform Feedback
gl.DRAW_FRAMEBUFFERλ“œλ‘œμš° ν”„λ ˆμž„λ²„νΌ
gl.READ_FRAMEBUFFER읽기 ν”„λ ˆμž„λ²„νΌ

μš”μ•½

ν˜•νƒœλΆ„λ₯˜μ—­ν• 
gl.clear()MethodGPU에 λͺ…령을 전달
gl.createBuffer()Method객체 생성
gl.drawArrays()Methodλ Œλ”λ§ μˆ˜ν–‰
gl.ARRAY_BUFFERConstant버퍼 μ’…λ₯˜ μ§€μ •
gl.TRIANGLESConstantλ Œλ”λ§ 방식 μ§€μ •
gl.FLOATConstant데이터 νƒ€μž… μ§€μ •
gl.COLOR_BUFFER_BITConstant버퍼 선택

WebGL은 μƒνƒœ 기반(State Machine) APIμž…λ‹ˆλ‹€. λ©”μ„œλ“œλŠ” GPU의 μƒνƒœλ₯Ό λ³€κ²½ν•˜κ±°λ‚˜ λͺ…령을 μˆ˜ν–‰ν•˜λ©°, μƒμˆ˜λŠ” κ·Έ λ™μž‘μ˜ λŒ€μƒκ³Ό 방식, 데이터 ν˜•μ‹μ„ μ§€μ •ν•©λ‹ˆλ‹€. λ”°λΌμ„œ λŒ€λΆ€λΆ„μ˜ WebGL μ½”λ“œλŠ” λ‹€μŒκ³Ό 같은 ꡬ쑰λ₯Ό λ°˜λ³΅ν•˜κ²Œ λ©λ‹ˆλ‹€.

gl.λ©”μ„œλ“œ(μƒμˆ˜, μƒμˆ˜, κ°’, κ°’);

즉, λ©”μ„œλ“œλŠ” "무엇을 ν•  것인가"λ₯Ό κ²°μ •ν•˜κ³ , μƒμˆ˜λŠ” "μ–΄λ–»κ²Œ ν•  것인가"λ₯Ό μ •μ˜ν•©λ‹ˆλ‹€. 이 ꡬ쑰λ₯Ό μ΄ν•΄ν•˜λ©΄ λ³΅μž‘ν•΄ λ³΄μ΄λŠ” WebGL API도 μΌκ΄€λœ νŒ¨ν„΄μœΌλ‘œ 해석할 수 μžˆμŠ΅λ‹ˆλ‹€.

profile
Coding Art with Blender / oF / Processing / p5.js / nannou

0개의 λŒ“κΈ€