首页 > web前端 > js教程 > 正文

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

霞舞
发布: 2025-10-11 12:20:01
原创
822人浏览过

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

本文档旨在指导开发者如何在 WebGPU 中使用 triangle-strip 拓扑结构,并为每个三角形指定不同的颜色。我们将深入探讨顶点着色器和片元着色器之间的数据传递,以及如何利用插值修饰符来实现精确的颜色控制。通过本文,你将能够掌握在 WebGPU 中创建具有丰富色彩变化的图形的技巧。

理解顶点着色器和片元着色器的独立性

在 WebGPU 中,顶点着色器和片元着色器被视为完全独立的程序。这意味着在顶点着色器中定义的变量,如果不经过特殊处理,无法直接在片元着色器中使用。例如,以下代码尝试在顶点着色器中设置 fi 变量,并在片元着色器中使用它,这是行不通的:

var<private> fi: i32; // fragment_index ( current triangle )

@vertex
fn vs( @builtin(vertex_index) vi: u32 ) -> @builtin(position) vec4f {
  if(vi<3){ fi = 1;
    var T = array<vec2f, 3>( vec2f(0,0), vec2f(.4,.7), vec2f(.8,0) );
    return vec4f(T[vi],0,1);
  };
  fi = 2;
  return vec4f(.6,-.5,0,1);
}

@fragment
fn fs() -> @location(0) vec4f {
  if(fi == 1){ return vec4f(.7,.2,.2,.5); }; // color for 1st triangle ?
  return vec4f(.3,.6,.4,.5);                 // color for 2nd triangle
}
登录后复制

这段代码的问题在于,顶点着色器和片元着色器各自拥有独立的 fi 变量实例,它们之间没有任何关联。因此,片元着色器中的 fi 变量的值是不确定的,无法正确地控制三角形的颜色。

使用 Inter-Stage Variables 传递数据

为了在顶点着色器和片元着色器之间传递数据,我们需要使用 Inter-Stage Variables。Inter-Stage Variables 允许我们将数据从顶点着色器传递到片元着色器,以便在片元着色器中使用这些数据进行着色。

要使用 Inter-Stage Variables,我们需要定义一个结构体,并在顶点着色器中返回该结构体。该结构体中的每个成员都使用 @location 修饰符进行标记,以便在片元着色器中访问它们。

以下是一个使用 Inter-Stage Variables 的示例:

struct VSOut {
  @builtin(position) pos: vec4f,
  @location(0) @interpolate(flat) fi: i32,
};

@vertex
fn vs( @builtin(vertex_index) vi: u32 ) -> VSOut {
  var vsOut: VSOut;
  vsOut.fi = 1;
  if (vi > 0) {
    vsOut.fi = 2;
  }

  if(vi<3){
    var T = array<vec2f, 3>( 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;
}

@fragment
fn 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
}
登录后复制

在这个示例中,我们定义了一个名为 VSOut 的结构体,它包含两个成员:pos 和 fi。pos 成员存储顶点的位置,fi 成员存储三角形的索引。我们使用 @location(0) 修饰符标记 fi 成员,以便在片元着色器中访问它。

在顶点着色器中,我们创建一个 VSOut 结构体的实例,并根据顶点索引设置 fi 成员的值。然后,我们将该结构体返回。

在片元着色器中,我们将 VSOut 结构体作为参数传递给 fs 函数。然后,我们可以使用 vsOut.fi 访问三角形的索引,并根据该索引设置三角形的颜色。

AI角色脑洞生成器
AI角色脑洞生成器

一键打造完整角色设定,轻松创造专属小说漫画游戏角色背景故事

AI角色脑洞生成器176
查看详情 AI角色脑洞生成器

插值修饰符 @interpolate(flat)

Inter-Stage Variables 通常会被插值。这意味着在片元着色器中,Inter-Stage Variables 的值是根据三角形的顶点值进行插值计算的。

然而,在某些情况下,我们可能不希望对 Inter-Stage Variables 进行插值。例如,在我们的示例中,我们希望为每个三角形指定一个固定的颜色,而不是根据顶点颜色进行插值。

为了禁用插值,我们可以使用 @interpolate(flat) 修饰符。该修饰符告诉 WebGPU 不要对 Inter-Stage Variables 进行插值,而是使用三角形的第一个顶点的值。

在我们的示例中,我们使用 @interpolate(flat) 修饰符标记 fi 成员:

struct VSOut {
  @builtin(position) pos: vec4f,
  @location(0) @interpolate(flat) fi: i32,
};
登录后复制

这确保了在片元着色器中,vsOut.fi 的值始终是三角形的第一个顶点的值。

完整示例代码

以下是一个完整的示例代码,演示了如何在 WebGPU 中使用 triangle-strip 拓扑结构,并为每个三角形指定不同的颜色:

<!DOCTYPE html>
<html>
<head>
<style>
body{ background-color: #000 }
canvas{ display: block; width: 600px; height: 400px; outline: 1px solid #666 }
</style>
</head>
<body>
<canvas width=900 height=600></canvas>
<script type="module">
let C = document.querySelector('canvas').getContext(`webgpu`),

code=`

struct VSOut {
  @builtin(position) pos: vec4f,
  @location(0) @interpolate(flat) fi: i32,
};

@vertex
fn 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, 3>( 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;
}

@fragment
fn 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()

</script>
</body>
</html>
登录后复制

这段代码将绘制两个三角形,第一个三角形是红色,第二个三角形是绿色。

总结

本文档介绍了如何在 WebGPU 中使用 triangle-strip 拓扑结构,并为每个三角形指定不同的颜色。我们讨论了顶点着色器和片元着色器的独立性,以及如何使用 Inter-Stage Variables 和插值修饰符来实现精确的颜色控制。通过本文,你已经掌握了在 WebGPU 中创建具有丰富色彩变化的图形的技巧。

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

相关标签:
最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号