首页
/ three.js 中的 ColorEnvironment:用统一颜色快速构建 IBL 环境光

three.js 中的 ColorEnvironment:用统一颜色快速构建 IBL 环境光

2026-09-06 15:20:30作者:郁楠烈Hubert

ColorEnvironment 是 three.js 提供的场景级环境类:它本身就是一个 Scene 的子类,内部只有一面“均匀颜色的球壳”,专门用来作为 PMREMGenerator#fromScene 的输入,一次性生成可复用、低成本的预滤波环境贴图(PMREM)。读完本文,你将掌握它的完整 API、导入方式、与 PMREMGenerator.fromScene 的配合流程,以及从源码层面理解它“为什么只需要一个球体”的原理,并了解其资源释放方式与同类环境类的区别。

类定位与继承链

ColorEnvironment 表示一个具有统一颜色的场景,可作为 PMREMGenerator#fromScene 的输入;生成的 PMREM 代表均匀的环境光(uniform ambient lighting),将其赋值给 Scene#environment 后即可用于基于图像的照明(Image Based Lighting, IBL)。

其继承关系为:

EventDispatcher → Object3D → Scene → ColorEnvironment

也就是说,它是一个可以直接参与场景图(Scene Graph)体系的对象——能被添加、被遍历、被 fromScene 渲染。官方文档页见 docs/pages/ColorEnvironment.html.md

导入方式:Addon 需要显式导入

ColorEnvironment 不是 three.js 核心库的一部分,而是 Addon,必须显式导入:

import { ColorEnvironment } from 'three/addons/environments/ColorEnvironment.js';

