WebGLãã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯ã«ããé«åºŠãªé ç¹åŠçãšããŒã¿ãã£ããã£ãæ¢æ±ããŸããå®è·µäŸã亀ããWebGLã¢ããªãæé©åããæ¹æ³ãåŠã³ãŸãããã
WebGLãã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯ïŒé ç¹åŠçãšããŒã¿ãã£ããã£
WebGL (Web Graphics Library)ã¯ããã©ã°ã€ã³ã䜿çšããã«ãŠã§ããã©ãŠã¶ã§2Dããã³3Dã°ã©ãã£ãã¯ã¹ãã¬ã³ããªã³ã°ããããã®åŒ·åãªAPIãæäŸããŸããWebGL 1.0ã¯ã°ã©ãã£ãã¯ã¹ããã°ã©ãã³ã°ã®å åºãªåºç€ãæäŸããŸããããWebGL 2.0ã§ã¯ãã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯ãå«ãããã€ãã®éèŠãªæ©èœåŒ·åãå°å ¥ãããŸããããã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯ã¯ãã·ã§ãŒããŒãé ç¹ããŒã¿ãåŸç¶ã®åŠç段éã®ããã«ãããã¡ã«æžãæ»ãããšãå¯èœã«ããã¡ã«ããºã ã§ãããã®æ©èœã«ãããå¹ åºãé«åºŠãªã¬ã³ããªã³ã°æè¡ãããŒã¿æäœæŠç¥ãå®çŸå¯èœã«ãªããWebGLã¢ããªã±ãŒã·ã§ã³ã®ããã©ãŒãã³ã¹ãšæè»æ§ãå€§å¹ ã«åäžããŸãã
ãã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯ãçè§£ãã
ãã®æ žå¿ã«ãããŠããã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯ã¯ãé ç¹ã·ã§ãŒããŒã«ãã£ãŠåŠçãããåŸã®é ç¹ããŒã¿ããã£ããã£ããããšãå¯èœã«ããŸãã倿ãããé ç¹ãåã«ç»é¢ã«ã¬ã³ããªã³ã°ããã®ã§ã¯ãªããé ç¹ã·ã§ãŒããŒã¯ãã®ããŒã¿ã1ã€ä»¥äžã®ãããã¡ãªããžã§ã¯ãã«åºåã§ããŸãããããã®ãããã¡ã¯ããããªãã¬ã³ããªã³ã°ãã¹ãä»ã®èšç®ã¿ã¹ã¯ã®å ¥åãšããŠäœ¿çšã§ããŸãããã®ããã»ã¹ã«ãããå埩çãªé ç¹åŠçãããŒãã£ã¯ã«ã·ã¹ãã ã·ãã¥ã¬ãŒã·ã§ã³ããã®ä»WebGL 1.0ã§ã¯å®è£ ãå°é£ãŸãã¯éå¹ççã ã£ãæ§ã ãªè€éãªãšãã§ã¯ããå¯èœã«ãªããŸãã
åŸæ¥ã®ã¬ã³ããªã³ã°ãã€ãã©ã€ã³ vs. ãã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯
ãã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯ã䜿çšããªãåŸæ¥ã®ã¬ã³ããªã³ã°ãã€ãã©ã€ã³ã§ã¯ãé ç¹ããŒã¿ã¯CPUããGPUã«æµããé ç¹ã·ã§ãŒããŒã§åŠçãããåŸããã¯ã»ã«åŠçã®ããã«ãã©ã°ã¡ã³ãã«ã©ã¹ã¿ã©ã€ãºãããŸããæçµçãªåºåã¯ç»é¢ã«è¡šç€ºããããããã¬ãŒã ãããã¡ãªããžã§ã¯ãïŒFBOïŒã«ã¬ã³ããªã³ã°ãããŸãããã®ãã€ãã©ã€ã³ã¯äž»ã«äžæ¹åã§ãããGPUããCPUãžã®ãã£ãŒãããã¯ã¯éå®çã§ãããã¬ãŒã ãããã¡ãããã¯ã»ã«ããŒã¿ãèªã¿æ»ãããšã¯å¯èœã§ãããäžéã®é ç¹ããŒã¿ã«ã¢ã¯ã»ã¹ããã®ã¯ç°¡åã§ã¯ãããŸããã
ãã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯ã¯ãé ç¹ã·ã§ãŒããŒæ®µéã®åŸã«é ç¹ããŒã¿ããããã¡ãªããžã§ã¯ãã«æžãæ»ãããçµè·¯ãå°å ¥ããããšã§ããã®ã¢ãã«ã倿ŽããŸããããã«ãããããåçã§å埩çãªé ç¹åŠçãå¯èœã«ãªããŸããé³¥ã®çŸ€ããã·ãã¥ã¬ãŒãããããšãæ³åããŠã¿ãŠãã ãããåŸæ¥ã®æ¹æ³ã§ã¯ãåé³¥ã®äœçœ®ãCPUã§èšç®ããæ¯ãã¬ãŒã GPUã«éä¿¡ããå¿ èŠããããŸããããã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯ã䜿ãã°ãGPUã¯éåãåŒåãæ¥åãªã©ã®åã«åºã¥ããŠé³¥ã®äœçœ®ãæŽæ°ããæ°ããäœçœ®ããããã¡ã«ä¿åã§ããŸããæ¬¡ã®ãã¬ãŒã ã§ã¯ããããã®æŽæ°ãããäœçœ®ãéå§ç¹ãšããŠäœ¿çšãããã·ãã¥ã¬ãŒã·ã§ã³ãå®å šã«GPUäžã§å®è¡ãããããã«ãªããŸãã
WebGLã§ãã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯ãèšå®ãã
ãã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯ã®äœ¿çšã«ã¯ãããã€ãã®äž»èŠãªã¹ããããå«ãŸããŸãïŒ
- ãããã¡ãªããžã§ã¯ãã®äœæãšãã€ã³ãïŒ é ç¹ã·ã§ãŒããŒã®åºåãä¿åããããã®ãããã¡ãªããžã§ã¯ããäœæããå¿ èŠããããŸãããããã®ãããã¡ã¯ã倿ããããã¹ãŠã®é ç¹ããŒã¿ãå容ããã®ã«ååãªå€§ããã§ãªããã°ãªããŸããã
- ãã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯ã®varying倿°ã®æå®ïŒ ã©ã®é ç¹ã·ã§ãŒããŒåºåããã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯ã§ãã£ããã£ããããWebGLã«éç¥ããå¿
èŠããããŸããããã¯
gl.transformFeedbackVaryings()颿°ã䜿çšããŠè¡ããŸãããã®é¢æ°ã¯ãèšé²ãã¹ãvarying倿°åïŒé ç¹ã·ã§ãŒããŒã§outããŒã¯ãŒãã§å®£èšããã倿°ïŒã®ãªã¹ããåãåããŸãã - ãã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯ãªããžã§ã¯ãã®äœæãšäœ¿çšïŒ ãã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯ãªããžã§ã¯ãã¯ããã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯æäœã®ç¶æ
ãã«ãã»ã«åããŸãã
gl.createTransformFeedback()ã§äœæãããgl.bindTransformFeedback()ã§ãã€ã³ããããŸãã - ãã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯ã®éå§ãšçµäºïŒ ãã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯æäœã¯
gl.beginTransformFeedback()ã§éå§ãããgl.endTransformFeedback()ã§çµäºããŸãã - ããªããã£ãã®æç»ïŒ æç»ã³ãã³ãïŒäŸïŒ
gl.drawArrays(),gl.drawElements()ïŒã¯é ç¹ã·ã§ãŒããŒãå®è¡ããæå®ãããvarying倿°ã®åºåããã€ã³ãããããããã¡ãªããžã§ã¯ãã«ãã£ããã£ããŸãã
ã³ãŒãäŸ
ãããã®ã¹ããããç°¡ç¥åãããã³ãŒãäŸã§ç€ºããŸãããïŒ
// Vertex Shader
const vertexShaderSource = `#version 300 es
in vec4 a_position;
out vec4 v_position;
void main() {
v_position = a_position + vec4(0.1, 0.0, 0.0, 0.0); // Example transformation
gl_Position = v_position;
}
`;
// Fragment Shader
const fragmentShaderSource = `#version 300 es
precision highp float;
out vec4 fragColor;
void main() {
fragColor = vec4(1.0, 0.0, 0.0, 1.0); // Red color
}
`;
// JavaScript code
const canvas = document.getElementById('glCanvas');
const gl = canvas.getContext('webgl2');
// ... (Shader compilation and program linking code - omitted for brevity) ...
const program = createProgram(gl, vertexShaderSource, fragmentShaderSource);
const positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
const positions = [
0.0, 0.0, 0.0,
0.5, 0.0, 0.0,
0.0, 0.5, 0.0
];
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);
const positionAttributeLocation = gl.getAttribLocation(program, 'a_position');
gl.enableVertexAttribArray(positionAttributeLocation);
gl.vertexAttribPointer(positionAttributeLocation, 3, gl.FLOAT, false, 0, 0);
// Create Transform Feedback buffer
const transformFeedbackBuffer = gl.createBuffer();
gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, transformFeedbackBuffer);
gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, new Float32Array(positions.length), gl.DYNAMIC_COPY);
// Create Transform Feedback object
const transformFeedback = gl.createTransformFeedback();
gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, transformFeedback);
gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, transformFeedbackBuffer); // Index 0
// Specify Transform Feedback varyings
const varyings = ['v_position'];
gl.transformFeedbackVaryings(program, varyings, gl.INTERLEAVED_ATTRIBS);
gl.linkProgram(program);
// Use the program
gl.useProgram(program);
// Begin Transform Feedback
gl.beginTransformFeedback(gl.TRIANGLES);
// Draw the primitives
gl.drawArrays(gl.TRIANGLES, 0, 3);
// End Transform Feedback
gl.endTransformFeedback();
// Unbind Transform Feedback buffer and object
gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, null);
gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, null);
// Read back the transformed data (optional)
const transformedPositions = new Float32Array(positions.length);
gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, transformFeedbackBuffer);
gl.getBufferSubData(gl.TRANSFORM_FEEDBACK_BUFFER, 0, transformedPositions);
console.log('Transformed positions:', transformedPositions);
ãã®äŸã¯ããã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯ã®åºæ¬çãªèšå®ã瀺ããŠããŸããé ç¹ã·ã§ãŒããŒã¯ãå
¥åãããé ç¹äœçœ®ã«åçŽã«å°ããªãªãã»ãããå ããŸãã倿ãããäœçœ®ã¯ãã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯ã«ãã£ãŠãã£ããã£ãããtransformFeedbackBufferã«ä¿åãããŸããgl.getBufferSubData颿°ã¯ãããŒã¿ãCPUã«èªã¿æ»ãããã®ãã¢ã³ã¹ãã¬ãŒã·ã§ã³ç®çã§ããã§äœ¿çšãããŠããŸããå®éã®ã¢ããªã±ãŒã·ã§ã³ã§ã¯ããã®ãããã¡ãåŸç¶ã®ã¬ã³ããªã³ã°ãã¹ã§çŽæ¥äœ¿çšããããšãå€ãã§ãããã
ãã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯ã®å®çšçãªå¿çš
ãã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯ã¯ãé«åºŠãªã¬ã³ããªã³ã°æè¡ãã·ãã¥ã¬ãŒã·ã§ã³ã«å€ãã®å¯èœæ§ãéããŸãã以äžã«ããã€ãã®æ³šç®ãã¹ãå¿çšäŸãæããŸãïŒ
- ããŒãã£ã¯ã«ã·ã¹ãã ïŒ åè¿°ã®éããããŒãã£ã¯ã«ã·ã¹ãã ã¯ãã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯ãèŒãå žåçãªäŸã§ããåããŒãã£ã¯ã«ã®äœçœ®ãé床ããã®ä»ã®å±æ§ã¯ãæ§ã ãªåãå¶çŽã«åºã¥ããŠGPUäžã§æŽæ°ã§ããŸããæŽæ°ãããããŒãã£ã¯ã«ããŒã¿ã¯ã次ã®ãã¬ãŒã ã§ããŒãã£ã¯ã«ãã¬ã³ããªã³ã°ããããã«äœ¿çšã§ããŸããè±ç«ãç ããããã¯ãªã¢ã«ãªæ°Žã®ãšãã§ã¯ããªã©ããã¹ãŠãGPUãšãã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯ã«ãã£ãŠé§åãããæ§åãæ³åããŠã¿ãŠãã ããã
- ã¡ãã·ã¥å€åœ¢ïŒ ãã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯ã¯ããªã¢ã«ã¿ã€ã ã§ã¡ãã·ã¥ãå€åœ¢ããããã«äœ¿çšã§ããŸããäŸãã°ãæ³¢ã®æ¹çšåŒã«åºã¥ããŠã¡ãã·ã¥ã®é ç¹äœçœ®ãæŽæ°ããããšã§ãæ°Žé¢ã®æ³¢ã®ã·ãã¥ã¬ãŒã·ã§ã³ãå®è£ ã§ããŸããå¥ã®å¿çšäŸãšããŠãã¹ã±ã«ã¿ã«ã¢ãã¡ãŒã·ã§ã³ããããŸããããã§ã¯ãããŒã³å€æãé©çšãããåŸã®æçµçãªé ç¹äœçœ®ãèšç®ããããã«ãã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯ã䜿çšã§ããŸãã
- è¡çªæ€åºïŒ 倿ãããé ç¹äœçœ®ããããã¡ã«æžã蟌ãããšã§ãGPUäžã§è¡çªæ€åºãå®è¡ã§ããŸããããã¯ã倿°ã®ãªããžã§ã¯ããé¢äžããã²ãŒã ãã·ãã¥ã¬ãŒã·ã§ã³ã§ç¹ã«åœ¹ç«ã¡ãŸããGPUã®äžŠååŠçèœåã¯ãCPUããŒã¹ã®æ¹æ³ãšæ¯èŒããŠè¡çªæ€åºãå€§å¹ ã«é«éåã§ããŸãã
- ãžãªã¡ããªçæïŒ ãã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯ã¯ãGPUäžã§æ°ãããžãªã¡ããªãçæããããã«äœ¿çšã§ããŸããäŸãã°ãäžè§åœ¢ãååž°çã«çްååãããã©ã¯ã¿ã«é¢æ°ã«åºã¥ããŠé ç¹ãå€äœãããããšã§ããã©ã¯ã¿ã«ãªå°åœ¢ãäœæã§ããŸãããã®æè¡ã¯ãæå°éã®CPUãªãŒããŒãããã§è€éã§è©³çްãªãžãªã¡ããªãäœæããããã«äœ¿çšã§ããŸãã
- ç©çã·ãã¥ã¬ãŒã·ã§ã³ïŒ ããŒãã£ã¯ã«ã·ã¹ãã ãè¶ ããŠããã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯ã¯ãåžãæµäœååŠã®ã·ãã¥ã¬ãŒã·ã§ã³ãªã©ãããäžè¬çãªç©çã·ãã¥ã¬ãŒã·ã§ã³ã«äœ¿çšã§ããŸããã·ãã¥ã¬ãŒã·ã§ã³ã®ç¶æ ïŒäŸïŒäœçœ®ãé床ãåïŒã¯ãããã¡ãªããžã§ã¯ãã«ä¿åãããã·ã§ãŒããŒã䜿çšããŠGPUäžã§æŽæ°ãããŸãã
æé©åæŠç¥
ãã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯ã¯å€§ããªããã©ãŒãã³ã¹äžã®å©ç¹ãæäŸããŸãããããã«ããã¯ãé¿ããããã«å¹ççã«äœ¿çšããããšãéèŠã§ãã以äžã«ããã€ãã®æé©åæŠç¥ãæããŸãïŒ
- ããŒã¿è»¢éã®æå°åïŒ CPUãšGPUéã®äžå¿ èŠãªããŒã¿è»¢éãé¿ããŠãã ãããå¯èœãªéãå€ãã®åŠçãGPUäžã§è¡ãããã«ããŠãã ããããã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯ãããã¡ããããŒã¿ãèªã¿æ»ãå¿ èŠãããå Žåã¯ãæ§ããã«è¡ã£ãŠãã ããã
- ã€ã³ã¿ãŒãªãŒãããã屿§ã®äœ¿çšïŒ ã€ã³ã¿ãŒãªãŒãããã屿§ã¯ãã¡ã¢ãªã¢ã¯ã»ã¹ã®åæ°ãæžããããšã§ããã©ãŒãã³ã¹ãåäžãããããšãã§ããŸããå屿§ãå¥ã ã®ãããã¡ã«ä¿åããã®ã§ã¯ãªããé ç¹ã®ãã¹ãŠã®å±æ§ãåäžã®é£ç¶ããã¡ã¢ãªãããã¯ã«ä¿åããŸãã
- ã·ã§ãŒããŒã³ãŒãã®æé©åïŒ é ç¹ã·ã§ãŒããŒã®ã³ãŒããããã©ãŒãã³ã¹ã®ããã«æé©åãããŠããããšã確èªããŠãã ãããè€éãªèšç®ã®äœ¿çšãæå°éã«æããäžèŠãªåå²ãé¿ããŠãã ãããã·ã§ãŒããŒã³ãŒãããããã¡ã€ãªã³ã°ããããšã§ãããã©ãŒãã³ã¹ã®ããã«ããã¯ãç¹å®ããã®ã«åœ¹ç«ã¡ãŸãã
- ãããã¡äœ¿çšæ³ã®æ€èšïŒ ãããã¡ãã©ã®ããã«äœ¿çšããããã«åºã¥ããŠãé©åãªãããã¡äœ¿çšæ³ãã©ã°ïŒäŸïŒ
gl.DYNAMIC_DRAW,gl.DYNAMIC_COPYïŒãéžæããŠãã ãããgl.DYNAMIC_COPYã¯ããããã¡ãGPUã«ãã£ãŠæžã蟌ãŸããCPUã«ãã£ãŠèªã¿åãããå¯èœæ§ãããããšã瀺ãããããã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯ãããã¡ã«é©ããŠããããšãå€ãã§ãã - ãã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯ã®varying倿°ã®æ°ãæžããïŒ ãã£ããã£ããvarying倿°ãå°ãªãã»ã©ããã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯æäœã¯é«éã«ãªããŸããåŸç¶ã®åŠç段éã§çµ¶å¯Ÿã«å¿ èŠãšãªãããŒã¿ã®ã¿ããã£ããã£ããŠãã ããã
ã¯ãã¹ãã©ãããã©ãŒã ã«é¢ããèæ ®äºé
ãã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯ã¯ãWebGL 2.0ããã³OpenGL ES 3.0ã®æ©èœã§ããã¿ãŒã²ãããã©ãããã©ãŒã ããããã®ããŒãžã§ã³ã®APIããµããŒãããŠããããšã確èªããŠãã ããããŠã§ãåãã«éçºããå Žåããã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯ã䜿çšããããšããåã«ãæ©èœæ€åºã䜿çšããŠWebGL 2.0ããµããŒããããŠãããã©ããã確èªããŠãã ãããæ¬¡ã®ãããªã³ãŒãã䜿çšã§ããŸãïŒ
const canvas = document.getElementById('glCanvas');
try {
const gl = canvas.getContext('webgl2');
if (!gl) {
throw new Error('WebGL 2.0 not supported.');
}
// WebGL 2.0 is supported
console.log('WebGL 2.0 is supported!');
} catch (e) {
console.error('Error initializing WebGL 2.0:', e);
// Fallback to WebGL 1.0 or display an error message
}
WebGL 2.0ãå©çšã§ããªãå Žåã¯ãWebGL 1.0ãä»ã®ã¬ã³ããªã³ã°æè¡ã䜿çšãããã©ãŒã«ããã¯ãœãªã¥ãŒã·ã§ã³ãæäŸã§ããŸãããã ãããã©ãŒã«ããã¯ãœãªã¥ãŒã·ã§ã³ã®ããã©ãŒãã³ã¹ãšæ©èœã¯ããã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯ãšæ¯èŒããŠå¶éãããå¯èœæ§ãããããšã«æ³šæããŠãã ããã
åºæ¬çãªäŸãè¶ ããŠïŒå®äžçã®å¿çšãšé«åºŠãªãã¯ããã¯
WebGLãã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯ã®åãšå€çšéæ§ã瀺ãããã«ãããå°ãè€éãªã·ããªãªãæãäžããŠã¿ãŸãããã
åãšå¶çŽãæã€é«åºŠãªããŒãã£ã¯ã«ã·ã¹ãã
åºæ¬çãªããŒãã£ã¯ã«ã·ã¹ãã ã®äŸãåºã«ãããæŽç·Žãããåãšå¶çŽãå°å ¥ããŠãèŠèŠçã«é åçã§ãªã¢ã«ãªãšãã§ã¯ããäœæã§ããŸããåžãã·ãã¥ã¬ãŒãããããŒãã£ã¯ã«ã·ã¹ãã ãèããŠã¿ãŸããããåããŒãã£ã¯ã«ã¯åžäžã®äžç¹ã衚ããããŒãã£ã¯ã«éã®æ¥ç¶ã¯åžã®ç¹ç¶ã衚ããŸããéåã颚ãè¡çªæ€åºãªã©ã®åãããŒãã£ã¯ã«ã«é©çšããåžã®åœ¢ç¶ãç¶æããããã®å¶çŽã課ãããšãã§ããŸãã
é ç¹ã·ã§ãŒããŒã§ã¯ããããã®èŠå ã«åºã¥ããŠåããŒãã£ã¯ã«ã«äœçšããååãèšç®ããŸããããŒãã£ã¯ã«ã®æ°ããé床ã¯ãåãæéã§ç©åããããšã«ãã£ãŠèšç®ãããŸããæ¬¡ã«ãæ°ããäœçœ®ã¯é床ãç©åããããšã«ãã£ãŠèšç®ãããŸããæ¥ç¶ãããããŒãã£ã¯ã«éã®è·é¢ãç¹å®ã®ç¯å²å ã«çãŸãããã«ãå¶çŽãé©çšãããŸãããã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯ã¯ãæŽæ°ãããäœçœ®ãšéåºŠãæ¬¡ã®ãã¬ãŒã ã®ã·ãã¥ã¬ãŒã·ã§ã³ã®ããã«ãããã¡ãªããžã§ã¯ãã«æžãæ»ãããã«äœ¿çšãããŸãã
GPUããŒã¹ã®æµäœååŠ
GPUäžã§æµäœååŠãã·ãã¥ã¬ãŒãããããšã¯ãææŠçã§ããããããã®ããã¿ã¹ã¯ã§ãããã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯ã¯ããã®ããã»ã¹ã§éèŠãªåœ¹å²ãæããããšãã§ããŸããäžè¬çãªã¢ãããŒãã®1ã€ã¯ãå¹³æ»åç²åæµäœååŠïŒSPHïŒæ³ã䜿çšããããšã§ããSPHã§ã¯ãæµäœã¯ç²åã®éåãšããŠè¡šçŸãããæµäœã®ç¹æ§ïŒäŸïŒå¯åºŠãå§åãé床ïŒã¯ãåç²åã®äœçœ®ã§ãã®è¿åã®ç²åã®ç¹æ§ã«åºã¥ããŠèšç®ãããŸãã
é ç¹ã·ã§ãŒããŒã¯SPHèšç®ãå®è¡ããŸããè¿åã®ç²åïŒç©ºéå岿è¡ã䜿çšããŠå¹ççã«æ±ºå®ã§ããïŒãå埩åŠçããåç²åã«äœçšããå¯åºŠãå§åãåãèšç®ããããã«å¿ããŠç²åã®äœçœ®ãšéåºŠãæŽæ°ããŸãããã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯ã¯ãæŽæ°ãããç²åããŒã¿ã次ã®ã·ãã¥ã¬ãŒã·ã§ã³ã¹ãããã®ããã«ãããã¡ãªããžã§ã¯ãã«æžãæ»ãããã«äœ¿çšãããŸããæµäœã®ã¬ã³ããªã³ã°ã¯ãç²åãå°ããªçãšããŠæç»ããããç²åããŒã¿ããæ»ãããªè¡šé¢ãäœæããããã®è¡šé¢åæ§ç¯æè¡ã䜿çšããããšã§è¡ããŸãã
ãªã¢ã«ã¿ã€ã ã®å°åœ¢çæãšå€æŽ
ãã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯ã¯ããªã¢ã«ã¿ã€ã ã§å°åœ¢ãäœæããã³å€æŽããããã«äœ¿çšã§ããŸãã1ã€ã®ã¢ãããŒãã¯ãå°åœ¢ã衚ãåçŽãªé ç¹ã®ã°ãªããããå§ããããšã§ããé ç¹ã·ã§ãŒããŒã䜿çšããŠããã€ããããããã©ã¯ã¿ã«é¢æ°ã«åºã¥ããŠé ç¹ãå€äœããããããªã¢ã«ãªå°åœ¢ãäœæã§ããŸãããã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯ã䜿çšããŠãå€äœããé ç¹äœçœ®ããããã¡ãªããžã§ã¯ãã«æžãæ»ãããšãã§ããŸãã
å°åœ¢ã¯ã浞é£ãã·ãã¥ã¬ãŒãããããæ€çã远å ããããã¯ã¬ãŒã¿ãŒãäœæãããããããšã§ããã«å€æŽã§ããŸãããããã®å€æŽã¯é ç¹ã·ã§ãŒããŒã§å®è¡ããããã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯ã䜿çšããŠãããã¡ãªããžã§ã¯ãã«æžãæ»ãããŸããããã«ããããªã¢ã«ã¿ã€ã ã§å€æŽå¯èœãªåçã§ã€ã³ã¿ã©ã¯ãã£ããªå°åœ¢ãå¯èœã«ãªããŸãã
ã€ã³ã¿ã©ã¯ãã£ããªã¡ãã·ã¥ã¹ã«ã«ããã£ã³ã°
å°åœ¢ã®å€æŽãšåæ§ã«ããã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯ã¯ã€ã³ã¿ã©ã¯ãã£ããªã¡ãã·ã¥ã¹ã«ã«ããã£ã³ã°ãå®è£ ããããã«äœ¿çšã§ããŸãããŠãŒã¶ãŒã¯ããŠã¹ãä»ã®å ¥åããã€ã¹ã䜿çšããŠã¡ãã·ã¥ãšå¯Ÿè©±ããé ç¹ã·ã§ãŒããŒã¯ãŠãŒã¶ãŒã®å ¥åã«åºã¥ããŠã¡ãã·ã¥ãå€åœ¢ãããããã«äœ¿çšã§ããŸããäŸãã°ããŠãŒã¶ãŒã¯ã¡ãã·ã¥ã®è¡šé¢äžã§ä»®æ³ãã©ã·ããã©ãã°ãããã©ã·ã®ååŸå ã®é ç¹ãå€äœãããããŸãããã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯ã¯ãå€åœ¢ããé ç¹äœçœ®ããããã¡ãªããžã§ã¯ãã«æžãæ»ãããã«äœ¿çšããã倿Žããªã¢ã«ã¿ã€ã ã§ã¬ã³ããªã³ã°ãããããã«ãªããŸãã
ãããã°ãšãã©ãã«ã·ã¥ãŒãã£ã³ã°
ãã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯ã®ãããã°ã¯é£ããå ŽåããããŸãããäžè¬çãªåé¡ããã©ãã«ã·ã¥ãŒãã£ã³ã°ããããã®ãã³ããããã€ã玹ä»ããŸãïŒ
- ãšã©ãŒã®ç¢ºèªïŒ ååŒã³åºãã®åŸã«åžžã«WebGLã®ãšã©ãŒã確èªããŠãã ãããçºçããå¯èœæ§ã®ãããšã©ãŒãååŸããã«ã¯
gl.getError()ã䜿çšããŸãã - ãããã¡ãµã€ãºã®æ€èšŒïŒ ãã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯ãããã¡ãã倿ããããã¹ãŠã®é ç¹ããŒã¿ãå容ããã®ã«ååãªå€§ããã§ããããšã確èªããŠãã ããããããã¡ãå°ãããããšããŒã¿ãåãæšãŠãããäºæããªãçµæã«ã€ãªãããŸãã
- varyingåã®æ€æ»ïŒ
gl.transformFeedbackVaryings()ã§æå®ãããvaryingåããé ç¹ã·ã§ãŒããŒã®åºå倿°ãšå®å šã«äžèŽããŠããããšãå確èªããŠãã ããã倧æåãšå°æåã®åºå¥ã¯éèŠã§ãïŒ - ãããã¬ã®äœ¿çšïŒ WebGLãããã¬ïŒSpector.jsãChromeãŸãã¯Firefoxã®çµã¿èŸŒã¿ãããã¬ãªã©ïŒã䜿çšããŠãWebGLããã°ã©ã ã®ç¶æ ãæ€æ»ããåé¡ãç¹å®ããŸãã
- ã·ã§ãŒããŒã®ç°¡ç¥åïŒ åé¡ã«ééããå Žåã¯ãåé¡ãç¹å®ããããã«é ç¹ã·ã§ãŒããŒãç°¡ç¥åããŠã¿ãŠãã ãããåã«é ç¹äœçœ®ããã¹ã¹ã«ãŒããæå°éã®ã·ã§ãŒããŒããå§ããåŸã ã«è€éããå ããŠãããŸãã
- ãã©ã€ãã®åé¡ã®ç¢ºèªïŒ ãŸãã«ããã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯ã®åé¡ããã©ã€ãã®ãã°ã«ãã£ãŠåŒãèµ·ããããããšããããŸããã°ã©ãã£ãã¯ã¹ãã©ã€ããææ°ããŒãžã§ã³ã«æŽæ°ããŠã¿ãŠãã ããã
ãã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯ãšWebGLã®æªæ¥
ãã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯ã¯ãWebGLã«ãããé«åºŠãªã¬ã³ããªã³ã°ãšã·ãã¥ã¬ãŒã·ã§ã³ã®å€ãã®å¯èœæ§ãè§£ãæŸã€åŒ·åãªæ©èœã§ããWebGLãé²åãç¶ããã«ã€ããŠããã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯ã®ããã«æŽç·Žãããå¿çšãèŠãããããšãæåŸ ãããŸããå°æ¥ã®WebGLããŒãžã§ã³ã§ã¯ããã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯ã®èœåãããã«æ¡å€§ãããã®äœ¿çšãããã«å®¹æã«ããæ°æ©èœãæ©èœåŒ·åãå°å ¥ããããããããŸããã
GPUã®æ§èœåäžãšãèŠèŠçã«è±ãã§ã€ã³ã¿ã©ã¯ãã£ããªãŠã§ãäœéšãžã®éèŠã®é«ãŸãã«äŒŽãããã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯ã¯WebGLã§å¯èœãªããšã®éçãæŒãäžããäžã§éèŠãªåœ¹å²ãæããç¶ããã§ãããããã®æè¡ãåãå ¥ããããšã§ãéçºè ã¯ãã€ãã£ãã¢ããªã±ãŒã·ã§ã³ã®ããã©ãŒãã³ã¹ãšå質ã«å¹æµãããèŠäºã§æ²¡å ¥æã®ãããŠã§ãã¢ããªã±ãŒã·ã§ã³ãäœæããåãåŸãããšãã§ããŸãã
çµè«
WebGLãã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯ã¯ããŠã§ãããŒã¹ã®ã°ã©ãã£ãã¯ã¹ã¢ããªã±ãŒã·ã§ã³å ã§é ç¹åŠçãšããŒã¿ãã£ããã£ã匷åããããã®åŒ·åãªããŒã«ã§ãããã®åçãèšå®ãæé©åæè¡ãçè§£ããããšã§ãäžçäžã®éçºè ã¯é«åºŠãªã¬ã³ããªã³ã°èœåãè§£æŸãããã髿§èœã§èŠèŠçã«èŠäºãªäœéšãåµé ã§ããŸããè€éãªããŒãã£ã¯ã«ã·ã¹ãã ã®ã·ãã¥ã¬ãŒã·ã§ã³ãããªã¢ã«ã¿ã€ã ã®ã¡ãã·ã¥å€åœ¢ãŸã§ããã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯ã¯æå 端ã®ã°ã©ãã£ãã¯ã¹ãšã·ãã¥ã¬ãŒã·ã§ã³ãçŽæ¥ãã©ãŠã¶ã«ããããåãäžããŸããããã¯ãããã©ãŒãã³ã¹ãç ç²ã«ããããå€éšãã©ã°ã€ã³ã«äŸåãããããããšãªãéæãããŸããWebGLãé²åãç¶ããäžã§ããã©ã³ã¹ãã©ãŒã ãã£ãŒãããã¯ãç¿åŸããããšã¯ããŠã§ãããŒã¹ã®ã°ã©ãã£ãã¯ã¹ããã°ã©ãã³ã°ã§å¯èœãªããšã®éçãæŒãåºããäžçèŠæš¡ã§ãããªãã€ãããŒã·ã§ã³ãä¿é²ããããã«äžå¯æ¬ ãšãªãã§ãããã