
本文介绍了如何在 WebGPU 中使用 `triangle-strip` 拓扑结构为每个三角形绘制不同的颜色。核心在于理解顶点着色器和片元着色器之间的数据传递,并使用 Inter-Stage Variables 以及 `flat` 插值模式来实现对每个三角形颜色控制。通过修改顶点着色器和片元着色器,并结合 blend 设置,最终实现为每个三角形赋予不同颜色的效果。
在 WebGPU 中,要实现 triangle-strip 模式下每个三角形拥有不同颜色,关键在于理解顶点着色器和片元着色器之间的数据传递机制。默认情况下,顶点着色器和片元着色器是相互独立的,它们之间的变量不能直接共享。为了解决这个问题,我们需要使用 Inter-Stage Variables。
Inter-Stage Variables
Inter-Stage Variables 允许我们从顶点着色器向片元着色器传递数据。这些变量需要在顶点着色器中定义,并通过一个结构体返回。同时,在片元着色器中,该结构体作为输入参数接收。@location 装饰器用于指定变量的位置,建立顶点着色器和片元着色器之间的数据通道。
示例代码:
以下代码展示了如何使用 Inter-Stage Variables 来传递三角形索引,从而在片元着色器中根据索引设置不同的颜色。
<!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 n*igator.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>代码解释:
定义结构体 VSOut: 该结构体包含了顶点位置 pos 和三角形索引 fi。@builtin(position) 声明 pos 为内置变量,用于指定顶点位置。@location(0) 声明 fi 变量位于 location 0,用于和片元着色器对应。@interpolate(flat) 关闭了插值,保证每个三角形的 fi 值是固定的。
顶点着色器 vs: 根据顶点索引 vi 设置 fi 的值。vi
片元着色器 fs: 根据接收到的 vsOut.fi 值,选择不同的颜色。如果 vsOut.fi 为 1,则返回红色,否则返回绿色。
九个不同动作和表情的柠檬矢量素材(EPS)
这张图片展示了一组活泼的柠檬卡通形象,每一个柠檬都表现出不同的情感和动作。从欢乐的微笑、自信的挥手,到忧郁的落泪、愤怒的表情,这些柠檬形象为我们带来了丰富多彩的情感表达。它们的身体都绘有简单的黑色手臂和腿,还穿着小白鞋,增加了趣味性。每个柠檬的形状和颜色保持了一致,但通过不同的面部表情和身体语言,为我们展现了它们独特的个性。这些柠檬角色可爱又充满活力,非常适合用作插图或设计元素。素材格式为 EPS
15
查看详情
插值模式
默认情况下,Inter-Stage Variables 会在三角形内部进行插值。这意味着片元着色器接收到的值是三角形顶点值的加权平均。为了避免颜色在三角形内部渐变,我们需要关闭插值。可以使用 @interpolate(flat) 装饰器来实现。加上这个装饰器后,片元着色器接收到的值将是三角形第一个顶点的值。
注意事项:
添加 Blend 设置
如果需要实现透明效果,可以添加 blend 设置。
<!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 n*igator.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()
</script>
</body>
</html>在 createRenderPipeline 中,对 fragment 的 target 添加 blend 属性,可以实现混合效果。
总结:
通过使用 Inter-Stage Variables 和 flat 插值模式,我们可以在 WebGPU 中轻松地为 triangle-strip 的每个三角形赋予不同的颜色。这种方法为实现更复杂的渲染效果提供了基础。同时,需要理解顶点顺序和插值模式,才能正确地控制每个三角形的颜色。
以上就是WebGPU:使用 Triangle Strip 为每个三角形绘制不同颜色的详细内容,更多请关注其它相关文章!
# 情况下
# 购物app推广营销方案
# b站推广网站2022
# 南宁专业网站seo优化网站
# 网站百科推广怎么做
# 文山哪有网站优化的地方
# seo商业价值排名
# 医院如何做网站宣传推广
# 杭州百度首页关键词排名怎么做
# 绕过seo检测
# 重庆企业网站建设招商
# 展示了
# html
# 来实现
# 自定义
# 第一个
# 器中
# 表单
# 插值
# 着色器
# 角形
# blend
# canva
# ai
相关栏目:
【
Google疑问12 】
【
Facebook疑问10 】
【
优化推广96088 】
【
技术知识133117 】
【
IDC资讯59369 】
【
网络运营7196 】
【
IT资讯61894 】
相关推荐:
Flask 应用中图片动态更新与上传:实现客户端定时刷新与服务器端文件管理
解决CSS布局中意外顶部空白问题的教程
win11资源管理器标签页怎么用 Win11文件管理器多标签高效操作【新功能】
悟空浏览器如何恢复关闭的标签页 悟空浏览器撤销关闭网页快捷键设置
苹果手机怎么合并照片_苹果手机合并多张照片的操作方法
Python csv 模块处理非字符串数据:列表写入 CSV 文件的机制解析
PSD转AI文件的简单方法
c++类和对象到底是什么_c++面向对象编程基础
泰拉瑞亚水晶无法放置问题
《一起考教师》账号注销方法
《全民k歌》网页版最新登录入口一览
J*aScript深度克隆:实现高效、健壮与安全的复杂对象复制
《战地6》反作弊已成功拦截240万次作弊 发售第一周98%比赛没有作弊
拷贝漫画2025网页版入口 拷贝漫画官网免费看全集
火狐浏览器如何刷新修复浏览器 火狐浏览器“重置Firefox”功能详解
谷歌邮箱官方入口链接 谷歌邮箱网页版电脑端快速登录
《单词速记宝》设置学习计划方法
苹果SE如何开启单手模式_苹果SE单手操作功能
智云Q3和Q2有什么升级_智云Q3与Q2手持云台功能与性能对比分析
抖音火山版注销账号抖音会注销吗 抖音火山版与抖音账号注销关系
C++怎么解决数值计算中的精度问题_C++浮点数误差与数值稳定性分析
在J*a中如何实现在线问答与评分系统_问答评分项目开发方法说明
C++如何将字符串转换为大写或小写_C++ transform函数的使用技巧
智慧团建活动报名入口 智慧团建活动报名入口手机端官网
Vue 3中独立响应式实例的创建与应用
胃动力不足?试试这5个调理方法
《狐友》联系客服方法
Chart.js 教程:自定义插件实现图表与图例间距调整
铁路12306座位怎么选_12306官方选座操作方法
sublime怎么快速在浏览器中预览HTML_sublime配置View in Browser教程
精通VS Code多光标编辑以实现闪电般快速的修改
创建您的便携版VS Code:让配置随身携带
批改网网页版登录 批改网电脑版学生登录入口
MongoDB聚合管道:高效统计列表中各项的文档数量
如何用mysql开发用户注册登录功能_mysql用户注册登录数据库设计
Dash应用多值文本输入处理与类型转换教程
J*aScript对象中深度嵌套URL键的查找与更新策略
12306售票时间最新规定 | 网上订票和车站窗口时间一样吗
PointNet++语义分割模型中类别变更引发的断言错误及标签处理策略
画质怪兽120帧安卓和平精英免费版
《爱笔思画x》涂色教程
宝妈做视频号该写什么标签话题?宝妈关注的话题有哪些?
OPPO手机参数配置如何开启护眼模式_OPPO手机参数配置护眼模式开启指南
Word如何将文字快速转成表格 Word文本转换成表格功能使用技巧【效率】
如何通过settings.json个性化您的VS Code体验
Apple Music无故扣费引质疑
教育查询官方网站入口 教育个人档案查询免费官网
高效调试PHP大型嵌套数组:JSON序列化与可视化工具实践
《画加》约稿流程
电脑双系统如何安装和卸载 Windows和Linux双系统安装教程【详解】
2025-10-13
运城市盐湖区信雨科技有限公司是一家深耕海外推广领域十年的专业服务商,作为谷歌推广与Facebook广告全球合作伙伴,聚焦外贸企业出海痛点,以数字化营销为核心,提供一站式海外营销解决方案。公司凭借十年行业沉淀与平台官方资源加持,打破传统外贸获客壁垒,助力企业高效开拓全球市场,成为中小企业出海的可靠合作伙伴。