ãã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯ã§WebGLã®ããã©ãŒãã³ã¹ãæå€§åãã¹ã ãŒãºãªã¢ãã¡ãŒã·ã§ã³ãé«åºŠãªããŒãã£ã¯ã«ã·ã¹ãã ãå¹ççãªããŒã¿åŠçã®ããã«é ç¹ãã£ããã£ãæé©åããæ¹æ³ãåŠã³ãŸãããã
WebGLãã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯ã®ããã©ãŒãã³ã¹ïŒé ç¹ãã£ããã£ã®æé©å
WebGLã®ãã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯æ©èœã¯ãé ç¹ã·ã§ãŒããŒåŠçã®çµæãé ç¹ãããã¡ãªããžã§ã¯ãïŒVBOïŒã«ãã£ããã£ããŠæ»ãããã®åŒ·åãªã¡ã«ããºã ãæäŸããŸããããã«ãããè€éãªããŒãã£ã¯ã«ã·ã¹ãã ãã¹ã±ã«ã¿ã«ã¢ãã¡ãŒã·ã§ã³ã®æŽæ°ãæ±çšGPUïŒGPGPUïŒèšç®ãªã©ãå¹ åºãé«åºŠãªã¬ã³ããªã³ã°æè¡ãå¯èœã«ãªããŸããããããäžé©åã«å®è£ ããããã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯ã¯ãããã«ããã©ãŒãã³ã¹ã®ããã«ããã¯ã«ãªãå¯èœæ§ããããŸãããã®èšäºã§ã¯ãWebGLã¢ããªã±ãŒã·ã§ã³ã®å¹çãæå€§åããããã«ãé ç¹ãã£ããã£ãæé©åããæŠç¥ã«ã€ããŠè©³ãã解説ããŸãã
ãã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯ãçè§£ãã
ãã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯ã¯ãæ¬è³ªçã«é ç¹ã·ã§ãŒããŒã®åºåããèšé²ãããããšãå¯èœã«ããŸãã倿ãããé ç¹ãã©ã¹ã¿ã©ã€ãºããŠæçµçã«è¡šç€ºããããã«ã¬ã³ããªã³ã°ãã€ãã©ã€ã³ã«éãã ãã§ãªããåŠçãããé ç¹ããŒã¿ãVBOã«ãªãã€ã¬ã¯ãããŠæ»ãããšãã§ããŸãããã®VBOã¯ãåŸç¶ã®ã¬ã³ããªã³ã°ãã¹ãä»ã®èšç®ã§äœ¿çšå¯èœã«ãªããŸããããã¯ãGPUäžã§å®è¡ãããé«åºŠã«äžŠååãããèšç®ã®åºåããã£ããã£ãããã®ãšèããŠãã ããã
ç°¡åãªäŸãšããŠãããŒãã£ã¯ã«ã·ã¹ãã å ã®ããŒãã£ã¯ã«ã®äœçœ®ãæŽæ°ããå ŽåãèããŠã¿ãŸããããåããŒãã£ã¯ã«ã®äœçœ®ãé床ããã®ä»ã®å±æ§ã¯é ç¹å±æ§ãšããŠæ ŒçŽãããŸããåŸæ¥ã®ã¢ãããŒãã§ã¯ããããã®å±æ§ãCPUã«èªã¿æ»ããããã§æŽæ°ããŠãããã¬ã³ããªã³ã°ã®ããã«GPUã«éãè¿ãå¿ èŠããã£ããããããŸããããã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯ã¯ãGPUãVBOå ã®ããŒãã£ã¯ã«å±æ§ãçŽæ¥æŽæ°ã§ããããã«ããããšã§ãCPUã®ããã«ããã¯ãæé€ããŸãã
äž»èŠãªããã©ãŒãã³ã¹èæ ®äºé
ããã€ãã®èŠå ããã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯ã®ããã©ãŒãã³ã¹ã«åœ±é¿ããŸãããããã®èæ ®äºé ã«å¯ŸåŠããããšã¯ãæé©ãªçµæãéæããããã«äžå¯æ¬ ã§ãã
- ããŒã¿ãµã€ãºïŒãã£ããã£ãããããŒã¿ã®éã¯ãããã©ãŒãã³ã¹ã«çŽæ¥åœ±é¿ããŸãã倧ããªé ç¹å±æ§ã倿°ã®é ç¹ã¯ãåœç¶ãªããããå€ãã®åž¯åå¹ ãšåŠçèœåãå¿ èŠãšããŸãã
- ããŒã¿ã¬ã€ã¢ãŠãïŒVBOå ã®ããŒã¿ã®æ§æã¯ãèªã¿æžãã®ããã©ãŒãã³ã¹ã«å€§ãã圱é¿ããŸããã€ã³ã¿ãŒãªãŒããããé åãšåå¥ã®é åãããŒã¿ã®ã¢ã©ã€ã¡ã³ããããã³å šäœçãªã¡ã¢ãªã¢ã¯ã»ã¹ãã¿ãŒã³ã¯éåžžã«éèŠã§ãã
- ã·ã§ãŒããŒã®è€éãïŒé ç¹ã·ã§ãŒããŒã®è€éãã¯ãåé ç¹ã®åŠçæéã«çŽæ¥åœ±é¿ããŸããè€éãªèšç®ã¯ãã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯ã®ããã»ã¹ãé ãããŸãã
- ãããã¡ãªããžã§ã¯ã管çïŒãããã¡ããŒã¿ãã©ã°ã®é©åãªäœ¿çšãå«ãVBOã®å¹ççãªå²ãåœãŠãšç®¡çã¯ããªãŒããŒããããåæžããå šäœçãªããã©ãŒãã³ã¹ãåäžãããããšãã§ããŸãã
- åæïŒCPUãšGPUéã®äžé©åãªåæã¯ãã¹ããŒã«ãåŒãèµ·ãããããã©ãŒãã³ã¹ã«æªåœ±é¿ãäžããå¯èœæ§ããããŸãã
é ç¹ãã£ããã£ã®æé©åæŠç¥
ããã§ã¯ããã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯ã䜿çšããŠWebGLã§ã®é ç¹ãã£ããã£ãæé©åããããã®å®è·µçãªãã¯ããã¯ãæ¢ã£ãŠã¿ãŸãããã
1. ããŒã¿è»¢éã®æå°å
æãåºæ¬çãªæé©åã¯ããã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯äžã«è»¢éãããããŒã¿éãæžããããšã§ããããã«ã¯ããã£ããã£ããå¿ èŠã®ããé ç¹å±æ§ãæ éã«éžæãããã®ãµã€ãºãæå°éã«æããããšãå«ãŸããŸãã
äŸïŒåããŒãã£ã¯ã«ãåæã«äœçœ®ïŒx, y, zïŒãé床ïŒx, y, zïŒãè²ïŒr, g, bïŒã寿åœã®å±æ§ãæã€ããŒãã£ã¯ã«ã·ã¹ãã ãæ³åããŠãã ãããããŒãã£ã¯ã«ã®è²ãæéãšãšãã«äžå®ã§ããå Žåãããããã£ããã£ããå¿ èŠã¯ãããŸãããåæ§ã«ã寿åœãæžå°ããã ãã®å Žåãåæå¯¿åœãšçŸåšå¯¿åœãæ ŒçŽãã代ããã«*æ®ãã®*寿åœãæ ŒçŽããããšãæ€èšããŠãã ãããããã«ãããæŽæ°ããã³è»¢éãå¿ èŠãªããŒã¿éãåæžãããŸãã
å®è·µçãªæŽå¯ïŒã¢ããªã±ãŒã·ã§ã³ããããã¡ã€ãªã³ã°ããŠãæªäœ¿çšãŸãã¯åé·ãªå±æ§ãç¹å®ããŸããããããæé€ããŠãããŒã¿è»¢éãšåŠçã®ãªãŒããŒããããåæžããŠãã ããã
2. ããŒã¿ã¬ã€ã¢ãŠãã®æé©å
VBOå ã®ããŒã¿ã®é 眮ã¯ãããã©ãŒãã³ã¹ã«å€§ãã圱é¿ããŸããåäžã®é ç¹ã®å±æ§ãã¡ã¢ãªå ã§é£ç¶ããŠæ ŒçŽãããã€ã³ã¿ãŒãªãŒãé åã¯ãç¹ã«é ç¹ã·ã§ãŒããŒå ã§è€æ°ã®å±æ§ã«ã¢ã¯ã»ã¹ããå Žåãåå¥ã®é åãããåªããããã©ãŒãã³ã¹ãæäŸããããšããããããŸãã
äŸïŒäœçœ®ãé床ãè²ã«åå¥ã®VBOã䜿çšãã代ããã«ïŒ
const positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);
const velocityBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, velocityBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(velocities), gl.STATIC_DRAW);
const colorBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);
ã€ã³ã¿ãŒãªãŒãé åã䜿çšããŸãïŒ
const interleavedBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, interleavedBuffer);
const vertexData = new Float32Array(numVertices * 9); // 3 (pos) + 3 (vel) + 3 (color) per vertex
for (let i = 0; i < numVertices; i++) {
vertexData[i * 9 + 0] = positions[i * 3 + 0];
vertexData[i * 9 + 1] = positions[i * 3 + 1];
vertexData[i * 9 + 2] = positions[i * 3 + 2];
vertexData[i * 9 + 3] = velocities[i * 3 + 0];
vertexData[i * 9 + 4] = velocities[i * 3 + 1];
vertexData[i * 9 + 5] = velocities[i * 3 + 2];
vertexData[i * 9 + 6] = colors[i * 3 + 0];
vertexData[i * 9 + 7] = colors[i * 3 + 1];
vertexData[i * 9 + 8] = colors[i * 3 + 2];
}
gl.bufferData(gl.ARRAY_BUFFER, vertexData, gl.STATIC_DRAW);
å®è·µçãªæŽå¯ïŒç¹å®ã®ãŠãŒã¹ã±ãŒã¹ã§ã©ã¡ããæãããã©ãŒãã³ã¹ãè¯ããã倿ããããã«ãç°ãªãããŒã¿ã¬ã€ã¢ãŠãïŒã€ã³ã¿ãŒãªãŒã vs. åå¥ïŒã詊ããŠãã ãããã·ã§ãŒããŒãè€æ°ã®é ç¹å±æ§ã«å€§ããäŸåããŠããå Žåã¯ãã€ã³ã¿ãŒãªãŒãã¬ã€ã¢ãŠããåªå ããŠãã ããã
3. é ç¹ã·ã§ãŒããŒããžãã¯ã®ç°¡çŽ å
è€éãªé ç¹ã·ã§ãŒããŒã¯ãç¹ã«å€æ°ã®é ç¹ãæ±ãå Žåã«ãé倧ãªããã«ããã¯ã«ãªãå¯èœæ§ããããŸããã·ã§ãŒããŒããžãã¯ãæé©åããããšã§ãããã©ãŒãã³ã¹ãåçã«åäžãããããšãã§ããŸãã
ãã¯ããã¯ïŒ
- èšç®ã®åæžïŒé ç¹ã·ã§ãŒããŒå ã§ã®ç®è¡æŒç®ããã¯ã¹ãã£ã«ãã¯ã¢ããããã®ä»ã®è€éãªèšç®ã®æ°ãæå°éã«æããŸããå¯èœã§ããã°ãCPUã§å€ãäºåèšç®ãããŠããã©ãŒã ãšããŠæž¡ããŸãã
- äœç²ŸåºŠã®äœ¿çšïŒå®å šãªç²ŸåºŠãå¿ èŠãªãèšç®ã«ã¯ãããäœã粟床ã®ããŒã¿åïŒäŸïŒ`mediump float`ãŸãã¯`lowp float`ïŒã䜿çšããããšãæ€èšããŠãã ãããããã«ãããåŠçæéãšã¡ã¢ãªåž¯åå¹ ãåæžã§ããŸãã
- å¶åŸ¡ãããŒã®æé©åïŒã·ã§ãŒããŒå ã§ã®æ¡ä»¶æïŒ`if`, `else`ïŒã®äœ¿çšãæå°éã«æããŸãããããã¯åå²ãåŒãèµ·ãããäžŠåæ§ãäœäžãããå¯èœæ§ããããŸãããã¯ãã«æŒç®ã䜿çšããŠãè€æ°ã®ããŒã¿ãã€ã³ãã§åæã«èšç®ãå®è¡ããŸãã
- ã«ãŒãã®ã¢ã³ããŒã«ïŒã«ãŒãã®ååŸ©åæ°ãã³ã³ãã€ã«æã«ããã£ãŠããå Žåãã«ãŒããã¢ã³ããŒã«ããããšã§ã«ãŒãã®ãªãŒããŒãããããªãããããã©ãŒãã³ã¹ãåäžãããããšãã§ããŸãã
äŸïŒåããŒãã£ã¯ã«ã«å¯ŸããŠé ç¹ã·ã§ãŒããŒå ã§é«äŸ¡ãªèšç®ãå®è¡ãã代ããã«ããããã®å€ãCPUã§äºåèšç®ãããŠããã©ãŒã ãšããŠæž¡ãããšãæ€èšããŠãã ããã
GLSLã³ãŒãäŸïŒéå¹çïŒïŒ
#version 300 es
in vec3 a_position;
uniform float u_time;
out vec3 v_newPosition;
void main() {
// Expensive calculation inside the vertex shader
float displacement = sin(a_position.x * u_time) * cos(a_position.y * u_time);
v_newPosition = a_position + vec3(displacement, displacement, displacement);
}
GLSLã³ãŒãäŸïŒæé©åæžã¿ïŒïŒ
#version 300 es
in vec3 a_position;
uniform float u_displacement;
out vec3 v_newPosition;
void main() {
// Displacement pre-calculated on the CPU
v_newPosition = a_position + vec3(u_displacement, u_displacement, u_displacement);
}
å®è·µçãªæŽå¯ïŒ `EXT_shader_timer_query`ã®ãããªWebGLæ¡åŒµæ©èœã䜿çšããŠé ç¹ã·ã§ãŒããŒããããã¡ã€ãªã³ã°ããããã©ãŒãã³ã¹ã®ããã«ããã¯ãç¹å®ããŸããäžèŠãªèšç®ãæå°éã«æããå¹çãåäžãããããã«ã·ã§ãŒããŒããžãã¯ããªãã¡ã¯ã¿ãªã³ã°ããŠãã ããã
4. ãããã¡ãªããžã§ã¯ãã®å¹ççãªç®¡ç
VBOã®é©åãªç®¡çã¯ãã¡ã¢ãªã¢ãã±ãŒã·ã§ã³ã®ãªãŒããŒããããé¿ããæé©ãªããã©ãŒãã³ã¹ã確ä¿ããããã«äžå¯æ¬ ã§ãã
ãã¯ããã¯ïŒ
- ãããã¡ãäºåã«ç¢ºä¿ããïŒåæåæã«äžåºŠã ãVBOãäœæããåŸç¶ã®ãã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯æäœã§åå©çšããŸãããããã¡ãç¹°ãè¿ãäœæããã³ç Žæ£ããããšã¯é¿ããŠãã ããã
- `gl.DYNAMIC_COPY`ãŸãã¯`gl.STREAM_COPY`ã䜿çšããïŒãã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯ã§VBOãæŽæ°ããéã`gl.bufferData`ãåŒã³åºããšãã«`gl.DYNAMIC_COPY`ãŸãã¯`gl.STREAM_COPY`ã®äœ¿çšãã³ãã䜿çšããŸãã`gl.DYNAMIC_COPY`ã¯ãããã¡ãç¹°ãè¿ã倿Žãããæç»ã«äœ¿çšãããããšã瀺ãã`gl.STREAM_COPY`ã¯ãããã¡ãäžåºŠæžã蟌ãŸããæ°åèªã¿åãããããšã瀺ããŸãã䜿çšãã¿ãŒã³ã«æãé©ãããã³ããéžæããŠãã ããã
- ããã«ãããã¡ãªã³ã°ïŒ2ã€ã®VBOã䜿çšããèªã¿åããšæžã蟌ã¿ã亀äºã«è¡ããŸããäžæ¹ã®VBOãã¬ã³ããªã³ã°ãããŠããéã«ãããäžæ¹ããã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯ã§æŽæ°ãããŸããããã«ãããã¹ããŒã«ãæžãããå šäœçãªããã©ãŒãã³ã¹ãåäžãããããšãã§ããŸãã
äŸïŒããã«ãããã¡ãªã³ã°ïŒïŒ
let vbo1 = gl.createBuffer();
let vbo2 = gl.createBuffer();
let currentVBO = vbo1;
let nextVBO = vbo2;
function updateAndRender() {
// Transform feedback to nextVBO
gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, nextVBO);
gl.beginTransformFeedback(gl.POINTS);
// ... rendering code ...
gl.endTransformFeedback();
gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, null);
// Render using currentVBO
gl.bindBuffer(gl.ARRAY_BUFFER, currentVBO);
// ... rendering code ...
// Swap buffers
let temp = currentVBO;
currentVBO = nextVBO;
nextVBO = temp;
requestAnimationFrame(updateAndRender);
}
å®è·µçãªæŽå¯ïŒç¹ã«åçãªããŒã¿æŽæ°ã®ããã«ãã¹ããŒã«ãæå°éã«æããããã©ãŒãã³ã¹ãåäžãããããã«ãããã«ãããã¡ãªã³ã°ãä»ã®ãããã¡ç®¡çæŠç¥ãå®è£ ããŠãã ããã
5. åæã®èæ ®äºé
CPUãšGPUéã®é©åãªåæã¯ãã¹ããŒã«ãé¿ããããŒã¿ãå¿ èŠãªãšãã«å©çšå¯èœã§ããããšãä¿èšŒããããã«äžå¯æ¬ ã§ããäžé©åãªåæã¯ãå€§å¹ ãªããã©ãŒãã³ã¹äœäžã«ã€ãªããå¯èœæ§ããããŸãã
ãã¯ããã¯ïŒ
- ã¹ããŒã«ã®åé¿ïŒçµ¶å¯Ÿã«å¿ èŠãªå Žåãé€ããGPUããCPUã«ããŒã¿ãèªã¿æ»ãããšã¯é¿ããŠãã ãããGPUããããŒã¿ãèªã¿æ»ãããšã¯é ãæäœã§ãããé倧ãªã¹ããŒã«ãåŒãèµ·ããå¯èœæ§ããããŸãã
- ãã§ã³ã¹ãšã¯ãšãªã®äœ¿çšïŒWebGLã¯ããã§ã³ã¹ãã¯ãšãªãªã©ãCPUãšGPUéã®æäœãåæããããã®ã¡ã«ããºã ãæäŸããŸãããããã䜿çšããŠãæŽæ°ãããããŒã¿ã䜿çšããããšããåã«ããã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯æäœãå®äºãããã©ããã倿ã§ããŸãã
- `gl.finish()`ãš`gl.flush()`ã®æå°åïŒãããã®ã³ãã³ãã¯ãGPUã«ä¿çäžã®ãã¹ãŠã®æäœãå®äºãããããšã匷å¶ããã¹ããŒã«ãåŒãèµ·ããå¯èœæ§ããããŸãã絶察ã«å¿ èŠãªå Žåãé€ãã䜿çšãé¿ããŠãã ããã
å®è·µçãªæŽå¯ïŒã¹ããŒã«ãé¿ããæé©ãªããã©ãŒãã³ã¹ã確ä¿ããããã«ãCPUãšGPUéã®åæãæ éã«ç®¡çããŠãã ããããã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯æäœã®å®äºã远跡ããããã«ããã§ã³ã¹ãšã¯ãšãªã掻çšããŠãã ããã
å®è·µçãªäŸãšãŠãŒã¹ã±ãŒã¹
ãã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯ã¯ãããŸããŸãªã·ããªãªã§äŸ¡å€ããããŸãã以äžã«ããã€ãã®åœéçãªäŸãæããŸãïŒ
- ããŒãã£ã¯ã«ã·ã¹ãã ïŒç ãç«ãæ°Žãªã©ã®è€éãªããŒãã£ã¯ã«ãšãã§ã¯ãã®ã·ãã¥ã¬ãŒã·ã§ã³ããã¹ããªç«å±±ïŒã€ã¿ãªã¢ïŒã®ãªã¢ã«ãªç«å±±ç°ã·ãã¥ã¬ãŒã·ã§ã³ãäœæãããããµãã©ç æŒ ïŒåã¢ããªã«ïŒã®ç åµãã·ãã¥ã¬ãŒããããããããšãæ³åããŠã¿ãŠãã ããã
- ã¹ã±ã«ã¿ã«ã¢ãã¡ãŒã·ã§ã³ïŒã¹ã±ã«ã¿ã«ã¢ãã¡ãŒã·ã§ã³ã®ããã«ããŒã³ãããªãã¯ã¹ããªã¢ã«ã¿ã€ã ã§æŽæ°ããŸããããã¯ãã²ãŒã ãã€ã³ã¿ã©ã¯ãã£ãã¢ããªã±ãŒã·ã§ã³ã§ãªã¢ã«ãªãã£ã©ã¯ã¿ãŒã®åããäœæããããã«äžå¯æ¬ ã§ããäŸãã°ãããŸããŸãªæåã®äŒçµ±çãªèžãïŒãã©ãžã«ã®ãµã³ããã€ã³ãã®ããªãŠãããã³ã¹ãªã©ïŒãèžããã£ã©ã¯ã¿ãŒãã¢ãã¡ãŒã·ã§ã³åãããªã©ã§ãã
- æµäœååŠïŒãªã¢ã«ãªæ°Žãã¬ã¹ã®ãšãã§ã¯ãã®ããã«æµäœã®åããã·ãã¥ã¬ãŒã·ã§ã³ããŸããããã¯ãã¬ã©ããŽã¹è«žå³¶ïŒãšã¯ã¢ãã«ïŒåšèŸºã®æµ·æµãå¯èŠåããããèªç©ºæ©èšèšã®ããã«é¢šæŽå ã®æ°æµãã·ãã¥ã¬ãŒããããããã®ã«äœ¿çšã§ããŸãã
- GPGPUèšç®ïŒç»ååŠçãç§åŠã·ãã¥ã¬ãŒã·ã§ã³ãæ©æ¢°åŠç¿ã¢ã«ãŽãªãºã ãªã©ãGPUã§æ±çšèšç®ãå®è¡ããŸããç°å¢ã¢ãã¿ãªã³ã°ã®ããã«äžçäžã®è¡æç»åãåŠçããããšãªã©ãèããŠã¿ãŠãã ããã
çµè«
ãã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯ã¯ãWebGLã¢ããªã±ãŒã·ã§ã³ã®ããã©ãŒãã³ã¹ãšèœåãåäžãããããã®åŒ·åãªããŒã«ã§ãããã®èšäºã§è°è«ããèŠå ãæ éã«èæ ®ããæŠèª¬ããæé©åæŠç¥ãå®è£ ããããšã§ãé ç¹ãã£ããã£ã®å¹çãæå€§åããèŠäºã§ã€ã³ã¿ã©ã¯ãã£ããªäœéšãåµé ããããã®æ°ããªå¯èœæ§ãåãéãããšãã§ããŸããããã©ãŒãã³ã¹ã®ããã«ããã¯ãç¹å®ããæé©åãã¯ããã¯ãæŽç·Žãããããã«ã宿çã«ã¢ããªã±ãŒã·ã§ã³ããããã¡ã€ãªã³ã°ããããšãå¿ããªãã§ãã ããã
ãã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯ã®æé©åãç¿åŸããããšã§ãäžçäžã®éçºè ãããæŽç·Žããã髿§èœãªWebGLã¢ããªã±ãŒã·ã§ã³ãäœæã§ããããã«ãªããç§åŠçå¯èŠåããã²ãŒã éçºãŸã§ãããŸããŸãªé åã§ããè±ããªãŠãŒã¶ãŒäœéšãå¯èœã«ãªããŸãã