轻量封装WebGPU渲染系统示例<43>- PBR材质与阴影实(源码)

原理简介:

        1. 基于rendering pass graph实现。

        2. WGSL Shader 基于文件系统和宏机制动态组装。

当前示例源码github地址:

https://github.com/vilyLei/voxwebgpu/blob/feature/rendering/src/voxgpu/sample/PBRShadowTest.ts

当前示例运行效果:

此示例基于此渲染系统实现,当前示例TypeScript源码如下:

class ShadowPassGraph extends WGRPassNodeGraph {private entities: Entity3D[] = [];private mDepthMaterials: WGMaterial[];shadowDepthRTT = { uuid: "rtt-shadow-depth", rttTexture: {}, shdVarName: 'shadowData' };depAttachment: WGRPassColorAttachment = {texture: this.shadowDepthRTT,clearValue: { r: 1, g: 1, b: 1, a: 1.0 },loadOp: "clear",storeOp: "store"};occVRTT = { uuid: "rtt-shadow-occV", rttTexture: {}, shdVarName: 'shadowData' };occHRTT = { uuid: "rtt-shadow-occH", rttTexture: {}, shdVarName: 'shadowData' };occVEntity: FixScreenPlaneEntity;occHEntity: FixScreenPlaneEntity;shadowBias = -0.0005;shadowRadius = 2.0;shadowMapW = 512;shadowMapH = 512;shadowViewW = 1300;shadowViewH = 1300;shadowCamera: Camera;constructor() {super();}private initMaterial(): void {const shadowDepthShdSrc = {shaderSrc: { code: shadowDepthWGSL, uuid: "shadowDepthShdSrc" }};this.mDepthMaterials = [this.createDepthMaterial(shadowDepthShdSrc)];}private createDepthMaterial(shaderSrc: WGRShderSrcType, faceCullMode = "none"): WGMaterial {let pipelineDefParam = {depthWriteEnabled: true,faceCullMode,blendModes: [] as string[]};const material = new WGMaterial({shadinguuid: "shadow-depth_material",shaderSrc,pipelineDefParam});return material;}private buildShadowCam(): void {const g = this;const cam = new Camera({eye: [600.0, 800.0, -600.0],near: 0.1,far: 1900,perspective: false,viewWidth: g.shadowViewW,viewHeight: g.shadowViewH});cam.update();g.shadowCamera = cam;}addEntity(entity: Entity3D): ShadowPassGraph {let pass = this.passes[0];let et = new Entity3D({ transform: entity.transform });et.materials = this.mDepthMaterials;et.geometry = entity.geometry;et.rstate.copyFrom(entity.rstate);this.entities.push(et);pass.addEntity(et);return this;}addEntities(entities: Entity3D[]): ShadowPassGraph {let es = entities;for (let i = 0; i < es.length; ++i) {this.addEntity(es[i]);}return this;}initialize(rc: RendererScene): ShadowPassGraph {let colorAttachments = [this.depAttachment];// create a separate rtt rendering passlet multisampleEnabled = false;let pass = rc.createRTTPass({ colorAttachments, multisampleEnabled });this.passes = [pass];rc.setPassNodeGraph(this);this.buildShadowCam();pass.node.camera = this.shadowCamera;this.initMaterial();this.initocc();return this;}private initocc(): void {let pass = this.passes[0];let extent = [-1, -1, 2, 2];let material = new ShadowOccBlurMaterial();let ppt = material.property;ppt.setShadowRadius(this.shadowRadius);ppt.setViewSize(this.shadowMapW, this.shadowMapH);material.addTextures([this.shadowDepthRTT]);this.occVEntity = new FixScreenPlaneEntity({ extent, materials: [material] });this.occVEntity.visible = false;pass.addEntity(this.occVEntity);material = new ShadowOccBlurMaterial();ppt = material.property;ppt.setShadowRadius(this.shadowRadius);ppt.setViewSize(this.shadowMapW, this.shadowMapH);ppt.toHorizonalBlur();material.addTextures([this.occVRTT]);this.occHEntity = new FixScreenPlaneEntity({ extent, materials: [material] });this.occHEntity.visible = false;pass.addEntity(this.occHEntity);}run(): void {let pass = this.passes[0];let attachment = this.depAttachment;attachment.texture = this.shadowDepthRTT;let es = this.entities;for (let i = 0; i < es.length; ++i) {es[i].visible = true;}pass.render();for (let i = 0; i < es.length; ++i) {es[i].visible = false;}attachment.texture = this.occVRTT;this.occVEntity.visible = true;pass.render();this.occVEntity.visible = false;attachment.texture = this.occHRTT;this.occHEntity.visible = true;pass.render();this.occHEntity.visible = false;}
}
export class PBRShadowTest {private mRscene = new RendererScene();private mGraph = new ShadowPassGraph();initialize(): void {this.mRscene.initialize({canvasWith: 512,canvasHeight: 512,rpassparam: { multisampleEnabled: true }});this.initShadowScene();this.initEvent();}private mEntities: Entity3D[] = [];private initShadowScene(): void {let rc = this.mRscene;let position = [-230.0, 100.0, -200.0];let materials = this.createMaterials(position);let sph = new SphereEntity({radius: 80,transform: {position},materials});this.mEntities.push(sph);rc.addEntity(sph);position = [160.0, 100.0, -210.0];materials = this.createMaterials(position);let box = new BoxEntity({minPos: [-30, -30, -30],maxPos: [130, 230, 80],transform: {position,rotation: [50, 130, 80]},materials});this.mEntities.push(box);rc.addEntity(box);position = [160.0, 100.0, 210.0];materials = this.createMaterials(position);let torus = new TorusEntity({transform: {position,rotation: [50, 30, 80]},materials});this.mEntities.push(torus);rc.addEntity(torus);this.buildShadow();}private buildShadow(): void {this.initShadowPass();this.initShadowReceiveDisp(true);this.buildShadowCamFrame();}private mShadowTransMat: Matrix4;private initShadowPass(): void {let rc = this.mRscene;const graph = this.mGraph;graph.initialize(rc).addEntities(this.mEntities);let cam = graph.shadowCamera;let transMatrix = new Matrix4();transMatrix.setScaleXYZ(0.5, -0.5, 0.5);transMatrix.setTranslationXYZ(0.5, 0.5, 0.5);let shadowMat = new Matrix4();shadowMat.copyFrom(cam.viewProjMatrix);shadowMat.append(transMatrix);this.mShadowTransMat = shadowMat;let extent = [-0.95, -0.95, 0.4, 0.4];let entity = new FixScreenPlaneEntity({ extent, flipY: true, textures: [{ diffuse: graph.shadowDepthRTT }] });rc.addEntity(entity);extent = [-0.5, -0.95, 0.4, 0.4];entity = new FixScreenPlaneEntity({ extent, flipY: true, textures: [{ diffuse: graph.occVRTT }] });rc.addEntity(entity);extent = [-0.05, -0.95, 0.4, 0.4];entity = new FixScreenPlaneEntity({ extent, flipY: true, textures: [{ diffuse: graph.occHRTT }] });rc.addEntity(entity);}private buildShadowCamFrame(): void {const graph = this.mGraph;const cam = graph.shadowCamera;const rsc = this.mRscene;let frameColors = [[1.0, 0.0, 1.0], [0.0, 1.0, 1.0], [1.0, 0.0, 0.0], [0.0, 1.0, 1.0]];let boxFrame = new BoundsFrameEntity({ vertices8: cam.frustum.vertices, frameColors });rsc.addEntity(boxFrame);}private initEvent(): void {const rc = this.mRscene;rc.addEventListener(MouseEvent.MOUSE_DOWN, this.mouseDown);new MouseInteraction().initialize(rc, 0, false).setAutoRunning(true);}private initShadowReceiveDisp(shadowReceived = false): void {let rc = this.mRscene;let position = new Vector3(0, -1, 0);let materials = this.createMaterials(position, shadowReceived);let plane = new PlaneEntity({axisType: 1,materials,extent:[-600,-600,1200,1200],transform: { position }});rc.addEntity(plane);}private hdrEnvtex = new SpecularEnvBrnTexture();private createBaseTextures(shadowReceived = false): WGTextureDataDescriptor[] {const albedoTex = { albedo: { url: `static/assets/pbrtex/rough_plaster_broken_diff_1k.jpg` } };const normalTex = { normal: { url: `static/assets/pbrtex/rough_plaster_broken_nor_1k.jpg` } };const armTex = { arm: { url: `static/assets/pbrtex/rough_plaster_broken_arm_1k.jpg` } };let textures = [this.hdrEnvtex,albedoTex,normalTex,armTex] as WGTextureDataDescriptor[];if(shadowReceived) {textures.push( this.mGraph.occHRTT );}return textures;}private createMaterials(position: Vector3DataType, shadowReceived = false, uvParam?: number[]): BasePBRMaterial[] {let textures0 = this.createBaseTextures(shadowReceived);let material0 = this.createMaterial(position, textures0, ["solid"]);this.applyMaterialPPt(material0, shadowReceived);let list = [material0];if (uvParam) {for (let i = 0; i < list.length; ++i) {list[i].property.uvParam.value = uvParam;}}return list;}private applyMaterialPPt(material: BasePBRMaterial, shadowReceived = false): void {let property = material.property;property.ambient.value = [0.0, 0.2, 0.2];property.albedo.value = [0.7, 0.7, 0.3];property.arms.roughness = 0.8;property.armsBase.value = [0, 0, 0];property.param.scatterIntensity = 32;const graph = this.mGraph;let cam = graph.shadowCamera;property.shadowReceived = shadowReceived;if(shadowReceived) {property.shadowMatrix.shadowMatrix = this.mShadowTransMat;let vsmParams = property.vsmParams;vsmParams.radius = graph.shadowRadius;vsmParams.bias = graph.shadowBias;vsmParams.setSize(graph.shadowMapW, graph.shadowMapH);vsmParams.direction = cam.nv;vsmParams.intensity = 0.5;}}private mLightParams: LightShaderDataParam[] = [];private createMaterial(position: Vector3DataType, textures: WGTextureDataDescriptor[], blendModes: string[], depthCompare = 'less', lightParam?: LightShaderDataParam): BasePBRMaterial {if (!lightParam) {lightParam = createLightData(position);this.mLightParams.push(lightParam);}let pipelineDefParam = {depthWriteEnabled: true,faceCullMode: 'back',blendModes,depthCompare};let material = new BasePBRMaterial({ pipelineDefParam });material.setLightParam(lightParam);material.addTextures(textures);return material;}private mouseDown = (evt: MouseEvent): void => {};run(): void {this.mRscene.run();}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/215106.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【C语言】【数据结构】自定义类型:结构体

引言 这是一篇对结构体的详细介绍&#xff0c;这篇文章对结构体声明、结构体的自引用、结构体的初始化、结构体的内存分布和对齐规则、库函数offsetof、以及进行内存对齐的原因、如何修改默认对齐数、结构体传参进行介绍和说明。 ✨ 猪巴戒&#xff1a;个人主页✨ 所属专栏&am…

手机升级到iOS15.8后无法在xcode(14.2)上真机调试

之前手机是iOS14.2的系统,在xcode上进行真机测试运行良好&#xff0c;因为想要使用Xcode的Instruments功能&#xff0c;今天将系统更新到了iOS15.8 &#xff0c;结果崩了 说是Xcode和手机系统不兼容不能进行真机测试。在网上查了好些方法&#xff0c;靠谱的就是下载相关版本的…

Centos7云服务器上安装cobalt_strike_4.7。附cobalt_strike_4.7安装包

环境这里是阿里的一台Centos7系统。 开始安装之前首先要确保自己安装了java11及以上环境。 安装java11步骤&#xff1a; sudo yum update sudo yum install java-11-openjdk-devel把服务器端&#xff08;CS工具分服务器端和客户端&#xff09;的CS安装到服务器上后给目录下的…

【Java探索之旅】我与Java的初相识(一):Java的特性与优点及其发展史

&#x1f3a5; 屿小夏 &#xff1a; 个人主页 &#x1f525;个人专栏 &#xff1a; Java入门到精通 &#x1f304; 莫道桑榆晚&#xff0c;为霞尚满天&#xff01; 文章目录 一. Java语言概述与优势1.1 Java的概述1.2 Java语言的优势 二. Java领域与发展史2.1 Java的使用领域2.…

【Linux20.04-qt5.12.4软件安装与初步使用-qt在Linux使用-记录-笔记】

【Linux-qt软件安装与初步使用-qt在Linux使用-记录-笔记】 1、概述2、环境说明3、步骤总结1、了解并选择自己想要安装的版本2、访问 Qt 官方网站3、在 Qt 网站上找到下载部分&#xff08;自己想下载&#xff09;4、下载完成后&#xff0c;给安装程序文件赋予执行权限。5、自动配…

《杂文选刊》明年休刊之随笔

笔者今天偶然发现&#xff0c;网民对于近期登上社交网站热搜榜的一条新闻&#xff0c;既感兴趣又觉迷惑&#xff0c;因此关注度显得较高。 荣登社交网站热搜榜的这条新闻是&#xff1a;12月4日发出“休刊启事 ”&#xff0c;在宣布“《 杂文选刊》2024年1月1日起休刊”的同时&…

django与数据库交互关于当前时间的坑

背景 在线上服务中使用时间进行数据库操作时发现异常&#xff0c;而在本地环境无法成功复现此问题&#xff0c;导致难以进行故障排查。 核心问题 view.py class XxxViewSet(viewsets.ModelViewSet):queryset Xxx.objects.with_status().order_by("status", &quo…

【组合数学】递推关系

目录 1. 递推关系建立2. 常系数齐次递推关系的求解3. 常系数非齐次递推关系的求解4. 迭代法 1. 递推关系建立 给定一个数的序列 f ( 0 ) , f ( 1 ) , . . . , f ( n ) , . . . , f (0), f(1), ..., f(n ),... , f(0),f(1),...,f(n),..., 若存在整数 n 0 n_0 n0​ &#xff…

java--LocalDate、LocalTime、LocalDateTime、ZoneId、Instant

1.为什么要学习JDK8新增的时间 LocalDate&#xff1a;代表本地日期(年、月、日、星期) LocalTime&#xff1a;代表本地时间(时、分、秒、纳秒) LocalDateTime&#xff1a;代表本地日期、时间(年、月、日、星期、时、分、秒、纳秒) 它们获取对象的方案 2.LocalDate的常用API(…

我的 CSDN 三周年创作纪念日:2020-12-12

本人大叔一枚&#xff0c;自1992年接触电脑&#xff0c;持续了30年的业余电脑发烧爱好者&#xff0c;2022年CSDN博客之星Top58&#xff0c;阿里云社区“乘风者计划”专家博主。自某不知名财校毕业后进入国有大行工作至今&#xff0c;先后任职于某分行信息科技部、电子银行部、金…

UG NX二次开发(C#)-求曲线在某一点处的法矢和切矢

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 1、前言2、在UG NX中创建一个曲线3、直接放代码4、测试案例1、前言 最近确实有点忙了,好久没更新博客了。今天恰好有时间,就更新下,还请家人们见谅。 今天我们讲一下如何获取一条曲线上某一条曲…

仅 CSS 阅读进度条

为了构建一个阅读进度条&#xff0c;即显示用户向下滚动时阅读文章的进度&#xff0c;很难不考虑 JavaScript。但是&#xff0c;事实证明&#xff0c;您也可以使用纯 CSS 构建阅读进度条。 从本质上讲&#xff0c;一个名为 animation-timeline 的新实验性 CSS 属性可以让你指定…

oracle 下载java之前版本

登录oracle官网&#xff1a;Oracle | Cloud Applications and Cloud Platform 点击resource 进入该页面 点击这个 出现之前版本

linux交换分区管理SWAP

概念查看当前的交换分区&#xff1a;free 6.2.5 交换分区管理SWAP 6.2.5.1 概念 作用&#xff1a; ”提升“内存容量&#xff0c;防止OOM&#xff08;out of memory&#xff0c;内存溢出&#xff09;。 ​ 对应windows中的虚拟内存。 ​ 从功能上讲&#xff0c;交换分区主要是…

Axure官方软件安装、汉化保姆级教程(带官方资源下载)

1.下载汉化包 百度云链接&#xff1a;https://pan.baidu.com/s/1lluobjjBZvitASMt8e0A_w?pwdjqxn 提取码&#xff1a; jqxn 2.解压压缩包 3.安装Axure 进行安装 点击next 打勾&#xff0c;然后next, 默认是c盘&#xff0c;修改成自己的文件夹&#xff08;不要什么都放c盘里…

Uber Go 语言编码规范

uber-go/guide 的中文翻译 English 文档链接 Uber Go 语言编码规范 Uber 是一家美国硅谷的科技公司&#xff0c;也是 Go 语言的早期 adopter。其开源了很多 golang 项目&#xff0c;诸如被 Gopher 圈熟知的 zap、jaeger 等。2018 年年末 Uber 将内部的 Go 风格规范 开源到 G…

FastAPI请求体-多个参数

路径参数、查询参数&#xff0c;和请求体混合 首先&#xff0c;我们需要导入所需的库。我们将使用FastAPI、Path和Annotated来处理路由和参数&#xff0c;并使用BaseModel和Union来自定义数据模型。 完整示例代码 from typing import Annotated, Unionfrom fastapi import F…

【lesson11】数据类型之string类型

文章目录 数据类型分类string类型set类型测试 enum类型测试 string类型的内容查找找所有女生&#xff08;enum中&#xff09;找爱好有游泳的人&#xff08;set中&#xff09;找到爱好中有足球和篮球的人 数据类型分类 string类型 set类型 说明&#xff1a; set&#xff1a;集…

C# 任务的异常和延续处理

写在前面 当Task在执行过程中出现异常或被取消等例外的情况时&#xff0c;为了让执行流程能够继续进行&#xff0c;可以使用延续方法实现这种链式处理&#xff1b;还可以针对前置任务不同的执行结果&#xff0c;选择执行不同的延续分支方法。子任务执行过程中的任何异常都会被…

排程系统中关于任务优先级的需求延伸与设计构思

无论是面向销售订单的MPS&#xff0c;还是基于多工序制约关系的APS&#xff0c;还是具体车间生产中针对单一工序的任务作业调度优化&#xff0c;都存在基于被排程对象(例如销售订单、生产工单、工序任务)的优先级进行优化的需求场景。当我们仅在宏观、较高层次的角度考虑&#…