轻量封装WebGPU渲染系统示例<54>- 表现GLB模型之拱形门

news2025/2/6 3:11:02

当前示例源码github地址:

https://github.com/vilyLei/voxwebgpu/blob/feature/material/src/voxgpu/sample/GLBMaterialTest.ts

当前示例运行效果:

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

export class GLBMaterialTest {
	private mRscene = new RendererScene();
	initialize(): void {
		this.loadImg();
	}
	initSys(): void {

		this.mRscene.initialize({
			canvasWith: 512,
			canvasHeight: 512,
			mtplEnabled: true,
			rpassparam:
			{
				multisampled: true
			}
		});
		this.initScene();
		this.initEvent();
	}
	private mPixels: Uint8ClampedArray;
	private mPixelsW = 128;
	private mPixelsH = 128;
	getRandomColor(s?: number): ColorDataType {
		if (s === undefined) {
			s = 1.0;
		}
		let i = 5;
		let j = Math.floor(Math.random() * this.mPixelsW);
		let k = i * this.mPixelsW + j;
		let vs = this.mPixels;
		k *= 4;
		let cs = [s * vs[k] / 255.0, s * vs[k + 1] / 255.0, s * vs[k + 2] / 255.0];
		return cs;
	}
	private loadImg(): void {
		let img = new Image();
		img.onload = evt => {
			this.mPixelsW = img.width;
			this.mPixelsH = img.height;
			let canvas = document.createElement("canvas");
			canvas.width = img.width;
			canvas.height = img.height;
			let ctx = canvas.getContext('2d');
			ctx.drawImage(img, 0, 0);
			this.mPixels = ctx.getImageData(0, 0, img.width, img.height).data;
			this.initSys();
		}
		img.src = 'static/assets/colorPalette.jpg';
	}
	private mLightData: MtLightDataDescriptor;
	private createLightData(): MtLightDataDescriptor {
		let ld = { pointLights: [], directionLights: [], spotLights: [] } as MtLightDataDescriptor;

		let space = new CylinderRandomRange();
		space.minRadius = 130;
		space.maxRadius = 260;
		space.minHeight = 10;
		space.maxHeight = 300;
		space.initialize();
		space.setSpaceScale(1.0, 1.0, 0.5);

		let total = 5;
		let scale = 8.0;
		for (let i = 0; i < total; ++i) {
			for (let j = 0; j < total; ++j) {
				space.calc();
				let position = space.value;
				let color = this.getRandomColor(scale);
				let factor1 = 0.0001;
				let factor2 = 0.0002;
				let pLight = new PointLight({ color, position, factor1, factor2 });
				ld.pointLights.push(pLight);
				if (Math.random() > 0.5) {
					space.calc();
					position = space.value;
					color = this.getRandomColor(scale);
					let direction = [(Math.random() - 0.5) * 8, -1, (Math.random() - 0.5) * 8];
					let degree = Math.random() * 10 + 5;
					let spLight = new SpotLight({ position, color, direction, degree, factor1, factor2 });
					ld.spotLights.push(spLight);
				}
			}
		}
		let dLight = new DirectionLight({ color: [0.5, 0.5, 0.5], direction: [-1, -1, 0] });
		ld.directionLights.push(dLight);
		return ld;
	}
	private createBillboard(pv: Vector3DataType, c: ColorDataType, type: number): void {
		let rc = this.mRscene;
		let diffuseTex0 = { diffuse: { url: "static/assets/flare_core_03.jpg" } };
		if (type > 1) {
			diffuseTex0 = { diffuse: { url: "static/assets/circleWave_disp.png" } };
		}
		let billboard = new BillboardEntity({ size: 5, textures: [diffuseTex0] });
		billboard.color = c;
		billboard.alpha = 1;
		billboard.transform.setPosition(pv);
		rc.addEntity(billboard, {layerIndex:1});
	}
	private createBillboards(): void {
		let lightData = this.mLightData;
		let pls = lightData.pointLights;
		for (let i = 0; i < pls.length; i++) {
			let lp = pls[i];
			this.createBillboard(lp.position, lp.color, 1);
		}
		let spls = lightData.spotLights;
		for (let i = 0; i < spls.length; i++) {
			let lp = spls[i];
			this.createBillboard(lp.position, lp.color, 2);
		}
	}
	private initScene(): void {

		let rc = this.mRscene;

		let mtpl = rc.renderer.mtpl;

		this.mLightData = this.createLightData();

		this.createBillboards();
		mtpl.light.lightData = this.mLightData;
		mtpl.shadow.intensity = 0.4;
		mtpl.shadow.radius = 1;

		this.mTexType = 1;
		let position = [0, 0, 0];
		let materials = this.createMaterials(true);
		let modelEntity = new ModelEntity({
			transform: { position },
			materials,
			modelUrl: "static/assets/draco/portal.drc"
		});
		rc.addEntity(modelEntity);
		
		this.mTexType = 0;
		position = [0, 0, 0];
		materials = this.createMaterials2(true, true, "back",[6,6]);
		let plane = new PlaneEntity({
			axisType: 1,
			materials,
			extent: [-600, -600, 1200, 1200],
			transform: { position }
		});
		rc.addEntity(plane);


	}
	
