Deprecated: imwpcache\f884414bce24ee67f\f73723ec7b1919fa5::__construct(): Implicitly marking parameter $YECBGYFECGEAFWHA as nullable is deprecated, the explicit nullable type must be used instead in /www/wwwroot/www.chuangxiangniao.com/wp-content/plugins/imwpcache-dist/build/f884414bce24ee67ff73723ec7b1919fa5.php on line 2

Deprecated: imwpcache\f884414bce24ee67f\f73723ec7b1919fa5::__construct(): Implicitly marking parameter $BBWFDDBHHYHDXXAB as nullable is deprecated, the explicit nullable type must be used instead in /www/wwwroot/www.chuangxiangniao.com/wp-content/plugins/imwpcache-dist/build/f884414bce24ee67ff73723ec7b1919fa5.php on line 2
WebGPU:使用 Triangle Strip 为每个三角形绘制不同颜色_创想鸟

WebGPU:使用 Triangle Strip 为每个三角形绘制不同颜色

webgpu:使用 triangle strip 为每个三角形绘制不同颜色

本文介绍了如何在 WebGPU 中使用 `triangle-strip` 拓扑结构为每个三角形绘制不同的颜色。核心在于理解顶点着色器和片元着色器之间的数据传递,并使用 Inter-Stage Variables 以及 `flat` 插值模式来实现对每个三角形颜色控制。通过修改顶点着色器和片元着色器,并结合 blend 设置,最终实现为每个三角形赋予不同颜色的效果。

在 WebGPU 中,要实现 triangle-strip 模式下每个三角形拥有不同颜色,关键在于理解顶点着色器和片元着色器之间的数据传递机制。默认情况下,顶点着色器和片元着色器是相互独立的,它们之间的变量不能直接共享。为了解决这个问题,我们需要使用 Inter-Stage Variables。

Inter-Stage Variables

Inter-Stage Variables 允许我们从顶点着色器向片元着色器传递数据。这些变量需要在顶点着色器中定义,并通过一个结构体返回。同时,在片元着色器中,该结构体作为输入参数接收。@location 装饰器用于指定变量的位置,建立顶点着色器和片元着色器之间的数据通道。

示例代码:

以下代码展示了如何使用 Inter-Stage Variables 来传递三角形索引,从而在片元着色器中根据索引设置不同的颜色。

