2
4

WebGLを用いた赤色三角形描画の計算プロセスに関する考察 という論文風のブログ記事。

Last updated at Posted at 2024-09-12

image.png

WebGLを用いた赤色三角形描画の計算プロセスに関する考察

  1. はじめに
    本稿では、WebGLを用いて二次元空間における赤色の三角形を描画するプロセスについて論じる。WebGLは、ブラウザ上で動作するOpenGL ESの仕様を基にしたAPIであり、HTML5に統合されている。本研究は、WebGLを通じたグラフィックス処理の基礎的な実装を通して、その計算プロセスとレンダリング手法の理解を深めることを目的とする。

  2. 初期化プロセス
    2.1 WebGLコンテキストの取得
    描画処理は、WebGLコンテキストの初期化から開始される。本研究では、HTML内の要素に対してgetContext()メソッドを用いてWebGLコンテキストを取得する。このコンテキストは、GPUを用いた描画処理の基盤となるものであり、図形の頂点情報や色の指定、レンダリングパイプラインの構成など、すべてのWebGL操作の起点となる。


var gl = canvas.getContext("webgl") || canvas.getContext("experimental-webgl");

ここでは、webglのコンテキストが利用可能か確認し、もし利用できない場合は、互換性のためにexperimental-webglが使用される。

2.2 背景色の設定
取得したWebGLコンテキストに対して、gl.clearColor()を用いて背景色を設定する。本研究では、背景色を黒(0, 0, 0, 1)に設定している。続いてgl.clear()を呼び出し、画面全体を指定された色で塗りつぶす。


gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
  1. シェーダーの設定
    3.1 頂点シェーダー
    シェーダーはGPUで実行されるプログラムであり、頂点シェーダーとフラグメントシェーダーに分けられる。本研究では、頂点シェーダーにおいて、三角形の各頂点の位置情報を処理する。以下のコードは、頂点の座標をaVertexPositionとして受け取り、クリップ空間に変換するプロセスを示す。

attribute vec2 aVertexPosition;
void main(void) {
    gl_Position = vec4(aVertexPosition, 0.0, 1.0);
}

ここでは、2次元ベクトルaVertexPositionを受け取り、gl_Positionに代入することで、三次元のクリップ空間に変換される。

3.2 フラグメントシェーダー
フラグメントシェーダーでは、各ピクセルの色を指定する。本研究では、赤色(1.0, 0.0, 0.0, 1.0)で三角形を描画する。


void main(void) {
    gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);  // Red color
}

gl_FragColorは、描画対象のピクセルの色を指定するための変数であり、RGBA形式で色を設定する。

  1. バッファの初期化
    4.1 頂点バッファの生成
    WebGLの描画プロセスにおいて、頂点バッファは重要な役割を果たす。頂点バッファは、描画する図形の頂点情報を格納するためのデータ構造である。本研究では、三角形の3つの頂点の座標をFloat32Arrayとして格納し、WebGLのバッファに転送する。

var triangleVertices = new Float32Array([
    0.0,  0.5,
   -0.5, -0.5,
    0.5, -0.5
]);

このコードは、頂点バッファ内に三角形の各頂点の位置を指定している。各頂点は、WebGLの座標系に基づき、2次元平面上の位置を示す。

4.2 バッファのバインドと転送
次に、gl.createBuffer()を用いてバッファを生成し、gl.bindBuffer()によってバッファをバインドする。頂点データをgl.bufferData()によってWebGLに転送し、描画時に使用される。


var triangleBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, triangleBuffer);
gl.bufferData(gl.ARRAY_BUFFER, triangleVertices, gl.STATIC_DRAW);

この処理により、GPU上に頂点データが格納され、描画処理の際に参照可能となる。

  1. 描画プロセス
    5.1 頂点データの指定
    描画プロセスでは、まずシェーダーに頂点データを渡す必要がある。gl.vertexAttribPointer()を用いて、シェーダーに頂点属性の情報を指定する。

gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, 2, gl.FLOAT, false, 0, 0);

ここでは、三角形の頂点データを、2つの浮動小数点数としてシェーダーに渡す設定を行っている。

5.2 描画の実行
頂点データの指定が完了した後、gl.drawArrays()を用いて、三角形を描画する。gl.TRIANGLESを用いることで、3つの頂点を三角形として解釈し、描画する。


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

この処理により、WebGLはGPUを用いて赤色の三角形を描画する。頂点データは事前に指定された座標に基づいて解釈され、フラグメントシェーダーで指定された色でレンダリングされる。

  1. 結論
    本研究では、WebGLを用いて赤色の三角形を描画する計算プロセスについて詳細に考察した。WebGLは、ブラウザ上でGPUを利用した高速なグラフィックス描画を実現するための強力なAPIであり、頂点バッファ、シェーダープログラム、描画命令の順に計算プロセスが進行する。本稿で示したプロセスは、WebGLの基本的な動作原理を理解する上で有用であり、さらなるグラフィックスアプリケーション開発の基礎となるものである。

