轻量封装WebGPU渲染系统示例<53>- 多盏灯灯光照在地面的效果

news2024/9/20 18:46:11

WebGPU实时渲染实现模拟多盏灯的灯光照在地面的效果灯光效果 。

当前示例源码github地址:

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

当前示例运行效果:

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

export class MultiLightsTest {
	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 py = 10;
		let total = 5;
		let scale = 7.0;
		for (let i = 0; i < total; ++i) {
			for (let j = 0; j < total; ++j) {
				let position = [-500 + 250 * j, py + Math.random() * 30, -500 + 250 * i];
				position[0] += Math.random() * 60 - 30;
				position[2] += Math.random() * 60 - 30;
				let color = this.getRandomColor(scale);
				let factor1 = 0.00001;
				let factor2 = 0.00002;
				let pLight = new PointLight({ color, position, factor1, factor2 });
				ld.pointLights.push(pLight);
				if (Math.random() > 0.5) {
					position = [-500 + 150 * j, py + Math.random() * 30, -500 + 150 * i];
					position[0] += Math.random() * 160 - 80;
					position[2] += Math.random() * 160 - 80;
					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: 10, 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.param.intensity = 0.4;
		mtpl.shadow.param.radius = 4;

		let position = [0, 0, 0];
		let materials = this.createMaterials(true, false, 'back');
		let plane = new PlaneEntity({
			axisType: 1,
			materials,
			extent: [-600, -600, 1200, 1200],
			transform: { position }
		});
		rc.addEntity(plane);


	}
	
	private createArmTextures(): 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` } };
		const parallaxTex = { parallax: { url: `static/assets/pbrtex/rough_plaster_broken_disp_1k.jpg` } };
		let envTex = { specularEnv: {} };
		let textures = [
			envTex,
			albedoTex,
			normalTex,
			armTex,
			parallaxTex
		] as WGTextureDataDescriptor[];
		return textures;
	}
	private createMaterials(shadowReceived = false, shadow = true, faceCullMode = 'back', uvParam?: number[]): BaseMaterial[] {

		let textures0 = this.createArmTextures();

		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 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[];// * 0.7;
		cvs[0] = cvs[0] * 0.3 + 0.4;
		cvs[1] = cvs[1] * 0.3 + 0.4;
		cvs[2] = cvs[2] * 0.3 + 0.4;
		ppt.albedo.value = cvs;
		ppt.arms.roughness = Math.random() * 0.95 + 0.05;
		ppt.arms.metallic = 0.2;
		ppt.armsBase.value = [0, 0.3, 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/1322283.html

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

相关文章

Java版直播商城规划:电商源码、小程序、三级分销与免 费搭建全攻略

【saas云平台】打造全行业全渠道全场景的saas产品&#xff0c;为经营场景提供一体化解决方案&#xff1b;门店经营区域化、网店经营一体化&#xff0c;本地化、全方位、一站式服务&#xff0c;为多门店提供统一运营解决方案&#xff1b;提供丰富多样的营销玩法覆盖所有经营场景…

git命令查看提交代码行数和次数

右键点击Git Bash Here 查看代码提交次数 git log --since2022-7-1 --before2022-8-1 --author"XXXX" --pretty%aN |sort |uniq -c | sort -k1 -n -r查看代码提交行数 git log --since2022-8-1 --before2022-9-1 --authorXXXX --prettytformat: --numstat |awk {add…

无锡市某厂区工人上岗未穿工作服,殒命车间 富维AI守护每位工友

2018年12月23日&#xff0c;凌晨6点半左右&#xff0c;江阴华士某铜业公司轧球车间内&#xff0c;独自上夜班的操作工朱某正在操作行车吊运一筐切好的铜粒&#xff0c;吊运完成后&#xff0c;他开始解除料筐上的吊具。就在这时&#xff0c;意外突然发生&#xff0c;他身上穿着的…

前端开发新趋势:Web3、区块链和虚拟现实

目录 前言 Web3&#xff1a;下一代互联网 区块链技术 去中心化应用程序&#xff08;DApps&#xff09; 区块链&#xff1a;重塑数字世界 数字钱包 NFT&#xff08;非同质化代币&#xff09; 虚拟现实&#xff1a;沉浸式体验 WebVR和WebXR 三维图形 新挑战与机会 性…

中海达加入通信行业首个“北斗+5G专业委员会”

12月12日&#xff0c;广东省通信学会“北斗5G专业委员会暨北斗5G产业联盟”在广州成立。中国电信广东公司、中海达、华为、中兴、高德、小米等52家成员单位代表共约100人参加大会。作为全国通信行业首个“北斗5G专业委员会”&#xff0c;旨在加强北斗5G自主创新&#xff0c;构建…

【Hive】——DQL

1 SELECT 1.1 语法 从哪里查询取决于FROM关键字后面的table_reference。可以是普通物理表、视图、join结果或子查询结果。 [WITH CommonTableExpression (, CommonTableExpression)*] SELECT [ALL | DISTINCT] select_expr, select_expr, ...FROM table_reference[WHERE wh…

sqlserver-事物日志

文章目录 前言事务日志逻辑体系结构事务日志物理体系结构虚拟日志文件 (VLF)事务日志的循环性质日志截断事务日志备份事务日志支持的操作恢复个别的事务。启动事务时恢复所有未完成SQL Server事务。将还原的数据库、文件、文件组或页前滚至故障点。支持事务复制。支持高可用性和…

虾多拉:帮助Shopee卖家提升运营效果的强大工具

在如今的电商领域&#xff0c;Shopee已经成为了一家备受欢迎的在线购物平台。然而&#xff0c;面对激烈的竞争&#xff0c;卖家们需要找到一种方法来提升他们的运营效果&#xff0c;实现更高的销售额和利润。幸运的是&#xff0c;有一款名为虾多拉&#xff08;Shopdora&#xf…

迅为RK3588开发板瑞芯微国产化工业ARM核心板AI人工智能

性能强 iTOP-3588开发板采用瑞芯微RK3588处理器&#xff0c;是全新一代AloT高端应用芯片&#xff0c;采用8nm LP制程&#xff0c;搭载八核64位CPU&#xff0c;四核Cortex-A76和四核Cortex-A55架构&#xff0c;主频高达2.4GHz&#xff0c;8GB内存&#xff0c;32GB EMMC。 四核心…

复旦团队提出思维交流框架EoT,由CoT到EoT,可跨模型通信,表现更出色

大型语言模型&#xff08;LLM&#xff09;通过利用庞大的训练语料和强大的计算资源&#xff0c;在众多 NLP 任务中表现卓越。然而&#xff0c;在理解和进行推理方面&#xff0c;这些模型仍显得相对薄弱&#xff0c;仅依靠增加模型的大小无法解决这一问题。 然而&#xff0c;现…

tcp/ip协议2实现的插图,数据结构5 (22 - 章)

(103) 103 二二1 协议控制块 结构 file, socket , rawcb , inpcb , tcpcb 之间的联系 (104) 104 二二2 回顾总结ip选项和 ip 多播一 ip_dooptions 中对源路由的处理 (105) 105 二二3 回顾总结ip选项和 ip 多播二 选项的定义图与源路由变化图 (106) 106 二二4 回顾总结ip选项和 …

微信小程序长按图片识别二维码

设置show-menu-by-longpress"true"即可&#xff0c;长按图片后会弹出一个菜单&#xff0c;若图片中包含二维码或小程序码&#xff0c;菜单中会有响应入口 <image src"图片地址" show-menu-by-longpress"true"></image>官方说明

Netty应用(七) ----MQTT编解码器

目录 0.前言1. MqttEncoder--编码器1.1 构造方法1.2 encodeConnectMessage -- 连接消息1.3 encodeConnAckMessage - 确认连接1.4 encodePublishMessage -- 发布消息1.5 encodeSubscribeMessage - 订阅主题1.6 encodeUnsubscribeMessage - 取消订阅1.7 encodeSubAckMessage - 订…

姿态识别、目标检测和跟踪的综合应用

引言&#xff1a; 近年来&#xff0c;随着人工智能技术的不断发展&#xff0c;姿态识别、目标检测和跟踪成为了计算机视觉领域的热门研究方向。这三个技术的综合应用为各个行业带来了巨大的变革和机遇。本文将分别介绍姿态识别、目标检测和跟踪的基本概念和算法&#xff0c;并探…

打开VScode时不打开上次使用的文件夹

是不是很烦VScode 打开新的文件夹&#xff0c;每次都打开上次使用过的文件夹&#xff0c;只需在设置里面改一个设置就可以避免了。 Ctrl &#xff0c;打开设置&#xff0c;搜索 window.restoreWindows 通过这种设置就可以让VScode 每次打开新的文件夹而不打开上次的文件夹。

保护您的Android应用程序:Android应用程序安全一览

保护您的Android应用程序&#xff1a;Android应用程序安全一览 我们都知道Android是为所有人设计的——开放、面向开发者、面向用户&#xff0c;这种开放性为今天和明天的移动技术提供了很多便利。然而&#xff0c;开放性也带来了需要妥善处理的安全风险。 安全是我们所有人都…

Linux的SSH(远程登录)

SSH定义&#xff1a; SSH&#xff08;Secure Shell 的缩写&#xff09;是一种网络协议&#xff0c;用于加密两台计算机之间的通信&#xff0c;并且支持各种身份验证机制。 实务中&#xff0c;它主要用于保证远程登录和远程通信的安全&#xff0c;任何网络服务都可以用这个协议…

什么是企业年报?

企业年报是指企业按照规定向相关部门报送的一种年度财务报告&#xff0c;它反映了企业在一年内的经营状况、财务状况、经营成果和现金流量等信息。对于投资者、债权人、政府部门等利益相关者来说&#xff0c;企业年报是非常重要的信息来源。下面就展开讲讲。 一、什么是年报&am…

什么牌子猫粮比较好?质量口碑较好的主食冻干猫粮分享

由于猫咪是肉食动物&#xff0c;对蛋白质的需求很高&#xff0c;如果摄入的蛋白质不足&#xff0c;就会影响猫咪的成长。而冻干猫粮本身因为制作工艺的原因&#xff0c;能保留原有的营养成分和营养元素&#xff0c;所以冻干猫粮蛋白含量比较高&#xff0c;营养又高&#xff0c;…

智能优化算法应用:基于适应度相关算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于适应度相关算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于适应度相关算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.适应度相关算法4.实验参数设定5.算法…