WebGL - キューブの回転
こんにちは、未来のWebGL魔術師たち!今日は、3Dグラフィックスの世界への興奮的な旅を始めます。このチュートリアルの最後に、あなたはWebGLを使って回転するキューブを作成できるようになるでしょう。素晴らしいですね?さあ、潜りましょう!
基本を理解する
キューブをDJのように回転させる前に、いくつかの基本的な概念を理解しましょう。
WebGLとは?
WebGL(Web Graphics Library)は、ブラウザ内で3Dグラフィックスを描画するためのJavaScript APIです。まるでブラウザに3D眼鏡を装着しているようなものです!
なぜキューブ?
「なぜキューブから始めるのか」と疑うかもしれません。そうですね、私の愛する学生们、キューブは3Dグラフィックスの「Hello World」とも言えます。簡単で理解しやすく、同時に重要な概念を教えてくれます。そして、誰もがキューブが好きですよね?
WebGL環境の設定
HTMLキャンバス
まず最初に、キューブがパフォーマンスを行うステージが必要です。WebGLでは、このステージをキャンバスと呼びます。以下のように設定しましょう:
<canvas id="glcanvas" width="640" height="480">
あなたのブラウザはHTML5キャンバスをサポートしていません
</canvas>
これで640x480ピクセルのキャンバスが作成されます。見えない場合は、今は無視して構いません - 現在は無形のダンスフロアのようなものです。
WebGLの初期化
次に、WebGLをパーティーの準備にしましょう:
var canvas = document.getElementById('glcanvas');
var gl = canvas.getContext('webgl');
if (!gl) {
console.log('WebGLがサポートされていません。experimental-webglにフォールバックします');
gl = canvas.getContext('experimental-webgl');
}
if (!gl) {
alert('あなたのブラウザはWebGLをサポートしていません');
}
このコードでWebGLのコンテキストを取得します。ブラウザがWebGLをサポートしていない場合、DVDをVHSプレイヤーで再生しようとするようなものです - 効かないでしょう!
3Dキューブの作成
頂点の定義
キューブには8つの角(頂点)があります。これらの角がどこにあるかをWebGLに伝える必要があります:
var vertices = [
//前面
-1.0, -1.0, 1.0,
1.0, -1.0, 1.0,
1.0, 1.0, 1.0,
-1.0, 1.0, 1.0,
//後面
-1.0, -1.0, -1.0,
-1.0, 1.0, -1.0,
1.0, 1.0, -1.0,
1.0, -1.0, -1.0,
//上面
-1.0, 1.0, -1.0,
-1.0, 1.0, 1.0,
1.0, 1.0, 1.0,
1.0, 1.0, -1.0,
//下面
-1.0, -1.0, -1.0,
1.0, -1.0, -1.0,
1.0, -1.0, 1.0,
-1.0, -1.0, 1.0,
//右面
1.0, -1.0, -1.0,
1.0, 1.0, -1.0,
1.0, 1.0, 1.0,
1.0, -1.0, 1.0,
//左面
-1.0, -1.0, -1.0,
-1.0, -1.0, 1.0,
-1.0, 1.0, 1.0,
-1.0, 1.0, -1.0
];
この3つの数のセットは、キューブの角を3D空間上で表現しています。まるでWebGLにキューブの地図を渡しているようなものです!
バッファーの作成
次に、このデータをGPUに送信する必要があります:
var vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
これは、キューブをスーツケース(バッファー)に詰め、GPUに送信するようなものです。
シェーダー - WebGLの魔術師
頂点シェーダー
頂点シェーダーは、頂点の位置を設定します:
var vertexShaderSource = `
attribute vec3 aVertexPosition;
uniform mat4 uModelViewMatrix;
uniform mat4 uProjectionMatrix;
void main(void) {
gl_Position = uProjectionMatrix * uModelViewMatrix * vec4(aVertexPosition, 1.0);
}
`;
このシェーダーは各頂点に変換行列を適用します。まるで魔術師がキューブの角を動かしているようなものです!
フラグメントシェーダー
フラグメントシェーダーは、キューブを色付けします:
var fragmentShaderSource = `
void main(void) {
gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
}
`;
このシンプルなシェーダーはすべてを白色にします。まるでキューブを塗装しているようなものです!
シェーダーのコンパイルとリンク
次に、シェーダーをコンパイルし、プログラムにリンクします:
function getShader(gl, source, type) {
var shader = gl.createShader(type);
gl.shaderSource(shader, source);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
alert('シェーダーのコンパイルにエラーが発生しました: ' + gl.getShaderInfoLog(shader));
return null;
}
return shader;
}
var vertexShader = getShader(gl, vertexShaderSource, gl.VERTEX_SHADER);
var fragmentShader = getShader(gl, fragmentShaderSource, gl.FRAGMENT_SHADER);
var shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader);
gl.linkProgram(shaderProgram);
if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
alert('シェーダープログラムの初期化に失敗しました: ' + gl.getProgramInfoLog(shaderProgram));
}
gl.useProgram(shaderProgram);
これは、魔術師(シェーダー)に技を教え、ステージに立てるようなものです!
キューブの回転
回転の設定
キューブを回転させるためには、時間とともに回転角度を更新する必要があります:
var cubeRotation = 0.0;
var then = 0;
function render(now) {
now *= 0.001; //秒に変換
const deltaTime = now - then;
then = now;
cubeRotation += deltaTime;
drawScene();
requestAnimationFrame(render);
}
この関数は繰り返し呼び出され、キューブの回転を更新します。
シーンの描画
次に、すべてをまとめ、回転するキューブを描画しましょう:
function drawScene() {
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
const projectionMatrix = mat4.create();
mat4.perspective(projectionMatrix, 45 * Math.PI / 180, gl.canvas.clientWidth / gl.canvas.clientHeight, 0.1, 100.0);
const modelViewMatrix = mat4.create();
mat4.translate(modelViewMatrix, modelViewMatrix, [-0.0, 0.0, -6.0]);
mat4.rotate(modelViewMatrix, modelViewMatrix, cubeRotation, [0, 1, 1]);
gl.uniformMatrix4fv(gl.getUniformLocation(shaderProgram, 'uProjectionMatrix'), false, projectionMatrix);
gl.uniformMatrix4fv(gl.getUniformLocation(shaderProgram, 'uModelViewMatrix'), false, modelViewMatrix);
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 36);
}
この関数はキャンバスをクリアし、視点を設定し、回転を適用し、最後にキューブを描画します。
結論
そして、みなさん!私たちはWebGLを使って回転する3Dキューブを作成しました。WebGLをマスターすることは、ジャグリングするのと同じで - 練習は必要ですが、一度習ったら素晴らしいことができます!
以下に、私たちが使用した主要なメソッドの表を示します:
メソッド | 説明 |
---|---|
gl.createBuffer() |
新しいバッファーオブジェクトを作成します |
gl.bindBuffer() |
バッファーオブジェクトをターゲットにバインドします |
gl.bufferData() |
バッファーオブジェクトのデータストアを作成および初期化します |
gl.createShader() |
シェーダーオブジェクトを作成します |
gl.shaderSource() |
シェーダーオブジェクトのソースコードを設定します |
gl.compileShader() |
シェーダーオブジェクトをコンパイルします |
gl.createProgram() |
プログラムオブジェクトを作成します |
gl.attachShader() |
シェーダーオブジェクトをプログラムオブジェクトにアタッチします |
gl.linkProgram() |
プログラムオブジェクトをリンクします |
gl.useProgram() |
指定されたプログラムを現在の描画状態として設定します |
gl.clear() |
バッファーを预设の値にクリアします |
gl.uniformMatrix4fv() |
現在のプログラムのユニフォーム変数の値を設定します |
gl.drawArrays() |
配列データからプリミティブをレンダリングします |
練習を続け、コードを書き続けると、すぐにブラウザ内で素晴らしい3Dグラフィックスを作成できるようになります。ハッピーコーディング!
Credits: Image by storyset