渲染基础理论的介绍(1)

渲染基础理论的介绍(1)

http://www.qiujiawei.com/rendering-equation/

Tags: math, computer graphics

基础概念

辐射度学 Radiometry

辐射度学是指测量电磁辐射(包括可见光)的一系列技术,它是和观察者无关的。而近似的光度学(photometric),是观察者相关的。这里我所说的观察者无关,是指测量值和人眼并无关系,是绝对值。

基于辐射度学来做渲染,需要了解下面这些东西:

  • 光谱 Spectrum
  • 光谱功率分布(SPD, spectral power distribution)
  • XYZ 和 RGB 两种CIE颜色系统以及它们之间、它们和SPD之间的转换
  • 辐射通量(Flux)
  • 立体角(Solid Angle)
  • 辐射密度(Irradiance)
  • 辐射亮度(Radiance)

光谱 Spectrum

现实中大部分光源(非直接光源也算),发射出的光都是复合光,即是由不同波长的色光混合而成的。 光谱就是指所有光波的分布。光谱图如下:

11.png

其中波长在 390 nm 到700 nm之间的光波称为可见光。

光谱功率分布spectral power distribution

光谱功率分布描述的是这样一件事情:对于一个直接或间接光源物体,它发射出的复合光中各个波长的色光分别有多少能量,或者说,这个光源的能量是如何分布到各个波长的光波的?

譬如,水银灯的光主成分是波长为404.7, 407.8, 435.8, 546.1, 577.0, 579.0纳米的光波(见下图)。这意味着能量分布非常不平衡,主要集中在这几个波长上了,相当于离散了。

12.png

上图就是水银灯的SPD曲线了。

而白炽灯的SPD曲线是这样子的:

13.png

注意上面两个图中,横轴是指波长,纵轴是指每单位纳米(10纳米一个单位)的波长的功率(能量)。

SPD曲线都是用Spectroradiometers 这种专门仪器测量的。

SPD一般用符号P(λ)表示。

XYZ 三色刺激值(tristimulus vlaues)

14.png

(CIE标准观察者颜色匹配函数)(The CIE standard observer color matching functions)

当看到CIE standard observer字眼时,其实指的就是上面这个图。这个图是通过测量获得的,好处是这个图相当于一个数据表,当需要把SPD曲线转换成XYZ三刺激值时,就可以用这个图做,坏处是它不是数学描述出来的,那么应用起来就有一定限制性。

那么SPD如何转换到XYZ呢?公式如下:

15.png

这里面用到了积分,但因为匹配函数是非数学描述的(上面的图的3条曲线),所以这个公式不可用,然而我们可以另辟蹊径,用采样和线性叠加的方法计算XYZ:

16.png

这里的下标i代表第几个刻度的采样。采样间隔(spacing)一般是1到20纳米,采样空间(span)是整个可见光波段(这个波段的具体范围取决于实际需求和SPD曲线)。

通过SPD计算XYZ:Computing XYZ From Spectral Data

XYZ和RGB之间的互相转换

XYZ到RGB

公式是:

17.png

(此矩阵只适用于 sRGB 定义中的RGB)

(对于右边的输入值XYZ,也是有要求的,这是因为左边的 RGBlinear

的取值范围是[0,1],所以右边的XYZ也需要做规范化。在我的下一篇文章中会介绍这部分。)

得到的 RGBlinear

是线性空间的,有什么意义呢?因为一般渲染器都是在线性空间下进行光照计算的,所以这个 RGBlinear 可直接用到光照等计算中。但是当要把最终的渲染结果输出时,例如写入到位图文件或显示到屏幕上,就需要对每个像素的 RGBlinear

做gamma校正,校正成sRGB,公式如下:

21.png

校正后的sRGB是单位化的,各个分量的取值范围是[0.0, 1.0],输出时需要乘以255并取整。

RGB到XYZ

当输入的RGB是sRGB时,需要做逆gamma校正,公式如下:

22.png

得到线性空间的RGB值后,就可以用下面的公式转换到XYZ空间:

23.png

辐射通量(Flux)

辐射通量(Radiant Flux),指的是单位时间到达一块平面(或一个局部空间区域)的能量总和。单位是焦耳每秒(joules/second,,J/s),或瓦特(watts,W)。符号是 Φ

一个点光源发射出去的能量大小可以用Flux来描述。其中要注意的是,Flux描述的是单位时间的能量,那么对于点光源来说,Flux只和光源的强弱有关,所以下图的2个圆圈的Flux值是一样的。

