- 图形学
- 游戏开发
- 3D渲染
【免费下载链接】Babylon.js
Babylon.js is a powerful, beautiful, simple, and open game and rendering engine packed into a friendly JavaScript framework.
本篇技术指南围绕 Babylon.js 官方材质库(Materials Library)的babylonjs-materials包展开,完整覆盖两种安装方式(公共 CDN 与 NPM)、TypeScript 类型配置,以及以SkyMaterial为代表的标准接入流程,并结合当前仓库中的@dev/materials源码、GLSL/WGSL 着色器与测试脚本,深入讲解材质参数的物理含义与底层实现。读完后,你将能在自己的 Babylon.js 场景中快速集成各种扩展材质,并理解如何向材质库新增自定义材质。
一、Materials Library 是什么
Babylon.js 的核心引擎(@babylonjs/core)自带 Standard、PBR 等通用材质,而Materials Library(材质库)是在核心之外独立分发的扩展材质集合,提供了一批"开箱即用"、无需额外贴图即可呈现特殊效果的材质。以当前仓库 packages/dev/materials/src/index.ts 的导出清单为准,材质库目前包含以下 15 类材质:
| 材质 | 源码目录 | 典型用途 |
|---|---|---|
CellMaterial | src/cell | 卡通"细胞"风格着色 |
CustomMaterial | src/custom | 基于 StandardMaterial 的着色器自定义入口 |
FireMaterial | src/fire | 程序化火焰效果 |
FurMaterial | src/fur | 程序化毛发效果 |
GradientMaterial | src/gradient | 渐变着色 |
GridMaterial | src/grid | 网格/格子着色 |
LavaMaterial | src/lava | 程序化岩浆效果 |
MixMaterial | src/mix | 多材质混合 |
NormalMaterial | src/normal | 法线可视化调试 |
ShadowOnlyMaterial | src/shadowOnly | 只显示阴影 |
SimpleMaterial | src/simple | 最简材质模板 |
SkyMaterial | src/sky | 程序化天空盒 |
TerrainMaterial | src/terrain | 地形纹理混合 |
TriPlanarMaterial | src/triPlanar | 三平面投影贴图 |
WaterMaterial | src/water | 水面反射/折射效果 |
这些材质全部通过index.ts统一导出,并在 src/legacy 目录下提供各自的 legacy 入口(如 legacy-sky.ts),用于生成 UMD 单文件版本。
二、安装方式一:公共 CDN(适合学习与小实验)
babylonjs-materials在公共 CDN 上同时提供了压缩版与未压缩版两个编译产物(对应main与min入口)。babylonjs-materials包本身依赖babylonjs核心,二者都需要引入。
<script src="https://preview.babylonjs.com/materialsLibrary/babylonjs.materials.js"></script> <!-- 或使用压缩版 --> <script src="https://preview.babylonjs.com/materialsLibrary/babylonjs.materials.min.js"></script>⚠️重要警告:公共 CDN 不应在生产环境中使用。官方明确说明,该 CDN 的用途是服务正在学习如何使用 Babylon.js 平台、或运行小型实验的用户;一旦你构建好了应用并准备面向大众发布,应当自行托管(自建 CDN)所有包。
三、安装方式二:NPM 包管理
对于新项目,官方在 readme.md 中明确建议使用ES6 包@babylonjs/materials。需要同时安装核心引擎与材质库:
npm install babylonjs babylonjs-materials当前仓库中babylonjs-materials的发布元数据(见 package.json)显示:包版本与核心引擎严格对齐(dependencies中声明"babylonjs": "9.28.0"),主入口为babylonjs.materials.min.js,类型声明文件为babylonjs.materials.module.d.ts,许可证为 Apache-2.0。也就是说,材质库的版本始终跟随核心引擎版本,安装时两者保持同版本是最稳妥的选择。
TypeScript 类型配置
如果使用 TypeScript,需要在tsconfig.json中添加两个类型包,否则类型检查无法识别BABYLON.SkyMaterial等材质库符号:
{ "compilerOptions": { "types": [ "babylonjs", "babylonjs-materials" ] } }引入并使用
材质库通过"副作用导入"(side-effect import)注册全局命名空间,随后即可在BABYLON命名空间下直接构造各类材质:
import * as BABYLON from "babylonjs"; import "babylonjs-materials"; const skyMaterial = new BABYLON.SkyMaterial("skyMaterial", scene); skyMaterial.backFaceCulling = false;import "babylonjs-materials"的作用是把材质类注册进BABYLON命名空间(这一点也可从 skyMaterial.ts 末尾的RegisterClass("BABYLON.SkyMaterial", SkyMaterial)调用得到印证),因此后续代码中不需要单独引用材质类名,直接通过new BABYLON.XXXMaterial(name, scene)创建即可。
四、实战:用 SkyMaterial 搭建程序化天空盒
SkyMaterial是材质库中最具代表性的成员——它完全不需要纹理贴图,而是通过大气散射模型在片元着色器中实时计算天空颜色,适合作为天空盒使用。官方给出的最小接入代码如下:
const sky = new BABYLON.SkyMaterial("sky", scene); sky.backFaceCulling = false; // 将天空材质赋给一个覆盖全场景的大球或盒子 const skybox = BABYLON.MeshBuilder.CreateSphere("skySphere", { diameter: 100, segments: 10 }, scene); skybox.material = sky;4.1 可调参数与取值范围
根据 skyMaterial.ts 中的公开属性定义,SkyMaterial提供了一组对应真实大气光学模型的物理参数(所有参数均带@serialize()装饰器,支持序列化/反序列化):
| 属性 | 类型 | 默认值 | 取值范围/说明 |
|---|---|---|---|
luminance | number | 1.0 | 整体亮度(区间]0, 1[语义;非 rawHDR 模式下参与色调映射) |
turbidity | number | 10.0 | 大气浑浊度,表示霾(haze)相对大气分子的散射程度 |
rayleigh | number | 2.0 | 天空观感(光强),对应 Rayleigh 散射系数 |
mieCoefficient | number | 0.005 | Mie 散射系数,区间[0, 0.1],影响mieDirectionalG表现 |
mieDirectionalG | number | 0.8 | Mie 散射理论下的霾粒子相位函数参数 |
distance | number | 500 | 太阳距离(相对场景活动相机) |
inclination | number | 0.49 | 太阳倾角,区间[-0.5, 0.5],非 0 表示太阳"倾斜" |
azimuth | number | 0.25 | 太阳方位角,区间[0, 1],表示水平面上与参考方向的角度 |
sunPosition | Vector3 | (0, 100, 0) | 太阳在世界空间的位置 |
useSunPosition | boolean | false | 是否直接使用sunPosition(false 时由inclination/azimuth反推) |
cameraOffset | Vector3 | (0,0,0) | 地平线偏移向量,如skyMaterial.cameraOffset.y = camera.globalPosition.y可让地平线对齐 Y=0 |
up | Vector3 | (0,1,0) | 天空材质视为"上"的方向向量 |
dithering | boolean | false | 是否启用抖动(Dithering),用于减少色带 |
rawHdrOutput | boolean | false | 是否输出场景参照(scene-referred)线性 HDR 颜色 |
cloudiness | number | 0 | 云量[0, 1],只软化太阳光盘,不改天空穹顶颜色 |
其中inclination与azimuth的换算逻辑在 skyMaterial.ts 中可见:当useSunPosition === false时,材质会在绑定时用theta = π * (inclination - 0.5)、phi = 2π * (azimuth - 0.5)实时计算太阳球面位置,并乘以distance,再按up方向做四元数旋转。这意味着你既可以手动摆sunPosition,也可以只调两个角度参数让引擎自动放置太阳。
4.2 参数调校参考(来自官方测试页)
仓库中的官方测试脚本 packages/dev/materials/test/addsky.js 为每个参数规定了 UI 滑杆范围,这些范围可以作为调参时的合理边界:
window.prepareSky = function () { var sky = new BABYLON.SkyMaterial("sky", scene); sky.backFaceCulling = false; // azimuth: 0 ~ 1 // inclination: 0 ~ 1 // luminance: 0 ~ 2 // mieDirectionalG: 0 ~ 1 // mieCoefficient: 0 ~ 0.1 // rayleigh: 0 ~ 4 // turbidity: 0 ~ 20 return sky; };backFaceCulling = false是天空材质的关键设置:因为相机位于球体/盒体内部向外看,必须关闭背面剔除才能看到内侧表面。
4.3 源码级原理:大气散射是如何在 GPU 上完成的
SkyMaterial继承自核心引擎的PushMaterial(skyMaterial.ts),其着色器加载器同时注册了 GLSL 与 WGSL 两套实现(_ShaderLoader,skyMaterial.ts),在 WebGPU 环境下会自动加载 wgsl/sky.fragment.fx 与 wgsl/sky.vertex.fx,WebGL 环境则使用 sky.fragment.fx 与 sky.vertex.fx。构造函数的第三个参数forceGLSL可在 WebGPU 上强制回退到 GLSL。
在片元着色器 sky.fragment.fx 中可以看到完整的物理模型:
- Rayleigh 散射(天空为什么是蓝色):
totalRayleigh()依据折射率n、分子数密度N、去极化因子pn计算,简化版系数为0.0005 / vec3(94, 40, 18),即蓝、绿、红三通道的散射强度递减; - Mie 散射(太阳周围的光晕/雾霾):
totalMie()结合浑浊度turbidity与mieCoefficient计算; - 太阳光盘:当
cloudiness === 0时使用smoothstep生成锐利的太阳圆盘;当cloudiness > 0时切换到基于Beer–Lambert 定律的云层透射模型,将移除的能量通过双瓣 Henyey–Greenstein 相位函数重新分布为光环(cloudPhase),并在注释中引用了 Frostbite 的物理天空与云渲染研究(Hillaire, SIGGRAPH 2016); - 色调映射:默认(非 rawHDR)走 Uncharted2 电影化色调映射曲线(
Uncharted2Tonemap)与曝光补偿;开启rawHdrOutput后则改为纯线性增益,并把颜色钳制在渲染目标可表示的最大值内(半浮点目标为 65504、浮点目标约 3.0e38、LDR 为 1.0,见 skyMaterial.ts 的_MaxColorValueForRenderTarget),以便把天空烘焙进 HDR IBL 环境立方体贴图。
顶点着色器 sky.vertex.fx 则非常简单:只计算viewProjection * world * position,并把世界坐标位置作为vPositionW传给片元阶段,供大气模型按视线方向计算散射积分。材质在bindForSubMesh阶段(skyMaterial.ts)会把相机世界位置、相机偏移、up向量以及全部大气参数作为 uniform 上传,并支持雾效(BindFogParameters)与对数深度缓冲(BindLogDepth)。
五、材质库的通用使用范式
所有材质库中的材质遵循同一套 API 约定,与SkyMaterial一致:
// 1. 创建材质实例(命名 + 所属场景) const simple = new BABYLON.SimpleMaterial("simple", scene); // 2. 赋给任意网格 sphere.material = simple;更完整的范式可参考 packages/dev/materials/readme.md:每个材质都由一个.ts(材质类)与两个.fx(GLSL 顶点/片元着色器)构成,SimpleMaterial被官方定位为最佳起点模板,因为它开箱即用且覆盖了 Babylon.js 材质的大多数标准能力——骨骼(Bones)支持、实例(Instances)支持、最多 4 盏灯、缓存支持、阴影支持、雾效支持、点渲染支持与裁剪平面(Clip plane)支持。如果自定义材质不依赖这些特性,也可以从零开始编写。
此外,所有材质都实现了标准的生命周期方法:
clone(name):通过SerializationHelper.Clone深拷贝材质;serialize():导出 JSON(如SkyMaterial会写入customType: "BABYLON.SkyMaterial");Parse(source, scene, rootUrl):从 JSON 反序列化恢复材质。
因此材质实例可以方便地通过场景序列化/反序列化流程保存与恢复。
六、从源码构建材质库
如果你希望自行构建babylonjs-materials,可以进入 packages/public/umd/babylonjs-materials(UMD 发布包)查看其脚本:package.json中的build:prod使用 rollup 以ROLLUP_MODE:production生成压缩产物,build:dev/build:dev:fast生成本地调试用未压缩产物,build:declaration生成.d.ts类型声明,test:escheck则用es-check校验产物是否符合 ES6 语法。构建流程会从@dev/materials(即 packages/dev/materials)编译、汇总后生成babylonjs.materials.js/babylonjs.materials.min.js。
若想在本地实时调参预览材质效果,官方推荐通过gulp webserver启动材质库测试页,该页面支持带动画网格、阴影、多种灯光与雾效的实时切换(UI 位于右侧);新增材质后,在测试页 UI 系统中注册一个选项即可对比验证(参考 packages/dev/materials/readme.md 的gui.add(options, 'material', ...)示例)。
七、小结
本文从babylonjs-materials的官方 readme 出发,完整梳理了材质库的两种安装路径(CDN 仅限学习/实验,NPM 适合生产)、TypeScript 类型配置与标准接入范式,并以SkyMaterial为例,结合 skyMaterial.ts、sky.fragment.fx、addsky.js 等仓库源码,剖析了参数语义、取值范围与底层大气散射/云层渲染原理。无论是快速接入现成材质,还是基于SimpleMaterial模板扩展自己的自定义材质,本文给出的路径都可以直接复用。
生产环境提醒:公共 CDN 仅用于学习与小型实验;正式发布时请将
babylonjs与babylonjs-materials一起托管到自有 CDN,并保持两者版本一致。
- 图形学
- 游戏开发
- 3D渲染
【免费下载链接】Babylon.js
Babylon.js is a powerful, beautiful, simple, and open game and rendering engine packed into a friendly JavaScript framework.
相关推荐
Leaflet 下载与安装全指南:从 CDN、npm 到源码构建
Leaflet 下载与安装全指南:从 CDN、npm 到源码构建 Leaflet 是一款专注于构建移动端友好交互地图的轻量级 JavaScript 库。本文围绕
前端数据可视化GISBabylon.js 快速上手指南:CDN/npm 安装、模块导入与第一个 3D 场景实战
Babylon.js 快速上手指南:CDN/npm 安装、模块导入与第一个 3D 场景实战 Babylon.js 是一个开源的 3D 游戏与渲染引擎,以纯 Ja
图形学游戏开发3D渲染Babylon.js GUI 模块入门:从 npm 安装到 AdvancedDynamicTexture 全屏 UI 实战
Babylon.js GUI 模块入门:从 npm 安装到 AdvancedDynamicTexture 全屏 UI 实战 Babylon.js GUI 是随
图形学游戏开发3D渲染
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考