尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

three.js 程序化木纹材质 WoodNodeMaterial:基于 TSL 的参数化木材材质完整指南

three.js 程序化木纹材质 WoodNodeMaterial:基于 TSL 的参数化木材材质完整指南 three.js 程序化木纹材质 WoodNodeMaterial基于 TSL 的参数化木材材质完整指南【免费下载链接】three.jsJavaScript 3D Library.项目地址: https://gitcode.com/GitHub_Trending/th/three.jsWoodNodeMaterial 是 three.js 官方扩展位于 examples/jsm/materials/WoodNodeMaterial.js中一款完全程序化无纹理贴图的木材材质基于 TSLThree.js Shading Language节点体系实时生成年轮、木纹翘曲、导管孔隙等微观结构并内置 10 种常见木材与 4 种饰面finish预设。它在 WebGPU / Node 渲染管线下可对几何体任意剖切处生成连续、无缝的木纹是家具、地板、产品可视化等场景中无需美术贴图的低成本选型。读完本文你将掌握fromPreset快速创建、构造函数自定义调参、预设与覆盖值混用三种用法理解其全部参数含义与底层噪声/翘曲/年轮算法结构并能基于示例工程落地到自己的渲染场景。什么是 WoodNodeMaterialWoodNodeMaterial 通过 TSL 从零构建木纹外观不依赖任何纹理图片。源码顶部注释明确指出Procedural wood material using TSL (Three.js Shading Language). some helpers below are ported from Blender and converted to TSL即它由 three.js 的 TSL 节点函数拼装而成其中若干辅助算法移植自 Blender 木纹着色器对应示例演示页中标注的 Based on Lance Phans Blender tutorialexamples/webgpu_tsl_wood.html。材质类直接继承THREE.MeshPhysicalMaterial见 材质源码因而天然具备物理材质的清漆层clearcoat能力——这正是其饰面概念的基础。模块顶层导出了 4 个符号源码 WoodNodeMaterial.js导出类型说明WoodNodeMaterialclass主材质类继承MeshPhysicalMaterialWoodGenusesstring[]10 种木材种类名teak, walnut, white_oak, pine, poplar, maple, red_oak, cherry, cedar, mahoganyFinishesstring[]4 种饰面raw, matte, semigloss, glossGetWoodPreset(genus, finish)function返回某个木材种类 × 饰面组合的完整参数字典典型引入方式参考示例 webgpu_tsl_wood.htmlimport { WoodNodeMaterial, WoodGenuses, Finishes, GetWoodPreset } from three/addons/materials/WoodNodeMaterial.js;环境前提WoodNodeMaterial 的colorNode/clearcoatNode等节点属性依赖基于节点的渲染后端示例使用THREE.WebGPURenderer运行。仓库通过npm run dev见 package.json内部执行utils/server.js -p 8080即可启动本地开发服务器预览examples/webgpu_tsl_wood.html并需在支持 WebGPU 的浏览器中访问。三种创建与使用方式原文档给出三种从开箱即用到完全定制的创建路径下面逐一展开并补充实现细节。方式一使用预设推荐日常使用WoodNodeMaterial.fromPreset( genus, finish )是静态工厂方法源码实现为WoodNodeMaterial.jsstatic fromPreset( genus teak, finish raw ) { const params GetWoodPreset( genus, finish ); return new WoodNodeMaterial( params ); }不传参时默认teak / raw原木无清漆。示例// Using presets (recommended for common wood types) const material WoodNodeMaterial.fromPreset(walnut, gloss);该方法内部先调用GetWoodPreset(genus, finish)拿到完整参数字典再交给构造函数统一实例化因此材质实例上会带有genus、finish等元信息字段。方式二全自定义参数直接new WoodNodeMaterial({ ... })传入所需参数。构造函数会以teak/raw预设为默认底子用传入参数覆盖之const finalParams { ...defaultParams, ...params }见 构造函数实现。原文档示例// Using custom parameters (for advanced customization) const material new WoodNodeMaterial({ centerSize: 1.2, ringThickness: 1 / 40, darkGrainColor: new THREE.Color(#2a1a0a), lightGrainColor: new THREE.Color(#8b4513), clearcoat: 1, clearcoatRoughness: 0.3 });构造过程中值得注意的两个实现细节字符串颜色自动转THREE.Color源码遍历finalParams时若属性值为string则自动执行this[key] new THREE.Color(finalParams[key])WoodNodeMaterial.js因此传#8b4513与new THREE.Color(#8b4513)等价genus/finish两个键会被跳过不写入实例属性而clearcoat、clearcoatRoughness会额外被设置为节点的clearcoatNode与物理属性驱动 MeshPhysicalMaterial 的清漆层。方式三预设与自定义混用推荐进阶玩法先用GetWoodPreset取到某组合的完整参数对象再在构造时用展开运算符局部覆盖实现指定木种但单独调纹理/饰面// Mixing presets with custom overrides const walnutParams GetWoodPreset(walnut, raw); const material new WoodNodeMaterial({ ...walnutParams, ringThickness: 1 / 50, // Override specific parameter clearcoat: 1 // Add finish });这种写法本质就是方式一的内部路径fromPreset也是取预设字典 → 传入构造函数。区别在于GetWoodPreset返回的字典包含全部参数可先取回任意修改再构造自由度最高。示例工程里的自定义材质正是这样做的webgpu_tsl_wood.html在一组teak风格参数上把clearcoat设为 1、clearcoatRoughness设为 0.2产生清漆质感后放进展示网格。参数全景每一个可调项的含义材质支持 18 个外观参数 3 个饰面参数 1 个空间变换矩阵。以下作用说明依据源码中对应的 TSLFn节点实现WoodNodeMaterial.js归纳年轮体系参数类型作用centerSizenumber控制树心区域范围。woodCenter取顶点 XY 径向长度后映射到[0, centerSize]值越大中心区域对翘曲影响越明显ringThicknessnumber年轮间距。实际年轮频率为1 / ringThickness源码中取w.mul(ringThickness).fract()数值越小年轮越密预设普遍在1/24 ~ 1/38即给分数形式ringBiasnumber年轮轮廓偏置。通过两次mapRange在0与ringBias之间塑造年轮明暗交界位置控制年轮边缘的锐利形状ringSizeVariancenumber年轮间距的随机波动幅度越大则年轮疏密越不规则ringVarianceScalenumber叠加到年轮上的低频噪声采样缩放控制年轮间距波动的空间频率barkThicknessnumber放大/压缩年轮层叠效果预设范围约0.07 ~ 1.01配合年轮颜色过渡年轮的最终锐利度还与视距相关woodRings用positionView.length()到相机的距离做自适应模糊smoothstep远处年轮被软化避免走样闪烁WoodNodeMaterial.js。空间翘曲木纹蜿蜒参数类型作用largeWarpScalenumber大尺度翘曲强度决定年轮整体扭动幅度影响木纹宏观走向largeGrainStretchnumber大尺度翘曲沿 Z纹理长度方向的采样拉伸值越小木纹沿长度方向拉得越直smallWarpStrengthnumber中尺度翘曲强度在年轮之上叠加第二层扰动源码里空间被连续翘曲两次spaceWarp( spaceWarp(p, ...) , ...)smallWarpScalenumber中尺度翘曲的空间采样频率fineWarpStrengthnumber细粒度翘曲强度影响细腻的木纤维摆动fineWarpScalenumber细粒度翘曲的采样频率预设多为 4.8 ~ 33.6 高频区间细部与导管splotch / cell参数类型作用splotchScalenumber斑点/斑驳细节的采样缩放频率越高细节越细密splotchIntensitynumber斑点细节的叠加强度示例中通过柔光混合进入底色值可大于 1 强化对比预设最高达 3.48cellScalenumber模拟木材导管/孔隙的 3D Voronoi 细胞噪声缩放预设约 630 ~ 1530表示采样单元极小、高频cellSizenumberVoronoi 细胞平均尺寸。注意 cellSize 会被除以一个与视距相关的因子positionView.length() * 10以做 LOD 处理配色参数类型作用darkGrainColorstring |THREE.Color年轮暗部颜色晚材色lightGrainColorstring |THREE.Color年轮亮部颜色早材色基色计算为mix(darkGrainColor, lightGrainColor, rings)WoodNodeMaterial.js因此这两色决定了木纹明暗对比主体。饰面与变换参数类型作用clearcoatnumber清漆强度0 无清漆1 全清漆走MeshPhysicalMaterial的 clearcoat 通道clearcoatRoughnessnumber清漆粗糙度0 为镜面高光clearcoatDarkennumber清漆导致的底色变暗系数清漆越亮漫反射贡献越小颜色整体被wood(...).mul(clearcoatDarken)压缩transformationMatrixTHREE.Matrix4顶点变换矩阵。因为木纹完全由对象空间坐标positionLocal计算若多个物体共用一个材质就会纹路完全相同示例用transformationMatrix加随机平移为每个木块制造不同切面webgpu_tsl_wood.html内置木材与饰面预设木材种类预设WoodGenuses以下数据直接来源于源码中的woodParams常量字典WoodNodeMaterial.js展示每组最关键的区分参数完整参数共 20 项/种木种centerSizeringThicknessringVarianceScalesplotchIntensitycellScaledarkGrainColorlightGrainColorteak1.111/344.40.541910#0c0504#926c50walnut1.071/325.50.97710#311e13#523424white_oak1.231/341.40.541800#8b4c21#c57e43pine1.231/2453.321480#c58355#d19d61poplar1.431/373.80.71830#716347#998966maple1.41/354.61.49800#b08969#bc9d7dred_oak1.211/345.63.48800#af613b#e0a27acherry1.331/366.51.241530#913f27#b45837cedar1.111/256.72.54630#9a5b49#ae745emahogany1.251/381.21.391400#501d12#6d3722可以看出预设之间的差异策略针叶木pine年轮稀疏、色浅、细胞更碎硬木walnut、teak色深、翘曲明显mahogany、cedar 纹理变量少、色调偏红棕。饰面预设Finishes饰面仅改变三个清漆相关参数GetWoodPreset内部 switchWoodNodeMaterial.jsfinishclearcoatclearcoatRoughnessclearcoatDarkenraw001不变暗纯漫反射原木matte110.6哑光清漆轻微变暗semigloss10.40.4半光清漆gloss10.10.2高光清漆底色显著变暗以腾出镜面反射能量底层原理从 Blender 移植到 TSL 的程序化纹理管线逐层信号处理流程木纹并非单一噪声而是若干 TSL 函数逐级叠加的结果完整函数链见 wood 主函数woodCenter提取顶点的径向距离vec3(1,1,0)屏蔽 Z 后取模长映射为树心强度三次spaceWarp大/中/细坐标先整体采样 3D 噪声获得偏移场再沿归一化的 XY 方向把坐标推歪。翘曲级联使木纹既整体蜿蜒又有局部纤维抖动woodRings在翘曲后的径向距离上叠加低频噪声 → 乘以1/ringThickness做fract()生成重复年轮 → 用mapRange 基于视距的smoothstep平滑边界woodDetail以翘曲坐标的极角构造旋转采样空间sin/cos组合叠加第三路噪声生成斑点状细节cellStructure调用内嵌的 WGSL 函数voronoi3d连同hash3d哈希见 WoodNodeMaterial.js生成 3D Voronoi 细胞纹理模拟木材径向导管颜色合成先用rings在深浅两色间mix出年轮底色再以源码注释所说的softLightMixBlender 柔光混合的 TSL 复刻WoodNodeMaterial.js把细胞结构强度 0.407与斑点细节逐层叠入。其中年轮与细节噪声复用了 MaterialX 语义的节点mx_noise_float/mx_noise_vec3源码 src/nodes/materialx/MaterialXNodes.js本质是基于 Perlin 噪声封装而 Voronoi 则直接以TSL.wgslFn内嵌 WGSL 源码实现体现了 TSL 灵活混排 JS 节点与 WGSL 的能力。WoodNodeMaterial 只是整个 TSL 生态的用例之一进阶可参考 docs/TSL.md。Uniform 与材质属性的双向同步每种外观参数在模块加载时都会创建对应 uniform并通过onObjectUpdate回调在每次材质对象更新时回读实例属性见 WoodNodeMaterial.js例如uniforms.centerSize TSL.uniform( params.centerSize ).onObjectUpdate( ( { material } ) material.centerSize ); uniforms.darkGrainColor TSL.uniform( new THREE.Color( params.darkGrainColor ) ).onObjectUpdate( ( { material }, self ) self.value.set( material.darkGrainColor ) );这意味着运行时直接修改材质实例属性如material.ringThickness 1/50即可实时生效无需重建材质——这也正是演示页 GUI 拖动滑条即可预览效果的原因。颜色类 uniform 通过self.value.set(...)同步THREE.Color其余标量直接赋值。实战调参与场景集成要点在示例页中交互调参打开 examples/webgpu_tsl_wood.html可看到 10 种木材 × 4 种饰面40 块圆角方块加一块自定义木块的展示矩阵。示例对自定义材质暴露了 GUI 调参其滑条范围webgpu_tsl_wood.html可作为调参的实用参考区间几何体为约0.125 × 0.9 × 0.9的圆角长方体参数GUI 调整范围参数GUI 调整范围centerSize0.0 ~ 2.0ringVarianceScale0.0 ~ 10.0largeWarpScale0.0 ~ 1.0barkThickness0.0 ~ 1.0largeGrainStretch0.0 ~ 1.0splotchScale0.0 ~ 1.0smallWarpStrength0.0 ~ 0.2splotchIntensity0.0 ~ 1.0smallWarpScale0.0 ~ 5.0cellScale100 ~ 2000fineWarpStrength0.0 ~ 0.05cellSize0.01 ~ 0.5fineWarpScale0.0 ~ 50.0clearcoat0.0 ~ 1.0ringThickness0.0 ~ 0.1clearcoatRoughness0.0 ~ 1.0ringBias-0.2 ~ 0.2darkGrainColor/lightGrainColor颜色选择器ringSizeVariance0.0 ~ 0.2注意滑条范围仅是演示页针对其几何体设定的经验区间预设本身不受此限例如 pine 的splotchIntensity 3.32、cellScale达 1480。以对象实际尺寸为准时需重新评估比例。集成到自己的场景参照示例的完整集成流程webgpu_tsl_wood.html// 1. 取材质 const material WoodNodeMaterial.fromPreset( teak, matte ); // 2. 关键若多个 Mesh 共享一个材质可用 transformationMatrix 让木纹切面错开 const mesh new THREE.Mesh( geometry, material ); material.transformationMatrix new THREE.Matrix4().setPosition( new THREE.Vector3( -0.1, 0, Math.random() ) ); // 3. 配合环境反射以获得真实清漆高光 scene.environment equirectTexture; // 示例加载 HDR 环境图environmentIntensity 2 scene.environmentIntensity 2;示例场景还给出了两项可复用的配套设置使用THREE.NeutralToneMapping且曝光为 1.0 的色调映射避免木色过饱和以及用 HDR 环境贴图驱动清漆反射。由于木纹是三维程序化函数而非贴图任何被几何体切到的剖面都会呈现连续自然的年轮断面——这是相对平面贴图材质的核心差异与优势。延伸阅读材质官方文档页docs/pages/WoodNodeMaterial.htmlMarkdown 源见 docs/pages/WoodNodeMaterial.html.md材质完整源码examples/jsm/materials/WoodNodeMaterial.js可交互演示工程examples/webgpu_tsl_wood.html依赖的 MaterialX 噪声节点实现src/nodes/materialx/MaterialXNodes.jsTSL 语言与 Node 体系文档docs/TSL.md【免费下载链接】three.jsJavaScript 3D Library.项目地址: https://gitcode.com/GitHub_Trending/th/three.js创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表