	private createTextures(ns: string): WGTextureDataDescriptor[] {
		return [
			{ specularEnv: {} },
			{ albedo: { url: `static/assets/pbr/${ns}/albedo.jpg` } },
			{ normal: { url: `static/assets/pbr/${ns}/normal.jpg` } },
			{ ao: { url: `static/assets/pbr/${ns}/ao.jpg` } },
			{ roughness: { url: `static/assets/pbr/${ns}/roughness.jpg` } },
			{ metallic: { url: `static/assets/pbr/${ns}/metallic.jpg` } },
			{ parallax: { url: `static/assets/pbr/${ns}/parallax.jpg` } }
		];
	}
	private createArmTextures2(): WGTextureDataDescriptor[] {
		
		let flipY = true;
		return [
			{ specularEnv: {} },
			{ albedo: { url: `static/assets/glb/portal/portal_img2.jpg`, flipY } },
			{ normal: { url: `static/assets/glb/portal/portal_img3.jpg`, flipY } },
			{ arm: { url: `static/assets/glb/portal/portal_img1.jpg`, flipY } },
			{ emissive: { url: `static/assets/glb/portal/portal_img0.jpg`, flipY } }
		];
	}
	private createArmTextures1(): WGTextureDataDescriptor[] {
		let flipY = false;
		let textures = [
			{ specularEnv: {} },
			{ albedo: { url: `static/assets/pbrtex/medieval_blocks_02_diff_1k.jpg`, flipY } },
			{ normal: { url: `static/assets/pbrtex/medieval_blocks_02_nor_1k.jpg`, flipY } },
			{ arm: { url: `static/assets/pbrtex/medieval_blocks_02_arm_1k.jpg`, flipY } },
			{ parallax: { url: `static/assets/pbrtex/medieval_blocks_02_disp_1k.jpg`, flipY } },
			{ opacity: { url: `static/assets/metal_02.jpg` } }
		];
		return textures;
	}
	private mTexType = 0;
	private createMaterials(shadowReceived = false, shadow = true, faceCullMode = 'back', uvParam?: number[]): BaseMaterial[] {

		let textures0 = this.mTexType < 1 ? this.createTextures("wall") : this.createArmTextures2();

		let material0 = this.createMaterial(textures0, ["solid"], 'less', faceCullMode);
		this.applyMaterialPPt(material0, shadowReceived, shadow);
		let list = [material0];
		if (uvParam) {
			for (let i = 0; i < list.length; ++i) {
				list[i].property.uvParam.value = uvParam;
			}
		}
		return list;
	}
	
	private createMaterials2(shadowReceived = false, shadow = true, faceCullMode = 'back', uvParam?: number[]): BaseMaterial[] {

		let textures0 = this.createTextures("wall");
		let textures1 = this.createArmTextures1();

		let material0 = this.createMaterial(textures0, ["solid"], 'less', faceCullMode);
		this.applyMaterialPPt(material0, shadowReceived, shadow);

		let material1 = this.createMaterial(textures1, ["transparent"], 'less-equal', faceCullMode);
		material1.property.inverseMask = false;
		this.applyMaterialPPt(material1, shadowReceived, shadow);
		let list = [material0, material1];
		if (uvParam) {
			for (let i = 0; i < list.length; ++i) {
				list[i].property.uvParam.value = uvParam;
			}
		}
		let cvs = this.getRandomColor(1.0) as number[];
		cvs[0] = cvs[0] * 0.7 + 0.3;
		cvs[1] = cvs[1] * 0.7 + 0.3;
		cvs[2] = cvs[2] * 0.7 + 0.3;
		material1.property.albedo.value = cvs;
		material1.property.uvParam.value = [2,2];
		return list;
	}

