天天看點

WebGPU[5] uniform顔色

代碼見:https://github.com/onsummer/my-dev-notes/tree/master/webgpu-Notes/05-uniform-color

原創,釋出日 2021年4月6日,更新日 2021年5月6日,@秋意正寒。若代碼失效請留言,或自行到官網根據最新 API 修改。

簡介

WebGPU[5] uniform顔色

這個案例示範 uniform 資料如何傳入着色器。

以一個綠色值為例,直接傳遞到片元着色器,令所有顔色為

vec4<f32>(0.0, 0.5, 0.0, 1.0)

1 建立

uniform buffer

const uniformBufferSize = 4 * 4 // vec4<f32>,即 16 byte
const uniformBuffer = device.createBuffer({
  size: uniformBufferSize,
  usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
})
/* 建立綁定組對象,細節參考上篇 */
const uniformBindGroup = device.createBindGroup({
  layout: bindGroupLayout, // <- 直接傳遞 綁定組布局對象,它是什麼請參考上一篇
  entries: [
    {
      binding: 0,
      resource: { // <- 指定資源類型為 buffer,并傳入 GPUBuffer 類型的對象
        buffer: uniformBuffer
      }
    }
  ]
})

/* 建立類型數組,并寫入 GPUBuffer */
const uniformColor = new Float32Array([0.0, 0.5, 0.0, 1.0])
device.queue.writeBuffer(uniformBuffer, 0, uniformColor.buffer, uniformColor.byteOffset, uniformColor.byteLength)
           

2 修改着色器

在着色器中,需要借助一個

block

的東西,聲明一個結構體,從結構體中拿到顔色值。

具體原因不明,後續查資料。

注意此例中 vbo 隻有坐标,是以 pipeline 中頂點、片元階段的

buffers

屬性中的值,都要跟着修改,不贅述,請讀者參考第 2 篇。

頂點着色器

[[builtin(position)]] var<out> out_position: vec4<f32>;
[[location(0)]] var<in> in_position_2d: vec2<f32>;

[[stage(vertex)]]
fn main() -> void {
  out_position = vec4<f32>(in_position_2d, 0.0, 1.0);
  return;
}
           

片元着色器

// 聲明一個結構體類型,其包含一個我們需要的顔色字段
[[block]] struct Uniforms {
  uniform_color: vec4<f32>;
};

// 聲明一個結構體變量,将其綁定到 js 代碼中綁定組的第 0 個資源值
[[binding(0), group(0)]] var<uniform> uniforms: Uniforms;
[[location(0)]] var<out> outColor: vec4<f32>;

[[stage(fragment)]]
fn main() -> void {
  outColor = uniforms.uniform_color; // <- 從 uniform 裡取一個顔色值
  return;
}
           

END

繼續閱讀