黒い三角形を1個だけ描画する

黒い三角形を1個だけ描画する

やっと三角形を1個だけ描画するところまできました(図3)。これだけのことなのに、これほど面倒ですね。今後の回以降はこれに肉付けしていき、複数の三角形を描画してオブジェクトを作ったり、様々な色にしたり、テクスチャを貼ったり、移動したり、アニメーションしたりします。

図3:黒い三角形を1個だけ描画

「index.html」ファイルで「lib」→「Model3D.js」を読み込む

三角形のデータを保持するクラスとして「Model3D」クラスをコーディングする「Model3D.js」ファイルを読み込みます。<script>タグの「init」関数でModel3Dクラスのインスタンスを生成して「_model」変数に代入し、頂点バッファを初期化します。「draw」関数でモデルを描画します。

・サンプルコード「index.html」
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8">
    <title>UltraMotion3D</title>
    <script src="lib/Model3D.js"></script>
    <script src="lib/WGSL.js"></script>
    <script src="lib/UltraMotion3D.js"></script>
    <script type="text/javascript">
var _model;
  
function init() {
  _model = new Model3D();
  _model.initBuffers();
}

function draw() {
  _model.draw();
}
    </script>
  </head>
  <body onload='initWebGPU("CanvasAnimation");'>
    <canvas id="CanvasAnimation" width="1000" height="900"></canvas>
  </body>
</html>

「lib」→「UltraMotion3D.js」に追記する

次のサンプルコードを「UltraMotion3D.js」ファイルに追記します。背景色を(R,G,B,A)=(1.0,1.0,1.0,1.0)の真っ白に変えました。描画のタイミングで「index.html」の「draw」関数を呼び出しているだけです。

・サンプルコード「lib」→「UltraMotion3D.js」
var _passEncoder = null;

async function initWebGPU(canvas) {
(中略)
}

function setPipeline(vertexWGSL,fragmentWGSL) {
(中略)
}

function everyFrame() {
  _commandEncoder = _device.createCommandEncoder();
  const textureView = _context.getCurrentTexture().createView();
  _renderPassDescriptor = {
    colorAttachments: [
      {
        view: textureView,
        clearValue: { r: 1.0, g: 1.0, b: 1.0, a: 1.0 },
        loadOp: 'clear',
        storeOp: 'store',
      },
    ],
    depthStencilAttachment: {
      view: _depthTexture.createView(),
      depthClearValue: 1.0,
      depthLoadOp: 'clear',
      depthStoreOp: 'store',
    },
  };
  _passEncoder = _commandEncoder.beginRenderPass(_renderPassDescriptor);
  draw();
  _passEncoder.end();
  _device.queue.submit([_commandEncoder.finish()]);
}

function resize() {
(中略)
}

Model3Dクラスを実装する

「lib」→「Model3D.js」ファイルに3Dモデルを持つModel3Dクラスを宣言します。コンストラクタで3頂点と、それらを指すインデックスのプロパティを宣言します。「initBuffers」メソッドで頂点を入れるバッファを用意します。「draw」メソッドで3頂点の三角形を描画します。

次のサンプルコードを実装したら、index.htmlファイルをGoogle Chromeで開いてください。黒い三角形が表示されましたね。

・サンプルコード「lib」→「Model3D.js」
class Model3D {
  constructor() {
    this.vertices = [0,1,0,1, -1,-1,0,1, 1,-1,0,1];
    this.indices = [0,1,2];
  }
  initBuffers() {
    this.vertexArray = new Float32Array(this.vertices);
    this.verticesBuffer = _device.createBuffer({
      size: this.vertexArray.byteLength,
      usage: GPUBufferUsage.VERTEX,
      mappedAtCreation: true,
    });
    new Float32Array(this.verticesBuffer.getMappedRange()).set(this.vertexArray);
    this.verticesBuffer.unmap();
  }
  getVertexCount() {
    return ~~(this.vertexArray.length/4);
  }
  draw() {
    _passEncoder.setPipeline(_pipeline);
    _passEncoder.setVertexBuffer(0,this.verticesBuffer);
    _passEncoder.draw(this.getVertexCount());
  }
}

【サンプルコードの解説】
コンストラクタ(「constructor」メソッド)で(X,Y,Z,W)の3頂点を「vertices」プロパティに代入し、3頂点を指すインデックスを「indices」プロパティに代入します。
「initBuffers」メソッドでverticesプロパティは「Float32Array」配列に変換し、頂点バッファに入れます。
「draw」メソッドでパスエンコーダーにパイプラインをセットし、頂点バッファをセットして頂点の数だけ描画します。

【コラム】「CUI→GUI→?の次を考え出したい」

新たなユーザーインターフェースを生み出したいです。昔は文字だけでOSを操っていて、今はグラフィカルにマウスでOSを操ります。そこでその次を考えていて、誰でも使えるぐらいシンプルなOSのユーザーインターフェースを考えました。例えば「Webブラウザを起動しますか?」と聞かれたら、YesかNoだけで答えます。他にも全てYesかNoだけで操作します。でも、あまりにも自由度が低過ぎました…。

おわりに

今回は3つの頂点をシェーダーに渡し、それを囲んで真っ黒な三角形を描画する解説をしました。まだ色のデータは渡していないため、フラグメントシェーダーの中で黒色限定で塗ってみました。

次回は、ベクトルとベクトルの計算を実装する解説をします。

この記事のキーワード :

人気記事トップ10

人気記事ランキングをもっと見る

企画広告も役立つ情報バッチリ! Sponsored

ClickHouse Cloudが実現した広告運用SaaS「ATOM」のデータ基盤革新、パフォーマンスを向上しながら、運用負荷とコストを削減 11月11日 6:20 AIで開発が加速する時代、品質保証はどう変わる? Tricentisが示すAIエージェント活用の実像 11月9日 6:45 悪用までの猶予が「1分」に迫るフロンティアAI時代に開発と本番を貫く脆弱性管理が必要 10月29日 8:30 欧州CRA対応とSBOM運用。AI生成コードのOSS混入問題の対策とは ――スニペット単位で検出する「FossID」「Insignary Clarity」によるSBOM運用 9月16日 6:40 PostgreSQLからTiDBへ、稼働中SaaSで進める段階的DB移行の実践と再設計への展望 9月7日 6:30 機能安全開発におけるGoogleTestの活用を支援!「Parasoft C/C++test CT」で実現する効率化&AI連携 4月14日 6:30 【CNDW2025】Grafanaが明かす「オブザーバビリティの哲学」ー最小限の労力で実用的なインサイトを得るには 1月23日 6:30 【CNDW2025】プロダクト急増に備える基盤刷新 ーウェルスナビがECSからEKSへの移行で得た知見とは 1月15日 6:30 【CNDW2025】250環境を5人で運用、構築時間は30分に ーKINTOテクノロジーズが語るインフラ基盤組織の作り方 2025年12月18日 6:30 新たな自動化で熱視線! AIエージェントの「推論能力」を支える2つのコンポーネントとは? 2025年11月28日 6:30