body{ background-color: #000 }canvas{ display: block; width: 600px; height: 400px; outline: 1px solid #666 }let C = document.querySelector('canvas').getContext(`webgpu`),code=`struct VSOut {  @builtin(position) pos: vec4f,  @location(0) @interpolate(flat) fi: i32,};@vertexfn vs( @builtin(vertex_index) vi: u32 ) -> VSOut {  // inter-stage variables are interpolated. In flat interpolation mode,  // the values passed to the fragment shader are from the "provoking vertex"  // which is the value set on the 1st vertex of the triangle  var vsOut: VSOut;  vsOut.fi = 1;  if (vi > 0) {    vsOut.fi = 2;  }  if(vi<3){    var T = array( vec2f(0,0), vec2f(.4,.7), vec2f(.8,0) );    vsOut.pos = vec4f(T[vi],0,1);    return vsOut;  };  vsOut.pos = vec4f(.6,-.5,0,1);  return vsOut;}@fragmentfn fs(vsOut: VSOut) -> @location(0) vec4f {  if(vsOut.fi == 1){ return vec4f(.7,.2,.2,.5); }; // color for 1st triangle ?  return vec4f(.3,.6,.4,.5);                 // color for 2nd triangle}`, format = `bgra8unorm`,adapter = await navigator.gpu.requestAdapter(), device = await adapter.requestDevice(),      Q = device.queue,      A = {loadOp: `clear`, storeOp: `store`}, // Attachments      O = {colorAttachments: [ A ]},           // Render Pass Descriptor      E, R, module = device.createShaderModule({ code }),      P = device.createRenderPipeline({ layout: `auto`, primitive: { topology: `triangle-strip` },             vertex: { module, entryPoint: `vs`, },           fragment: { module, entryPoint: `fs`, targets: [{ format }] }          });C.configure({ device, format });function F(){  A.view = C.getCurrentTexture().createView();  E = device.createCommandEncoder();  R = E.beginRenderPass(O);  R.setPipeline(P);  R.draw(4);  R.end();  Q.submit([E.finish()]);  requestAnimationFrame(F)}F()

代码解释:

定义结构体 VSOut: 该结构体包含了顶点位置 pos 和三角形索引 fi。@builtin(position) 声明 pos 为内置变量,用于指定顶点位置。@location(0) 声明 fi 变量位于 location 0,用于和片元着色器对应。@interpolate(flat) 关闭了插值,保证每个三角形的 fi 值是固定的。

顶点着色器 vs: 根据顶点索引 vi 设置 fi 的值。vi

片元着色器 fs: 根据接收到的 vsOut.fi 值,选择不同的颜色。如果 vsOut.fi 为 1,则返回红色,否则返回绿色。

插值模式

默认情况下,Inter-Stage Variables 会在三角形内部进行插值。这意味着片元着色器接收到的值是三角形顶点值的加权平均。为了避免颜色在三角形内部渐变,我们需要关闭插值。可以使用 @interpolate(flat) 装饰器来实现。加上这个装饰器后,片元着色器接收到的值将是三角形第一个顶点的值。

注意事项:

triangle-strip 的顶点顺序非常重要。每个三角形的第一个顶点决定了 @interpolate(flat) 装饰器传递的值。确保顶点着色器和片元着色器中的 @location 值匹配,否则数据将无法正确传递。

添加 Blend 设置

如果需要实现透明效果,可以添加 blend 设置。

body{ background-color: #000 }canvas{ display: block; width: 600px; height: 400px; outline: 1px solid #666 }let C = document.querySelector('canvas').getContext(`webgpu`),code=`struct VSOut {  @builtin(position) pos: vec4f,  @location(0) @interpolate(flat) fi: i32,};@vertexfn vs( @builtin(vertex_index) vi: u32 ) -> VSOut {  // inter-stage variables are interpolated. In flat interpolation mode,  // the values passed to the fragment shader are from the "provoking vertex"  // which is the value set on the 1st vertex of the triangle  var vsOut: VSOut;  vsOut.fi = 1;  if (vi > 0) {    vsOut.fi = 2;  }  if(vi<3){    var T = array( vec2f(0,0), vec2f(.4,.7), vec2f(.8,0) );    vsOut.pos = vec4f(T[vi],0,1);    return vsOut;  };  vsOut.pos = vec4f(.6,-.5,0,1);  return vsOut;}@fragmentfn fs(vsOut: VSOut) -> @location(0) vec4f {  if(vsOut.fi == 1){ return vec4f(.7,.2,.2,.5); }; // color for 1st triangle ?  return vec4f(.3,.6,.4,.5);                 // color for 2nd triangle}`, format = `bgra8unorm`,adapter = await navigator.gpu.requestAdapter(), device = await adapter.requestDevice(),      Q = device.queue,      A = {loadOp: `clear`, storeOp: `store`}, // Attachments      O = {colorAttachments: [ A ]},           // Render Pass Descriptor      E, R, module = device.createShaderModule({ code }),      P = device.createRenderPipeline({ layout: `auto`, primitive: { topology: `triangle-strip` },             vertex: { module, entryPoint: `vs`, },           fragment: { module, entryPoint: `fs`, targets: [{ format,           blend: {            color: {              srcFactor: 'one',              dstFactor: 'one-minus-src-alpha',              operation: 'add',            },            alpha: {              srcFactor: 'one',              dstFactor: 'one-minus-src-alpha',              operation: 'add',            },          }, }] }          });C.configure({ device, format });function F(){  A.view = C.getCurrentTexture().createView();  E = device.createCommandEncoder();  R = E.beginRenderPass(O);  R.setPipeline(P);  R.draw(4);  R.end();  Q.submit([E.finish()]);  requestAnimationFrame(F)}F()

在 createRenderPipeline 中,对 fragment 的 target 添加 blend 属性,可以实现混合效果。

总结:

通过使用 Inter-Stage Variables 和 flat 插值模式,我们可以在 WebGPU 中轻松地为 triangle-strip 的每个三角形赋予不同的颜色。这种方法为实现更复杂的渲染效果提供了基础。同时,需要理解顶点顺序和插值模式,才能正确地控制每个三角形的颜色。

以上就是WebGPU:使用 Triangle Strip 为每个三角形绘制不同颜色的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1529052.html

赞 (0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
如何构建一个支持热重载(Hot Module Replacement)的开发环境?
上一篇 2025年12月20日 20:47:33
JavaScript 字符串解析:动态替换括号内内容并应用函数
下一篇 2025年12月20日 20:47:44

相关推荐

发表回复

登录后才能评论
关注微信