4.png

辐射密度(Irradiance) (或称辐射照度(Radiant Exitence))

辐射密度也叫辐射照度。定义了辐射通量后,就可以定义辐射照度了,辐射照度指的是单位面积进入的辐射通量,单位是 W/m2

。根据这个定义用符号E表示。

辐射照度和辐射密度是近似的东西,辐射照度指的是单位面积离开的辐射通量,单位也是 W/m2

。用符号M表示。

以上面的点光源来分析,可以知道上图中内圆圈的辐射照度比外圆圈的辐射照度大,这是因为内圆圈的面积更小而点光源的Flux值恒定,所以内圆圈的E值就大。

用公式表示:

E==Φ4πr2

可见,W恒定,半径r越小,那么辐射照度E越大。

当假设光源在无限远处时,可把光源认为是一块平面(这种光源叫方向光)。此时,光源平面与被照射平面存在2种情形:光源平面与被照射平面平行(下图中的A)、光源平面与被照射平面不平行(下图中的B):

5.png

(图中的平面附近的A指的是面积Area)

当光源平面与被照射平面平行时,有:

E1=ΦA

当光源平面与被照射平面不平行时,需要根据平面的法向量和光线方向的夹角θ,先求出 A

cosθ=AA
A=Acosθ

于是得到:

E2=ΦA=ΦAcosθ=ΦcosθA

也可以记为

E=ΦcosθA