	private applyMaterialPPt(material: BaseMaterial, shadowReceived = false, shadow = true): void {
		let ppt = material.property;
		ppt.ambient.value = [0.2, 0.2, 0.2];
		let cvs = this.getRandomColor(1.0) as number[];
		cvs[0] = cvs[0] * 0.3 + 0.7;
		cvs[1] = cvs[1] * 0.3 + 0.7;
		cvs[2] = cvs[2] * 0.3 + 0.7;
		ppt.albedo.value = cvs;
		ppt.arms.roughness = Math.random() * 0.95 + 0.05;
		ppt.arms.metallic = 0.2;
		ppt.armsBase.value = [0, 0.2, 0];
		ppt.specularFactor.value = [0.1, 0.1, 0.1];

		ppt.shadow = shadow;
		ppt.lighting = true;

		ppt.shadowReceived = shadowReceived;
	}
	private createMaterial(textures: WGTextureDataDescriptor[], blendModes: string[], depthCompare = 'less', faceCullMode = 'back'): BaseMaterial {

		let pipelineDefParam = {
			depthWriteEnabled: true,
			faceCullMode,
			blendModes,
			depthCompare
		};
		let material = new BaseMaterial({ pipelineDefParam });
		material.addTextures(textures);
		return material;
	}
	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.coloradmin.cn/o/1336851.html

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

相关文章

java内存溢出初步排查

java内存模型 java内存空间主要包括以下几个部分&#xff1a;方法区、堆内存、虚拟机栈、本地方法栈 方法区&#xff1a;主要存放已被加载的类信息&#xff0c;常量&#xff0c;静态变量等。堆内存&#xff1a;Java堆是JVM所管理的最大一块内存空间&#xff0c;几乎所有的对象…

【ai】阿里云 大模型 api 聚合平台 dashscope

阿里云登录 - 欢迎登录阿里云&#xff0c;安全稳定的云计算服务平台 快速调用 前提条件 已开通服务并获得API-KEY&#xff1a;开通DashScope并创建API-KEY。 已安装最新版SDK&#xff1a;安装DashScope SDK。 DashScope灵积模型服务建立在“模型即服务”&#xff08;Model-a…

Sqlserver-查询和kill杀死正在运行的事务

Sqlserver-查询和kill杀死正在运行的事务 1.查询正在运行的事务2.杀死运行的事务Kill 1.查询正在运行的事务 SELECT session_id, task_state, pending_io_count, context_switches_count FROM sys.dm_os_tasks WHERE session_id > 50 ORDER BY task_state asc2.杀死运行的事…

【51单片机系列】DS18B20温度传感器模块

本文是关于温度传感器的相关内容。 文章目录 一、 DS18B20数字温度传感器介绍1.1、 DS18B20温度传感器的特点1.2、DA18B20内部结构1.3、 DS18B20的温度转换规则1.4、 DS18B20的ROM指令表1.6、 计算温度1.7、 读写时序 二、DS18B20使用示例 一、 DS18B20数字温度传感器介绍 DS1…

真心建议,入职业务部门前先学会BI数据分析

不管进入哪个业务部门&#xff0c;都需要具备一定的数据分析能力&#xff0c;能够从不断累积的数据中发现并解决问题。比如销售部门的需要通过分析销售数据&#xff0c;及时发现销售不佳的商品&#xff0c;调整销售策略&#xff0c;提高销售额、销售利润等。而随着精细化数据分…

一体式读卡器:引领数据读取新潮流

一体式读卡器&#xff1a;引领数据读取新潮流 随着科技的发展&#xff0c;读卡器在各个领域的应用越来越广泛&#xff0c;如工业自动化生产、身份认证、门禁控制、数据采集等。读卡器主要有两种类型&#xff1a;一体式读卡器和分体式读卡器。这两种类型的读卡器各有其优缺点&a…

Pr2024 for Mac/win中文版:为创意无限延展的全新时代

随着科技的不断进步和创新&#xff0c;影视制作行业也在不断发展。作为专业视频编辑软件的领军者&#xff0c;Premiere Pro于2024年推出了全新的版本Pr2024&#xff0c;为创意无限延展的全新时代揭开了崭新的篇章。 Pr2024以其强大的功能和卓越的性能&#xff0c;为用户带来了…

基于图搜索的自动驾驶规划算法 - BFS,Dijstra,A*

本文将讲解BFS&#xff0c;Dijstra&#xff0c;A*&#xff0c;动态规划的算法原理&#xff0c;不正之处望读者指正&#xff0c;希望有兴趣的读者能在评论区提出一些这些算法的面试考点&#xff0c;共同学习&#xff0c;一起进步 0 图论基础 图有三种&#xff1a;无向图、有向…

软件架构师的主要职责说明文(合集)

软件架构师的主要职责说明文1 职责&#xff1a; 1、挖掘和分析业务需求&#xff0c;对公司业务平台进行架构改进和升级设计&#xff0c;制定架构升级规划和过渡方案; 2、承担软件产品核心功能的开发工作&#xff0c;牵头保障整个系统不出现重大技术故障; 3、进行技术评估与产品…

有什么好用的C/C++源代码混淆工具?

​ 有什么好用的C/C源代码混淆工具&#xff1f; 开始使用ipaguard 前言 iOS加固保护是直接针对ios ipa二进制文件的保护技术&#xff0c;可以对iOS APP中的可执行文件进行深度混淆、加密。使用任何工具都无法逆向、破解还原源文件。对APP进行完整性保护&#xff0c;防止应用…

财务分析进阶篇:终于有人把利润分析怎么做给讲清了!

在之前的BI系列文章中&#xff0c;我们给大家介绍了如何用BI进行企业费用分析和毛利分析的方法。   发布后有小伙伴提到&#xff1a;“既然费用和毛利都分析了&#xff0c;顺便把利润表的数据分析一起做了呗”&#xff0c;因此这就有了本期内容。我希望结合前两篇文章&#xf…

ssh工具 从ssh服务器下载文件夹

此文分享一个python脚本,用于快速的定位、选择ssh服务器上的文件夹,并将其下载到本地指定的位置。 效果演示 🔥完整演示效果 👇 第一步,显然,我们需要选择功能 👇 第二步,确认我们需要从哪个ssh服务器上下载文档 👇 第三步,定位、选择、确认需要下载的文件夹…

计网03-数据的封装和解封装

数据封装和解封装的过程 实例&#xff1a;有两台电脑 PC&#xff11;和PC&#xff12;&#xff0c;PC1要给PC&#xff12;发送一个文本文件 1、数据的封装过程&#xff1a; 应用层&#xff1a;将原始数据转换成计算机能识别的二进制数传输层&#xff1a;在传输层是有固定的传…

vr虚拟高压电器三维仿真展示更立体全面

VR工业虚拟仿真软件的应用价值主要体现在以下几个方面&#xff1a; 降低成本&#xff1a;通过VR技术进行产品设计和开发&#xff0c;可以在虚拟环境中进行&#xff0c;从而减少对物理样机的依赖&#xff0c;降低试错成本和时间。此外&#xff0c;利用VR技术构建的模拟场景使用方…

Guava自加载缓存LoadingCache使用指南

第1章&#xff1a;引言 大家好&#xff0c;我是小黑&#xff0c;今天我们来聊聊缓存。在Java世界里&#xff0c;高效的缓存机制对于提升应用性能、降低数据库负担至关重要。想象一下&#xff0c;如果每次数据请求都要跑到数据库里取&#xff0c;那服务器岂不是要累趴了&#x…

如何在Photoshop中创建色彩鲜艳的文本效果

如何在 Photoshop 中制作霓虹灯 1. 如何创建背景 步骤 1 学习如何在 Photoshop 中制作霓虹灯文本的第一步是背景。创建一个新的 1160 x 750 像素文档&#xff0c;并将分辨率设置为 300。 转到"文件">"嵌入位置"&#xff0c;然后打开"垃圾灰色砖…

苹果证书p12和描述文件的创建方法

​ 苹果证书p12和描述文件的创建方法 在2020年之前&#xff0c;我们在使用appuploder创建苹果证书的时候&#xff0c;只需要注册苹果开发者账号&#xff0c;但不需要缴费成为开发者。 在2020年之后&#xff0c;需要先缴费成为苹果开发者。 假如你还没有注册苹果开发者账号&…

ElasticSearch 文档操作

批量操作 语法 批量操作对json有严格的要求&#xff0c;每个json串不能换行&#xff0c;只能放在同一行&#xff0c;相邻的json串之间必须要有换行。每个操作必须是一对json串&#xff08;delete语法除外&#xff09; { action: { metadata }} { request body } { ac…

同步与互斥(三)

一、递归锁 /* 创建一个递归锁&#xff0c;返回它的句柄。 * 此函数内部会分配互斥量结构体 * 返回值: 返回句柄&#xff0c;非NULL表示成功 */ SemaphoreHandle_t xSemaphoreCreateRecursiveMutex( void );/* 释放 */ BaseType_t xSemaphoreGiveRecursive( SemaphoreHandle_t…

WAVE SUMMIT+ 2023倒计时2天,传文心一言将曝最新进展!

10句话2分钟&#xff0c;挑战成功说服宿管阿姨开门&#xff0c;这个人群中的“显眼包”是一个接入文心大模型4.0游戏里的NPC&#xff0c;妥妥 “工具人”实锤&#xff5e; 尝试用AI一键自动识别好坏咖啡豆&#xff0c;看一眼便知好坏&#xff0c;真正“颜值即正义”&#xff0…