three.js 编辑器中的材质与 Shader 能力
本文围绕 three.js 编辑器(一款基于 Three.js 的 AI 驱动可视化低代码编辑器)展开。
- 🌐 在线预览: https://z2586300277.github.io/threejs-editor/
- 📦 GitHub 开源仓库: https://github.com/z2586300277/three-editor
- 📚 文档地址: https://z2586300277.github.io/three-editor/docs/dist
材质决定了一个 3D 对象“长什么样”,Shader 则决定了它“怎么动、怎么变”。three.js 编辑器在材质与 Shader 层面提供了从标准 PBR 材质到自定义 GLSL、从面板调色到 AI 一键应用的完整链路,让没有图形学背景的用户也能做出高质感的视觉效果。
标准材质:PBR 面板化编辑
编辑器内置了 Three.js 的全套标准材质支持,包括 MeshBasicMaterial、MeshStandardMaterial、MeshPhysicalMaterial 等。当选中一个普通 Mesh 时,右侧面板会展示“材质配置”页签,用户可以实时调节颜色、金属度、粗糙度、自发光、透明度、贴图通道等参数。修改会立即反馈到渲染视图,所见即所得。
对于组件化对象,编辑器会识别其是否包含 RootMaterials 数组。例如“光柱”组件把立柱材质与面片材质都注册到 group.RootMaterials,并在 createPanel 中为它们分别生成颜色、透明度等控制项。这样即使一个组件内部有多个子材质,也能被统一管理。
自定义 ShaderMaterial 组件
three.js 编辑器支持以组件形式封装任意 ShaderMaterial。“彩虹漩涡”组件就是一个典型案例:它使用 PlaneGeometry 搭配自定义顶点与片段着色器,在片段着色器中通过迭代循环生成迷幻的彩虹波纹。uniform iTime 在每帧递增,驱动图案持续演化。组件还声明了 initParameters 与 createPanel,让用户可以调节尺寸和速度。
“极光”组件则展示了顶点动画与颜色混合的结合:顶点着色器对平面顶点做正弦波动,片段着色器根据波动高度和 UV 横向位置混合两种颜色并控制透明度。这种组件化 Shader 让原本需要写一堆样板代码的特效,变成了拖入场景即可使用的资产。
混合着色器库
除了完整 ShaderMaterial 组件,three.js 编辑器还提供了一套“混合着色器”机制。ThreeEditor.__GLSLLIB__ 中预置了如“荧光流动”、“太阳照射”等着色片段,用户可以通过 AI 或右侧面板把这些 Shader 叠加到任意 Mesh 上。shaderCores.setObjectBlendShader 会基于 onBeforeCompile 把 GLSL 片段注入到目标材质的编译流程,既保留了原始 PBR 属性,又增加了动态特效。
环境反射与高级材质
“磨砂反射的地面”组件展示了编辑器对高级材质的支持。它继承 MeshStandardMaterial,在 onBeforeCompile 中注入平面反射逻辑,每帧用虚拟相机渲染反射贴图,并结合粗糙度图、法线贴图与 KawaseBlur 实现带模糊的真实反射。CubeEnvMap 组件则使用 THREE.CubeCamera 动态拍摄周围环境,作为模型材质的 envMap,让金属表面呈现实时镜面反射。
AI 与材质 Shader 的协作
AI 助手可以直接调用 applyBlendShader 和 setObjectParams,对选中对象修改 uniform 与 params。编辑器还提供了 validateEditInput 校验:如果目标是组件或 Shader 对象,AI 会被强制要求走 params/uniforms 通道,而不是直接改 color/metalness,从而避免破坏组件内部状态。
代码一瞥
以下是“极光”组件中自定义 ShaderMaterial 与参数面板的简化片段:
const material = new THREE.ShaderMaterial({transparent: true, side: THREE.DoubleSide, uniforms: { uTime: { value: 0 }, uColor1: { value: new THREE.Color(params.color1) }, uColor2: { value: new THREE.Color(params.color2) } }, vertexShader:
uniform float uTime; varying vec2 vUv; varying float vElevation; void main() { vUv = uv; vec3 pos = position; float wave = sin(pos.x 0.5 + uTime) cos(pos.x 0.3 - uTime 0.7); pos.z += wave * 3.0; vElevation = wave; gl_Position = projectionMatrix modelViewMatrix vec4(pos, 1.0); }, fragmentShader:uniform vec3 uColor1; uniform vec3 uColor2; uniform float uTime; varying vec2 vUv; varying float vElevation; void main() { float pattern = sin(vUv.x 10.0 + uTime) 0.5 + 0.5; vec3 color = mix(uColor1, uColor2, pattern); float alpha = (1.0 - abs(vUv.y - 0.5) 2.0) 0.6; alpha *= smoothstep(-1.0, 1.0, vElevation); gl_FragColor = vec4(color, alpha); }});
scene.addUpdateListener(() => { material.uniforms.uTime.value += 0.016 * params.speed; });
从标准材质面板到自定义 GLSL,从混合着色器到实时反射,three.js 编辑器把材质与 Shader 能力分层开放。你可以只调几个滑块做出金属质感,也可以写完整 Shader 打造独一无二的视觉特效。

468

被折叠的 条评论
为什么被折叠?



