Skip to content

レンダリングプロセス

最終更新日時: 2025年08月25日 12:57

  • nothing

THREE.js/WebGL のレンダリングプロセス

Section titled “THREE.js/WebGL のレンダリングプロセス”
  1. CPU 側で WebGL のセットアップ

    • THREE.WebGLRenderer()でHTMLのcanvas要素の生成or設定とrendererを生成
    • シーンの作成(オブジェクト、ライトなど)
    • ジオメトリ、マテリアルを用意し、Meshを設定
    • ShaderMaterial/RawShaderMaterialでシェーダーを設定
      • MeshStandardMaterial や MeshBasicMaterial などの組み込みマテリアルは GLSL シェーダーを内部で保持している
    • renderer.render(scene,camera)で描画命令
    • WebGL API を介して GPU にデータを送信
  2. GPU での処理

    • 頂点シェーダー(Vertex Shader)
      • 3D 座標をスクリーン座標へ変換
      • gl_Position に結果を出力
    • クリッピングとビューポート変換
      • 各頂点の座標を NDC(クリッピング座標) に変換
      • 視錐台外の部分を破棄(クリッピング)
      • NDC をスクリーン座標に変換(ビューポート変換)
    • ラスタライズ(Rasterization)
      • gl_Position の情報を元に、画面のピクセルへ変換
    • フラグメントシェーダー(Fragment Shader)
      • 各ピクセルの色を計算し、out vec4 FragColorに出力
        • gl_FragColor は GLSL 4.1 以降で非推奨
        • gl_FragColorはGLSL 3.0以降では使われない
    • フレームバッファへの出力
      • フラグメントシェーダーの結果を GPU のフレームバッファへ保存
      • 画面にレンダリングされる

フレームバッファ(Framebuffer)は、GPU が描画結果を一時的に格納するメモリ領域である。 すべてのレンダリング結果(ピクセルデータ、深度情報、ステンシルバッファなど)がここに保存され、 最終的に画面へ出力される。

WebGL では、フレームバッファのクリア動作がデフォルトで有効になっており、 各フレームの描画後にその内容が消去される。 これにより、特定のシナリオ(画像の保存など)で問題が発生することがある。

  • WebGLRendererはHTMLに設定したcanvas要素を渡してレンダラーを生成する場合と、 canvas要素を渡さないで自動生成させる場合がある。
  • どちらの場合でもrenderer.domElementがcanvas要素として参照可能。
<canvas id="myCanvas"></canvas>
<script>
const canvas = document.getElementById("myCanvas");
const renderer = new THREE.WebGLRenderer({ canvas });
</script>
const renderer = new THREE.WebGLRenderer();
document.body.appendChild(renderer.domElement);

CPU 側で描画結果の取得し、ファイル出力する方法

Section titled “CPU 側で描画結果の取得し、ファイル出力する方法”
  • preserveDrawingBuffer: true の設定を行う必要がある。
  • デフォルトでは preserveDrawingBuffer: false で、 各フレーム描画後にフレームバッファはクリアされる
  • preserveDrawingBuffer: true に設定すると、描画結果が次のフレームまで維持される。
// Three.js シーン & カメラ設定
const scene = new THREE.Scene();
const camera = new THREE.OrthographicCamera(-1, 1, 1, -1, 0.1, 10);
camera.position.z = 1;
const renderer = new THREE.WebGLRenderer({ canvas,preserveDrawingBuffer: true});
renderer.setSize(window.innerWidth, window.innerHeight);
// 変換後のテクスチャを保存
const saveButton = document.getElementById("saveButton") as HTMLButtonElement;
saveButton.addEventListener("click", () => {
renderer.domElement.toBlob((blob) => {
if (!blob) return;
const link = document.createElement("a");
link.href = URL.createObjectURL(blob);
link.download = "output_texture.png";
link.click();
});
});

  • renderer.domElementはhtml内部にあるcanvas要素である
    • メリット

      • toBlob()readPixels() を使用して 描画結果を保存できる
      • 連続したフレームのキャプチャ や 静止画のエクスポート が可能
      • バッファを活用したポストプロセス効果(一時的に保存したフレームを利用する)
    • デメリット

      • パフォーマンスの低下(フレームごとに不要なバッファが保持されるため、VRAM の使用量が増加)
      • 一部のWebGL実装では preserveDrawingBuffer: true がサポートされていないことがある
      • 手動でのバッファクリアが必要になる(新しいフレームを描画する際に gl.clear() を明示的に呼ぶ必要がある)

WebGLRenderer のその他のオプション

Section titled “WebGLRenderer のその他のオプション”
  • WebGLRenderer には、以下のオプションが存在する。
オプション説明デフォルト値
canvas描画する HTMLCanvasElementundefined
context既存の WebGL コンテキストを使用undefined
precisionシェーダーの浮動小数点精度
highp, mediump, lowp
highp
alpha背景のアルファチャンネルを有効にするfalse
depth深度バッファを有効にするtrue
stencilステンシルバッファを有効にするtrue
antialiasアンチエイリアスを有効にするfalse
premultipliedAlphatrue の場合、アルファ値を事前乗算true
preserveDrawingBuffer描画バッファを保持するかfalse
powerPreferenceGPU の電力設定
high-performance, low-power, default
default
failIfMajorPerformanceCaveatパフォーマンスの低い GPU でレンダリングを拒否するfalse
xrCompatibleWebXR 互換モードを有効にするfalse
  • WebGLRenderer の precision オプションは、シェーダーの precision 指定と異なり、レンダリング全体の精度を設定する。一般的に、WebGLRendererprecision はデフォルトで highp となっており、シェーダーの precision 指定がない場合に適用される。
  • シェーダー内で明示的に precision highp float; を指定すれば、その設定が優先される。

ステンシルバッファの効果とメリット・デメリット

Section titled “ステンシルバッファの効果とメリット・デメリット”
  • メリット
    • 複雑なマスク処理(特定の領域のみ描画するなど)が可能。
    • マルチパスレンダリングで一部のオブジェクトのみ影響を受ける処理が可能。
  • デメリット:
    • メモリ使用量が増加。
    • すべてのデバイスでサポートされているわけではない。
  • メリット
    • エッジのギザギザを滑らかにすることで、レンダリングの品質が向上。
  • デメリット:
    • 計算負荷が増大し、GPU の処理が重くなる。
    • モバイルデバイスでは負荷が大きく、パフォーマンスが低下する可能性がある。