参考文献
Khronos Group. "WebGL Specification." https://www.khronos.org/webgl/ (参照日: 2024年9月).

HTMLとWebGLを使用して簡単な赤い三角形を描画するコードです。

image.png


<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>WebGL 赤い三角形</title>
    <style>
        body { margin: 0; }
        canvas { display: block; }
    </style>
</head>
<body>
    <!-- キャンバス要素 -->
    <canvas id="glcanvas" width="640" height="480"></canvas>
    
    <script>
        // WebGLのコンテキストを初期化する関数
        function initWebGL(canvas) {
            // WebGLコンテキストを取得(標準的なWebGLが使えない場合は実験的なものを使用)
            var gl = canvas.getContext("webgl") || canvas.getContext("experimental-webgl");
            if (!gl) {
                alert("WebGLがサポートされていません。");
                gl = canvas.getContext("experimental-webgl");
            }
            if (!gl) {
                alert("このブラウザはWebGLをサポートしていません。");
            }
            return gl;
        }

        // シェーダーを初期化する関数
        function initShaders(gl) {
            // 頂点シェーダーのソースコード
            var vsSource = `
                attribute vec2 aVertexPosition;
                void main(void) {
                    gl_Position = vec4(aVertexPosition, 0.0, 1.0);
                }
            `;

            // フラグメントシェーダーのソースコード(赤色を指定)
            var fsSource = `
                void main(void) {
                    gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);  // 赤色
                }
            `;

            // 頂点シェーダーを作成してコンパイル
            var vertexShader = gl.createShader(gl.VERTEX_SHADER);
            gl.shaderSource(vertexShader, vsSource);
            gl.compileShader(vertexShader);

            // フラグメントシェーダーを作成してコンパイル
            var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
            gl.shaderSource(fragmentShader, fsSource);
            gl.compileShader(fragmentShader);

            // シェーダープログラムを作成してシェーダーをリンク
            var shaderProgram = gl.createProgram();
            gl.attachShader(shaderProgram, vertexShader);
            gl.attachShader(shaderProgram, fragmentShader);
            gl.linkProgram(shaderProgram);

            // シェーダープログラムが正しくリンクされたかを確認
            if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
                alert("シェーダープログラムの初期化に失敗しました。");
            }

            // シェーダープログラムを使用
            gl.useProgram(shaderProgram);
            shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");
            gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);

            return shaderProgram;
        }

        // 三角形の頂点データをバッファに設定する関数
        function initBuffers(gl) {
            // 三角形の頂点座標を定義
            var triangleVertices = new Float32Array([
                0.0,  0.5,   // 上の頂点
               -0.5, -0.5,   // 左下の頂点
                0.5, -0.5    // 右下の頂点
            ]);

            // バッファを作成してデータを転送
            var triangleBuffer = gl.createBuffer();
            gl.bindBuffer(gl.ARRAY_BUFFER, triangleBuffer);
            gl.bufferData(gl.ARRAY_BUFFER, triangleVertices, gl.STATIC_DRAW);

            return triangleBuffer;
        }

        // シーンを描画する関数
        function drawScene(gl, shaderProgram, triangleBuffer) {
            // 画面をクリア
            gl.clear(gl.COLOR_BUFFER_BIT);

            // バッファから頂点データを取り出してシェーダーに送信
            gl.bindBuffer(gl.ARRAY_BUFFER, triangleBuffer);
            gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, 2, gl.FLOAT, false, 0, 0);

            // 三角形を描画
            gl.drawArrays(gl.TRIANGLES, 0, 3);
        }

        // 実行開始
        function start() {
            // キャンバスを取得
            var canvas = document.getElementById("glcanvas");

            // WebGLコンテキストを初期化
            var gl = initWebGL(canvas);
            if (!gl) return;

            // 背景色(黒)を設定してクリア
            gl.clearColor(0.0, 0.0, 0.0, 1.0);
            gl.clear(gl.COLOR_BUFFER_BIT);

            // シェーダーとバッファを初期化
            var shaderProgram = initShaders(gl);
            var triangleBuffer = initBuffers(gl);

            // 三角形を描画
            drawScene(gl, shaderProgram, triangleBuffer);
        }

        // ページが読み込まれたらstart関数を実行
        window.onload = start;
    </script>
</body>
</html>

説明
このコードは、WebGLを使用してキャンバス上に赤い三角形を描画します。
initWebGL()関数でWebGLコンテキストを初期化します。
initShaders()関数でシェーダーを設定し、三角形の座標を頂点シェーダーに渡し、赤色をフラグメントシェーダーで設定しています。
initBuffers()関数で三角形の頂点バッファを設定し、drawScene()関数で三角形を描画します。
このコードをブラウザで開くと、赤い三角形が表示されます。

2
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
4