( A

指A'在光线的方向的正交平面上的投影)

微分形式:

dE=dΦcosθdA

根据这个式子,可以想到,当θ逼近0度时,cosθ等于1,法向量和光线方向平行(上图中的A);当θ逼近90度时,cosθ等于0,辐射照度E为0(光线垂直于法向量了)。

立体角(Solid Angle)

立体角的介绍请访问:立体角(Solid Angle)详解

辐射亮度(Radiance)

辐射亮度是指辐射通量与单位面积(注意,是与光线方向正交的那块)单位立体角的比值。符号为L。定义式如下:

L=dΦdωdA=dΦdωdAcosθ

或:

L=ΦωA

物理含义如下图所示:

7.png

辐射密度E和辐射亮度L的关系是"总体"和"个体"的区别,可以对比下两者的公式来理解:

E=ΦA
L=ΦωA

E是指进入目标区域的总辐射通量与目标区域总面积的比值;而L是指进入目标区域的总辐射通量与目标区域总面积、总的入射立体角的比值,也就是说L是比E多除了立体角。直观图示如下:

19.png

也就是说其实E和L可以认为是同一个东西,只是L描述的是E的局部。用一句话记住两者的区别:有特定方向时是L,无特定方向时是E。这个区别相当重要,因为它体现在了渲染方程中。

注意:在计算机图形学中,辐射亮度比起上面其他物理量,都重要地得多。

如果要求平面上某点p的某方向 ω

的辐射亮度L(Radiance),可用下面的符号表示:

L(p,ω)

其中, ω

的方向需要注意,因为它是一个立体角,立体角的圆心是p, ω

的朝向必然是从圆心p往外(向量起点是p)。

实际上,需要区分成入射(input)和出射(output)2种辐射亮度L,用下面2个符号表示:

Li(p,ω)
Lo(p,ω)

且在现实世界中有:

Li(p,ω)Lo(p,ω)

还有,上面的这个p不能简单认为真的是一个无体积的点,它也可能是一个无限小的平面块,即它是一个有面积A、有法向量n的“点”。对于这样一个“点”,我们可以求出它的上半球(沿着n的方向)的辐射密度值 E(p,n)

E(p,n)=ΩLi(p,ω)|cosθ|dω

分析下这个式子的由来。首先搬出上文给出的L和E的公式:

L=dΦdωdA
dE=dΦcosθdA

所以有:

dΦ=LdωdA
dE=dΦcosθdA=LdωdAcosθdA=Ldωcosθ

对上式做整个半球的积分,就得到了:

E=ΩL|cosθ|dω

也就是:

E(p,n)=ΩLi(p,ω)|cosθ|dω

其中的 cosθ

加绝对值是因为我们求的是半球的积分,立体角 ω

和法向量的夹角必然是锐角,锐角的余弦值必然大于等于0。

如果把式子中的 dω

替换成球形角(Sphere Angle),则得到:

dω=sinθdθdϕ
E(p,n)=ΩLi(p,ω)|cosθ|sinθdθdϕ

这个式子是不对的,因为积分那里用了立体角,需要将其转换成对 θϕ

的积分。因为这里积分的是半球,那么 θ 的取值范围是 [0,π2] ϕ 的取值范围是 [0,2π]

E(p,n)=2π0π20Li(p,θ,ϕ)cosθsinθdθdϕ

(因为已经明确限定了 θ

的取值范围,所以 cosθ

必然大于等于0,可去掉绝对值符号)

如果 Li(p,θ,ϕ)

是一个常量值,那么就意味着任意方向的Radiance都是相等的,于是上式可以求出积分:

E(p,n)=Li(p,θ,ϕ)2π0π20cosθsinθdθdϕ
=Li(p,θ,ϕ)2π0(12sin2θ)|π20dϕ
=Li(p,θ,ϕ)2π0(12sin2π212sin20)dϕ
=Li(p,θ,ϕ)2π012dϕ
=Li(p,θ,ϕ)12(2π0)
=Li(p,θ,ϕ)π

注意,这个简化公式在渲染中很重要。因为当计算一个点到摄像机的Radiance,第一步就是先求这个点的入射E(求E的过程可以很复杂),当求出E之后,就可以认为这个点对任意方向的出射Radiance是均等的,也就是 L=Eπ

渲染方程 Rendering Equation

把wiki的渲染方程贴进来:

18.png

https://en.wikipedia.org/wiki/Rendering_equation

各个组成元素的解释:

  • λ 指代波长为λ的光

  • t 某一时间点

  • x 指空间上的某个点,也即被渲染的点(微分平面) (其实应该写成p吧)

  • n 被渲染的点(平面)的法向量,可以人为指定也可以根据一定规则自动生成

  • ωo

  • 出射光线的方向(是一个立体角),起点在x(被渲染的点)

  • ωi

  • 入射光线的反方向(是一个立体角),起点也在x,所以才叫反方向

  • Lo(x,ωo,λ,t)

    在t时刻、从x点往 ωo
  • 方向的光(λ)的总辐射亮度(Radiance)

  • Le(x,ωo,λ,t)

    指x点自身发射出的辐射亮度(Radiance),其他参数含义同 Lo(x,ωo,λ,t)

  • Ω

  • 是以x为圆心的单位半球,半球的朝向和法向量n一致

  • Ωdωi

  • 指对这个半球做积分

  • fr(x,ωi,ωo,λ,t)

  • BRDF函数,函数的返回值是一个比值(ratio scalar)

  • Li(x,ωi,λ,t)

    在t时刻、沿着 ωi
  • 方向进入x点的光(λ)的辐射亮度(Radiance)

  • ωin

    是一个衰减比值(一般是0到1),指入射光的方向和法向量的夹角 θi ,这个夹角导致产生的衰减。原因请参考上面的辐射通量小节。这个参数也可以写成 cosθi

    上面的可能太教科书了,下面展示一个简化的渲染方程:

    Lo(p,ωo)=Le(p,ωo)+Ωf(p,ωo,ωi)Li(p,ωi)|cosθi|dωi

    能简化成这个式子的原因是,在做渲染器的时候,本来就是把t值固定的,即做动画渲染的话,也是把动画离散成一帧帧来渲染,对每一帧来说t值是常量值;而另外的λ值蕴含在颜色空间(XYZ RGB)中。

    还有一个要说清楚的,就是这个方程3个部分的含义:

    20.png

    为什么右边那坨是E?上文已经说过了:"有特定方向时是L,无特定方向时是E",因为它是对L做整个半球的积分(注意,积分的是入射角度),也就是无特定方向,所以它是E。而另外2个分部都是指定了朝向了 ωo

    (出射方向)的,所以是L。

    整个渲染方程可以说就是在求出射方向到底有多少辐射通量(为什么不是L?因为被渲染区域的面积一般都限定为单位面积,即等于1,所以L相当于 Φ

    ),辐射通量一旦确定就可以知道这个被渲染区域的颜色。

    基于光线追踪的离线渲染中,是可以直接基于上面的渲染方程去做工程实现的。(相比而言,实时渲染更多的是用各种trick技术来近似渲染方程。)

<think>嗯,用户想了解图形学渲染基础理论和相关语言。首先,我需要确定他们的背景,可能是学生或者刚入行的开发者?可能需要从基础讲起,但又不能太浅显。 图形学渲染涉及很多方面,得先分清楚理论基础和编程语言部分。理论方面,光线追踪、光栅化、着色这些是核心。得解释清楚每个概念,比如光栅化是怎么把3D模型转成像素的,光线追踪和路径追踪的区别在哪里。用户可能听说过这些术语,但需要系统化的梳理。 然后,数学基础部分,用户可能需要知道向量、矩阵变换、光照模型涉及的公式。这里要注意用LaTeX格式,按照用户的要求,行内公式用$...$,独立公式用$$...$$。比如Phong模型中的各个分量,得用公式展示清楚。 关于渲染流程,固定管线和可编程管线的区别,可能得提到传统方法如OpenGL和现代的可编程着色器。这部分需要简明扼要,避免太深入细节。 语言和工具方面,OpenGL、DirectX、Vulkan这些API的区别和应用场景。还有HLSL、GLSL这些着色语言,以及新兴的WebGPU。用户可能对实际应用感兴趣,比如游戏开发常用什么,科研用什么。 最后,学习路径的建议也很重要。用户可能想知道从哪里入手,是否需要很强的数学基础,推荐哪些资源。比如先学线性代数,再接触OpenGL,然后深入光线追踪。 需要检查结构是否清晰,分点是否明确,有没有遗漏重要概念。比如是否提到了实时光追和离线渲染的区别,或者最新的技术趋势。另外,确保使用中文,术语准确,LaTeX格式正确,避免错误。</think>我将分步骤介绍图形学渲染基础理论与常用语言: 一、数学基础(图形学核心) 1. 几何表示 - 向量运算:$ \vec{a} \cdot \vec{b} = |\vec{a}||\vec{b}|\cos\theta $ - 矩阵变换:$$ \begin{bmatrix} x' \\ y' \\ z' \\ 1 \end{bmatrix} = \mathbf{T} \cdot \mathbf{R} \cdot \mathbf{S} \cdot \begin{bmatrix} x \\ y \\ z \\ 1 \end{bmatrix} $$ 2. 光照模型 - Phong反射模型: $$ I = I_a + I_d(\vec{n} \cdot \vec{l}) + I_s(\vec{r} \cdot \vec{v})^s $$ 二、核心渲染理论 1. 光栅化(Rasterization) - 将3D几何转换为2D像素的过程 - 关键算法:扫描线算法、Z-Buffer算法 2. 光线追踪(Ray Tracing) - 递归公式: $$ L_o = L_e + \int_{\Omega} f_r L_i (\omega_i \cdot \mathbf{n}) d\omega_i $$ 3. 全局光照 - 辐射度量学基础:$$ L(x \to \Theta) = L_e(x \to \Theta) + \int_{\Omega} f_r(x, \Psi \to \Theta) L(x \leftarrow \Psi) \cos\theta d\omega $$ 三、渲染管线架构 1. 固定功能管线(传统) ```mermaid graph LR 顶点数据 --> 顶点处理 --> 图元装配 --> 光栅化 --> 片段处理 --> 帧缓冲 ``` 2. 可编程管线(现代) - 顶点着色器 - 几何着色器 - 片段着色器 四、着色语言与API 1. 底层图形API - OpenGL:跨平台标准,使用GLSL ```glsl // GLSL顶点着色器示例 #version 450 core layout(location=0) in vec3 aPos; uniform mat4 modelViewProj; void main() { gl_Position = modelViewProj * vec4(aPos, 1.0); } ``` - Vulkan:新一代跨平台API - DirectX 12:Windows平台专属 2. 高级着色语言 - HLSL(DirectX) - Metal Shading Language(Apple生态) 五、现代渲染技术趋势 1. 实时光线追踪 - 结合DXR/Vulkan RT扩展 - 降噪算法:SVGF、BMFR 2. 基于物理的渲染(PBR) - BRDF模型:$$ f_r = \frac{DFG}{4(\omega_o \cdot \mathbf{n})(\omega_i \cdot \mathbf{n})} $$ 3. 延迟渲染(Deferred Shading) - 多Pass架构优化光照计算 六、学习路径建议 1. 基础阶段 - 线性代数 - OpenGL/Vulkan基础 - 《Real-Time Rendering》经典教材 2. 进阶方向 - GPU架构(SIMT执行模型) - 光线追踪加速结构(BVH、KD-Tree) - 并行计算优化 最新发展: - 机器学习与渲染结合(NeRF、DLSS) - 云端渲染技术(WebGPU标准) - 跨平台渲染引擎(Unreal Engine 5 Nanite) 建议从OpenGL/Vulkan入手实践,结合理论逐步深入光线追踪和GPU计算领域。数学基础(特别是线性代数和微积分)是理解渲染算法的关键。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值