尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
vgpu/scene完整指南:用自有着色器构建3D场景——变换层级、实例化与相机控制
vgpu/scene完整指南用自有着色器构建3D场景——变换层级、实例化与相机控制【免费下载链接】vgpuModular cross-runtime WebGPU library for shaders, 3D scenes, GPU tensors, neural networks, and math viz项目地址: https://gitcode.com/gh_mirrors/vgpu/vgpuvgpu/scene 是开源 WebGPU 图形库 vgpu 中的 3D 场景工具集变换层级、父子节点、实例化渲染和相机控制全部在 CPU 端完成而着色器、光照和渲染循环完全由你自己掌控。本文将带你用最小代码搭建一个由自有 WGSL 着色器驱动的完整 3D 场景。 vgpu/scene 能做什么三个模块的清晰分工vgpu/scene 不是一套渲染器而是一个场景计算层——它提供矩阵运算、层级求值、实例集合和相机状态但不注入任何着色器代码、不预留任何绑定组。你的 WGSL 决定一切vgpu/scene 只负责把数据送到你声明的位置。模块提供什么需要 GPUvgpu/scene几何配方box、sphere等、变换数学、group节点、实例集合、相机函数否纯 CPUvgpu/scene/gpuinstanceGeometry——把实例集合作为顶点流发布给 GPU是vgpu/wgsl-std/sceneinstanceWorldMatrix、transformNormal等纯 WGSL 辅助函数着色器端整个数据流只有一条单向链路每一步都是你主动调用的显式函数局部变换 ──► 世界矩阵 ──► 实例记录 ──► GPU 实例流 ──► 你的 draw 官方完整指南见 docs/topics/scene-composition.docs.md配合 docs/topics/scene-math.docs.md 理解外部矩阵如何接入。 构建变换层级父子节点 vs 你自己的数组用group()描述几个联动的零件当你只有少量需要联动旋转的部件比如底座→手臂→夹爪三段机械臂group()是最简单的选择。它创建一个SceneNode一个带父子和子节点的变换没有几何、没有材质const claw group({ label: claw, position: [0, 1.6, 0] }); const arm group({ label: arm, position: [0, 0.5, 0], children: [claw] }); const base group({ label: base, position: [0, 0.25, 0], children: [arm] }); base.set({ rotation: [0, time * 0.3, 0] }); // 只改底座 claw.worldPosition; // 自动得到 base * arm * claw 的世界坐标节点是惰性求值的set()只把该节点及后代标记为脏读取worldMatrix时才重新计算变化部分。旋转用四元数或欧拉角均可坐标系是右手系、Y 向上。用扁平数组求值大型层级ECS / 物理引擎如果层级数据已经存在你的 ECS 或物理引擎里不必镜像成节点。hierarchyOrder一次性编译拓扑evaluateHierarchy从局部矩阵算出全部世界矩阵const parents new Int32Array([-1, 0, 1]); // base 是根arm 的父是 baseclaw 的父是 arm const locals new Float32Array(3 * 16); // 每行一个局部矩阵 const worlds new Float32Array(3 * 16); // 输出世界矩阵 const order hierarchyOrder(parents); evaluateHierarchy({ order, parents, locals, worlds, changed });配合changed脏标记每帧只重算变化的行及其后代——这是官方 examples/by-example-s06-scene/src/composition.ts 中三条求值路径nodes / hierarchy / final-worlds之一。变换数学函数composeMatrix、multiplyMatrices、invertAffine的实现在 packages/vgpu-api/src/scene/transforms.ts节点在 packages/vgpu-api/src/scene/nodes.ts。 一次绘制调用画出成千上万个物体实例化渲染声明一个紧凑的实例集合instances()创建固定容量的 CPU 实例集合每条记录 一个 64 字节世界矩阵 你声明的自定义属性颜色、尺寸、拾取 ID 等。它没有几何、没有材质、没有 GPU 资源const boxes instances({ capacity: 2003, attributes: { size: float32x3, tint: { format: float32x4, default: [1, 1, 1, 1] }, }, }); boxes.add({ size: [0.4, 0.4, 0.4], tint: [0.6, 0.45, 0.3, 1] }); // 返回稳定句柄 InstanceId世界矩阵有三种写入方式按需选择方式调用适用场景直接写入setWorld(id, world)单次放置、偶尔移动批量写入setWorlds(ids, worlds)物理引擎每帧输出一大批矩阵绑定来源bindWorld(id, () node.worldMatrix) 每帧syncWorlds()让实例自动跟随某个节点发布到 GPU一座桥接instanceGeometry来自vgpu/scene/gpu实现在 packages/vgpu-api/src/scene/instance-geometry.ts把基础网格和实例流合成一个新的Geometry。实例流是stepMode: instance的顶点缓冲每条记录按顺序携带world0..world3世界矩阵四列和自定义属性在你的着色器里按名字声明location(3) world0: vec4f, location(4) world1: vec4f, location(5) world2: vec4f, location(6) world3: vec4f, location(7) size: vec3f, // 实例属性 size: float32x3 location(8) tint: vec4f, // 实例属性 tint: float32x4vgpu/wgsl-std/scene提供了每个实例化着色器都要写的数学见 packages/wgsl-std/src/scene/import { instanceWorldMatrix, transformPosition, transformNormal } from vgpu/wgsl-std/scene; let world instanceWorldMatrix(input.world0, input.world1, input.world2, input.world3); out.clip camera.viewProjection * vec4f(transformPosition(model, input.position), 1.0); out.normal transformNormal(model, input.normal); // 正确处理非均匀缩放的法线每帧先bridge.publish()上传变化并拿到实例数量再传给绘制调用pass.draw(boxDraw, { instances: count })。一个基础网格 一次绘制调用即可渲染整个粒子矩阵——这正是 instanced-rendering 示例的效果⚠️ 一个易踩的坑所有使用该 bridge 的着色器都必须声明全部实例输入world0..world3 你的每个自定义属性即使某个 pass 用不到它否则管线创建时就会抛出VGPU-MESH-ATTRIBUTE-UNMATCHED。 相机控制轨道、平移、推拉与平滑跟随相机函数操作的是你自己分配并持有的普通对象——不监听 DOM、不调度帧。核心是一个OrbitRig轨道装置围绕支点target pan旋转函数作用orbit(rig, deltaYaw, deltaPitch)水平/俯仰旋转俯仰自动限位pan(rig, right, up)沿相机的右/上轴平移dolly(rig, factor)缩放距离factor 1 拉远zoom(lens, factor)改变镜头 FOV不移动相机smoothRig(current, goal, dt, { timeConstant })指数平滑产生惯性感推荐模式是双 rig 平滑输入只写入goal渲染用smoothRig让current逐帧逼近goal得到带阻尼的运镜const goal orbitRig({ yaw: 0.6, pitch: 0.35, distance: 9 }); const current orbitRig(goal); orbit(goal, input.yaw, input.pitch); // 1. 输入 → goal smoothRig(current, goal, dt, { timeConstant: 0.15 }); // 2. current 平滑逼近 perspective(lens, aspect, projection); // 3. 投影矩阵 viewMatrices(rigPose(current, pose), projection, matrices); // 4. 视图 视图投影 boxDraw.set({ camera: { viewProjection: matrices.viewProjection } }); // 5. 按绑定名连接着色器最后一步是关键相机矩阵通过set()以WGSL 绑定名而不是 group/binding 编号传给着色器着色器里声明group(1) binding(0) varuniform camera: CameraData;即可。注意set()在调用时就打包数据——每帧viewMatrices之后都要重新set()一次。指针输入留在你的应用里把movementX/Y换算成弧度增量累加每 tick 应用一次。worldPerPixel(distance, lens, heightPixels)返回支点上一个像素对应多少世界单位让平移跟手。相机源码在 packages/vgpu-api/src/scene/camera-state.ts。 串起来一帧的数据流把上面三块拼起来每帧的固定顺序是输入 →goalrigorbit / pan / dolly 后清零更新局部变换group().set()或你的局部矩阵数组求解世界矩阵节点惰性读取或evaluateHierarchy把世界矩阵写入集合syncWorlds/setWorlds让goal.target跟随目标物体如夹爪的worldPositionsmoothRig→perspective→viewMatricesdraw.set({ camera: { viewProjection } })bridge.publish()拿到实例数编码 passpass.draw(draw, { instances: count })可运行的完整示例在 examples/by-example-s06-scene/composition.ts 演示了 group、外部层级、直接世界矩阵三条路径渲染同一场景配套着色器 composition.wgsl 展示了世界矩阵 自定义属性tint、pickingId的完整顶点入口声明。批量绘制同一网格的大规模效果可参考 apps/docs/examples/batch-rendering/。 官方文档与源码索引资料路径场景组合完整指南docs/topics/scene-composition.docs.md场景数学外部矩阵接入docs/topics/scene-math.docs.md从旧版vgpu/scene迁移docs/topics/scene-migration.docs.md变换数学源码packages/vgpu-api/src/scene/transforms.ts节点与层级源码packages/vgpu-api/src/scene/WGSL 场景辅助函数packages/wgsl-std/src/scene/可运行示例examples/by-example-s06-scene/AI 技能场景指引skills/vgpu/scene.md现在你手里已经有了全部零件用group或自己的数组搭建层级用instancesinstanceGeometry一次绘制海量物体用OrbitRig加平滑写出手感出色的相机——着色器、光照、渲染循环始终是你的。【免费下载链接】vgpuModular cross-runtime WebGPU library for shaders, 3D scenes, GPU tensors, neural networks, and math viz项目地址: https://gitcode.com/gh_mirrors/vgpu/vgpu创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED

