WebGPU学习(九):学习“fractalCube”示例
大家好,本文学习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”示例的更多相关文章
- WebGPU学习(七):学习“twoCubes”和“instancedCube”示例
大家好,本文学习Chrome->webgpu-samplers->twoCubes和instancedCube示例. 这两个示例都与"rotatingCube"示例差不 ...
- Angular 快速学习笔记(1) -- 官方示例要点
创建组件 ng generate component heroes {{ hero.name }} {{}}语法绑定数据 管道pipe 格式化数据 <h2>{{ hero.name | u ...
- SQL 数据库 学习 007 通过一个示例简单介绍什么是字段、属性、列、元组、记录、表、主键、外键 (上)
SQL 数据库 学习 007 通过一个示例简单介绍什么是字段.属性.列.元组.记录.表.主键.外键 (上) 我们来介绍一下:数据库是如何存储数据的. 数据库是如何存储数据的 来看一个小例子 scott ...
- Deep Learning(深度学习)学习笔记整理系列之(五)
Deep Learning(深度学习)学习笔记整理系列 zouxy09@qq.com http://blog.csdn.net/zouxy09 作者:Zouxy version 1.0 2013-04 ...
- Deep Learning(深度学习)学习笔记整理系列之(八)
Deep Learning(深度学习)学习笔记整理系列 zouxy09@qq.com http://blog.csdn.net/zouxy09 作者:Zouxy version 1.0 2013-04 ...
- Deep Learning(深度学习)学习笔记整理系列之(七)
Deep Learning(深度学习)学习笔记整理系列 zouxy09@qq.com http://blog.csdn.net/zouxy09 作者:Zouxy version 1.0 2013-04 ...
- Deep Learning(深度学习)学习笔记整理系列之(六)
Deep Learning(深度学习)学习笔记整理系列 zouxy09@qq.com http://blog.csdn.net/zouxy09 作者:Zouxy version 1.0 2013-04 ...
- Deep Learning(深度学习)学习笔记整理系列之(四)
Deep Learning(深度学习)学习笔记整理系列 zouxy09@qq.com http://blog.csdn.net/zouxy09 作者:Zouxy version 1.0 2013-04 ...
- Deep Learning(深度学习)学习笔记整理系列之(三)
Deep Learning(深度学习)学习笔记整理系列 zouxy09@qq.com http://blog.csdn.net/zouxy09 作者:Zouxy version 1.0 2013-04 ...
- Deep Learning(深度学习)学习笔记整理系列之(二)
Deep Learning(深度学习)学习笔记整理系列 zouxy09@qq.com http://blog.csdn.net/zouxy09 作者:Zouxy version 1.0 2013-04 ...
随机推荐
- pssh系列命令详解
安装 pssh提供OpenSSH和相关工具的并行版本.包括pssh,pscp,prsync,pnuke和pslurp.该项目包括psshlib,可以在自定义应用程序中使用.pssh是python写的可 ...
- python-javascript之dom
DOM DOM:(document object mode)文档对象模型.DOM为文档提供了结构化表示,并定义了如何通过脚本来访问文档结构. 目的就是为了能让js操作html元素而制定的一个规范 DO ...
- 还抱着 Java 8 不放,也是醉了!
作者 | Trisha Gee原文:https://dzone.com/articles/beyond-java-8译者 | 弯月 责编 | 屠敏出品 | CSDN(ID:CSDNnews) 不说 A ...
- FZU 2060 The Sum of Sub-matrices(状态压缩DP)
The Sum of Sub-matrices Description Seen draw a big 3*n matrix , whose entries Ai,j are all integer ...
- java并发编程之美-阅读记录10
同步器 10.1CountDownLatch 在开发过程中经常会遇到在主线程中开启多个子线程去并行执行任务,并且主线程需要等待子线程执行完毕后在进行汇总.在CountDownLatch出现之前使用线程 ...
- c#静态变量和非静态变量的区别
静态变量的类型说明符是static.静态变量当然是属于静态存储方式,但是属于静态存储方式的量不一定就是静态变量,例如外部变量虽属于静态存储方式,但不一定是静态变量,必须由 static加以定义后才能成 ...
- h5py库
参考文献:http://docs.h5py.org/en/latest/high/dataset.html h5py文件存放数据集(dataset)和组(group). dataset类似数组类的数据 ...
- 在windows下使用secure crt传文件到linux的主目录下
SECURT CRT上传文件 使用secure crt连接到Linux上 通过alt+p打开sftp服务 使用put D:\视觉\代码\ch.10.zip 即可传输完成 进入linux直接在主目录下可 ...
- PHP如何使用AES加密和解密
AES加密在php5的版本中使用的mcrypt_decrypt 函数,该函数已经在php7.1后弃用了,取而代之的是openssl的openssl_encrypt和openssl_decrypt,并且 ...
- MySQL 8.0.12安装教程 (windows 64位)
先去官网下载点击的MySQL的下载 下载完成后解压 解压完是这个样子,(解压后并没有Data目录,要手动创建,Data目录是自己创建的设置mysql数据库的数据的存放目录,解压后的目录也没有的my. ...