SceneJS光照与材质详解:3步让3D场景呈现真实质感
【免费下载链接】scenejsAn extensible WebGL-based 3D engine. This is an archived project.项目地址: https://gitcode.com/gh_mirrors/sce/scenejs
SceneJS 是一款基于 WebGL 的可扩展 3D 引擎,即便项目已归档,它简洁的"节点树 + 状态继承"设计依然是学习 WebGL 光照与材质体系的绝佳教材。很多新手用 SceneJS 建模后总觉得画面"假、平、灰",问题几乎都出在光照和材质上——光照决定物体"被怎么照亮",材质决定物体"如何反光"。本文不堆代码,用 3 个步骤带你搞懂 SceneJS 光照与材质的核心原理,让 3D 场景立刻拥有真实质感。🎨
第 1 步:点亮场景——认识 SceneJS 的 4 种光源
SceneJS 把光源封装为lights节点,一个节点内可以同时挂载多个光源,子节点范围内的几何体都会受其影响。它一共支持 4 种模式(mode),对应 4 种现实中的光:
| 模式 | 中文名 | 特点 | 典型用途 |
|---|---|---|---|
ambient | 环境光 | 无方向、无位置,均匀照亮所有表面 | 提亮暗部,防止死黑 |
dir | 平行光 | 只有方向、没有位置,如太阳 | 模拟日光、主光 |
point | 点光源 | 有位置,向四周均匀发光 | 灯泡、蜡烛 |
spot | 聚光灯 | 有位置有方向,带圆锥范围 | 舞台灯、手电筒 |
光源的完整属性都定义在 lights.js 中:color(颜色)、diffuse/specular(是否贡献漫反射/高光)、pos(位置)、dir(方向)、innerCone/outerCone(聚光灯光锥)、constantAttenuation/linearAttenuation/quadraticAttenuation(衰减系数)以及space(世界空间或视图空间)。
💡 小技巧:
space:"world"的光源固定在场景里,相机旋转时光相对静止,更像"真实世界的灯";space:"view"的光源会跟着视角走,适合"头灯"效果。
如果不配置任何光源,SceneJS 会提供默认的 1 个环境光 + 2 个平行光,画面发灰发白正是它们的"杰作"。想看到立竿见影的对比,可以运行官方示例 lighting_material_defaults.html 与 lighting_directional_world.html。
上图是项目内置的玻璃幕墙纹理,注意窗户上"透出窗帘"与"反射天空"的差异——这正是环境反射 + 透明材质的典型效果,也是你在 SceneJS 中想模拟的建筑玻璃质感。
第 2 步:赋予表面灵魂——理解材质 5 大核心参数
光照是"光源",材质则是"表面如何回应光"。SceneJS 用material节点定义材质,所有参数可在 material.js 中查到,核心就 5 个:
color(漫反射基色):物体本身的固有色,直接决定表面主色调;specular与specularColor(高光强度与颜色):控制高光反射的强弱和色调,数值越大表面越"油亮";shine(光泽度):高光斑的锐利程度,值越大高光越集中,金属、陶瓷质感靠它;emit与emitColor(自发光):让物体自己发光,如指示灯、发热的金属;alpha(透明度):0~1 之间控制透明度,配合材质实现玻璃、水面。
// 在 SceneJS 中定义材质的写法(示意) { type: "material", color: { r: 0.5, g: 0.5, b: 0.6 }, // 固有色 specular: 1.0, // 高光强度 shine: 70.0, // 光泽度 emit: 0, // 自发光 alpha: 1.0 // 不透明 }默认材质是"高光 1.0 + 光泽 70 + 全不透明",你可以从 lighting_material_custom.html 这个官方示例看到:即使光与材质参数完全相同,只要改变shine或specular,同一颗茶壶就会呈现哑光、亮光、金属感的巨大差异。
上面这张菲涅尔效果图很直观:玻璃茶壶正面透光、边缘反射强烈。这种"入射角越大反射越强"的物理现象就是菲涅尔反射(Fresnel),SceneJS 专门提供了 fresnel.js 节点来模拟它,是让玻璃、水面、车漆"活起来"的关键。
第 3 步:质感升级——用贴图与高级效果锦上添花
光靠参数调色还不够,真实世界的表面都有细节纹理。SceneJS 支持多种贴图与材质结合,最常用的是这三种组合:
- 漫反射贴图(Diffuse Map):定义表面颜色细节。比如项目自带的 earthDiffuse.jpg(1600×800 的地球纹理),直接决定陆地、海洋的色彩分布;
- 法线贴图(Normal Map):在不增加面数的情况下模拟凹凸起伏。项目里的 chesterfieldNormalMap.png 就是典型的皮革法线贴图,配合 chesterfieldColorMap.png 这张绿色皮沙发漫反射贴图,能呈现纽扣、褶皱的真实立体感;
- 高光贴图(Specular Map):用贴图控制表面哪些区域反光、哪些不发亮,比如 chesterfieldSpecularMap.png 只让皮革纽扣处产生高光。
另外别忘了材质节点的状态继承机制:父节点设置材质后,所有子节点默认继承,子节点可以局部覆盖——这正是 SceneJS 场景图设计的精髓。底层实现可查看 materialCore.js 与 lightsCore.js,它们以"共享核心"方式让相同材质/光照在多对象间零成本复用。
实践建议:3 步法快速调试你的场景
想快速验证这套思路,直接运行examples/目录下的灯光系列示例即可:平行光看 lighting_directional_world.html,点光源看 lighting_point_world.html,聚光灯看 lighting_spot_world.html,它们都带实时 GUI 可以拖拽参数。
新手调试时记住这个顺序:
- 先关掉默认光,从"环境光 + 一盏平行光"起步,确认主光方向;
- 再调材质,
specular从 0 慢慢加到 1,shine从 10 试到 200,观察高光变化; - 最后加贴图,用漫反射打底、法线贴图补细节、高光贴图定光泽,三步组合出真实质感。
SceneJS 用最朴素的节点 API 把 3D 光照与材质的核心原理讲得明明白白——理解这套体系,无论以后用 Three.js 还是原生 WebGL,都能触类旁通。动手调一调,你的 3D 场景马上就能告别"塑料感"!🚀
【免费下载链接】scenejsAn extensible WebGL-based 3D engine. This is an archived project.项目地址: https://gitcode.com/gh_mirrors/sce/scenejs
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考