大家好,本文学习Chrome->webgpu-samplers->fractalCube示例。

上一篇博文:

WebGPU学习(八):学习“texturedCube”示例

下一篇博文:

WebGPU学习(十):介绍“GPU实现粒子效果”

学习fractalCube.ts

最终渲染结果:

该示例展示了如何用上一帧渲染的结果作为下一帧的纹理。

“texturedCube”示例相比,该示例的纹理并不是来自图片,而是来自上一帧渲染的结果

下面,我们打开fractalCube.ts文件,分析相关代码:

传输顶点的color

它与“texturedCube”示例->“传递顶点的uv数据”类似,这里不再分析

上一帧渲染的结果作为下一帧的纹理

  • 配置swapChain

因为swapChain保存了上一帧渲染的结果,所以将其作为下一帧纹理的source。因此它的usage需要增加GPUTextureUsage.COPY_SRC:

  const swapChain = context.configureSwapChain({
device,
format: "bgra8unorm",
usage: GPUTextureUsage.OUTPUT_ATTACHMENT | GPUTextureUsage.COPY_SRC,
});
  • 创建空纹理(cubeTexture)和sampler,设置到uniform bind group中

相关代码如下:


const fragmentShaderGLSL = `#version 450
...
layout(set = 0, binding = 2) uniform texture2D myTexture;
... void main() {
vec4 texColor = texture(sampler2D(myTexture, mySampler), fragUV * 0.8 + 0.1); ... outColor = mix(texColor, fragColor, f);
}`; ... const cubeTexture = device.createTexture({
size: { width: canvas.width, height: canvas.height, depth: 1 },
format: "bgra8unorm",
usage: GPUTextureUsage.COPY_DST | GPUTextureUsage.SAMPLED,
}); const sampler = device.createSampler({
magFilter: "linear",
minFilter: "linear",
}); const uniformBindGroup = device.createBindGroup({
layout: bindGroupLayout,
bindings: [
...
{
binding: 1,
resource: sampler,
}, {
binding: 2,
//传递cubeTexture到fragment shader中
resource: cubeTexture.createView(),
}],
});
  • 绘制和拷贝

在每一帧中:

绘制带纹理的立方体;

将渲染结果(swapChainTexture)拷贝到cubeTexture中。

相关代码如下:

  return function frame() {
const swapChainTexture = swapChain.getCurrentTexture(); renderPassDescriptor.colorAttachments[0].attachment = swapChainTexture.createView(); const commandEncoder = device.createCommandEncoder({});
const passEncoder = commandEncoder.beginRenderPass(renderPassDescriptor);
...
passEncoder.setBindGroup(0, uniformBindGroup);
...
passEncoder.draw(36, 1, 0, 0);
passEncoder.endPass(); commandEncoder.copyTextureToTexture({
texture: swapChainTexture,
}, {
texture: cubeTexture,
}, {
width: canvas.width,
height: canvas.height,
depth: 1,
}); device.defaultQueue.submit([commandEncoder.finish()]); ... }

分析shader代码

本示例的vertex shader与“texturedCube”示例的vertex shader相比,增加了color attribute:

  const vertexShaderGLSL = `#version 450
...
layout(location = 1) in vec4 color;
... layout(location = 0) out vec4 fragColor;
... void main() {
...
fragColor = color;
...
}`;

fragment shader的代码如下:

  const fragmentShaderGLSL = `#version 450
layout(set = 0, binding = 1) uniform sampler mySampler;
layout(set = 0, binding = 2) uniform texture2D myTexture; layout(location = 0) in vec4 fragColor;
layout(location = 1) in vec2 fragUV;
layout(location = 0) out vec4 outColor; void main() {
vec4 texColor = texture(sampler2D(myTexture, mySampler), fragUV * 0.8 + 0.1); // 1.0 if we're sampling the background
float f = float(length(texColor.rgb - vec3(0.5, 0.5, 0.5)) < 0.01); outColor = mix(texColor, fragColor, f);
}`;

第10行对fragUV进行了处理,我们会在分析渲染时间线中分析它。

第13行和第15行相当于做了if判断:

if(纹理颜色 === 背景色){
outColor = fragColor
}
else{
outColor = 纹理颜色
}

这里之所以不用if判断而使用计算的方式,是为了减少条件判断,提高gpu的并行性

分析渲染时间线

下面分析下渲染的时间线:

第一帧

因为纹理为空纹理,它的颜色为背景色,所以fragment shader的outColor始终为fragColor,因此立方体的所有片段的颜色均为fragColor。

第一帧的渲染结果如下:

第一帧绘制结束后,渲染结果会被拷贝到cubeTexture中。

第二帧

分析执行的fragment shader代码:

  const fragmentShaderGLSL = `#version 450
layout(set = 0, binding = 1) uniform sampler mySampler;
layout(set = 0, binding = 2) uniform texture2D myTexture; layout(location = 0) in vec4 fragColor;
layout(location = 1) in vec2 fragUV;
layout(location = 0) out vec4 outColor; void main() {
vec4 texColor = texture(sampler2D(myTexture, mySampler), fragUV * 0.8 + 0.1); // 1.0 if we're sampling the background
float f = float(length(texColor.rgb - vec3(0.5, 0.5, 0.5)) < 0.01); outColor = mix(texColor, fragColor, f);
}`;
  • 第10行的“fragUV * 0.8 + 0.1”是为了取纹理坐标u、v方向的[0.1-0.9]部分,从而使纹理中立方体所占比例更大。