相关推荐

异常响应机制

异常响应机制

【一生一芯 / PA】异常响应机制:从 ecall 到 mtvec 再到 mret 的完整代码解析代码环境: NEMU:~/ysyx-workbench/nemu AM:~/ysyx-workbench/abstract-machine ISA:riscv32一、异常响应机制到底在解决什么问题在 PA3 中&…

📅 2026/10/4 22:28:30
Sentinel HASP HL 3.5 驱动安装全指南:老加密狗在 Win10/11 上的识别与修复

Sentinel HASP HL 3.5 驱动安装全指南:老加密狗在 Win10/11 上的识别与修复

简介:面向软件授权与版权保护场景的Sentinel硬件安全模块USB驱动程序包,专门解决Windows系统下Sentinel设备无法被识别、频繁报错或与操作系统通信异常的问题,适合IT运维及软件管理人员快速恢复加密狗等设备的正常连接,在软件授权…

📅 2026/10/4 22:23:30
用Cursor和ChatGPT大半年上线3个小程序:我的AI赚钱之路与TaoToken配置复盘

用Cursor和ChatGPT大半年上线3个小程序:我的AI赚钱之路与TaoToken配置复盘

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📅 2026/10/4 22:23:30
MORE NEWS

更多资讯

📰

C#调用USB摄像头实战:DirectShow/AForge/OpenCvSharp选型与避坑指南

