轻量封装WebGPU渲染系统示例<40>- 多层材质的Mask混合(源码)

当前示例源码github地址:

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

当前示例运行效果:

两层材质效果:

三层材质效果:

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

export class MaskTextureEffect {private mRscene = new RendererScene();initialize(): void {this.mRscene.initialize({ canvasWith: 512, canvasHeight: 512, rpassparam: { multisampleEnabled: true } });this.initScene();this.initEvent();}private hdrEnvtex = new SpecularEnvBrnTexture();private createMaskTextures(ns: string, maskns='displacement_01.jpg'): WGTextureDataDescriptor[] {const albedoTex = { albedo: { url: `static/assets/pbr/${ns}/albedo.jpg` } };const normalTex = { normal: { url: `static/assets/pbr/${ns}/normal.jpg` } };const aoTex = { ao: { url: `static/assets/pbr/${ns}/ao.jpg` } };const roughnessTex = { roughness: { url: `static/assets/pbr/${ns}/roughness.jpg` } };const metallicTex = { metallic: { url: `static/assets/pbr/${ns}/metallic.jpg` } };// mask textureconst opacityTex = { opacity: { url: `static/assets/${maskns}` } };let textures = [this.hdrEnvtex,albedoTex,normalTex,aoTex,roughnessTex,metallicTex,opacityTex] as WGTextureDataDescriptor[];return textures;}private createBaseTextures(): 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[];return textures;}private initScene(): void {const rc = this.mRscene;let entity0 = new FixScreenPlaneEntity().setColor([0.2, 0.5, 0.4]);rc.addEntity(entity0);this.initEntities();}private initEntities(): void {this.initTexDisp();}private initTexDisp(): void {let rc = this.mRscene;let position = new Vector3(0, 0, 180);let materials = this.createMaterials(position);let sphere = new SphereEntity({radius: 150.0,materials,transform: { position }});rc.addEntity(sphere);position = new Vector3(0, 0, -180);materials = this.createMaterials(position, [4,1]);let torus = new TorusEntity({axisType: 1,materials,transform: { position }});rc.addEntity(torus);}private createMaterials(position: Vector3, uvParam?: number[]): BasePBRMaterial[] {let textures0 = this.createBaseTextures();let textures1 = this.createMaskTextures("plastic");let textures2 = this.createMaskTextures("wall", 'circleWave_disp.png');let material0 = this.createMaterial(position, textures0, ["solid"]);this.applyMaterialPPt(material0);let material1 = this.createMaterial(position, textures1, ["transparent"], 'less-equal', material0.getLightParam());material1.property.inverseMask = false;this.applyMaterialPPt(material1);let material2 = this.createMaterial(position, textures2, ["transparent"], 'less-equal', material0.getLightParam());material2.property.inverseMask = true;this.applyMaterialPPt(material2);let list = [material0, material1, material2];// let list = [material0, material1];if(uvParam) {for(let i = 0; i < list.length; ++i) {list[i].property.uvParam.value = uvParam;}}return list;}private applyMaterialPPt(material: BasePBRMaterial): 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.uvParam.value = [2, 2];property.param.scatterIntensity = 32;}private mLightParams: LightShaderDataParam[] = [];private createMaterial(position: Vector3DataType, textures: WGTextureDataDescriptor[], blendModes: string[], depthCompare = 'less', lightParam?: LightShaderDataParam): BasePBRMaterial {if (!lightParam) {lightParam = this.createLightData(position);}let pipelineDefParam = {depthWriteEnabled: true,faceCullMode: 'back',blendModes,depthCompare};let material = new BasePBRMaterial({ pipelineDefParam });material.setLightParam(lightParam);material.addTextures(textures);return material;}private createLightData(position: Vector3DataType): LightShaderDataParam {let pos = new Vector3().setVector4(position);let pv0 = pos.clone().addBy(new Vector3(0, 200, 0));let pv1 = pos.clone().addBy(new Vector3(200, 0, 0));let pv2 = pos.clone().addBy(new Vector3(0, 0, 200));let pv3 = pos.clone().addBy(new Vector3(-200, 0, 0));let pv4 = pos.clone().addBy(new Vector3(0, 0, -200));let posList = [pv0, pv1, pv2, pv3, pv4];let c0 = new Color4(0.1 + Math.random() * 13, 0.1 + Math.random() * 13, 0.0, 0.00002);let c1 = new Color4(0.0, 0.1 + Math.random() * 13, 1.0, 0.00002);let c2 = new Color4(0.0, 0.1 + Math.random() * 13, 0.1 + Math.random() * 13, 0.00002);let c3 = new Color4(0.1 + Math.random() * 13, 1.0, 0.1 + Math.random() * 13, 0.00002);let c4 = new Color4(0.5, 1.0, 0.1 + Math.random() * 13, 0.00002);let colorList = [c0, c1, c2, c3, c4];let pointLightsTotal = posList.length;let j = 0;let lightsData = new Float32Array(4 * pointLightsTotal);let lightColorsData = new Float32Array(4 * pointLightsTotal);for (let i = 0; i < lightsData.length;) {const pv = posList[j];pv.w = 0.00002;pv.toArray4(lightsData, i);const c = colorList[j];c.toArray4(lightColorsData, i);j++;i += 4;}let param = { lights: lightsData, colors: lightColorsData, pointLightsTotal };this.mLightParams.push(param);return param;}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 => { };run(): void {this.mRscene.run();}
}

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

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

相关文章

2243:Knight Moves

文章目录 题目描述思路1. DFS2. BFS3. 动态规划 解题方法1. DFS2. BFS3. 动态规划 题目描述 题目链接 翻译如下&#xff1a; 注&#xff1a;骑士移动是和象棋里的马一样走的是日字型 你的一个朋友正在研究旅行骑士问题 &#xff08;TKP&#xff09;&#xff0c;你要找到最短的…

TCP与UDP的区别

TCPUDP连接传送数据前要先建立连接无需建立连接直接传送数据服务对象一对一一对多、多对一、多对多可靠性可靠交付&#xff08;保证数据包的无差错、不失序、不丢包、不重复&#xff09;尽最大努力交付&#xff0c;不保证可靠性&#xff08;但我们可以基于UDP协议实现一个可靠传…

一、Zookeeper基本知识

目录 1、ZooKeeper概述 2、ZooKeeper特性 3、ZooKeeper集群角色 ​​​​​​​1、ZooKeeper概述 Zookeeper是一个分布式协调服务的开源框架。主要用来解决分布式集群中应用系统的一致性问题。 ZooKeeper本质上是一个分布式的小文件存储系统。提供基于类似于文件系统的目录…

web前端之JavaScrip的笔试题

MENU Promise笔试题-02prototype和__proto__的笔试题JavaScript引用类型值值操和运算符优先级比较--笔试原型与原型链--笔试-05作用域-笔试事件队列-笔试题JavaScript之变量提升-笔试题JavaScript之原型链--笔试题 Promise笔试题-02 console.log(1); // 宏仁务 2 setTimeout(_…

[蓝桥杯 2020 省 AB1] 解码

做题前思路&#xff1a; 1.因为是多组输入&#xff0c;又包含字符于是我们可以先定义一个char类型数组arr 2.定义数组的长度&#xff1a;题目说简写&#xff08;字母加数字&#xff09;长度不超过100&#xff0c;但原来的长度可能超过100&#xff0c;加上小明不会将连续超过9…

CSS 滚动捕获 scroll-margin

CSS滚动捕获 scroll-margin 非滚动捕获容器语法兼容性 CSS滚动捕获 scroll-margin 设置元素的滚动外边距 非滚动捕获容器 之前在 scroll-padding 中说过如何用 scroll-padding 避免锚点定位时元素贴着容器边缘的问题, 现在我们尝试用 scroll-margin 解决 <body><ma…

如何使用Java进行人工智能开发?

Java作为一门面向对象的编程语言&#xff0c;在人工智能领域也发挥着重要作用。Java可以借助常见的机器学习库&#xff0c;例如TensorFlow和Keras等&#xff0c;进行机器学习和深度学习的开发。下面是使用Java进行人工智能开发的一些步骤和工具。 准备工作 在使用Java进行人工智…

【C/C++指针】指针*与引用的区别

指针变量的值是所指对象的地址&#xff08;准确说是首地址&#xff0c;其类型定义其所指对象的字节长度&#xff09;引用变量的值是所引用对象本身的值 1 初始化 指针变量 可不初始化 且 可以更换指向对象 int *p;//此时是个野指针&#xff0c;该指针变量的值是任意值&#x…

Kubernetes技术与架构-策略

Kubernetes集群提供系统支持的策略&#xff0c;也提供开放接口给第三方定义的策略&#xff0c;这些策略用于可定义的配置文件或者Kubernetes集群的运行时环境&#xff0c;其中包括进程ID数量的申请与限制策略&#xff0c;服务器节点Node内的进程ID的数量限制策略&#xff0c;Po…

RocketMQ阅读源码前的准备

本文将讲解如何在IDEA中导入 RocketMQ 源码&#xff0c;并运行 Broker 和 NameServer&#xff0c;编写一个消息发送与消息消费的示例。 一. 源码导入及调试 1.1 导入源码 RocketMQ 原先是阿里巴巴集团内部的消息中间件&#xff0c;于2016年提交至Apache基金会孵化&#xff0…

代码随想录算法训练营第三十四天|62.不同路径,63. 不同路径 II

62. 不同路径 - 力扣&#xff08;LeetCode&#xff09; 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish” &#…

oj赛氪练习题

数组调整 import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner scanner new Scanner(System.in);int n scanner.nextInt();int k scanner.nextInt();int[] arr new int[n];for (int i 0; i < n; i) {arr[i] scanner.nextIn…

python+Qt5+sqllite 个性化单词记忆软件设计

问题描述&#xff1a; 设计一款背诵英语单词的软件。用户可以根据自己的需求导入需背诵的词库&#xff0c;并可以编辑自己的词库。背单词时有两种模式供选择&#xff1a;系统可以给出中文提示&#xff0c;用户输入对应的单词&#xff0c;也可输出单词让用户输入中文意思。系统判…

react-native实践日记--6.ReactNative 项目版本升级,0.61到0.72升级的问题记录(二)

接上一篇&#xff0c;ReactNative项目升级&#xff0c;0.61到0.72的升级问题。 在升级过程中&#xff0c;发现react-native-scrollable-tab-view这个tab插件&#xff0c;这是一个tab导航栏插件&#xff0c;可以实现切换页面、页面滚动、下拉刷新、上拉加载更多等&#xff0c;功…

二叉树的前,中,后序遍历(递归法和迭代法) Python

二叉树的前序遍历 递归法&#xff1a; # 定义二叉树节点的类 # class TreeNode: # def __init__(self, x): # self.val x # self.left None # self.right Noneclass Solution:def preorderTraversal(self, root: Optional[TreeNode]) -> List[…

【pytest】执行环境切换的两种解决方案

一、痛点分析 在实际企业的项目中&#xff0c;自动化测试的代码往往需要在不同的环境中进行切换&#xff0c;比如多套测试环境、预上线环境、UAT环境、线上环境等等&#xff0c;并且在DevOps理念中&#xff0c;往往自动化都会与Jenkins进行CI/CD&#xff0c;不论是定时执行策略…

SQL解惑 - 谜题2

文章目录 一、谜题描述二、分析三、答案四、总结 一、谜题描述 创建一个记录雇员缺勤率的数据库。使用的表结构如下&#xff1a;Absenteeism 主键&#xff1a;PRIMARY KEY (emp_id, absent_date) 字段名字段类型字段中文名字段描述emp_idINTERGER雇员id-absent_dateSTRING缺勤…

【数据中台】开源项目(5)-Amoro

介绍 Amoro is a Lakehouse management system built on open data lake formats. Working with compute engines including Flink, Spark, and Trino, Amoro brings pluggable and self-managed features for Lakehouse to provide out-of-the-box data warehouse experience,…

SQL优化的面试题

1. **针对慢查询进行性能优化**&#xff1a; - 使用数据库提供的工具&#xff08;如MySQL的EXPLAIN语句&#xff09;分析查询计划&#xff0c;找出潜在的性能问题。 - 优化查询语句的结构&#xff0c;确保索引被充分利用。 - 对于大表&#xff0c;考虑分页或缓存部分结…

6-2 统计大于等于平均分人数

函数 fun 的功能是&#xff1a;从m个学生的成绩中统计出高于和等于平均分的学生人数&#xff0c; 此人数由函数值返回。平均分通过形参传回&#xff0c;输入学生成绩时&#xff0c; 用-1结束输入&#xff0c;由程序自动统计学生人数。 函数接口定义&#xff1a; int fun ( fl…