mcpField
T
threejs-procedural-materials

threejs-procedural-materials

github.com/linegel开发11140 次安装5 周前更新
代码仓库

关于 threejs-procedural-materials

这是一项通过共享成因、材质身份和过滤微结构设计 Three.js 程序化 PBR 材质的技能。它指导开发者选择坐标与映射、配置 NodeMaterial 插槽,并管理动态状态、着色稳定性和验证。

主要功能

  1. 01将 PBR 通道追溯到共享成因
  2. 02根据缺陷和成本选择纹理映射
  3. 03将成因接入 NodeMaterial 插槽
  4. 04过滤法线与镜面反射响应
  5. 05管理动态状态和资源生命周期
  6. 06验证材质、阴影与颜色转换

适用场景

  1. 01构建 PBR 通道一致的程序化表面
  2. 02针对接缝或纹理重复选择映射
  3. 03稳定不同距离下的法线和镜面细节
  4. 04保持动态透明度与阴影一致

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/linegel/threejs-complete-set-of-skill --skill threejs-procedural-materials

安装后在 Claude Code 中输入/threejs-procedural-materials确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

LICENSE
agents/
openai.yaml
examples/
filtered-height-normal.mjs
references/
procedural-pbr-system.md

详细介绍

程序化材质

构建因果图,而不是一组通道效果:

stable coordinates -> structural causes -> identity weights
  -> causal modifiers -> filtered microstructure
  -> NodeMaterial PBR slots -> final-image owner

标准的不透明/发光 PBR 使用 MeshStandardNodeMaterial,只有当表面需要其额外波瓣或传输属性时才使用 MeshPhysicalNodeMaterial。通过赋值节点插槽,而不是替换整个片元输出,保留 Three.js 的光照、环境、阴影和能量处理。

对于多系统场景,$threejs-choose-skills 是可选的协调器。场负责共享标量/向量因果量,几何负责轮廓,水负责表面/传输,最终图像管线负责色调映射和显示转换。使用每个动态或跨系统因果量时,都要声明其单位、坐标/参考系约定、生产者和消费者归属、版本、空间/时间支持范围及滤波方式、有效域、误差界限、更新频率和过时规则。视觉材质状态不会因此成为另一个模拟归属方。

在分配存储、调度由计算着色器写入的因果贴图或编译基于存储的材质分支之前,先初始化并检查渲染器:

await renderer.init();
if (renderer.backend.isWebGPUBackend !== true) {
  throw new Error('Native WebGPU is required for procedural material GPU branches.');
}
const { features, limits } = renderer.backend.device;

根据已初始化的特性和限制,选择采样/存储绑定、可写格式和滤波方式。

1. 固定坐标、因果量和身份

根据物理因果量或创作因果量,选择 UV、对象、世界、径向或生成纹理空间。以米或声明的美术单位记录尺度。只有在表示不同因果量时,混合空间才有效,例如在对象空间颗粒上叠加世界高度湿度。

定义归一化材质身份权重,并为每种身份指定响应束:

linear base reflectance
roughness alpha and metal/dielectric endpoint
resolved height/normal spectrum plus removed variance
causal modifiers such as wetness, wear, heat, or coverage
semantic/material ID and diagnostic color

所有通道都使用相同的滤波权重。硬性语义资格与可见混合宽度保持分离。当一个 GGX 波瓣近似亚像素混合时,混合 alpha=roughness^2,再通过 sqrt(alpha) 还原粗糙度。

涉及地形或海床时,在连接海岸距离、湿度、浅水、泡沫或焦散之前,先阅读底质与水的归属。

完成此步骤的标准:每个 PBR 通道都能追溯到同一坐标/尺度约定中的具名因果量和身份权重;任何零权重区域都有硬性语义回退。

2. 根据缺陷和成本选择映射方式

按以下顺序选择:

  1. 当接缝和纹素密度失真均达标时,使用 UV。
  2. 当图层具有相同的尺寸、格式、mip、颜色语义和采样器策略时,使用纹理数组。
  3. 当不满足数组约束且有明确归属的 mip 安全边距时,使用图集。
  4. 对于主导方向或顶面/侧面拆分,使用单轴/双轴投影。
  5. 只有在没有成本更低的参数化方式能保留尺度时,才使用三平面映射。
  6. 只有在观察到的缺陷是重复,而非参数化问题时,才使用随机平铺。

分别统计绑定数和实际执行的采样次数。已安装的 r185 triplanarTexture() 对每个绑定的纹理执行三次投影采样,并使用法线绝对值作为权重;它不会重新定向切线空间法线,也不提供随机平铺。数组/图集可减少绑定数,但不会减少采样次数。

在使用图集、纹理数组、三平面映射或随机平铺之前,请阅读 映射与滤波。

完成此步骤的标准:所选映射解决了观察到的缺陷;每种纹理的颜色/数据语义和 mip 策略都已明确;编译后的绑定/采样次数符合目标管线要求,且新增采样的价值经过了测量。

3. 将共享成因接入 NodeMaterial 插槽

仅管理材质所需的插槽:

colorNode             linear identity color and causal shifts
roughnessNode         identity alpha plus filtered modifiers
metalnessNode         conductor/dielectric identity
normalNode            normalMap, texture bump, or shared-height gradient
aoNode                local cavity/contact term
opacity/mask/alphaTest cutout or dissolve
emissiveNode          actual scene-linear emitted radiance
positionNode          visible local displacement
castShadowPositionNode matching caster displacement
castShadow/maskShadow matching cutout or dissolve

在 r185 中,receivedShadowPositionNode 是独立的世界空间接收器覆盖项;除非明确推导并验证了替代方案,否则应将其留空。可见位移和投射阴影位移共用一个局部空间成因。发光输入 HDR 材质结果;泛光和色调映射仍由下游负责。

数据纹理使用 NoColorSpace;编码为 sRGB 的颜色使用 SRGBColorSpace,而线性 sRGB HDR 使用 LinearSRGBColorSpace。其他颜色编码需要使用其声明的转换;创作时指定颜色空间并不意味着就是 sRGB。通过 RenderPipeline.outputColorTransform 或一次 renderOutput(),确保最终输出转换只有一个负责者。

当每个受管理的插槽都有一个成因、可见/阴影遮罩与位移保持一致、颜色/数据编码正确,且没有材质节点重复执行最终输出转换时,此步骤即告完成。

4. 过滤微结构与镜面响应

在扰动法线之前,先过滤高度/法线频带。片元表面梯度须在导数一致的控制流中计算;顶点/计算位移使用解析梯度或存储的梯度。在各级 mip 中保留法线均值及方差,而不是将均值归一化后丢弃其长度。

Three.js r185 已在 getRoughness() 中加入几何法线变化。自定义镜面抗锯齿只添加尚未解析的材质细节方差。添加程序化凹凸、自定义法线过滤或粗糙度方差前,请先阅读导数法线与镜面抗锯齿。

当标量程序化高度同时用于法线细节和镜面抗锯齿时,请阅读过滤高度法线示例。根据完整的变形后 Jacobian 谱范数提供无量纲的 footprintCyclesPerSample、以每个长度单位的周期数表示的物理支撑频率,以及围绕所提供均值的正频带半宽。heightHalfAmplitude 使用与表面相同的长度单位。它将衰减、移除的斜率方差、双面表面的梯度法线处理以及 roughness^2 扩宽整合到一条因果路径中。字面量输入会按 f32 精度检查;动态节点需要通过等效的生产端准入检查。退化的表面坐标系会返回基础法线和 normalValid=false,而不是对零向量归一化。验证条件数下限,并确保完整的导数路径保持一致。

当所有保留的频带都通过投影足迹检查、移除的斜率/法线方差只被计入一次,且无后期处理的近/中/远距离对比能够排除随距离变化的锐化和掠射角闪烁时,此步骤即告完成。

5. 自主管理动态状态和实例级状态

一个材质图服务一个批次。静态实例差异使用属性;只有在实测更新/访问模式更有优势时,才使用存储缓冲支持的实例数据来实现由 GPU 负责的高频变化。溶解、湿润度、变体或生命周期字段会根据同一稳定的对象/世界原因驱动可见遮罩和阴影遮罩。内置阴影重写不会自动复制动态不透明度/alpha 测试节点;请使用参考中介绍的共享布尔遮罩路径。替换材质节点图时,通过设置 material.needsUpdate = true 使 material.version 失效,以便重建缓存的投射体路径。

原因映射遵循程序化字段的直接计算与烘焙判定。静态映射只构建一次;动态映射按其所有者的更新频率更新,并使依赖的 mip 失效。计算任务的提交先于其消费渲染。在 r185 中,computeAsync() 不是 GPU 完成栅栏。

状态代次在被帧引用期间保持不可变。调整大小、材质标识变化、坐标变化、映射编码变化和设备丢失都会使依赖的历史记录、绑定和诊断信息失效。每种材质、纹理、存储资源和生成的变体都必须有明确的释放负责人。

满足以下条件即表示此步骤完成:每个动态原因都由一个负责人推进,每条实例记录都具有稳定的标识和重置行为,而且无需逐对象克隆材质或执行影响帧关键路径的 CPU 回读。

6. 诊断与验证

公开坐标模式/比例、标识权重与回退、每种结构性原因、映射权重/mip/边缘留白、绑定和采样次数、抗锯齿前后的粗糙度、法线均值/方差、可见物与投射体的一致性、原始自发光、未应用后期处理的美术效果,以及最终后期处理结果。

验证近景/中景/远景和运动视图;导体/电介质端点;所选滤波下的图集边缘留白;编译阶段限制;色彩空间标志;稳定的实例/阴影行为;以及在声称性能时的目标整帧耗时/字节数。

满足以下条件即表示此步骤完成:每种 PBR 标识、映射分支、滤波法线分支、动态状态、阴影路径、颜色转换、资源生命周期,以及声称的目标预算,都有直接的诊断证据。

完成

满足以下条件即表示材质系统完成:一个共享的原因/标识图为所有自主管理的 PBR 槽提供数据;映射与滤波决策有证据支持;材质细节在不同覆盖范围和运动下保持稳定;动态状态只有一个负责人和重置路径;原始材质输出、阴影、后期处理和资源生命周期彼此一致。

评论

支持 Markdown