大家好,本文学习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. linux超级块和inode 详解 和 df 、du 命令详解与环境变量

    一.inode块,Unix文件的核心. 首先需要明白的是,在Unix操作系统中的任何资源都被当作文件来管理.如目录.光驱.终端设备等等,都被当作是一种文件.从这方面来说,Unix操作系统中的所有的目录 ...

  2. Gradle Wrapper 介绍

    回顾 上一篇介绍了如何使用 Gradle 快速创建 Java 项目,开始讲 Gradle Wrapper 之前先来重温一下通过 gradle init 命令创建的 Java 项目目录结构 ├── bu ...

  3. python 装饰器 第五步(2):带有返回值得装饰器

    #第五步:带有返回值的装饰器 把第四步复制过来 #用于扩展基本函数的函数 def kuozhan(func): #内部函数(扩展之后的eat函数) def neweat(): #以下三步就是扩展之后的 ...

  4. qtp的三种录制模式(转)

    QTP提供三种不同的录制方式:正常录制(Normal Recording).模拟录制(Analog Recording)和低级录制(Low Level Recording). 1.正常录制(Norma ...

  5. Embedding和Word2Vec实战

    在之前的文章中谈到了文本向量化的一些基本原理和概念,本文将介绍Word2Vec的代码实现 https://www.cnblogs.com/dogecheng/p/11470196.html#Word2 ...

  6. [fw]Linux 的 time 指令

    Linux 的 time 指令   Linux 有個很有意思的 time 指令,可以用來查看另一個指令的執行時間,例如執行 time helloworld 會顯示 helloworld 這支程式的執行 ...

  7. Groovy学习:第一章 用Groovy简化Java代码

    1. Groovy的安装 目前Groovy的最新版本为2.1.2版,下载地址为:http://groovy.codehaus.org/Download下载后解压groovy-binary-2.1.2. ...

  8. elasticsearch 嵌套对象使用Multi Match Query、query_string全文检索设置

    参考: https://www.elastic.co/guide/en/elasticsearch/reference/1.7/mapping-nested-type.html https://sta ...

  9. scroll兼容性

    document.html=>document.documentElement function scroll() { if(window.pageYOffset != null) // ie9 ...

  10. 11.Container With Most Water (Array; Two-Pointers)

    Given n non-negative integers a1, a2, ..., an, where each represents a point at coordinate (i, ai).  ...