得到的纹理区域如下图的红色区域所示:

  • 第13行和第15行代码,将纹理中的背景色替换为了fragColor

第二帧的渲染结果如下:

  • 第三帧

依次类推,第三帧的渲染结果如下:

参考资料

WebGPU规范

webgpu-samplers Github Repo

WebGPU-7

WebGPU学习(九):学习“fractalCube”示例的更多相关文章

  1. WebGPU学习(七):学习“twoCubes”和“instancedCube”示例

    大家好,本文学习Chrome->webgpu-samplers->twoCubes和instancedCube示例. 这两个示例都与"rotatingCube"示例差不 ...

  2. Angular 快速学习笔记(1) -- 官方示例要点

    创建组件 ng generate component heroes {{ hero.name }} {{}}语法绑定数据 管道pipe 格式化数据 <h2>{{ hero.name | u ...

  3. SQL 数据库 学习 007 通过一个示例简单介绍什么是字段、属性、列、元组、记录、表、主键、外键 (上)

    SQL 数据库 学习 007 通过一个示例简单介绍什么是字段.属性.列.元组.记录.表.主键.外键 (上) 我们来介绍一下:数据库是如何存储数据的. 数据库是如何存储数据的 来看一个小例子 scott ...

  4. Deep Learning(深度学习)学习笔记整理系列之(五)

    Deep Learning(深度学习)学习笔记整理系列 zouxy09@qq.com http://blog.csdn.net/zouxy09 作者:Zouxy version 1.0 2013-04 ...

  5. Deep Learning(深度学习)学习笔记整理系列之(八)

    Deep Learning(深度学习)学习笔记整理系列 zouxy09@qq.com http://blog.csdn.net/zouxy09 作者:Zouxy version 1.0 2013-04 ...

  6. Deep Learning(深度学习)学习笔记整理系列之(七)

    Deep Learning(深度学习)学习笔记整理系列 zouxy09@qq.com http://blog.csdn.net/zouxy09 作者:Zouxy version 1.0 2013-04 ...

  7. Deep Learning(深度学习)学习笔记整理系列之(六)

    Deep Learning(深度学习)学习笔记整理系列 zouxy09@qq.com http://blog.csdn.net/zouxy09 作者:Zouxy version 1.0 2013-04 ...

  8. Deep Learning(深度学习)学习笔记整理系列之(四)

    Deep Learning(深度学习)学习笔记整理系列 zouxy09@qq.com http://blog.csdn.net/zouxy09 作者:Zouxy version 1.0 2013-04 ...

  9. Deep Learning(深度学习)学习笔记整理系列之(三)

    Deep Learning(深度学习)学习笔记整理系列 zouxy09@qq.com http://blog.csdn.net/zouxy09 作者:Zouxy version 1.0 2013-04 ...

  10. Deep Learning(深度学习)学习笔记整理系列之(二)

    Deep Learning(深度学习)学习笔记整理系列 zouxy09@qq.com http://blog.csdn.net/zouxy09 作者:Zouxy version 1.0 2013-04 ...

随机推荐

  1. (四)添加yaffs2文件系统支持

    1. 获取yaffs2源码 在linux工作目录下进行clone操作: git clone git://www.aleph1.co.uk/yaffs2 完成后会在当前目录下产生yaffs2的源码目录: ...

  2. ASP.NET Core 菜鸟之路:从Startup.cs说起 转发https://www.cnblogs.com/chenug/p/6869109.html

    1.前言 本文主要是以Visual Studio 2017 默认的 WebApi 模板作为基架,基于Asp .Net Core 1.0,本文面向的是初学者,如果你有 ASP.NET Core 相关实践 ...

  3. chromedriver安装报错

     解决方法:   可以使用 npm init -f命令生成package.json,package.json中缺少的字段可以参照模板 package.json进行填充,package.json中的字段 ...

  4. android ndk 编译 libevent

    1. 下载 libevent 2.1.8 版本 https://github.com/libevent/libevent/releases/download/release-2.1.8-stable/ ...

  5. [LeetCode] 181.超过经理收入的员工

    Employee表包含所有员工,他们的经理也属于员工.每个员工都有一个 Id,此外还有一列对应员工的经理的 Id. +----+-------+--------+-----------+ | Id | ...

  6. luoguP1080 国王游戏 题解(NOIP2012)(贪心+高精)

    luoguP1080 国王游戏 题目 #include<iostream> #include<cstdlib> #include<cstdio> #include& ...

  7. ubantu18.04中mysql8.0设置远程连接的问题

    在mysql8.0中的配置文件中默认是没有绑定地址的,但是可以自己配置,在my.cnf中 这里使用另一种方式: 首先先连接到自己的数据库执行: use mysql; select host,user ...

  8. 修改默认runlevel

    CentOS直接修改文件  /etc/inittab 就好了 # Default runlevel. The runlevels used are: # - halt (Do NOT set init ...

  9. C#设计模式V2(1)——单例模式

    出自:https://www.cnblogs.com/zhili/p/SingletonPatterm.html 一.引言 最近在设计模式的一些内容,主要的参考书籍是<Head First 设计 ...

  10. 软件安装 RPM SRPM YUM

    RPM介绍 RPM是已经编译好的软件安装库.编译是有相应环境相适应的,包括系统,版本等相关信息都要跟编译版本一致才行,否则肯定会出现安装不成功的情况,强制安装的话,也会出现各种各样的问题. 在这种情况 ...