ãã®è¨äºã§ã¯ã WebGL ããã¸ã§ã¯ãå ã§ãã¼ã¿ãåå¾ãããããé©åãªç©ºéã«æå½±ãã¦ç»é¢ã«è¡¨ç¤ºããæ¹æ³ã«ã¤ãã¦èª¬æãã¾ãã並é²ãæ¡ç¸®ãå転è¡åã使ç¨ããåºæ¬çãªè¡åè¨ç®ã®ç¥èããããã¨ãåæã¨ãã¦ãã¾ãã3D ã·ã¼ã³ãæ§æããã¨ãã«é常使ç¨ãããä¸å¿ç㪠3 ã¤ã®è¡åã§ãããã¢ãã«ããã¥ã¼ãæå½±è¡åã«ã¤ãã¦èª¬æãã¾ãã
ã¡ã¢: ãã®è¨äºã¯ MDN ã³ã³ãã³ããããã¨ãã¦ãå©ç¨å¯è½ã§ããã¾ãã MDN
ã°ãã¼ãã«ãªãã¸ã§ã¯ãã®ä¸ã§å©ç¨å¯è½ãªã¦ã¼ãã£ãªãã£é¢æ°ã®ã³ã¬ã¯ã·ã§ã³ã使ç¨ãã¦ãã¾ãã
WebGL ã®ç©ºéå ã®ç¹ã¨ããªã´ã³ã®åã ã®å¤æã¯ã並é²ãæ¡ç¸®ãå転ãªã©ã®åºæ¬çãªå¤æè¡åã«ãã£ã¦å¦çããã¾ãã ãããã®è¡åã¯ãè¤é㪠3D ã·ã¼ã³ã®æç»ã«å½¹ç«ã¤ããã«ãä¸ç·ã«æ§æããç¹å¥ãªæ¹æ³ã§ã°ã«ã¼ãåã§ãã¾ãããããã®æ§æãããè¡åã¯ãæçµçã«å ã®ã¢ãã«ãã¼ã¿ãã¯ãªãã空éã¨å¼ã°ããç¹å¥ãªåº§æ¨ç©ºéã«ç§»åãã¾ãããã㯠2 ã¦ãããã®å¹ ã®ç«æ¹ä½ã§ãä¸å¿ã (0,0,0)ã対è§ã (-1,-1,-1) ãã (1,1,1) ã«ãªãã¾ãããã®ã¯ãªãã空é㯠2 次å å¹³é¢ã«å§ç¸®ãããç»åã¸ã©ã¹ã¿ã©ã¤ãºããã¾ãã
以ä¸ã§èª¬æããæåã®è¡åã¯ã¢ãã«è¡åã§ããããã¯ãå ã®ã¢ãã«ãã¼ã¿ãåå¾ã㦠3 次å ã¯ã¼ã«ã空éå ã§ç§»åããæ¹æ³ãå®ç¾©ãã¾ãã æå½±è¡åã¯ãã¯ã¼ã«ã空é座æ¨ãã¯ãªãã空é座æ¨ã«å¤æããããã«ä½¿ç¨ããã¾ãã ä¸è¬çã«ä½¿ç¨ãããæå½±è¡åã§ããéè¦æå½±æå½±è¡åã¯ã3D ä»®æ³ä¸çã®è¦è´è ã®ä»£çã¨ãã¦æ©è½ããä¸è¬çãªã«ã¡ã©ã®å¹æã模å£ããããã«ä½¿ç¨ããã¾ãã ãã¥ã¼è¡åã¯ã夿´ãããã«ã¡ã©ã®ä½ç½®ãã·ãã¥ã¬ã¼ãããã·ã¼ã³å ã®ãªãã¸ã§ã¯ããç§»åãã¦è¦è´è ãç¾å¨ä½ãè¦ããããã夿´ãã¾ãã
以ä¸ã®ã»ã¯ã·ã§ã³ã§ã¯ãã¢ãã«ããã¥ã¼ãæå½±è¡åã®èæ¯ã«ããèãæ¹ã¨å®è£ ã«ã¤ãã¦è©³èª¬ãã¾ãã ãããã®è¡åã¯ãç»é¢ä¸ã§ãã¼ã¿ãç§»åããããã®æ ¹å¹¹ã§ãããåã ã®ãã¬ã¼ã ã¯ã¼ã¯ãã¨ã³ã¸ã³ãè¶ ããæ¦å¿µã§ãã
ã¯ãªãã空éWebGL ããã°ã©ã ã§ã¯ãé常ããã¼ã¿ã¯èªåã®åº§æ¨ç³»ã§ GPU ã«ã¢ãããã¼ããããæ¬¡ã«é ç¹ã·ã§ã¼ãã¼ããããã®ç¹ãã¯ãªãã空éã¨å¼ã°ããç¹å¥ãªåº§æ¨ç³»ã«å¤æãã¾ããã¯ãªãã空éã®å¤å´ã«ãããã¼ã¿ã¯åãåãããæç»ããã¾ããããã ããä¸è§å½¢ããã®ã¹ãã¼ã¹ã®å¢çãè·¨ãå ´åã¯ãæ°ããä¸è§å½¢ã«åå²ãããã¯ãªããã¹ãã¼ã¹ã«ããæ°ããä¸è§å½¢ã®é¨åã®ã¿ãæ®ãã¾ãã
ä¸ã®å³ã¯ãå ¨ã¦ã®ç¹ãåã¾ãå¿ è¦ã®ããã¯ãªãã空éãè¦è¦åãããã®ã§ããããã¯ãå辺ã 2 ã®ç«æ¹ä½ã§ãããçæ¹ã®è§ã (-1,-1,-1) ã«ããã対è§ã (1,1,1) ã«ããã¾ããç«æ¹ä½ã®ä¸å¿ã¯ç¹ (0,0,0) ã§ãã ã¯ãªãã空éã«ä½¿ç¨ããããã® 8 ç«æ¹ã¡ã¼ãã«ã®åº§æ¨ç³»ã¯ãæ£è¦åããã¤ã¹åº§æ¨ï¼NDCï¼ã¨å¼ã°ãã¾ããWebGL ã³ã¼ãã調ã¹ã¦ä½æ¥ãã¦ããéããã®ç¨èªãæã è³ã«ããããããã¾ããã
ãã®ã»ã¯ã·ã§ã³ã§ã¯ããã¼ã¿ãã¯ãªãã空é座æ¨ç³»ã«ç´æ¥é ç½®ããä»çµã¿ã説æãã¾ãã é常ãä»»æã®åº§æ¨ç³»ã«ããã¢ãã«ãã¼ã¿ã使ç¨ããããã®å¾ãè¡åã使ç¨ãã¦å¤æãããã¢ãã«åº§æ¨ãã¯ãªãã空é座æ¨ç³»ã«å¤æããã¾ãããã®ä¾ã§ã¯ãã¯ãªãã空éãã©ã®ããã«æ©è½ããããæãç°¡åã«èª¬æããçºãåç´ã« (-1, -1, -1) ãã (1,1,1) ã¾ã§ã®ç¯å²ã®ã¢ãã«åº§æ¨ã使ç¨ãã¾ãã以ä¸ã®ã³ã¼ãã¯ãç»é¢ä¸ã«æ£æ¹å½¢ãæãçºã« 2 ã¤ã®ä¸è§å½¢ã使ãã¾ããæ£æ¹å½¢ã® Z 深度ã¯ãæ£æ¹å½¢ãåã空éãå ±æããã¨ãã«ä½ãä¸ã«æç»ãããããæ±ºå®ãã¾ããå°ãã Z å¤ã¯å¤§ãã Z å¤ã®ä¸ã«ã¬ã³ããªã³ã°ããã¾ãã
WebGLBox ã®ä¾ãã®ä¾ã§ã¯ãç»é¢ä¸ã« 2D ããã¯ã¹ãæç»ããã«ã¹ã¿ã WebGLBox
ãªãã¸ã§ã¯ãã使ãã¾ãã
ã¡ã¢: WebGLBox ã®ããããã®ä¾ã®ã³ã¼ãã¯ããã® GitHub ãªãã¸ããªã¼ã«ãããã»ã¯ã·ã§ã³ãã¨ã«æ´çããã¦ãã¾ããã¾ããåã»ã¯ã·ã§ã³ã®ä¸çªä¸ã« JSFiddle ã¸ã®ãªã³ã¯ãããã¾ãã
WebGLBox ã³ã³ã¹ãã©ã¯ã¿ã¼ã³ã³ã¹ãã©ã¯ã¿ã¼ã¯æ¬¡ã®ããã«ãªãã¾ãã
function WebGLBox() {
// Setup the canvas and WebGL context
this.canvas = document.getElementById("canvas");
this.canvas.width = window.innerWidth;
this.canvas.height = window.innerHeight;
this.gl = MDN.createContext(canvas);
const gl = this.gl;
// Setup a WebGL program, anything part of the MDN object is defined outside of this article
this.webglProgram = MDN.createWebGLProgramFromIds(
gl,
"vertex-shader",
"fragment-shader",
);
gl.useProgram(this.webglProgram);
// Save the attribute and uniform locations
this.positionLocation = gl.getAttribLocation(this.webglProgram, "position");
this.colorLocation = gl.getUniformLocation(this.webglProgram, "color");
// Tell WebGL to test the depth when drawing, so if a square is behind
// another square it won't be drawn
gl.enable(gl.DEPTH_TEST);
}
WebGLBox æç»
次ã«ãç»é¢ä¸ã«ããã¯ã¹ãæç»ããã¡ã½ããã使ãã¾ãã
WebGLBox.prototype.draw = function (settings) {
// Create some attribute data; these are the triangles that will end being
// drawn to the screen. There are two that form a square.
const data = new Float32Array([
//Triangle 1
settings.left,
settings.bottom,
settings.depth,
settings.right,
settings.bottom,
settings.depth,
settings.left,
settings.top,
settings.depth,
//Triangle 2
settings.left,
settings.top,
settings.depth,
settings.right,
settings.bottom,
settings.depth,
settings.right,
settings.top,
settings.depth,
]);
// Use WebGL to draw this onto the screen.
// Performance Note: Creating a new array buffer for every draw call is slow.
// This function is for illustration purposes only.
const gl = this.gl;
// Create a buffer and bind the data
const buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW);
// Setup the pointer to our attribute data (the triangles)
gl.enableVertexAttribArray(this.positionLocation);
gl.vertexAttribPointer(this.positionLocation, 3, gl.FLOAT, false, 0, 0);
// Setup the color uniform that will be shared across all triangles
gl.uniform4fv(this.colorLocation, settings.color);
// Draw the triangles to the screen
gl.drawArrays(gl.TRIANGLES, 0, 6);
};
ã·ã§ã¼ãã¼ã¯ GLSL ã§è¨è¿°ãããã³ã¼ãã®ä¸é¨ã§ããããã¼ã¿ãã¤ã³ããåå¾ãã¦æçµçã«ç»é¢ã«æç»ãã¾ãã便å®ä¸ããããã®ã·ã§ã¼ãã¼ã¯ãã«ã¹ã¿ã 颿° MDN.createWebGLProgramFromIds()
ãä»ãã¦ããã°ã©ã ã«åãè¾¼ã¾ããè¦ç´ <script>
ã«æ ¼ç´ããã¾ãããã®é¢æ°ã¯ããããã®ãã¥ã¼ããªã¢ã«ç¨ã«ä½æããã ã¦ã¼ãã£ãªãã£é¢æ°ç¾¤ ã®ä¸é¨ã§ãããããã§ã¯è©³ãã説æãã¾ããããã®é¢æ°ã¯ãããã¤ãã® GLSL ã½ã¼ã¹ã³ã¼ããåå¾ã㦠WebGL ããã°ã©ã ã«ã³ã³ãã¤ã«ããåºæ¬ãå¦çãã¾ãã颿°ã¯ 3 ã¤ã®ãã©ã¡ã¼ã¿ã¼ãåãã¾ããããã°ã©ã ãã¬ã³ããªã³ã°ããã³ã³ããã¹ããé ç¹ã·ã§ã¼ãã¼ãå«ãè¦ç´ ã® ID <script>
ããã©ã°ã¡ã³ãã·ã§ã¼ãã¼ãå«ãè¦ç´ ã® ID <script>
ã§ããé ç¹ã·ã§ã¼ãã¼ã¯é ç¹ãé
ç½®ãããã©ã°ã¡ã³ãã·ã§ã¼ãã¼ã¯åãã¯ã»ã«ã«è²ãä»ãã¾ãã
æåã«ãç»é¢ä¸ã§é ç¹ãç§»åãããé ç¹ã·ã§ã¼ãã¼ãè¦ã¦ã¿ã¾ãããã
// The individual position vertex
attribute vec3 position;
void main() {
// the gl_Position is the final position in clip space after the vertex shader modifies it
gl_Position = vec4(position, 1.0);
}
次ã«ããã¼ã¿ãå®éã«ãã¯ã»ã«ã«ã©ã¹ã¿ã©ã¤ãºããããã«ããã©ã°ã¡ã³ãã·ã§ã¼ãã¼ã¯ãã¯ã»ã«ãã¨ã«å ¨ã¦ãè©ä¾¡ããä¸ã¤ã®è²ãè¨å®ãã¾ããGPU ã¯ãã¬ã³ããªã³ã°ããå¿ è¦ããããã¯ã»ã«ãã¨ã«ã·ã§ã¼ãã¼é¢æ°ãå¼ã³åºãã¾ããã·ã§ã¼ãã¼ã®ä»äºã¯ããã®ãã¯ã»ã«ã«ä½¿ç¨ããè²ãè¿ããã¨ã§ãã
precision mediump float;
uniform vec4 color;
void main() {
gl_FragColor = color;
}
ãããã®è¨å®ãå«ã¾ãã¦ããã®ã§ãã¯ãªãã空é座æ¨ã使ç¨ãã¦ç»é¢ã«ç´æ¥æç»ãã¾ãã
const box = new WebGLBox();
æåã«ä¸å¤®ã«èµ¤ãããã¯ã¹ãæãã¾ãã
box.draw({
top: 0.5, // x
bottom: -0.5, // x
left: -0.5, // y
right: 0.5, // y
depth: 0, // z
color: [1, 0.4, 0.4, 1], // red
});
次ã«ãç·è²ã®ããã¯ã¹ã赤ãããã¯ã¹ã®ä¸é¨ã«æç»ãã¾ãã
box.draw({
top: 0.9, // x
bottom: 0, // x
left: -0.9, // y
right: 0.9, // y
depth: 0.5, // z
color: [0.4, 1, 0.4, 1], // green
});
æå¾ã«ãã¯ãªããã³ã°ãå®éã«è¡ããã¦ãããã¨ã示ãããã«ããã®ããã¯ã¹ã¯å®å ¨ã«ã¯ãªãã空éã®å¤å´ã«ãããããæç»ããã¾ãããæ·±ãã -1.0 ãã 1.0 ã®ç¯å²å¤ã§ãã
box.draw({
top: 1, // x
bottom: -1, // x
left: -1, // y
right: 1, // y
depth: -1.5, // z
color: [0.4, 0.4, 1, 1], // blue
});
çµæ
æ¼ç¿
ãã®æç¹ã§å½¹ç«ã¤æ¼ç¿ã¯ãã³ã¼ãã夿´ãã¦ããã¯ã¹ãã¯ãªãã空éå ã§ç§»åããç¹ãã¯ãªãã空éå ã§ã©ã®ããã«ã¯ãªãããããç§»åãããããæãåããã¨ã§ããèæ¯ãæã¤ããã¯ã¹ç¶ã®ã¹ãã¤ã«ã®ãããªçµµãæãã¦ã¿ã¦ãã ããã
忬¡åº§æ¨åã®ã¯ãªãã空éã®é ç¹ã·ã§ã¼ãã®ã¡ã¤ã³ã©ã¤ã³ã¯ããã®ã³ã¼ããå«ãã§ãã¾ããã
gl_Position = vec4(position, 1.0);
夿° position
ã¯ã draw()
ã¡ã½ããã§å®ç¾©ããã屿§ã¨ãã¦ã·ã§ã¼ãã¼ã«æ¸¡ããã¾ãããããã¯ä¸æ¬¡å
ã®ç¹ã§ããããã¤ãã©ã¤ã³ãä»ãã¦æ¸¡ããããã¨ã«ãªã夿° gl_Position
ã¯å®éã«ã¯å次å
ã§ããããªãã¡ã (x, y, z)
ã®ä»£ããã« (x, y, z, w)
ã¨ãªã£ã¦ãã¾ããz
ã®å¾ã«ã¯æåããªããããæ
£ä¾ã«ããããã® 4 çªç®ã®æ¬¡å
ã«ã¯ w
ã¨ããã©ãã«ãä»ãã¦ãã¾ãã ä¸è¨ã®ä¾ã§ã¯ã w
座æ¨ã¯ 1.0 ã«è¨å®ããã¦ãã¾ãã
æãããªçåã¯ãããªãä½åãªæ¬¡å
ãããã®ãï¼ãã§ãããã®è¿½å ã«ããã3D ãã¼ã¿ãæä½ããããã®å¤ãã®åªããææ³ãå¯è½ã«ãªããã¨ãåããã¾ãããã®è¿½å ãããæ¬¡å
ã«ãããé è¿æ³ã®æ¦å¿µã座æ¨ç³»ã«å°å
¥ããã¾ãããããé
ç½®ããã¨ã3D 座æ¨ã 2D 空éã«ãããã³ã°ã§ãã¾ããããã«ããã2 æ¬ã®å¹³è¡ç·ãé ãã«é¢ããã¨ãã«äº¤å·®ããããã«ãªãã¾ããå¤ w
ã¯ã座æ¨ã®ä»ã®ã³ã³ãã¼ãã³ãã®é¤æ°ã¨ãã¦ä½¿ç¨ãããããã x
ãy
ãz
ã®çã®å¤ã¯ãx/w
ãy/w
ãz/w
ã¨ãã¦è¨ç®ããã¾ãï¼ããã¦ãw
ã w/w
ã§ 1 ã«ãªãã¾ãï¼ã
䏿¬¡å ã®ç¹ã¯ãå ¸åçãªãã«ã«ã座æ¨ç³»ã§å®ç¾©ããã¾ãã忬¡å ç®ãå ãããã¨ã§ããã®ç¹ã¯å次座æ¨ã«å¤åãã¾ããããã¯ã¾ã 3 次å 空éã®ç¹ã表ãã¦ããããã®ãããªåº§æ¨ãã©ã®ããã«æ§ç¯ãããã¯ãåç´ãªé¢æ°ã®çµã«ãã£ã¦ç°¡åã«ç¤ºãã¾ãã
function cartesianToHomogeneous(point) {
let x = point[0];
let y = point[1];
let z = point[2];
return [x, y, z, 1];
}
function homogeneousToCartesian(point) {
let x = point[0];
let y = point[1];
let z = point[2];
let w = point[3];
return [x / w, y / w, z / w];
}
åè¿°ããããã«ãã¾ãä¸ã®é¢æ°ã§ç¤ºããããã«ã w æå㯠xãyãz æåãé¤ç®ãã¾ãã w æåãã¼ãã§ãªã宿°ã§ããã¨ãã忬¡åº§æ¨ã¯ç´äº¤ç©ºéã®æ³ç·ç¹ã«ç°¡åã«æ»ãã¾ããã§ã¯ã w æåãã¼ãã®å ´åã¯ã©ããªãã§ããããã JavaScript ã§ã¯æ¬¡ã®ãããªå¤ãè¿ããã¾ãã
homogeneousToCartesian([10, 4, 5, 0]);
ãã㯠[Infinity, Infinity, Infinity]
ã¨è©ä¾¡ããã¾ãã
ãã®å次座æ¨ã¯ç¡éã®ä½ç½®ã«ããç¹ã表ãã¾ããããã¯ãåç¹ããç¹å®ã®æ¹åã«æ¾ãããå ç·ã表ã便å©ãªæ¹æ³ã§ããå ç·ã ãã§ãªããæ¹åãã¯ãã«ã®è¡¨ç¾ã¨èãããã¨ãã§ãã¾ãããã®å次座æ¨ãå¹³è¡ç§»åã®ããè¡åã¨æãåãããã¨ãå¹³è¡ç§»åã¯å¹æçã«åãé¤ããã¾ãã
ã³ã³ãã¥ã¼ã¿ã¼ä¸ã§æ°åãæ¥µç«¯ã«å¤§ããï¼ãããã¯æ¥µç«¯ã«å°ããï¼ãªãã¨ãããã表ç¾ããã®ã«ä½¿ããã 1 㨠0 ã®æ°ãéãããããã精度ãã©ãã©ãè½ã¡ã¦ããã¾ãã大ããªæ°ãéå¶ããæ¼ç®åãå¢ããã°å¢ããã»ã©ãçµæã«èª¤å·®ãèç©ããã¦ããã¾ããw ã§å²ãå ´åã 2 ã¤ã®æ½å¨çã«å°ããã¦èª¤å·®ã®å°ãªãæ°ãæä½ãããã¨ã§ãé常ã«å¤§ããªæ°ã®ç²¾åº¦ã广çã«é«ãããã¨ãã§ãã¾ãã
忬¡åº§æ¨ã使ç¨ããæå¾ã®å¥½ã¾ãããã¨ã¯ã 4x4 è¡åã«å¯¾ãã¦ä¹ç®ããã®ã«ã¨ã¦ããã¾ãé©åããã¨ãããã¨ã§ããè¡åã«å¯¾ãã¦ä¹ç®ããããã«ã¯ãé ç¹ã¯è¡åã®å°ãªãã¨ã 1 ã¤ã®æ¬¡å ã¨ä¸è´ããªããã°ãªãã¾ããã 4x4 è¡åã¯ããã¾ãã¾ãªæçãªå¤æãã¨ã³ã³ã¼ãããããã«ä½¿ç¨ãããã¨ãã§ãã¾ããå®éï¼å ¸åçãªéè¦æå½±è¡åã¯ï¼ãã®å¤æãå®ç¾ããããã« w æåã«ããé¤ç®ã使ç¨ãã¦ãã¾ãï¼
ã¯ãªãã空éããã®ç¹ã¨ããªã´ã³ã®ã¯ãªããã³ã°ã¯ã忬¡åº§æ¨ãï¼w ã§å²ããã¨ã«ãã£ã¦ï¼ãã«ã«ã座æ¨ã«å¤æãããåã«è¡ããã¾ãããã®æçµç©ºéã¯æ£è¦åæ©å¨åº§æ¨ã¾ã㯠NDC ã¨ãã¦ç¥ããã¦ãã¾ãã
ãã®ã¢ã¤ãã£ã¢ãéã³å§ããã«ã¯ãååã®ä¾ã夿´ã㦠w
æåã使ç¨ãããã¨ãã§ãã¾ãã
//Redefine the triangles to use the W component
const data = new Float32Array([
//Triangle 1
settings.left,
settings.bottom,
settings.depth,
settings.w,
settings.right,
settings.bottom,
settings.depth,
settings.w,
settings.left,
settings.top,
settings.depth,
settings.w,
//Triangle 2
settings.left,
settings.top,
settings.depth,
settings.w,
settings.right,
settings.bottom,
settings.depth,
settings.w,
settings.right,
settings.top,
settings.depth,
settings.w,
]);
ãã®å¾ãé ç¹ã·ã§ã¼ãã¼ã¯æ¸¡ããã 4 次å ç®ã®ç¹ã使ç¨ãã¾ãã
attribute vec4 position;
void main() {
gl_Position = position;
}
æåã«çãä¸ã«èµ¤ãæ ãæç»ãã¾ããã W 㯠0.7 ã«è¨å®ãã¾ãã座æ¨ã 0.7 ã§åå²ãããã¨ããã¹ã¦æ¡å¤§ããã¾ãã
box.draw({
top: 0.5, // y
bottom: -0.5, // y
left: -0.5, // x
right: 0.5, // x
w: 0.7, // w - enlarge this box
depth: 0, // z
color: [1, 0.4, 0.4, 1], // red
});
ããã§ä¸é¨ã«ç·è²ã®ããã¯ã¹ãæç»ãã¾ããã w æåã 1.1 ã«è¨å®ããã«ã¯ç¸®å°ãã¾ãã
box.draw({
top: 0.9, // y
bottom: 0, // y
left: -0.9, // x
right: 0.9, // x
w: 1.1, // w - shrink this box
depth: 0.5, // z
color: [0.4, 1, 0.4, 1], // green
});
ãã®æå¾ã®ããã¯ã¹ã¯ã¯ãªãã空éã®å¤ãªã®ã§æç»ããã¾ãããæ·±ã㯠-1.0 ãã 1.0 ã®ç¯å²å¤ã§ãã
box.draw({
top: 1, // y
bottom: -1, // y
left: -1, // x
right: 1, // x
w: 1.5, // w - Bring this box into range
depth: -1.5, // z
color: [0.4, 0.4, 1, 1], // blue
});
çµæ
ç·´ç¿åé¡
ã¯ãªãã空éã«ç¹ãç´æ¥é ç½®ãã¦ãã使ç¨ãããã¨ã«ã¯éçãããã¾ããå®éã®ã¢ããªã±ã¼ã·ã§ã³ã§ã¯ããã¹ã¦ã®ã½ã¼ã¹åº§æ¨ãã¯ãªãã空é座æ¨ã«ãã§ã«åã¾ã£ã¦ããã¨ã¯éãã¾ããããã®ãããã»ã¨ãã©ã®å ´åãã¢ãã«ãã¼ã¿ãä»ã®åº§æ¨ãã¯ãªãã空éã«å¤æããå¿ è¦ãããã¾ããå°å³ãªç«æ¹ä½ã¯ããã®æ¹æ³ã®åç´ãªä¾ã§ããç«æ¹ä½ã®ãã¼ã¿ã¯ãé ç¹ä½ç½®ãç«æ¹ä½ã®é¢ã®è²ãããã³åã ã®å¤è§å½¢ãæ§æããé ç¹ä½ç½®ã®é åºï¼ç«æ¹ä½ã®é¢ãæ§æããä¸è§å½¢ãæ§æãã3ã¤ã®é ç¹ã®ã°ã«ã¼ãï¼ã§æ§æããã¾ããä½ç½®ã¨è²ã¯ GL ãããã¡ã«æ ¼ç´ããã屿§ã¨ãã¦ã·ã§ã¼ãã«éãããåå¥ã«å¦çããã¾ãã
æå¾ã«ãåä¸ã®ã¢ãã«è¡åãè¨ç®ãããè¨å®ããã¾ãããã®è¡åã¯ãã¢ãã«ãæ§æãããã¹ã¦ã®ç¹ã«å¯¾ãã¦ãã¢ãã«ãæ£ãã空éã«ç§»åãããã¢ãã«ã®åç¹ã«å¯¾ãã¦ä»ã«ãå¿ è¦ãªå¤æãè¡ãããã«å®è¡ããã夿ã表ãã¾ããããã¯ãåé ç¹ã ãã§ãªããã¢ãã«ã®ãã¹ã¦ã®é¢ä¸ã®åä¸ã®ç¹ã«ãé©ç¨ããã¾ãã
ãã®å ´åãã¢ãã¡ã¼ã·ã§ã³ã®ãã¬ã¼ã ãã¨ã«ãä¸é£ã®æ¡å¤§ç¸®å°ãå転ãå¹³è¡ç§»åã®è¡åããã¼ã¿ãã¯ãªãã空éã®ç®çã®å ´æã«ç§»åããã¾ããç«æ¹ä½ã¯ã¯ãªãã空éã®ãµã¤ãº (-1,-1,-1) ãã (1,1,1) ãªã®ã§ãã¯ãªãã空éå ¨ä½ãåããªãããã«ç¸®å°ããå¿ è¦ãããã¾ãããã®è¡åã¯ãããããã JavaScript ã§ä¹ç®ããå¾ãç´æ¥ã·ã§ã¼ãã¼ã«éããã¾ãã
以ä¸ã®ã³ã¼ããµã³ãã«ã§ã¯ãã¢ãã«è¡åã使ãã CubeDemo
ãªãã¸ã§ã¯ãã®ã¡ã½ãããå®ç¾©ãã¾ãã MDN WebGL ã®å
±æã³ã¼ãã§å®ç¾©ããã¦ããããã«ãè¡åã使ãããä¹ç®ãããããã«ã¹ã¿ã 颿°ã使ç¨ãã¦ãã¾ããæ°ãã颿°ã¯æ¬¡ã®ããã«ãªãã¾ãã
CubeDemo.prototype.computeModelMatrix = function (now) {
//Scale down by 50%
const scale = MDN.scaleMatrix(0.5, 0.5, 0.5);
// Rotate a slight tilt
const rotateX = MDN.rotateXMatrix(now * 0.0003);
// Rotate according to time
const rotateY = MDN.rotateYMatrix(now * 0.0005);
// Move slightly down
const position = MDN.translateMatrix(0, -0.1, 0);
// Multiply together, make sure and read them in opposite order
this.transforms.model = MDN.multiplyArrayOfMatrices([
position, // step 4
rotateY, // step 3
rotateX, // step 2
scale, // step 1
]);
};
ãããã·ã§ã¼ãã¼ã§ä½¿ç¨ããã«ã¯ãã¦ããã©ã¼ã ã®ä½ç½®ã«è¨å®ããå¿
è¦ãããã¾ããã¦ããã©ã¼ã ã®ä½ç½®ã¯ä¸è¨ã«ç¤ºã locations
ãªãã¸ã§ã¯ãã«ä¿åããã¾ãã
this.locations.model = gl.getUniformLocation(webglProgram, "model");
ããã¦æå¾ã«ã¦ããã©ã¼ã ããã®å ´æã«è¨å®ãã¾ããããã§è¡åã GPU ã«æ¸¡ããã¾ãã
gl.uniformMatrix4fv(
this.locations.model,
false,
new Float32Array(this.transforms.model),
);
ã·ã§ã¼ãã¼ã§ã¯ãåä½ç½®ã®é ç¹ã¯æåã«å次座æ¨ï¼vec4
ãªãã¸ã§ã¯ãï¼ã«å¤æãããæ¬¡ã«ã¢ãã«è¡åã«å¯¾ãã¦ä¹ç®ããã¾ãã
gl_Position = model * vec4(position, 1.0);
ã¡ã¢: JavaScript ã§è¡åã®ä¹ç®ã¯ã«ã¹ã¿ã 颿°ãè¦æ±ããã¾ãããã·ã§ã¼ãã¼ã§ã¯åç´ãª * æ¼ç®åã§è¨èªã«çµã¿è¾¼ã¾ãã¦ãã¾ãã
çµæãã®æç¹ã§ã¯ã夿ç¹ã® w å¤ã¯ 1.0 ã®ã¾ã¾ã§ããç«æ¹ä½ã«ã¯ã¾ã è¦ç¹ä½ç½®ãããã¾ãããæ¬¡ã®ç« ã§ã¯ããã®è¨å®ããã¨ã«ã w å¤ã夿´ãã¦è¦ç¹ãæä¾ãã¾ãã
ç·´ç¿åé¡rotateZ
è¡åã追å ãã¾ããããç«æ¹ä½ã®ã¢ãã«ã®è¦ç¹ãå§ããã«ã¯ãZ 座æ¨ãåããããã w 座æ¨ã«ã³ãã¼ããã®ãç°¡åã§ããé常ããã«ã«ãç¹ãåå¤ã«å¤æããã¨ã㯠(x,y,z,1)
ã¨ãªãã¾ãããããã§ã¯ (x,y,z,z)
ã®ããã«è¨å®ãã¾ããå®éã«ã¯ã z ã 0 ãã大ããç¹ããã¥ã¼ã«åãè¾¼ã¿ããã®ã§ããã®å¤ãå°ã夿´ã㦠((1.0 + z) * scaleFactor)
ã¨ãã¾ããããã¯é常ã¯ãªãã空é (-1 ï½ 1) ã«ããç¹ããã¹ã±ã¼ã«ä¿æ°ã®è¨å®ã«å¿ã㦠(0 ï½ 1) ã®ãããªç©ºéã«ç§»ãã¾ããã¹ã±ã¼ã«ä¿æ°ã¯æçµç㪠w ã®å¤ãå
¨ä½çã«é«ããããä½ãããããã¾ãã
ã·ã§ã¼ãã¼ã®ã³ã¼ãã¯ãããªæãã§ãã
// First transform the point
vec4 transformedPosition = model * vec4(position, 1.0);
// How much effect does the perspective have?
float scaleFactor = 0.5;
// Set w by taking the z value which is typically ranged -1 to 1, then scale
// it to be from 0 to some number, in this case 0-1.
float w = (1.0 + transformedPosition.z) * scaleFactor;
// Save the new gl_Position with the custom w component
gl_Position = vec4(transformedPosition.xyz, w);
çµæ
ç´ºè²ã®å°ããªä¸è§å½¢ãè¦ãã¾ããï¼ããã¯ãªãã¸ã§ã¯ãã«è¿½å ãããé¢ã§ããå³å½¢ãå転ãããã¨ã«ãã£ã¦ããã®è§ãã¯ãªãã空éã®å¤ã«ã¯ã¿åºããè§ãã¯ãªããã³ã°ãããç¾è±¡ãçºçããããã§ããããè¤éãªè¡åã使ç¨ãã¦ã¯ãªããã³ã°ãå¶å¾¡ããã鲿¢ãããããæ¹æ³ã«ã¤ãã¦ã¯ãä¸è¨ã®éè¦æå½±è¡åãåç §ãã¦ãã ããã
ç·´ç¿åé¡å°ãæ½è±¡çã«èããããªããé ç¹ã·ã§ã¼ãã¼ãéãã¦ã¹ã±ã¼ã«ä¿æ°ã調æ´ããé ç¹ããµã¼ãã§ã¹ã«åãã£ã¦ã©ã®ããã«ç¸®å°ããããè¦ã¦ãã ããã w æåã®å¤ãå®å ¨ã«å¤ããã¨ãå®ã«å·§å¦ãªç©ºé表ç¾ãã§ãã¾ãã
次ã®ç¯ã§ã¯ããã® Z ã w ã¹ãããã«ã³ãã¼ããæ¹æ³ãã¨ããè¡åã«å¤ãã¾ãã
åç´ãªæå½±w æåãåããæå¾ã®æé ã¯ãå®ã¯åç´ãªè¡åã§å®ç¾ã§ãã¾ããå§ããã«ã¯æçè¡åã使ãã¾ãã
const identity = [
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1
];
MDN.multiplyPoint(identity, [2, 3, 4, 1]);
//> [2, 3, 4, 1]
ããã¦æå¾ã®åã® 1 ã 1 ã¤ä¸ã«ç§»åãã¾ãã
const copyZ = [
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 1,
0, 0, 0, 0
];
MDN.multiplyPoint(copyZ, [2, 3, 4, 1]);
//> [2, 3, 4, 4]
ããããæå¾ã®ä¾ã§ã¯ (z + 1) * scaleFactor
ãå®è¡ãã¾ããã
const scaleFactor = 0.5;
const simpleProjection = [
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, scaleFactor,
0, 0, 0, scaleFactor,
];
MDN.multiplyPoint(simpleProjection, [2, 3, 4, 1]);
//> [2, 3, 4, 2.5]
ããå°ã詳ããåæããã¨ããããã©ã®ããã«åä½ããã®ãããããã¾ãã
let x = 2 * 1 + 3 * 0 + 4 * 0 + 1 * 0;
let y = 2 * 0 + 3 * 1 + 4 * 0 + 1 * 0;
let z = 2 * 0 + 3 * 0 + 4 * 1 + 1 * 0;
let w = 2 * 0 + 3 * 0 + 4 * scaleFactor + 1 * scaleFactor;
æå¾ã®è¡ã¯åç´åããã¨ãããªãã¾ãã
w = 4 * scaleFactor + 1 * scaleFactor;
ããã¦ã scaleFactor ãå æ°åè§£ããã¨ããã®ããã«ãªãã¾ãã
w = (4 + 1) * scaleFactor;
ããã¯ååã®ä¾ã§ä½¿ç¨ãã (z + 1) * scaleFactor
ã¨å
¨ãåãã§ãã
ãã®ãã¢ã§ã¯ã computeSimpleProjectionMatrix()
ã¡ã½ããã追å ããã¦ãã¾ãããã㯠draw()
ã¡ã½ããã®ä¸ã§å¼ã³åºãããã¹ã±ã¼ã«ä¿æ°ã渡ããã¾ããçµæã¯ååã®ä¾ã¨åãã«ãªãã¯ãã§ãã
CubeDemo.prototype.computeSimpleProjectionMatrix = function (scaleFactor) {
this.transforms.projection = [
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, scaleFactor,
0, 0, 0, scaleFactor
];
};
çµæã¯åãã§ãããããã§ã®éè¦ãªæé ã¯é ç¹ã·ã§ã¼ãã¼ã«ããã¾ããé ç¹ãç´æ¥å¤æ´ããã®ã§ã¯ãªãã追å ã® æå½±è¡å ã¨ä¹ç®ãã¾ãããã®è¡åã¯ï¼ãã®ååã示ãããã«ï¼ 3D ç¹ã 2D ã®æç»é¢ã«æå½±ãã¾ãã
// Make sure to read the transformations in reverse order
gl_Position = projection * model * vec4(position, 1.0);
çµæ è¦éå°
è¦ç¹ä½ç½®ã®æå½±è¡åã®è¨ç®æ¹æ³ã«ç§»ãåã«ãè¦éå°ï¼view frustum ã¨ãå¼ã°ãã¾ãï¼ã®æ¦å¿µãç´¹ä»ããå¿ è¦ãããã¾ããããã¯ãç¾æç¹ã§ã¦ã¼ã¶ã¼ã«ã³ã³ãã³ããè¦ãã¦ãã空éã®é åã§ããè¦éè§ã¨ãã¬ã³ããªã³ã°ãããã¹ãæãè¿ãã³ã³ãã³ãã¨æãé ãã³ã³ãã³ãã¨ãã¦æå®ããè·é¢ã«ãã£ã¦å®ç¾©ããã空éã® 3D é åã§ãã
ã¬ã³ããªã³ã°ä¸ã«ãã·ã¼ã³ã表ãããã«ã©ã®ããªã´ã³ãã¬ã³ããªã³ã°ããå¿ è¦ãããããæ±ºå®ããå¿ è¦ãããã¾ãããããå®ç¾©ããã®ãè¦éå°ã§ããããããããããéå°ã¨ã¯ä½ã§ããããï¼
éå°ã¨ã¯ãä»»æã®ç«ä½ã 2 ã¤ã®å¹³è¡ããå¹³é¢ã使ç¨ã㦠2 ã¤ã®é¨åã«åãåã£ãçµæã® 3D ç«ä½ã®ãã¨ã§ããç§ãã¡ã®ã«ã¡ã©ã¯ãã¬ã³ãºã®ããåããå§ã¾ããé ãã¸åºãã£ã¦ããé åãè¦ã¦ããã¨ãã¾ããè¦ããç¯å²ã¯åè§éã§ãé ç¹ã¯ã¬ã³ãºã 4 ã¤ã®è¾ºã¯å¨è¾ºè¦éã®ç¯å²ã«å¯¾å¿ããåºè¾ºã¯ãã®ããã«æãé ãã«è¦ãã¾ãã
ããã使ç¨ãã¦ãã¬ã¼ã ãã¨ã«ã¬ã³ããªã³ã°ããããªã´ã³ã決å®ããã¨ãã¬ã³ãã©ã¼ã¯ãã®ãã©ãããå ã®ãã¹ã¦ã®ããªã´ã³ãã¬ã³ããªã³ã°ããå¿ è¦ããããã¬ã³ãºããã¨ã¦ãè¿ãããªã´ã³ãå«ãã¦ãç¡éé ã¾ã§ã¬ã³ããªã³ã°ããå¿ è¦ãããã¾ãã
ããã§ãè¨ç®ã¨ã¬ã³ããªã³ã°ã«å¿ è¦ãªããªã´ã³æ°ã忏ããæåã®æé ã¨ãã¦ããã®ãã©ããããè¦éå°ã«ãã¾ããããªã´ã³æ°ã縮å°ããããã«ãé ç¹ãæ¸ããã®ã«ä½¿ç¨ãã 2 æã®å¹³é¢ã¯ãåæ¹ã¯ãªããã³ã°å¹³é¢ã¨å¾æ¹ã¯ãªããã³ã°å¹³é¢ã§ãã
WebGL ã§ã¯ãåæ¹ããã³å¾æ¹ã¯ãªããã³ã°é¢ã¯ãã¬ã³ãºããè¦ç·æ¹åã«åç´ãªé¢ä¸ã®æãè¿ããã®ç¹ã¾ã§ã®è·é¢ãæå®ãããã¨ã§å®ç¾©ãã¾ããåæ¹ã¯ãªããã³ã°é¢ãããã¬ã³ãºã«è¿ããã®ãã徿¹ã¯ãªããã³ã°é¢ãããã¬ã³ãºããé ããã®ã¯é¤å»ããã¾ãããã®çµæãè¦éå°ã¯æ¬¡ã®ããã«ãªãã¾ãã
åãã¬ã¼ã ã§ã¬ã³ããªã³ã°ããããªãã¸ã§ã¯ãã®éåã¯ãåºæ¬çã«ã·ã¼ã³å ã®ãã¹ã¦ã®ãªãã¸ã§ã¯ãã®éåãã使ãå§ãã¾ããããã¦ãè¦éå°ã®å®å ¨ã«å¤å´ã«ãããªãã¸ã§ã¯ãã¯ãã®éåããé¤å¤ããã¾ããæ¬¡ã«ãé¨åçã«è¦éå°ã®å¤å´ã«ã¯ã¿åºãã¦ãããªãã¸ã§ã¯ãã¯ãè¦éå°ã®å¤å´ã«ããããªã´ã³ããã¹ã¦åé¤ããè¦éå°ã®å¤å´ã横åãããªã´ã³ãã¯ãªãããããã¨ã§ãè¦éå°ããåºãªããªãã¾ãã
ãããå®äºããã¨ãè¦éå°å ã«ããããªã´ã³ã®æå¤§éåãå¾ããã¾ãããã®ãªã¹ãã¯é常ãèé¢ã«ãªã³ã°ï¼è£å´ãã«ã¡ã©ã«åãã¦ããããªã´ã³ãé¤å»ï¼ããé°é¢å¤å® ï¼ã¬ã³ãºã«è¿ãããªã´ã³ã«å®å ¨ã«é®ããã¦è¦ããªãããªã´ã³ãé¤å»ããï¼ã使ç¨ãããªã¯ã«ã¼ã¸ã§ã³ã«ãªã³ã°ãªã©ã®å¦çã使ã£ã¦ãããã«åæ¸ããã¾ãã
éè¦æå½±è¡åãã®ç¹ã¾ã§ãèªåèªèº«ã§ 3D ã¬ã³ããªã³ã°ã®ã»ããã¢ãããæ®µéçã«æ§ç¯ãã¦ãã¾ãããããããç¾å¨ã®ã³ã¼ãã«ã¯ããã¤ãã®èª²é¡ãããã¾ããä¸ã¤ã¯ãã¦ã£ã³ãã¦ã®ãµã¤ãºã夿´ãããã³ã«æªãã§ãã¾ããã¨ã§ããããã²ã¨ã¤ã¯ãèªåã®åç´ãªããã¸ã§ã¯ãã§ã¯ãã·ã¼ã³ãã¼ã¿ã®å¤ã®åºãç¯å²ãå¦çããªããã¨ã§ããã»ã¨ãã©ã®ã·ã¼ã³ã¯ã¯ãªãã空éã§åä½ãã¾ãããæ°å¤ã®å¤æã§ç²¾åº¦ã失ãããªãããã«ãã·ã¼ã³ã«é¢é£ããè·é¢ãå®ç¾©ãã¦ããã¨ä¾¿å©ã§ããããæå¾ã«ãã©ã®ç¹ãã¯ãªãã空éã®å å´ã¨å¤å´ã«é ç½®ãããããç´°ããå¶å¾¡ããã¨ã¨ã¦ã便å©ã§ããååã®ä¾ã§ã¯ãç«æ¹ä½ã®è§ãã¯ãªããããããã¨ãããã¾ããã
éè¦æå½±è¡åã¯ããããã®è¦æ±ããã¹ã¦éæããæå½±è¡åã®ç¨®é¡ã§ããæ°å¦ãå°ãè¤éã«ãªãå§ããã®ã§ããã®ä¾ã§ã¯ååã«èª¬æãã¾ãããè¦ããã«ãï¼ååä¾ã§è¡ã£ãããã«ï¼ w ã§å²ããã¨ã¨ãç¸ä¼¼ä¸è§å½¢ã«åºã¥ãããã¤ãã®å·§å¦ãªæä½ãçµã¿åããããã®ã§ãããã®èå¾ã«ããæ°å¦çã«å®å ¨ãªèª¬æãèªãã«ã¯ã以ä¸ã®ãªã³ã¯ã調ã¹ã¦ãã ããã
ä¸è¨ã§ä½¿ç¨ããè¦ç¹ä½ç½®æå½±è¡åã§æ³¨æãã¹ãéè¦ãªãã¨ã¯ã z 軸ãå転ãããã¨ãããã¨ã§ããã¯ãªãã空éã§ã¯ z ãå¢å ãããã¨è¦ã人ããé ãããã¾ããããã®è¡åã§ã¯è¦ãäººã®æ¹ã«æ¥ã¾ãã
z 軸ãå転ãããçç±ã¯ãã¯ãªãã空é座æ¨ç³»ãå·¦æåº§æ¨ç³»ï¼z 軸ãè¦è´è ããç»é¢ã®å å´ã¸åãï¼ã§ããã®ã«å¯¾ããæ°å¦ãç©çå¦ã 3D ã¢ããªã³ã°ã OpenGL ã®ãã¥ã¼/è¦ç·åº§æ¨ç³»ã§ã¯ãå³æåº§æ¨ç³»ï¼z 軸ãè¦è´è ã«åãã£ã¦ç»é¢ã®å¤å´ãåãï¼ã使ç¨ããã®ãæ £ä¾ã ããã§ãã詳ããã¯ã¦ã£ãããã£ã¢ã®é¢é£è¨äºããã«ã«ã座æ¨ç³»ãå³æã®æ³åãåç §ãã¦ãã ããã
ããã§ã¯ãéè¦æå½±è¡åãè¨ç®ãã颿° perspectiveMatrix()
ãè¦ã¦ããã¾ãããã
MDN.perspectiveMatrix = function (
fieldOfViewInRadians,
aspectRatio,
near,
far,
) {
const f = 1.0 / Math.tan(fieldOfViewInRadians / 2);
const rangeInv = 1 / (near - far);
return [
f / aspectRatio, 0, 0, 0,
0, f, 0, 0,
0, 0, (near + far) * rangeInv, -1,
0, 0, near * far * rangeInv * 2, 0
];
};
ãã®é¢æ°ã® 4 ã¤ã®å¼æ°ã¯ä»¥ä¸ã®éãã§ãã
fieldOfViewInRadians
ã©ã¸ã¢ã³åä½ã§æå®ãããè§åº¦ã§ãã·ã¼ã³ã®ã©ã®ç¨åº¦ãä¸åº¦ã«è¦è´è ã«è¦ãããã示ãã¾ããæ°å¤ã大ããã»ã©ãã«ã¡ã©ããè¦ããç¯å²ãåºããªãã¾ããåºè§ã¬ã³ãºã«ç¸å½ããå¨è¾ºé¨ã®å½¢ç¶ã¯ã©ãã©ãæªãã§ããã¾ããè¦éè§ã大ãããªãã¨ãä¸è¬çã«ãªãã¸ã§ã¯ãã¯å°ãããªãã¾ããè¦éè§ãå°ãããªãã¨ãã«ã¡ã©ã§è¦ããç¯å²ãçã¾ã£ã¦ããã¾ããè¦ç¹ä½ç½®ã«ãããªãã¸ã§ã¯ãã®æªã¿ãå°ãªããªãããªãã¸ã§ã¯ããã«ã¡ã©ã«è¿ãè¦ãã¾ãã
aspectRatio
ã·ã¼ã³ã®ã¢ã¹ãã¯ãæ¯ã¯ãå¹ ãé«ãã§å²ã£ããã®ã§ãããã®ä¾ã§ã¯ãã¦ã£ã³ãã¦ã®å¹ ãã¦ã£ã³ãã¦ã®é«ãã§å²ã£ããã®ã§ãããã®å¼æ°ãå°å ¥ãããã¨ã§ããã£ã³ãã¹ã®ãµã¤ãºã夿´ãããããå½¢ãå¤ãã£ããããã¨ã¢ãã«ããããã§ãã¾ãã¨ããåé¡ãæçµçã«è§£æ±ºããã¾ãã
nearClippingPlaneDistance
ç»é¢å´ã¸ãåºã«åç´ãªé¢ã¾ã§ã®è·é¢ãç¤ºãæ£ã®å¤ã§ãããããè¿ããã¹ã¦ãã¯ãªããããã¾ããããã¯ã¯ãªãã空éã§ã¯ -1 ã«å²ãå½ã¦ããã¦ããã0 ã«è¨å®ãã¦ã¯ããã¾ããã
farClippingPlaneDistance
ã¸ãªã¡ããªã¼ãåãåãããå¹³é¢ã¾ã§ã®è·é¢ãç¤ºãæ£ã®å¤ãã¯ãªãã空éã§ã¯ 1 ã«å²ãå½ã¦ããã¦ãã¾ãããã®å¤ã¯ãã¬ã³ããªã³ã°ä¸ã«ç²¾åº¦ã®èª¤å·®ãçããã®ãé¿ããããã«ãã¸ãªã¡ããªã¼ã®è·é¢ã«é©åº¦ã«è¿ãå¤ã«éãããã¦ããå¿ è¦ãããã¾ãã
ãã®ãã¢ã®ææ°ãã¼ã¸ã§ã³ã§ã¯ã computeSimpleProjectionMatrix()
ã¡ã½ãã㯠computePerspectiveMatrix()
ã¡ã½ããã«ç½®ãæãããã¦ãã¾ãã
CubeDemo.prototype.computePerspectiveMatrix = function () {
const fieldOfViewInRadians = Math.PI * 0.5;
const aspectRatio = window.innerWidth / window.innerHeight;
const nearClippingPlaneDistance = 1;
const farClippingPlaneDistance = 50;
this.transforms.projection = MDN.perspectiveMatrix(
fieldOfViewInRadians,
aspectRatio,
nearClippingPlaneDistance,
farClippingPlaneDistance,
);
};
ã·ã§ã¼ãã¼ã³ã¼ãã¯ååã®ä¾ã¨åãã§ãã
gl_Position = projection * model * vec4(position, 1.0);
ããã«ï¼è¡¨ç¤ºããã¦ãã¾ãããï¼ãã¢ãã«ã®ä½ç½®ã¨æ¡å¤§ç¸®å°è¡åã¯ãã¯ãªãã空éãã大ããªåº§æ¨ç³»ã«å°ãããã«å¤æ´ããã¦ãã¾ãã
çµæ ç·´ç¿åé¡MDN.orthographicMatrix()
ãããã¾ãããã㯠CubeDemo.prototype.computePerspectiveMatrix()
ã® MDN.perspectiveMatrix()
颿°ãç½®ãæãããã¨ãã§ãã¾ããã°ã©ãã£ãã¯ã©ã¤ãã©ãªã¼ã®ä¸ã«ã¯ãã·ã¼ã³ãæ§æããéã«ä½ç½®ãç¹ãæå®ã§ããä»®æ³ã«ã¡ã©ãæã£ã¦ãããã®ãããã¾ãããOpenGLï¼ã²ãã¦ã¯ WebGLï¼ã«ã¯ããã¾ãããããã§ãã¥ã¼è¡åã®åºçªã§ãããã®ä»äºã¯ãã·ã¼ã³ã®ãªãã¸ã§ã¯ããå¹³è¡ç§»åãåè»¢ãæ¡å¤§ç¸®å°ããããã¥ã¼ã¢ã¼ã®ä½ç½®ã¨æ¹åããè¦ã¦ç¸å¯¾çã«æ£ããé ç½®ã«ãªãããã«ãããã¨ã§ãã
ã«ã¡ã©ã®ã·ãã¥ã¬ã¼ã·ã§ã³ããã¯ãã¢ã¤ã³ã·ã¥ã¿ã¤ã³ã®ç¹æ®ç¸å¯¾æ§çè«ã®åºæ¬çãªå´é¢ã®1ã¤ã使ç¨ãã¦ãã¾ããåç §ãã¬ã¼ã ã¨ç¸å¯¾éåã®åçã¯ãé²è¦§è ã®è¦ç¹ãããã·ã¼ã³å ã®ãªãã¸ã§ã¯ãã«å対ã®å¤æ´ãé©ç¨ãããã¨ã«ãã£ã¦ãé²è¦§è ã®ä½ç½®ã¨æ¹åã夿´ãããã¨ãã·ãã¥ã¬ã¼ã·ã§ã³ã§ããã¨è¨ãã¾ãããããã«ããããã®çµæã¯é²è¦§è ã«ã¯åãã«ç¾ãã¾ãã
ãã¼ãã«ã®ä¸ã«ç®±ãç½®ãã¦ããã 1 ã¡ã¼ãã«é¢ãããã¼ãã«ã®ä¸ã«ã«ã¡ã©ãç½®ãã¦ãããç®±ã®æ£é¢ãã«ã¡ã©ã«åãã¦ããã¨ãã¾ããæ¬¡ã«ãã«ã¡ã©ãç®±ãã 2 ã¡ã¼ãã«é¢ããã¾ã§ç§»åããï¼ã«ã¡ã©ã® Z ã®ä½ç½®ã« 1 ã¡ã¼ãã«è¶³ãï¼ã 10 ã»ã³ãå·¦å´ã«ã¹ã©ã¤ããããã¨ãã¾ããç®±ã¯ã«ã¡ã©ãããã®åé ããããå°ãå³ã«ã¹ã©ã¤ããã¾ãããããããã¨ã§ãã«ã¡ã©ã«ã¯å°ããç¾ããã«ã¡ã©ã«ã¯ç®±ã®å·¦å´ãå°ãå ¬éããã¾ãã
ããã§ã·ã¼ã³ã¯ãªã»ãããããç®±ã¯ãã®éå§ç¹ã«ã¯æ»ãããã«ã¡ã©ã¯ç®±ãã 2 ã¡ã¼ãã«é¢ããçæ£é¢ã«é ç½®ããã¾ããããããã®æãã«ã¡ã©ã¯ãã¼ãã«ã®ä¸ã«åºå®ãããç§»åãããåããå¤ããããããã¨ã¯ã§ãã¾ãããããã WebGL ã§ä½æ¥ããã¨ãã®ç¶æ ã§ããã§ã¯ã空éãéãã¦ã«ã¡ã©ãç§»åãããã«ã¯ã©ãããã°ããã®ã§ããããï¼
ã«ã¡ã©ã徿¹å·¦ã«ç§»åããã代ããã«ãé夿ãç®±ã«é©ç¨ãã¾ããç®±ã徿¹ã« 1 ã¡ã¼ãã«ç§»åãããæ¬¡ã«ãã®å³ã« 10 ã»ã³ãç§»åããã¾ãããã®çµæã 2 ã¤ã®ãªãã¸ã§ã¯ãããããã®è¦ç¹ä½ç½®ã¯åãã«ãªãã¾ãã
ãã®ãã¹ã¦ã®æçµæé ã¯ããã¥ã¼è¡åã使ãããã¨ã§ããããã¯ãã·ã¼ã³å ã®ãªãã¸ã§ã¯ãã夿ãã¦ãã«ã¡ã©ã®ç¾å¨ã®ä½ç½®ã¨æ¹åãã·ãã¥ã¬ã¼ã·ã§ã³ããããã«é ç½®ãã¾ãããã®ã¾ã¾ã®ã³ã¼ãã§ã¯ãã¯ã¼ã«ã空éã§ç«æ¹ä½ãåããã¦ããã¹ã¦ãè¦ç¹ä½ç½®ãããããã«æå½±ãããã¨ã¯ã§ãã¾ãããã«ã¡ã©ãç§»åããããã¨ã¯ã§ãã¾ããã
ç©ççãªã«ã¡ã©ã§æ ç»ãæ®å½±ãããã¨ãæ³åãã¦ã¿ã¦ãã ãããã«ã¡ã©ãåºæ¬çã«å¥½ããªå ´æã«é ç½®ãã好ããªæ¹åã«ã«ã¡ã©ãåããèªç±ãããã¾ããããã3Dã°ã©ãã£ãã¯ã§ã·ãã¥ã¬ã¼ã·ã§ã³ããããã«ãç§ãã¡ã¯ãã¥ã¼è¡åã使ç¨ãã¦ãç©ççãªã«ã¡ã©ã®ä½ç½®ã¨å転ãã·ãã¥ã¬ã¼ã·ã§ã³ãã¾ãã
ã¢ãã«ã®é ç¹ãç´æ¥å¤æããã¢ãã«è¡åã¨ã¯ç°ãªãããã¥ã¼è¡åã¯æ½è±¡çãªã«ã¡ã©ãç§»åããã¾ããå®éã«ã¯ãé ç¹ã·ã§ã¼ãã¼ã¯ã¢ãã«ãç§»åãããã ãã§ããã«ã¡ã©ãã¯ãã®å ´ã«çã¾ãã¾ããããããã¾ãè¡ãã«ã¯ã夿è¡åã®éè¡åã使ç¨ããªããã°ãªãã¾ãããéè¡åã¯æ¬è³ªçã«å¤æãå転ãããã®ã§ãã«ã¡ã©ãã¥ã¼ãåæ¹ã«ç§»åãããã¨ãéè¡åã¯ã·ã¼ã³å ã®ãªãã¸ã§ã¯ãã徿¹ã«ç§»åããã¾ãã
以ä¸ã® computeViewMatrix()
ã¡ã½ããã§ã¯ããã¥ã¼è¡åãã¢ãã¡ã¼ã·ã§ã³ã®ããã«å
ã¨å¤ãå·¦ã¨å³ã«ç§»åãã¾ãã
CubeDemo.prototype.computeViewMatrix = function (now) {
const moveInAndOut = 20 * Math.sin(now * 0.002);
const moveLeftAndRight = 15 * Math.sin(now * 0.0017);
// Move the camera around
const position = MDN.translateMatrix(moveLeftAndRight, 0, 50 + moveInAndOut);
// Multiply together, make sure and read them in opposite order
const matrix = MDN.multiplyArrayOfMatrices([
// Exercise: rotate the camera view
position,
]);
// Inverse the operation for camera movements, because we are actually
// moving the geometry in the scene, not the camera itself.
this.transforms.view = MDN.invertMatrix(matrix);
};
ããã§ãã·ã§ã¼ãã¼ã¯ 3 ã¤ã®è¡åã使ç¨ããããã«ãªãã¾ãã
gl_Position = projection * view * model * vec4(position, 1.0);
ãã®æé ã®å¾ã GPU ãã¤ãã©ã¤ã³ã¯ç¯å²å¤ã®é ç¹ãã¯ãªããããã©ã¹ã¿ã©ã¤ãºã®ããã«ã¢ãã«ããã©ã°ã¡ã³ãã·ã§ã¼ãã¼ã«éãã¾ãã
çµæ ç¸å¯¾åº§æ¨ç³»ãã®æç¹ã§ã䏿©ä¸ãã£ã¦ã使ç¨ãã¦ããæ§ã ãªåº§æ¨ç³»ãè¦ã¦ã©ãã«ä»ããããã¨ãæçã§ããããã¾ãæåã«ãç«æ¹ä½ã®é ç¹ã¯ ã¢ãã«ç©ºé ã§å®ç¾©ãã¾ããã¢ãã«ãã·ã¼ã³ã®å¨ãã§ç§»ãããããã§ãããããã®é ç¹ã¯ãã¢ãã«è¡åãé©ç¨ãã¦ã¯ã¼ã«ã空éã«å¤æããå¿ è¦ãããã¾ãã
ã¢ãã«ç©ºé â ã¢ãã«è¡å â ã¯ã¼ã«ã空é
ã«ã¡ã©ã¯ã¾ã ä½ããã®åãããã¦ããªãã®ã§ããã®ç¹ã¯ããä¸åº¦ç§»åããå¿ è¦ãããã¾ããç¾å¨ã¯ã¯ã¼ã«ã空éã«ããã¾ãããã«ã¡ã©ã®é ç½®ã表ãããã«ãã¥ã¼ç©ºéã«ç§»åããå¿ è¦ãããã¾ãï¼ãã¥ã¼è¡åã使ç¨ãã¾ãï¼ã
ã¯ã¼ã«ã空é â ãã¥ã¼è¡å â ãã¥ã¼ç©ºé
æå¾ã«ãã¯ã¼ã«ã座æ¨ãã¯ãªãã空é座æ¨ã«å²ãå½ã¦ãããã«ãæå½±ï¼ããã§ã¯è¦ç¹ä½ç½®æå½±è¡åï¼ã追å ããå¿ è¦ãããã¾ãã
ãã¥ã¼ç©ºé â æå½±è¡å â ã¯ãªãã空é
ç·´ç¿åé¡RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4