首页
/ Forge项目中的Dyno着色器系统深度解析

Forge项目中的Dyno着色器系统深度解析

2025-06-04 22:14:32作者:贡沫苏Truman

概述

Forge项目中的dyno着色器图系统是一个革命性的GPU计算框架,它允许开发者使用JavaScript(可选GLSL)创建自定义计算图,这些计算图最终会被编译为GLSL并在GPU上执行。这一系统类似于现代3D图形引擎中的着色器图系统,但提供了更高级的抽象和类型安全保证。

核心概念

Dyno计算单元

Dyno类及其子类是系统的核心构建块,可以将其视为具有多个类型化输入和输出的函数模块。这些模块之间传递的值类型为DynoVal<T>,其中T必须是DynoType,代表GLSL中的GPU类型。

关键特性:

  • 类型安全:通过TypeScript确保GPU计算图的类型正确性
  • 静态验证:在编译前就能捕获类型错误
  • 可组合性:可以自由组合现有模块或创建自定义模块

类型系统

DynoType可以是:

  1. 内置GLSL类型(如"int""float""vec"等)
  2. 用户自定义类型(如{ type: "MyType" }

内置类型分类

  • 单值类型:"int""uint""float""bool"
  • 向量类型:"vec4""ivec3""bvec2"
  • 矩阵类型:"mat4""mat2x3"
  • 采样器类型:"sampler2D""usampler3D"

自定义类型示例

Forge定义了几个有用的自定义类型:

  • Gsplat:表示一个完整的splat参数
  • TPackedSplats:高效存储的splat集合
  • SdfArray:有符号距离场数组
  • TRgbaArray:RGBA值数组
  • SplatSkinning:splat蒙皮相关数据

实际应用场景

Forge目前主要在以下两个场景中使用Dyno系统:

  1. 动态splat生成:通过SplatGenerator/SplatMesh动态生成场景中的splat
  2. splat距离度量计算:为CPU回读和排序计算splat距离度量

底层执行机制

这些操作通过以下类作为伪计算着色器执行:

  • PackedSplats:以16字节/splat的高效格式存储splat集合
  • Readback:将索引映射到RGBA8值,生成可读回CPU的32位值

Dyno值类型详解

值类型分类

  1. 字面量(DynoLiteral)

    • 直接提供GLSL字面量字符串
    • 示例:new DynoLiteral("float", "1.0")
  2. 常量(DynoConst)

    • 提供JavaScript值,自动转换为GLSL字面量
    • 示例:new DynoConst("vec3", new THREE.Vector3(1.0, 2.0, 3.0))
  3. 输出值(DynoOutput)

    • 表示Dyno块的特定命名输出
    • 示例:const { opacity } = dyno.splitGsplat(gsplat)

Dyno块设计与实现

构造函数选项

选项 描述
inTypes 输入名称到类型的映射
outTypes 输出名称到类型的映射
inputs 输入值的映射
update 每次执行前调用的更新函数
globals 提供所需全局GLSL定义的函数
statements 提供执行GLSL语句的函数
generate 编译器调用的生成函数

生成上下文(GenerateContext)

属性 描述
inputs 输入键到实际GLSL变量名的映射
outputs 输出键到实际GLSL变量名的映射
compile 编译上下文实例

使用模式

// 基本用法
const { sum } = new dyno.Add({ a, b }).outputs;

// 简化写法
const { sum } = dyno.add(a, b).outputs;

// 单输出简化
const sum = dyno.add(a, b);

高级功能:DynoBlock

DynoBlock是一种特殊的Dyno,可以包含内部子图。推荐使用dynoBlock辅助函数创建:

const generator = dyno.dynoBlock(
  { index: "int" }, // 输入
  { gsplat: Gsplat }, // 输出
  ({ index }) => { // 子图构建
    let gsplat = dyno.readPackedSplat(myPackedSplats, index);
    const opacity = dyno.dynoConst("float", 1.0);
    gsplat = dyno.combineGsplat({ gsplat, opacity });
    return { gsplat };
  }
);

开发辅助工具

  1. 代码格式化工具

    • unindentLines:处理多行字符串,移除公共前导空格
    • unindent:同上,但返回单个字符串
  2. 操作符辅助类

    • UnaryOp:一元操作
    • BinaryOp:二元操作
    • TrinaryOp:三元操作

学习建议

对于初学者,建议从以下方面入手:

  1. 研究粒子模拟示例
  2. 分析SplatMesh.constructGenerator()的复杂图结构
  3. 探索SplatMesh的两个注入点:
    • objectModifier:渲染前修改splat对象
    • worldModifier:修改现有splat对象

通过掌握这些概念和工具,开发者可以充分利用Forge的Dyno系统创建高效、类型安全的GPU计算图,为图形应用带来前所未有的灵活性和性能。

登录后查看全文
热门项目推荐
相关项目推荐