轻量封装WebGPU渲染系统示例<21>- 3D呈现元胞自动机之生命游戏(源码)

实现原理: 基本PBR光照与gpu compute计算

尽量用数据化/语义化的松散描述数据的方式来呈现相关对象逻辑

当前示例源码github地址:

https://github.com/vilyLei/voxwebgpu/blob/feature/rendering/src/voxgpu/sample/GameOfLife3DPBR.ts
当前示例运行效果:

其他效果截图:

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

const gridSize = 256;
const shdWorkGroupSize = 8;const compShdCode = `
@group(0) @binding(0) var<uniform> grid: vec2f;@group(0) @binding(1) var<storage> cellStateIn: array<u32>;
@group(0) @binding(2) var<storage, read_write> cellStateOut: array<u32>;
@group(0) @binding(3) var<storage, read_write> lifeState: array<f32>;fn cellIndex(cell: vec2u) -> u32 {return (cell.y % u32(grid.y)) * u32(grid.x) +(cell.x % u32(grid.x));
}fn cellActive(x: u32, y: u32) -> u32 {return cellStateIn[cellIndex(vec2(x, y))];
}@compute @workgroup_size(${shdWorkGroupSize}, ${shdWorkGroupSize})
fn compMain(@builtin(global_invocation_id) cell: vec3u) {// Determine how many active neighbors this cell has.let activeNeighbors = cellActive(cell.x+1, 		cell.y+1) +cellActive(cell.x+1, 	cell.y) +cellActive(cell.x+1, 	cell.y-1) +cellActive(cell.x, 		cell.y-1) +cellActive(cell.x-1, 	cell.y-1) +cellActive(cell.x-1, 	cell.y) +cellActive(cell.x-1, 	cell.y+1) +cellActive(cell.x, 		cell.y+1);let i = cellIndex(cell.xy);// Conway's game of life rules:switch activeNeighbors {case 2: { // Active cells with 2 neighbors stay active.cellStateOut[i] = cellStateIn[i];if(cellStateOut[i] > 0) {lifeState[i] += 0.05;} else {lifeState[i] -= 0.05;}}case 3: { // Cells with 3 neighbors become or stay active.cellStateOut[i] = 1;lifeState[i] += 0.1;}default: { // Cells with < 2 or > 3 neighbors become inactive.cellStateOut[i] = 0;lifeState[i] -= 0.05;}}lifeState[i] = max(lifeState[i], 0.01);
}`;
export class GameOfLife3DPBR {private mRscene = new RendererScene();initialize(): void {console.log("GameOfLife3DPBR::initialize() ...");this.initEvent();this.initScene();}private initEvent(): void {const rc = this.mRscene;rc.addEventListener(MouseEvent.MOUSE_DOWN, this.mouseDown);new RenderStatusDisplay(this.mRscene, true);new MouseInteraction().initialize(rc, 0, false).setAutoRunning(true);}private mouseDown = (evt: MouseEvent): void => {};private createUniformValues(): { ufvs0: WGRBufferData[], ufvs1: WGRBufferData[] }[] {const gridsSizesArray = new Float32Array([gridSize, gridSize]);const cellStateArray0 = new Uint32Array(gridSize * gridSize);for (let i = 0; i < cellStateArray0.length; i++) {cellStateArray0[i] = Math.random() > 0.6 ? 1 : 0;}const cellStateArray1 = new Uint32Array(gridSize * gridSize);for (let i = 0; i < cellStateArray1.length; i++) {cellStateArray1[i] = i % 2;}const lifeStateArray3 = new Float32Array(gridSize * gridSize);for (let i = 0; i < lifeStateArray3.length; i++) {lifeStateArray3[i] = 0.01;}const posisitonArray4 = new Float32Array(gridSize * gridSize * 4);let sizeV = new Vector3(40, 1, 40);let posV = new Vector3().copyFrom(sizeV);posV.scaleBy(gridSize);posV.scaleBy(-0.5);let k = 0;for (let i = 0; i < gridSize; i++) {for (let j = 0; j < gridSize; j++) {let pv = new Vector3(j * sizeV.x, 0, i * sizeV.z).addBy(posV);posisitonArray4[k] = pv.x;posisitonArray4[k+1] = pv.y;posisitonArray4[k+2] = pv.z;k += 4;}}let shared = true;let sharedData0 = { data: cellStateArray0, shared };let sharedData1 = { data: cellStateArray1, shared };let sharedData3 = { data: lifeStateArray3, shared };let sharedData4 = { data: posisitonArray4, shared };const v0 = { data: gridsSizesArray, stride: 2, shared, layout: { visibility: 'all' } };// build rendering uniformsconst va1 = {storage: { bufData: sharedData0, stride: 1, shared }, layout: { visibility: 'vert_comp' }};const vb1 = {storage: { bufData: sharedData1, stride: 1, shared }, layout: { visibility: 'vert_comp' }};const vc1 = {storage: { bufData: sharedData3, stride: 1, shared, layout: { visibility: 'all' }  }};const v4 = {storage: { bufData: sharedData4, stride: 3, shared, layout: { visibility: 'vert_comp' }  }};// build computing uniformsconst compva1 = {storage: { bufData: sharedData0, stride: 1, shared, layout: { visibility: 'vert_comp' } }};const compva2 = {storage: { bufData: sharedData1, stride: 1, shared, layout: { visibility: 'comp' } }};const compvb1 = {storage: { bufData: sharedData1, stride: 1, shared, layout: { visibility: 'vert_comp' } }};const compvb2 = {storage: { bufData: sharedData0, stride: 1, shared, layout: { visibility: 'comp', access: "read_write" } }};const compv3 = {storage: { bufData: sharedData3, stride: 1, shared, layout: { visibility: 'comp', access: "read_write" }  }};return [{ ufvs0: [v0, va1, vc1, v4], ufvs1: [v0, vb1, vc1, v4] },{ ufvs0: [v0, compva1, compva2, compv3], ufvs1: [v0, compvb1, compvb2, compv3] }];}private mEntity: Entity3D;private mStep = 0;private createMaterial(uniformValues: WGRBufferData[]): WGMaterial {const instanceCount = gridSize * gridSize;let shaderCodeSrc = {vert: {code: vertWGSL,uuid: "vert-gameOfLife",},frag: {code: fragWGSL,uuid: "frag-gameOfLife",}} as WGRShderSrcType;return new WGMaterial({shadinguuid: 'rendering',shaderCodeSrc,instanceCount,uniformValues,uniformAppend: false});}private createCompMaterial(uniformValues: WGRBufferData[]): WGCompMaterial {const workgroupCount = Math.ceil(gridSize / shdWorkGroupSize);let shaderCodeSrc = {code: compShdCode,uuid: "shader-computing",};return new WGCompMaterial({shadinguuid: 'computing',shaderCodeSrc,uniformValues,uniformAppend: false}).setWorkcounts(workgroupCount, workgroupCount);}private initScene(): void {const rc = this.mRscene;const ufvsObjs = this.createUniformValues();// build ping-pong material rendering/computing processconst materials: WGMaterial[] = [this.createMaterial(ufvsObjs[0].ufvs0),this.createMaterial(ufvsObjs[0].ufvs1),this.createCompMaterial(ufvsObjs[1].ufvs1),this.createCompMaterial(ufvsObjs[1].ufvs0),];let entity = new CylinderEntity({radius: 20, height: 38,longitudeNumSegments: 10, latitudeNumSegments: 10,alignYRatio : 0.0, materials});rc.addEntity(entity);this.mEntity = entity;}private mFrameDelay = 3;run(): void {let flag = this.mEntity.isRendering();const ms = this.mEntity.materials;if (flag) {for (let i = 0; i < ms.length; i++) {ms[i].visible = (this.mStep % 2 + i) % 2 == 0;}if (this.mFrameDelay > 0) {this.mFrameDelay--;flag = false;}else {this.mFrameDelay = 3;this.mStep++;}}if(!flag) {ms[2].visible = false;ms[3].visible = false;}this.mRscene.run();}
}


 

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

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

相关文章

解决方案 |法大大电子合同推动汽车后市场多元数智化发展

近日&#xff0c;商务部等9部门联合发布《关于推动汽车后市场高质量发展的指导意见》&#xff08;以下简称《指导意见》&#xff09;&#xff0c;明确了汽车后市场发展的总体目标和主要任务&#xff0c;系统部署推动汽车后市场高质量发展&#xff0c;促进汽车后市场规模稳步增长…

Day26力扣打卡

打卡记录 搜索旋转排序数组&#xff08;二分&#xff09; 链接 class Solution {int findMin(vector<int> &nums) {int left -1, right nums.size() - 1; // 开区间 (-1, n-1)while (left 1 < right) { // 开区间不为空int mid left (right - left) / 2;if…

easyexcel==省市区三级联动

省市区三级联动&#xff0c;不选前面的就没法选后面的 package com.example.demoeasyexcel.jilian2; import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder; import org.apache.poi.ss.use…

【Java 进阶篇】Java Web 开发之 JQuery 快速入门

嗨&#xff0c;各位小伙伴们&#xff01;欢迎来到 Java Web 开发的继续学习之旅。在前面的博客中&#xff0c;我们学习了 Servlet、JSP、Filter、Listener 等基础知识&#xff0c;今天我们将进入前端领域&#xff0c;学习一下如何使用 JQuery 来简化和优化我们的前端开发。 1.…

SpringBoot_01

Spring https://spring.io/ SpringBoot可以帮助我们非常快速的构建应用程序、简化开发、提高效率。 SpringBootWeb入门 需求&#xff1a;使用SpringBoot开发一个web应用&#xff0c;浏览器发起请求/hello后&#xff0c;给浏览器返回字符串"Hello World~~~"。 步骤…

学习pytorch15 优化器

优化器 官网如何构造一个优化器优化器的step方法coderunning log出现下面问题如何做反向优化&#xff1f; 官网 https://pytorch.org/docs/stable/optim.html 提问&#xff1a;优化器是什么 要优化什么 优化能干什么 优化是为了解决什么问题 优化模型参数 如何构造一个优化器…

postgis函数学习

1.特定功能的SQL 转为完整的json&#xff0c;前端调用用json_build_object、jsonb_agg等函数&#xff0c;处理mass_test表 select json_build_object(type,FetureCollection,features,jsonb_agg(st_asgeojson(mt.*)::json)) from mass_test mt获取图形边界范围的坐标 select…

企业计算机中了mkp勒索病毒怎么办,服务器中了勒索病毒如何处理

计算机技术的不断发展给企业的生产生活提供了极大便利&#xff0c;但也为企业带来了网络安全威胁。近期&#xff0c;云天数据恢复中心陆续接到很多企业的求助&#xff0c;企业的计算机服务器遭到了mkp勒索病毒攻击&#xff0c;导致企业的所有工作无法正常开展&#xff0c;给企业…

docker去掉sudo权限方法

查看用户组及成员 sudo cat /etc/group | grep docker 可以添加docker组 sudo groupadd docker 添加用户到docker组 sudo gpasswd -a huangxiujie docker 增加读写权限 sudo chmod arw /var/run/docker.sock 重启docker sudo systemctl restart docker

自动化测试测试框架封装改造

PO模式自动化测试用例 PO设计模式是自动化测试中最佳的设计模式&#xff0c;主要体现在对界面交互细节的封装&#xff0c;在实际测试中只关注业务流程就可以了。 相较于传统的设计&#xff0c;在新增测试用例后PO模式有如下优点&#xff1a; 1、易读性强 2、可扩展性好 3、…

代码随想录算法训练营Day 49 || 123.买卖股票的最佳时机III 、188.买卖股票的最佳时机IV

123.买卖股票的最佳时机III 力扣题目链接(opens new window) 给定一个数组&#xff0c;它的第 i 个元素是一支给定的股票在第 i 天的价格。 设计一个算法来计算你所能获取的最大利润。你最多可以完成 两笔 交易。 注意&#xff1a;你不能同时参与多笔交易&#xff08;你必须…

postgresql 实现计算日期间隔排除周末节假日方案

前置条件&#xff1a;需要维护一张节假日日期表。例如创建holiday表保存当年假期日期 CREATE TABLE holiday (id BIGINT(10) ZEROFILL NOT NULL DEFAULT 0,day TIMESTAMP NULL DEFAULT NULL,PRIMARY KEY (id) ) COMMENT假期表 COLLATEutf8mb4_0900_ai_ci ;返回日期为xx日xx时x…

Windows查看端口占用情况

Windows如何查看端口占用情况 方法1. cmd命令行执行netstat命令&#xff0c;查看端口占用情况 netstat -ano 以上命令输出太多信息&#xff0c;不方便查看&#xff0c;通过如下命令搜索具体端口占用情况&#xff0c;例如&#xff1a;8080端口 netstat -ano | findstr "…

Ubuntu LTS 坚持 10 年更新不动摇

Linux 内核开发者 Jonathan Corbet 此前在欧洲开源峰会上宣布&#xff0c;LTS 内核的支持时间将从六年缩短至两年&#xff0c;原因在于缺乏使用和缺乏支持。稳定版内核维护者 Greg Kroah-Hartman 也表示 “没人用 LTS 内核”。 近日&#xff0c;Ubuntu 开发商 Canonical 发表博…

VB.NET—Bug调试(参数话查询、附近语法错误)

目录 前言: BUG是什么&#xff01; 事情的经过: 过程: 错误一: 错误二: 总结: 前言: BUG是什么&#xff01; 在计算机科学中&#xff0c;BUG是指程序中的错误或缺陷&#xff0c;它通过是值代码中的错误、逻辑错误、语法错误、运行时错误等相关问题&#xff0c;这些问题…

基于51单片机RFID射频门禁刷卡系统设计

**单片机设计介绍&#xff0c; 基于51单片机RFID射频门禁刷卡系统设计 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序程序 六、 文章目录 一 概要 基于51单片机RFID射频门禁刷卡系统&#xff0c;是一种将单片机技术和射频标识技术应用于门禁控制系统的…

Python与ArcGIS系列(二)获取地图文档

目录 0 简述1 获取当前地图文档2 获取磁盘中的地图文档3 获取地图文档的图层0 简述 本篇开始介绍实际代码操作,即利用arcpy(python 包)执行地理数据分析、数据转换、数据管理和地图自动化。通过arcpy调用ArcGIS中任意工具,将其与其他python工具结合使用,形成自己的工作流…

python设计模式12:状态模式

什么是状态机&#xff1f; 关键属性&#xff1a; 状态和转换 状态&#xff1a; 系统当前状态 转换&#xff1a;一种状态到另外一种状态的变化。 转换由触发事件或是条件启动。 状态机-状态图 状态机使用场景&#xff1a; 自动售货机 电梯 交通灯 组合锁 停车计时…

文心耀乌镇,“大模型之光”展现了什么?

“乌镇的小桥流水&#xff0c;能照见全球科技的风起云涌。” 多年以来&#xff0c;伴随着中国科技的腾飞&#xff0c;以及世界互联网大会乌镇峰会的连续成功举办&#xff0c;这句话已经成为全球科技产业的共识。乌镇是科技与互联网的风向标、晴雨表&#xff0c;也是无数新故事开…

Install Nginx in Linux

Nginx是一款轻量级的Web服务器、反向代理服务器&#xff0c;由于它的内存占用少&#xff0c;启动极快&#xff0c;高并发能力强&#xff0c;在互联网项目中广泛应用。 1.yum 安装 nginx [rootVM-8-7-centos nginx]# yum install -y nginx Loaded plugins: fastestmirror, lang…