three.js TSL 中的 AmbientLightNode:把环境光接入 WebGPU 节点光照系统
AmbientLightNode 是 three.js 节点系统(TSL,The Shading Language)中表示环境光的节点类。在 WebGPU 渲染管线中,场景中每加入一个 AmbientLight,渲染器都会通过节点库为其自动创建一个对应的 AmbientLightNode,由它把环境色以“辐照度(irradiance)”的形式累加进材质的光照模型。读完本篇,你将理解它的继承链路、构造参数、setup 阶段的行为,以及渲染器如何完成“灯 → 节点”的自动映射。
类定位与继承链
官方 API 文档(docs/pages/AmbientLightNode.html.md)对 AmbientLightNode 的定义是:Module for representing ambient lights as nodes(以节点形式表示环境光的模块),其继承关系为:
EventDispatcher → Node → LightingNode → AnalyticLightNode → AmbientLightNode
各层职责可以结合源码逐层确认:
- LightingNode:所有光照节点的基类,构造时以
'vec3'作为输出类型(光照颜色是 RGB 向量),并提供isLightingNode类型标志。 - AnalyticLightNode:解析式光源(环境光、平行光、点光、聚光灯等)的通用基类,持有光源引用、颜色 uniform 与阴影机制,并把
updateType覆盖为NodeUpdateType.FRAME(每帧更新一次,见 AnalyticLightNode.js#L97)。 - AmbientLightNode:只实现了“把颜色累加进环境辐照度”这一件事,是整个光照节点体系中最简单的具体类。
它通过 src/nodes/Nodes.js 统一导出,可在 ESM 环境里 import { AmbientLightNode } from 'three/tsl' 方式使用。
构造函数与关键属性
文档给出的构造签名为:
new AmbientLightNode( light : AmbientLight )
light:要表示的环境光光源,默认值为 null。
从 AmbientLightNode.js#L21-L25 看,构造逻辑只有一句 super( light ),全部属性都来自基类 AnalyticLightNode.js#L29-L97:
| 属性 | 类型/默认值 | 作用 |
|---|---|---|
light |
?Light,默认 null |
持有传入的光源对象引用,getHash() 直接返回 light.uuid,使节点与光源一一绑定 |
color |
Color |
节点自身的颜色缓存,每帧由 update() 写入 |
colorNode |
Node |
若光源上设置了 light.colorNode 则直接复用它;否则基于 this.color 创建 uniform( this.color ).setGroup( renderGroup )(见 AnalyticLightNode.js#L54),随渲染器 renderGroup 统一更新 |
baseColorNode |
?Node,默认 null |
保留 colorNode 的原始引用;启用阴影时最终颜色节点会被替换,此字段用于还原 |
shadowNode / shadowColorNode |
?Node,默认 null |
光源阴影节点与阴影颜色节点 |
isAnalyticLightNode |
boolean,只读,默认 true |
类型测试标志 |
updateType |
'frame' |
每帧刷新 uniform |
每帧的 update()(AnalyticLightNode.js#L299-L305)执行:
this.color.copy( light.color ).multiplyScalar( light.intensity );
也就是说,节点最终暴露的 color 是光源颜色 × 强度的乘积,这与传统 WebGL 管线中 lightColor uniform 的计算方式一致,保证了节点化前后光照结果的可比性。
setup:把颜色累加进环境辐照度
AmbientLightNode 的核心实现在它唯一重写的 setup 方法中(AmbientLightNode.js#L27-L31):
setup( { context } ) {
context.irradiance.addAssign( this.colorNode );
}
这行代码说明了两件事:
- 环境光的接入点是
context.irradiance。节点上下文(NodeBuilder.context)维护了一个irradiance累加器,addAssign( this.colorNode )表示“把本光源的颜色节点累加到环境辐照度上”。场景中可以有多个环境光,最终辐照度是它们的总和。 - 光照节点不参与常规求值输出。基类 AnalyticLightNode.js#L248-L290 的注释明确指出:与大多数节点不同,光照节点的
setup不返回输出节点,其目的只是配置当前LightingModel或调用相关接口。AmbientLightNode没有方向,因此它不实现setupDirect(方向性光才需要),只走“环境项”这一条路径。
由于基类构造器还为 light.shadow 注册了 dispose 监听、setup() 中会按需调用 setupShadow( builder )(AnalyticLightNode.js#L255-L290),从源码结构看 AmbientLightNode 也继承了完整阴影框架——但 AmbientLight 本身不产生阴影,实际使用中这条路径不会生效。
渲染器如何自动创建 AmbientLightNode
用户通常不需要手工 new AmbientLightNode( light )。在 WebGPU 后端,渲染器通过 NodeLibrary 的 addLight( lightNodeClass, lightClass )(NodeLibrary.js#L142-L146)登记“光源类 → 节点类”的映射,getLightNodeClass( light ) 按类查询。WebGPU 两套节点库都完成了登记:
this.addLight( AmbientLightNode, AmbientLight );
因此只需像普通场景那样加入环境光即可:
import * as THREE from 'three/webgpu';
const scene = new THREE.Scene();
// WebGPU 渲染器会为这个灯自动创建 AmbientLightNode,
// 并在 setup 阶段把它的颜色累加进 irradiance
const ambientLight = new THREE.AmbientLight( 0xffffff, 1 );
scene.add( ambientLight );
const renderer = new THREE.WebGPURenderer();
若需要更精细的控制,也可以在 TSL 中显式构造节点,利用光源上可选的 colorNode 覆盖默认 uniform:
import { nodeObject } from 'three/tsl';
// 手动构造:颜色将参与 context.irradiance 的累加
const node = new THREE.AmbientLightNode( ambientLight );
从源码看,一旦 light.colorNode 存在,节点会直接复用该节点而不是自建 uniform(AnalyticLightNode.js#L54),这意味着可以在 TSL 中给环境光接上程序化颜色。
小结与适用边界
AmbientLightNode是 three.js 节点系统中环境光的“适配层”:持有AmbientLight引用,每帧把color × intensity写入 uniform,并在setup时通过context.irradiance.addAssign( colorNode )累加进环境辐照度(AmbientLightNode.js#L27-L31)。- 它的全部公共 API 就是文档中的构造签名
new AmbientLightNode( light )(默认null)与静态type = 'AmbientLightNode';其余属性与生命周期逻辑(update、dispose、getHash等)均继承自 AnalyticLightNode。 - 自动创建路径依赖 WebGPU 后端的节点库登记(BasicNodeLibrary / StandardNodeLibrary),因此该机制的适用前提是使用 WebGPU 渲染管线;传统 WebGL 渲染器走的是着色器 uniform 管线,并不经过此类。
- 更多 API 细节可查阅文档页 docs/pages/AmbientLightNode.html.md,实现细节以 src/nodes/lighting/AmbientLightNode.js 为准。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0624
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00