Open3

WebGPUの細かいテクニック達

shogonirshogonir

キャスト

シェーダ(WGSL)のコードでキャストしたい場合は T() のように「型の名前 + 丸カッコ」と書く。
以下は例のソースコード。u32 型を f32 にキャストしている。

struct VertexInput {
  @location(0) position: vec3f,
  @builtin(vertex_index) vertexId: u32,
};

@vertex
fn vertexMain(input: VertexInput) -> VertexOutput {
  let half = f32(input.vertexId) / 2.0; // u32型をf32型にキャストする例
  ...
}
shogonirshogonir

三項演算子

シェーダ(WGSL)内では三項演算子はないので、組み込み関数の select() を使う。
select(f, t, condition) のようにすると、 conditiontrue の場合は t を、false の場合は f を返す。
条件が true の時に、第一引数ではなく第二引数を返す点に注意が必要。

仕様書はこちら。
https://www.w3.org/TR/WGSL/#select-builtin

shogonirshogonir

複数のオブジェクトを描画する

これはテクニックというより自分の凡ミスだったのですが、同じ問題にハマる人も少しはいるかもということでメモしておきます。

2つのオブジェクトを表示できないぞと思ったら、2つ目のオブジェクトの beginRenderPass の時に loadOp: 'clear' で描画内容をクリアしていただけでした。。笑

まずは問題のソースコード例。

// 2つ目のオブジェクト描画
const renderPass = encoder.beginRenderPass({
  colorAttachments: [
    {
      view: webgpu.getCurrentTexture().createView(),
      loadOp: 'clear',
      storeOp: 'store',
    },
  ],
});
// 中略
renderPass.drawIndexed(geometry.indexCount);
renderPass.end();
device.queue.submit([encoder.finish()]);

loadOp: 'load' にすることで前回の描画内容を引き継げます。

// 2つ目のオブジェクト描画
const renderPass = encoder.beginRenderPass({
  colorAttachments: [
    {
      view: webgpu.getCurrentTexture().createView(),
      loadOp: 'load', // <- ここが変更箇所
      storeOp: 'store',
    },
  ],
});
// 中略
renderPass.drawIndexed(geometry.indexCount);
renderPass.end();
device.queue.submit([encoder.finish()]);