它定义在 examples/jsm/environments/ColorEnvironment.js 中,并通过 examples/jsm/Addons.jsexport * from './environments/ColorEnvironment.js'; 的形式统一再导出。使用 three/addons/* 路径前,需要先完成 three.js 官方手册 Installation → Addons 一节所说明的安装配置(例如配置包管理器导出或导入映射)。

API 详解

构造函数 new ColorEnvironment( color )

const environment = new ColorEnvironment( 0x00ff00 );
参数 类型 说明 默认值
color number | Color 环境的颜色 16777215(即 0xffffff,白色)

从源码 examples/jsm/environments/ColorEnvironment.js 可以看到,构造函数签名 constructor( color = 0xffffff ) 与文档一致:不传参时环境为白色。构造过程做了三件事:

  1. 将实例 name 设为 'ColorEnvironment'
  2. 创建一个 SphereGeometry( 1, 16, 16 )(半径 1、16×16 段的球体);
  3. MeshBasicMaterial( { color, side: BackSide } ) 创建背面渲染的材质,并组合成 Mesh 加入场景。

.dispose()

environment.dispose();

当环境不再需要时应调用此方法释放内部资源。其实现(见 examples/jsm/environments/ColorEnvironment.js#L50-L55)非常直接:

dispose() {

    this.children[ 0 ].geometry.dispose();
    this.children[ 0 ].material.dispose();

}

即只释放唯一子网格的几何体与材质。注意:它释放的是环境场景自身的 GPU 资源,fromScene 生成的 PMREM 渲染目标(及其纹理)属于另一个对象的生命周期,仍需在使用完毕后自行处置。

完整使用流程:从颜色到 IBL 环境贴图

文档给出的标准用法如下:

import { ColorEnvironment } from 'three/addons/environments/ColorEnvironment.js';

const environment = new ColorEnvironment( 0x00ff00 );
const pmremGenerator = new THREE.PMREMGenerator( renderer );
const envMap = pmremGenerator.fromScene( environment ).texture;
scene.environment = envMap;

流程拆解为四步:

  1. 构造环境场景new ColorEnvironment( color ) 得到一个仅含均匀颜色球壳的 Scene
  2. 创建生成器new THREE.PMREMGenerator( renderer ) 需要传入一个 WebGLRenderer(或 WebGPURenderer);
  3. 生成 PMREMfromScene( environment ) 返回一个 WebGLRenderTarget,取其 .texture 即得到预滤波后的 CubeUV 环境贴图;
  4. 赋给场景scene.environment = envMap 后,所有使用 PBR 材质(如 MeshStandardMaterialMeshPhysicalMaterial)的物体都会采样该环境贴图获得间接光照。

fromScene 的完整参数

结合 src/extras/PMREMGenerator.js#L107-L139 中的实现,fromScene 的完整签名为:

fromScene( scene, sigma = 0, near = 0.1, far = 100, options = {} )
参数 默认值 说明
scene 要渲染的场景,这里传入 ColorEnvironment 实例
sigma 0 场景模糊强度,大于 0 时先对立方体贴图做一次模糊
near 0.1 内部立方相机的近裁剪面
far 100 内部立方相机的远裁剪面
options.size 256 生成 PMREM 的贴图尺寸
options.position 原点 内部立方相机的位置

ColorEnvironment 而言,由于场景只有一面半径为 1 的球壳且相机位于原点,默认的 near = 0.1far = 100 完全够用,通常无需调整任何参数。

方法内部流程(见 src/extras/PMREMGenerator.js#L107-L139):临时切换渲染目标并关闭 XR 状态 → 通过 _sceneToCubeUV 将场景渲染为 CubeUV 格式 → 可选的 sigma 模糊 → 执行 PMREM 滤波 _applyPMREM → 清理临时状态后返回渲染目标。

WebGPU 后端的注意事项

从源码结构看,WebGPU 后端的 PMREMGenerator 在调用 fromScene 之前要求渲染器已初始化,否则会抛出错误(见 src/renderers/common/extras/PMREMGenerator.js#L133-L145):

THREE.PMREMGenerator: .fromScene() called before the backend is initialized.
Use "await renderer.init();" before using this method.

因此在 WebGPURenderer 项目中,应在 await renderer.init() 完成后再调用 fromScene

源码级原理:为什么一个球壳就能当环境

ColorEnvironment 全部实现只有 50 余行(见 examples/jsm/environments/ColorEnvironment.js),关键在于两处选择:

  1. MeshBasicMaterial + BackSide:材质不接收任何光照,输出恒为设定的颜色;BackSide 让相机(位于球心)看到的是球体内壁。从相机视角看,整个方向域(360°)都被这一颜色覆盖,等效于一个各向同性的“环境色罩”。
  2. SphereGeometry( 1, 16, 16 ):半径 1 且 16×16 分段足够低——因为要渲染的就是纯平色,多边形密度只影响性能而几乎不影响观感,16 段在球心视角下足以把球面近似为均匀。

fromScene 通过六个方向(CubeUV 布局)从原点渲染这个场景,得到的立方体贴图六个方向全是同一颜色;随后 PMREM 滤波生成不同粗糙度(mipmap)级别。由于输入本身各向均匀,最终环境贴图的各级 mipmap 也是同一颜色——这正是“uniform ambient lighting”的含义:物体表面的 PBR 反射在各个粗糙度下都得到一致的色调。

与同目录环境类的对比

同一目录 examples/jsm/environments/ 下还有两个结构相近的环境类,便于理解 ColorEnvironment 在“环境类家族”中的定位:

  • DebugEnvironment.js:用 BoxGeometry 房间 + PointLight + 三块自发光“色板”构成简易房间,其文档注释明确写着“should only be used for development purposes”,用于肉眼调试 IBL 效果;
  • RoomEnvironment.js:更精细的房间布光方案,适合生产环境使用。

三者的使用方式完全一致(都是 fromScene 的输入、都提供 dispose()),区别只在场景内容:ColorEnvironment 提供完全均匀、无方向性、无光源细节的“纯色氛围光”,适合只需给场景铺一层基础环境色、又不想加载 HDR/RGB 环境贴图的场景。

实践要点小结

  • 构造new ColorEnvironment( color )color 可为 16 进制颜色值或 Color 对象,缺省为白色(0xffffff);
  • 生成:必须经过 PMREMGenerator.fromScene( environment ).texture 获得可用的环境贴图,不能把 ColorEnvironment 本身直接赋给 scene.environment
  • 释放:环境用完后调用 environment.dispose() 释放球壳几何体与材质;PMREM 渲染目标/生成器按各自的生命周期另行处置;
  • 适用边界:它表达的是“均匀环境光”,没有高光方向与明暗变化。若需要带方向感的高光或更真实的反射细节,应改用 HDR/等距柱状贴图、RoomEnvironment 等方案。
登录后查看全文
热门项目推荐
相关项目推荐