轻量封装WebGPU渲染系统示例<29>- 深度模糊DepthBlur(源码)
实现方式:
step1. 通过mrt机制,输出颜色和深度相关数据的两张rtt纹理。
step2. 基于上述颜色纹理,生成一张模糊之后的新rtt纹理。
setp3. 基于深度(也就是距离摄像机的远近)数据,合成颜色和模糊纹理数据,并最终输出。
当前示例源码github地址:
https://github.com/vilyLei/voxwebgpu/blob/feature/rendering/src/voxgpu/sample/DepthBlur.ts
当前示例运行效果:

微调一点代码,即可获得下述效果:

代码微调方式:
第一处, 将下述片段着色器中的 f = 1.0 - f * f; 改为 f = f * f;
第二处, 将
const attachment1 = {texture: vposRTTTex,clearValue: [0.2, 0.25, 0.2, 1.0]};
改为
const attachment1 = {texture: vposRTTTex,clearValue: [800, 800, 800, 1]};
当然也可以通过第四个分量,来做实际的区分参数,统一处理。
合成模糊效果的WGSL片段着色器代码:
@group(0) @binding(0) var<uniform> param: vec4f;
@group(0) @binding(1) var colorSampler0: sampler;
@group(0) @binding(2) var colorTexture0: texture_2d<f32>;
@group(0) @binding(3) var blurSampler1: sampler;
@group(0) @binding(4) var blurTexture1: texture_2d<f32>;
@group(0) @binding(5) var vposSampler1: sampler;
@group(0) @binding(6) var vposTexture1: texture_2d<f32>;fn calcColor(uv: vec2f) -> vec4f {var color = textureSample(colorTexture0, colorSampler0, uv) * param;var blurColor = textureSample(blurTexture1, blurSampler1, uv);var vpos = textureSample(vposTexture1, vposSampler1, uv);var f = clamp((length(vpos.xyz) - 300.0)/200.0, 0.0, 1.0);f = 1.0 - f * f;var result = vec4f(color.xyz * (1.0 - f) + f * blurColor.xyz, 1.0);return result;
}@fragment
fn main(@location(0) uv: vec2f) -> @location(0) vec4f {var color4 = calcColor( uv );return color4;
}
此示例基于此渲染系统实现,当前示例TypeScript源码如下:
const blurRTTTex0 = { diffuse: { uuid: "rtt0", rttTexture: {} } };
const blurRTTTex1 = { diffuse: { uuid: "rtt1", rttTexture: {} } };
const rtts = [blurRTTTex0, blurRTTTex1];
const attachment = {texture: blurRTTTex0,clearValue: [] as ColorDataType,loadOp: "clear",storeOp: "store"
} as WGRPassColorAttachment;
const colorAttachments = [attachment];const colorRTTTex = { diffuse: { uuid: "colorRTT", rttTexture: {} } };
const vposRTTTex = { diffuse: { uuid: "floatRTT", rttTexture: {}, format: 'rgba16float' } };class PassGraph extends WGRPassNodeGraph {blurEntity: FixScreenPlaneEntity;srcEntity: FixScreenPlaneEntity;constructor() {super();}run(): void {let pass = this.passes[0];const entity = this.blurEntity;let ms = entity.materials;for (let i = 0; i < 11; ++i) {const ia = i % 2;const ib = (i + 1) % 2;pass.colorAttachments[0].clearEnabled = i < 1;this.srcEntity.visible = i < 1;this.blurEntity.visible = i > 0;attachment.texture = rtts[ia];ms[ia].visible = false;ms[ib].visible = true;pass.render();}}
}export class DepthBlur {private mRscene = new RendererScene();private mGraph = new PassGraph();private uniformValues = [{ data: new Float32Array([512, 512, 3.0, 0]) }];initialize(): void {let multisampleEnabled = true;let depthTestEnabled = false;let rpassparam = { multisampleEnabled, depthTestEnabled };this.mRscene.initialize({ rpassparam });this.initEvent();this.initScene();}private initEvent(): void {const rc = this.mRscene;rc.addEventListener(MouseEvent.MOUSE_DOWN, this.mouseDown);new MouseInteraction().initialize(rc, 0, false).setAutoRunning(true);}private mouseDown = (evt: MouseEvent): void => {}private createMaterial(shadinguuid: string, textures: WGTextureDataDescriptor[], type: number): WGMaterial {let shaderCodeSrc = {vert: { code: vertWGSL, uuid: "vert" },frag: { code: type > 0 ? blurVWGSL : blurHWGSL, uuid: "frag" }};shadinguuid += "-" + type;let pipelineDefParam = {depthWriteEnabled: false};const material = new WGMaterial({shadinguuid,shaderCodeSrc,pipelineDefParam});material.uniformValues = this.uniformValues;material.addTextures(textures);return material;}private applyBlurPass(clearColor: ColorDataType, extent: number[]): void {let rs = this.mRscene;const graph = this.mGraph;attachment.clearValue = clearColor;let rPass = rs.createRenderPass({ separate: true, colorAttachments });graph.passes = [rPass];let materials = [this.createMaterial("shd-00", [blurRTTTex0], 0), this.createMaterial("shd-01", [blurRTTTex1], 1)];let rttEntity = new FixScreenPlaneEntity({ extent: [-1, -1, 2, 2], flipY: true, textures: [colorRTTTex] });rttEntity.uuid = "src-entity";rPass.addEntity(rttEntity);graph.srcEntity = rttEntity;rs.setPassNodeGraph(graph);let entity = new FixScreenPlaneEntity({ extent, flipY: true, materials });entity.materials[0].visible = false;entity.uuid = "blur-entity";rPass.addEntity(entity);graph.blurEntity = entity;let shaderSrc = {vert: { code: vertWGSL, uuid: "vert" },frag: { code: depthBlurFragWGSL, uuid: "depthBlur" }};// display blur rendering resultlet textures = [colorRTTTex, blurRTTTex0, vposRTTTex];extent = [-0.8, -0.8, 1.6, 1.6];entity = new FixScreenPlaneEntity({ extent, flipY: false, shaderSrc, textures, shadinguuid: "smallImgMaterial" });rs.addEntity(entity);}private applyMRTPass(extent: number[]): void {let rs = this.mRscene;const attachment0 = {texture: colorRTTTex,clearValue: [0.15, 0.15, 0.15, 1.0]};const attachment1 = {texture: vposRTTTex,clearValue: [0.2, 0.25, 0.2, 1.0]};const colorAttachments = [attachment0, attachment1];let rPass = rs.createRenderPass({ separate: true, colorAttachments });let shaderSrc = {vert: { code: entityVertWGSL, uuid: "vertMRT" },frag: { code: entityFragWGSL, uuid: "fragMRT" }};let torus = new TorusEntity({shaderSrc, radius: 150});torus.setAlbedo([0.7,0.02,0.1]);rPass.addEntity(torus);shaderSrc = {vert: { code: vertWGSL, uuid: "vert" },frag: { code: vposReadFragWGSL, uuid: "readNromal" }};// display depth value drawing resultextent = [-0.95, -0.95, 0.6, 0.6];let entity = new FixScreenPlaneEntity({ extent, shaderSrc, textures: [vposRTTTex], shadinguuid: "readDepth" });rs.addEntity(entity);// display albedo drawing resultextent = [-0.33, -0.95, 0.6, 0.6];entity = new FixScreenPlaneEntity({ extent, textures: [colorRTTTex] });rs.addEntity(entity);// display blur drawing resultextent = [0.3, -0.95, 0.6, 0.6];entity = new FixScreenPlaneEntity({ extent, textures: [blurRTTTex0] });rs.addEntity(entity);}private initScene(): void {this.applyBlurPass([0.0, 0.0, 0.03, 1.0], [-1, -1, 2, 2]);this.applyMRTPass( [-1, -1, 2, 2] );}run(): void {this.mRscene.run();}
}
相关文章:
轻量封装WebGPU渲染系统示例<29>- 深度模糊DepthBlur(源码)
实现方式: step1. 通过mrt机制,输出颜色和深度相关数据的两张rtt纹理。 step2. 基于上述颜色纹理,生成一张模糊之后的新rtt纹理。 setp3. 基于深度(也就是距离摄像机的远近)数据,合成颜色和模糊纹理数据,并最终输出。 当前示例…...
LeetCode226. Invert Binary Tree
文章目录 一、题目二、题解2.1 前序遍历版本2.2 中序遍历版本2.3 后序遍历版本 一、题目 Given the root of a binary tree, invert the tree, and return its root. Example 1: Input: root [4,2,7,1,3,6,9] Output: [4,7,2,9,6,3,1] Example 2: Input: root [2,1,3] Ou…...
Java设计模式-创建型模式-建造者模式
建造者模式 建造者模式案例与工厂模式的区别:Builder 注解 建造者模式 建造者模式是将一个复杂对象的构件与表示分离,使得同样的构件过程可以创建不同的表示。 建造者模式将内部构件的创建和组装分割开,一般使用链式编程,代码整洁…...
PyQt中QFrame窗口中的组件不显示的原因
文章目录 问题代码(例)原因和解决方法 问题代码(例) from PyQt5.QtWidgets import * from PyQt5.QtGui import QFont, QIcon, QCursor, QPixmap import sysclass FrameToplevel(QFrame):def __init__(self, parentNone):super().…...
git 命令行回退版本
git 命令行回退版本 git 命令行回退版本命令: 1.切换到需要回退的分支 git checkout branch-v2.0.02.更新远程分支 git fetch3.找到需要回退版本的版本号git revert a6914da55ff40a09e67ac2426b86f1212e6580eb4.清除工作区缓存git clean -df5.强制提交git push -f...
IntelliJ IDEA 安装 GitHub Copilot插件 (最新)
注意: GitHub Copilot 插件对IDEA最低版本要求是2021.2,建议直接用2023.3,一次到位反正后续要升级的。 各个版本的依赖关系,请参照: ##在线安装: 打开 IntelliJ IDEA扩展商店,输入 "Git…...
viewpage选择器
GitHub - hackware1993/MagicIndicator: A powerful, customizable and extensible ViewPager indicator framework. As the best alternative of ViewPagerIndicator, TabLayout and PagerSlidingTabStrip —— 强大、可定制、易扩展的 ViewPager 指示器框架。是ViewPagerIndi…...
vue中如何将json数组指定的key赋值给el-form-item并均匀的分成2列
在Vue中,你可以使用v-for指令来遍历JSON数组,并将指定的key赋值给el-form-item。下面是一个示例: <template><el-form><el-row><el-col :span"6" v-for"item in jsonArray" :key"item.key&qu…...
笔记本分屏怎么操作?3个方法提高工作效率!
“有朋友知道笔记本怎么才能实现分屏吗?我在工作时,经常需要来回切换屏幕,效率真的太低了,有什么方法可以实现两个屏幕同时使用吗?” 在现代生活中,多任务处理已成为常态,而笔记本分屏技术为用户…...
Android 使用poi生成Excel ,word并保存在指定路径内
一添加依赖(一定要用新版依赖防止一些bug) minSdk 26 //注意最小支持SDK26 dependencies {implementation org.apache.poi:poi:5.2.4implementation org.apache.poi:poi-ooxml:5.2.4implementation javax.xml.stream:stax-api:1.0-2 }二,创…...
嵌入式杂记 -- MCU的大小端模式
MCU的大小端模式 大端模式小端模式大小端模式测试联合体概念MCU大小端模式测试大端模式测试小端模式测试 大小端模式转换 在进行MCU开发的时候,我们需要注意MCU的数据存储模式,在嵌入式中有两种不同的存储模式,分别是 大端模式和小端模式。 …...
对这套BI零售数据分析方案心动,是零售人天性
零售数据分析做了这么多年,难道真的没累积点经验,摸索出一条又快又能满足绝大多数需求的数据分析捷径?别人不知道,奥威BI还真就有这么一套标准化的BI零售数据分析方案,不管是服装零售、医药连锁、商超都能利用这套方案…...
vuekeyclock 集成
前端集成keycloak鉴权的主要写法, 在main.js里面写 import VueKeycloakJs from dsb-norge/vue-keycloak-js import { KeycloakInstance } from "keycloak-js";// 回调地址 const pageIndex process.env.NODE_ENV production ? http://xxxx/#/ : http:…...
ARM Linux 基础学习 / 配置交叉编译工具链 / 编译 Linux 应用和驱动 / 编译内核
编辑整理 by Staok。 本文部分内容摘自 “100ask imx6ull” 开发板的配套资料(如 百问网的《嵌入式Linux应用开发完全手册》,在 百问网 imx6ull pro 开发板 页面 中的《2.1 100ASK_IMX6ULL_PRO:开发板资料》或《2.2 全系列Linux教程…...
通讯协议学习之路(实践部分):SPI开发实践
通讯协议之路主要分为两部分,第一部分从理论上面讲解各类协议的通讯原理以及通讯格式,第二部分从具体运用上讲解各类通讯协议的具体应用方法。 后续文章会同时发表在个人博客(jason1016.club)、CSDN;视频会发布在bilibili(UID:399951374) 本文…...
【系统安装】ubuntu20.04启动盘制作,正经教程,小白安装教程,百分百成功安装
1.所需材料: 64GBU盘(其实8g和16g也可以) 2.制作U盘启动盘 使用windows制作ubuntu 20.04启动盘 1)下载制作工具:Rufus:Rufus - 轻松创建 USB 启动盘 2)插入用来做启动盘的U盘 3࿰…...
2023云计算发展趋势
目录 一、云计算是什么? 二、云计算发展趋势 三、总结 一、云计算是什么? 云计算是一种基于互联网的计算方式,通过网络连接的方式提供计算能力、存储服务、应用程序和数据资源。它通常通过虚拟化技术实现多个计算机资源的池化,…...
C# .NET Core API Controller以及辅助专案
准备工作 Windows 10Visual Studio 2019(2017就有可以集中发布到publish目录的功能了吧)C#将方法封装(据说可以提高效率,就像是我们用的dll那种感觉新增专案作为我们API的辅助专案(作用类似dll,此处,你也可以在你自己的API专案里建文件夹,但…...
asp.net图书管理系统
asp.net图书管理系统 基本操作图书管理 读者管理 借书 修改资料 修改密码 说明文档 运行前附加数据库.mdf(或sql生成数据库) 主要技术: 基于C#winform架构和sql server数据库 功能模块: 图书管理 读者管理 借书 修改资料 修改…...
概念解析 | LoRA:低秩矩阵分解在神经网络微调中的作用
注1:本文系“概念解析”系列之一,致力于简洁清晰地解释、辨析复杂而专业的概念。本次辨析的概念是:基于低秩矩阵分解的神经网络微调方法LoRA LoRA: Low-Rank Adaptation of Large Language Models LoRA由如下论文提出,详细信息请参见论文原文 https://arxiv.org/abs/2106.0968…...
MPNet:旋转机械轻量化故障诊断模型详解python代码复现
目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...
vscode里如何用git
打开vs终端执行如下: 1 初始化 Git 仓库(如果尚未初始化) git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...
【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15
缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下: struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...
定时器任务——若依源码分析
分析util包下面的工具类schedule utils: ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类,封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz,先构建任务的 JobD…...
Spring Boot面试题精选汇总
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...
JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作
一、上下文切换 即使单核CPU也可以进行多线程执行代码,CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短,所以CPU会不断地切换线程执行,从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...
汇编常见指令
汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX(不访问内存)XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...
rnn判断string中第一次出现a的下标
# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...
服务器--宝塔命令
一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行! sudo su - 1. CentOS 系统: yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...
springboot整合VUE之在线教育管理系统简介
可以学习到的技能 学会常用技术栈的使用 独立开发项目 学会前端的开发流程 学会后端的开发流程 学会数据库的设计 学会前后端接口调用方式 学会多模块之间的关联 学会数据的处理 适用人群 在校学生,小白用户,想学习知识的 有点基础,想要通过项…...
