WebGpu非正式发布也有一段时间了,迭代比较快,几个月前的代码有的也不能正常运行了,提示函数deprecated,自己修改了下,整理了一份最新可用的。

代码如下

 1 //因为有await操作所以声明一个async函数
 2 const init= async() => {
 3  var canvas = document.getElementById('testCanvas');//你的html里的canvas元素的id
 4 canvas.width  = 800;
 5 canvas.height = 600;
 6  const adapter = await navigator.gpu.requestAdapter(); 
 7  const device = await adapter.requestDevice(); 
 8  const context = canvas.getContext('webgpu'); 
 9  const size = [ 
10   canvas.clientWidth * devicePixelRatio, 
11   canvas.clientHeight * devicePixelRatio 
12 ]
13  const format = context.getPreferredFormat(adapter); 
14  context.configure({ 
15   device, 
16   format, 
17   size, 
18   usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.COPY_SRC ,
19    compositingAlphaMode: "opaque",
20 }) 
21 //两个shader的string
22 const triangleVertWGSL=`@stage(vertex)
23 fn main(@builtin(vertex_index) VertexIndex : u32)
24      -> @builtin(position) vec4<f32> {
25   var pos = array<vec2<f32>, 3>(
26       vec2<f32>(0.0, 0.5),
27       vec2<f32>(-0.5, -0.5),
28       vec2<f32>(0.5, -0.5));
29 
30   return vec4<f32>(pos[VertexIndex], 0.0, 1.0);
31 }`;
32 const redFragWGSL =`@stage(fragment)
33 fn main() -> @location(0) vec4<f32> {
34   return vec4<f32>(1.0, 0.5, 0.0, 1.0);
35 }`;
36 
37  const pipeline = device.createRenderPipeline({ 
38     vertex: { 
39       module: device.createShaderModule({ 
40         code: triangleVertWGSL  
41       }), 
42       entryPoint: 'main',   // 入口函数 
43     }, 
44     fragment: { 
45       module: device.createShaderModule({ 
46         code:redFragWGSL
47       }), 
48       entryPoint: 'main',  // 入口函数 
49       targets: [ 
50         { 
51           format: format,  // 即上文的最终渲染色彩格式 
52         }, 
53       ], 
54     }, 
55     primitive: {           // 绘制模式 
56       topology: 'triangle-list',   // 按照三角形绘制 
57     }, 
58   }); 
59 //循环render的函数
60   function frame() {
61     // Sample is no longer the active page.
62     if (!canvas) return;
63 
64     const commandEncoder = device.createCommandEncoder();
65     const textureView = context.getCurrentTexture().createView();
66 
67     const renderPassDescriptor = { 
68       colorAttachments: [ 
69         { 
70           view: context.getCurrentTexture().createView(), 
71           clearValue: { r: 0.5, g: 0.5, b: 0.5, a: 1.0 },
72           loadOp: 'clear',
73           storeOp: 'store', 
74         }, 
75       ], 
76     };
77 
78     const passEncoder = commandEncoder.beginRenderPass(renderPassDescriptor);
79     passEncoder.setPipeline(pipeline);
80     passEncoder.draw(3, 1, 0, 0);
81     passEncoder.end();
82 
83     device.queue.submit([commandEncoder.finish()]);
84     requestAnimationFrame(frame);
85   }
86 
87   requestAnimationFrame(frame);//固定用法,实现循环调用
88   }
89 //正式运行,可以放入page load事件
90 init();

 

运行效果截图:

 

 

 

老代码的常见报错

1. context.configure(这行报错如下:
The default GPUCanvasCompositingAlphaMode will change from "premultiplied" to "opaque". Please explicitly pass "premultiplied" if you would like to continue using that compositing mode.

解决办法:
  可以在configure的参数里加上:

1 compositingAlphaMode: "opaque", 


2. 网络上有些代码的renderPassDescriptor中使用了 loadValue: { r: 0.5, g: 0.5, b: 0.5, a: 1.0 },会提示

loadValue has been deprecated and will soon be removed. Use loadOp and clearValue instead.

解决办法:
删除loadValue,用

1 clearValue: { r: 0.5, g: 0.5, b: 0.5, a: 1.0 },

2 loadOp: 'clear',

代替之.