简介:面向在.NET平台使用C#操作USB摄像头的开发者,这份资源提供一套可直接运行的完整示例,覆盖摄像头枚举、连接、视频流启停、拍照抓帧与图片保存等关键环节。压缩包内共38个文件,包括6个C#源文件、10个动态库、3个可执行程序以及…

📰

中控Java二次开发demo实战:跑通、避坑与封装指南

简介:面向企业级考勤系统的开发者,中控Java二次开发demo.zip提供了一套直接可用的对接方案,适用于需要读取考勤记录、维护人员信息或集成考勤数据到业务系统的场景。资源以Java源码与配套文档为核心,压缩包整体约37.77MB&#xff…

📰

C# TCP/IP最简例程:TcpClient与TcpListener服务端客户端互通指南

简介:面向C#初学者的TCP/IP通信例程包,内含服务端与客户端两个独立完整模块,清晰演示了传输控制协议下如何通过TcpListener、TcpClient和Socket类完成建立连接、发送数据与接收响应的全过程,适合刚刚接触网络编程、希望快速跑通首…

📰

插件加载与激活失败:IAR、web boot与MusicFree排查指南

如果你最近在搜索引擎里只敲了 plugins 这一个词,大概率正面对下面三个场景之一:刚装好的嵌入式开发环境里多了一个 plugins 目录,不知道它到底是干嘛的;某个 Web 类应用启动时刷出一条以 "failed to load plugins web boot:…

📰

Chrome DevTools MCP 实战完整教程:把 MCP 配置改到 TaoToken 的调试链路

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

openrig 配置编排指南:Claude Code 与 Codex 多模型环境装配实践

1. 从零认识 openrig:它到底解决什么问题第一次看到 openrig 这个名字,很多人会以为是某个硬件支架项目,毕竟 rig 在英文里有“装配、支架”的意思。但结合 Claude Code、Codex、YAML、Node.js 这一串关键词,答案就清晰了&#xf…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