文章摘要
光可以看作是由无数“光子快递员”传递的能量。每个光子携带的能量由其颜色(波长)决定:蓝光(波长短)能量大,红光(波长长)能量小。光子的能量总和构成光能,以焦耳(J)为单位。光能通过光子传递到物体上,使我们感受到温暖(如阳光)、照明(如灯泡)或发电(如太阳能板)。不同颜色的光就像不同大小的快递员,共同为我们带来光能与热量。
1. 光其实是“能量的快递员”
想象一下,光像一支支“无形的小箭”从太阳或灯泡飞出来——
每根小箭,我们叫做“光子(photon)”。
每个光子都装着一份能量包裹,快递到你身上、眼睛里,甚至照亮屋子、温暖大地。
2. 光子的能量由什么决定?
每个光子快递员能带多少“包裹”?这主要取决于光子的颜色(波长):
- 颜色偏蓝(波长短):快递的能量大(“大颗快递员”)
- 颜色偏红(波长长):快递的能量小(“小颗快递员”)
这就像蓝球员是壮汉,红球员是小个子。
物理学公式告诉我们:
E=hcλE = \frac{hc}{\lambda}E=λhc
其中:
- (E):单个光子的能量(焦耳,J)
- (h):普朗克常数,光的“最小能量单元”(一个超级小的常数)
- (c):光速
- λ\lambdaλ:光的波长(越短,能量越高)
3. 光能如何被我们感知和利用?
所有光子的能量加在一起,就叫“光能”。
- 太阳晒在脸上:无数光子撞在你皮肤上,把能量交给你,让你暖和
- 充电的太阳能板:太阳的光子把能量交给太阳能板,变成电
- 照亮房间:灯泡发出的光子把能量传递到房间里的每个角落
4. 如何描述光的总能量?
- 光能,一般用字母 (E) 表示,单位是焦耳 (J)。
- 你可以想象“一个大包裹”,里边是无数小个快递员(无数光子)带来的能量总和。
5. 形象总结
光能就是“光子快递员”们带到你身边、变成热、亮、甚至电的能量总和。
不同颜色(波长)的光,每个光子快递员能力不同,蓝色最厉害,红色温柔。
数百亿个光子不断飞来飞去,把整个世界点亮、加热、甚至养活了我们。
下面用生动的方式聊聊**光能(Energy)在基于物理的渲染(PBR, Physically Based Rendering)**里是怎么起作用的:
1. 游戏画面和电影画面,都在模拟“天上地下的光能接力赛”
想象一下你在树林里行走,阳光透过树叶,地面亮斑、阴影交错。这一切画面之所以真实,是因为幕后模拟了无数光子和它们的能量流动。
在PBR里,光能的传递遵循了物理世界的保能守恒——光来了,就会被吸收、反射、或者透过,没有能量是凭空消失或者凭空产生的。
2. 光源出发——能量带着方向、颜色和亮度
在渲染引擎场景里,太阳、灯泡、萤火虫等都是能量的发射站:
- 蒙德里安的白墙被日光照亮
- 银色水壶反射出明亮的光斑
- 橙色火把把能量撒在地上变成金灿灿的暖色
每个光源都有指定的输出能量(即功率,单位瓦特)的属性。光能会沿着各种方向“分派”出去,有的地方接收多,有的地方少。
3. 路上碰到什么——光能怎么决定表面明暗?
每束能量(光子流)飞到场景里,首先遇到一个表面(比如人物皮肤、金属刀刃、地面砖块)。
这时候,渲染就要解决两个问题:
a. 光有多少被吸收?多少能反射?
这就是材质的反射率、吸收率(以及透明度)——白色墙吸收少反射多,黑色衣服吸收多反射少,玻璃还会传递穿过去。
b. 反射往哪去?(BRDF决定)
每个材料会用不同的方式,把收到的光能量分配到各个方向(有的类似镜子、有的像粉刷墙)。PBR严格遵守物理定律,输入的能量绝不会比输出的少(能量守恒)。
4. 采样和累计——能量积分,逐步构建明亮与阴影
因为环境中光到达某点的路径、方向无限多,PBR会像上一句话说的:
把半球“分片”,每个方向的光都带着能量,乘以材质对这个方向的反应(BRDF),加总出某一个观察方向上能量流强度(就是像素的“高光”或“暗部”)。
公式直观解释:
像素亮度=所有方向上的能量流动×材质反射函数×夹角像素亮度 = \text{所有方向上的能量流动} \times \text{材质反射函数} \times \text{夹角}像素亮度=所有方向上的能量流动×材质反射函数×夹角
5. 高级特效和真实感——能量决定一切PBR美感
- 高光、镜面反射:金属表面把大部分能量朝一个角度反射,出现强光点;
- 漫反射、环境光:粗糙表面把能量四面八方分散,视觉上更“柔和”;
- 颜色和能量关联:只有特定波长的光能被反射(比如红苹果只反射红色),能量的“分配”决定色彩还原真实性。
- 阴影:能量被遮掉的就变暗,漏下来的就变亮——全靠能量流动计算真伪!
6. 总结(为什么必须用“能量观念”来做现代渲染?)
- 不按能量算,渲染会“魔法发光”,画面不真实(比如墙反射比收到的还多,会“自己发亮”)。
- 用能量的语言描述,保证了所有光现象、光与材质交互都“靠谱”——这是PBR数值和视觉统一的核心。
- 不论是在写真实的光照算法、还是直接用现成PBR引擎美术调节参数,变化的始终是能量如何被世界传递、分配和保存。
7. 一句话比喻结尾
PBR渲染就像一场全场直播的能量接力——每一缕光子从光源出场,跑遍世界,最后落在你眼睛里的,就是能量的故事!
8.继续探究PBR引擎参数如何影响能量(如albedo、metalness、roughness)、或各式物理光照模型的能量平衡,或者代码实现细节
PBR(物理基渲染,Physically-Based Rendering)强调能量守恒、基于物理的光照与材质交互。要探究PBR参数(如albedo、metalness、roughness)对能量的影响,或分析各种物理光照模型(如Lambert,Cook-Torrance)在能量平衡方面的实现,我们可以分几个层次讨论:
1. PBR参数与能量守恒的关系
Albedo(反照率/基础色)
- 表示表面可以反射的光的比例,其余即被吸收。
- 能量守恒要求表面的反射比例Albedo不能大于1(否则创造了能量)。
Metalness(金属度)
- 控制表面是金属还是非金属,通常非金属的反射高光颜色是白色或浅色(固定F0),金属则是自身颜色(Albedo)。
- 能量转移:非金属的Albedo主要是漫反射部分,金属的Albedo主要贡献镜面反射(高光),且几乎没有漫反射。
Roughness(粗糙度)
- 控制高光的散射,粗糙表面使高光变宽且能量分布更广。
- 能量平衡要求不论粗糙与否,反射的总能量(累积的反射光强)与表面的Fresnel反射率有关,不能无中生有或无端减少能量。
2. 常见PBR光照模型的能量平衡
漫反射模型
Lambert反射:
输出 = Albedo × (入射光 × cosθ) / π
此模型天生守恒,原因在于π的除法保证积分后反射不会多于入射能量。
能量守恒分析:
- 入射能量无论分散在多少角度,最后反射总和不会超过Albedo × 入射能量。
镜面反射模型
Cook-Torrance BRDF:
[fspec(l,v)=D(h)F(v,h)G(l,v,h)4(n⋅l)(n⋅v)][ f_{spec}(l, v) = \frac{D(h) F(v, h) G(l, v, h)}{4 (n \cdot l) (n \cdot v)} ][fspec(l,v)=4(n⋅l)(n⋅v)D(h)F(v,h)G(l,v,h)]
- D:法线分布函数(NDF),如GGX或Beckmann,反映表面微结构分布。
- F:Fresnel项,描述角度变化下的反射比例。
- G:几何遮蔽(Geometry),表面自遮挡系数。
能量守恒分析:
- 通过BRDF的合理构造保证其反射的能量不会大于入射光。
- 实际代码中常用微表面理论的NDF归一化系数,确保对整个半球积分能量<1。
Diffuse与Specular的能量分配
将Fresnel 0度反射(F0)作为分界:
- 非金属通常F0很小,绝大部分能量走漫反射路径。
- 金属物体F0很大,几乎所有能量都反射为镜面。
代码层面,Unity/UE4等引擎通常采用如下合成方式:
vec3 diffuseColor = albedo * (1.0 - metallic);
vec3 specularColor = mix(vec3(0.04), albedo, metallic);
vec3 F = fresnelSchlick(..., specularColor);
// cookTorrance = D * F * G / denom
vec3 kS = F; // 镜面反射分量
vec3 kD = 1.0 - kS; // 漫反射分量(instancing能量分给漫反射)
kD *= 1.0 - metallic; // 金属没有漫反射
这样做,保证了两个分量的和≤1,实现了能量守恒。
3. 典型PBR实现的代码片段分析
一个简单的Cook-Torrance实现伪代码(GLSL/Cg风格):
// Inputs: L光线、V视线、N法线、albedo、metallic、roughness、lightColor、lightIntensity
vec3 H = normalize(L + V);
float NdotL = max(dot(N, L), 0.0);
float NdotV = max(dot(N, V), 0.0);
float alpha = roughness*roughness;
// Specular F0
vec3 F0 = mix(vec3(0.04), albedo, metallic);
// Fresnel项
vec3 F = fresnelSchlick(max(dot(H, V), 0.0), F0);
// 正确能量分配
vec3 kS = F;
vec3 kD = (1.0 - kS) * (1.0 - metallic); // 金属无漫反射
// Lambert 漫反射
vec3 diffuse = kD * albedo / PI;
// Specular (用GGX分布举例)
float D = GGX_NDF(N, H, alpha);
float G = GeometrySmith(N, V, L, alpha);
float denom = 4.0 * NdotV * NdotL + 0.001;
vec3 spec = D * F * G / denom;
// 总和
vec3 color = (diffuse + spec) * lightColor * lightIntensity * NdotL;
重点
- kS + kD 不超过1,实现能量守恒
- F0决定高光反射的上限
- metallic参数让材质在金属与非金属行为间切换
4. 额外探究:粗糙度与能量汇总(能量损失/漏出问题)
- 微表面模型,如GGX若采样不充分,积分会“漏”掉能量,造成高光变暗。
- 部分实现会加能量补偿:如布林菲特(Burley)反射补偿,对粗糙高光提高能量。
5. 总结
- PBR各参数直接影响表面反射/吸收能量的分配,代码实现时需保护能量守恒。
- 光照模型如Cook-Torrance、Lambert等结构上就保证了能量平衡。
- 代码实现的关键在于Fresnel、漫反射分配、金属-非金属切换、NDF归一化。
2251

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



