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',
代替之.