从零开始的跨平台渲染引擎(番外一)——光和相机

Posted 董小虫

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从零开始的跨平台渲染引擎(番外一)——光和相机相关的知识,希望对你有一定的参考价值。

前言

基于物理渲染中使用的光和相机也需要符合物理性质,那么首先需要确定在物理世界中,光和相机是如何描述的。而其中最核心的,就是如何划定参与计算的数值类型和范围。
本文主要阐述了物理世界中,光如何量定,相机参数含义,以及它们如何参与到着色计算,以及实际应用。


光的单位

光学术语标记单位定义
光通量 Luminous flux / Luminous power Φ \\mathrm\\Phi Φ流明 Lumen ( l m = c d ⋅ s r \\mathrmlm=cd\\cdot sr lm=cdsr)单位时间内由光源所发出或由被照物所吸收的总光能
发光强度、光度 Luminous Intensity I \\mathrmI I坎德拉 Candela ( c d = l m / s r \\mathrmcd=lm/sr cd=lm/sr)光源在给定方向上,每单位立体角内所发出的光通量
照度 Illuminance E \\mathrmE E勒克斯 Lux ( l x = l m / m 2 \\mathrmlx=lm/m^2 lx=lm/m2)物体表面每单位面积所吸收或发出可见光的光通量
亮度、辉度 Luminance L \\mathrmL L尼特、坎德拉每平米 ( n i t = c d / m 2 \\mathrmnit=cd/m^2 nit=cd/m2)单位面积光源在给定方向上,在每单位面积内所发出的总光通量

通过上表中,各种单位的定义可以确定各种类型光源的单位;

光源类型单位原因
方向光Illuminance ( l x \\mathrmlx lx)方向统一(不能使用 c d \\mathrmcd cd),且没有固定的发光物,无法统计总光能(不能使用 l m \\mathrmlm lm)
点光源Luminous power ( l m \\mathrmlm lm)有固定发光物,可以统计总光能
聚光灯Luminous power ( l m \\mathrmlm lm)原因同上
IBL基于图像的光源Luminance ( c d / m 2 \\mathrmcd/m^2 cd/m2)对于引擎捕获光探头使用亮度单位非常直观

光的使用

方向光

L o u t = f ( v , l ) E ⊥ ⟨ n ⋅ l ⟩ \\mathrmL_out=f(v,l)\\mathrmE_\\perp\\langle n\\cdot l\\rangle Lout=f(v,l)Enl
输出值的单位是亮度单位,尼特( n i t \\mathrmnit nit)。

一般用方向光模拟日光、月光,下表是实际测量晴天时的照度:

光源10:00 am12:00 pm5:30 pm
S k y ⊥ + S u n ⊥ Sky_\\perp+Sun_\\perp Sky+Sun 120 , 000 120,000 120,000 130 , 000 130,000 130,000 90 , 000 90,000 90,000
S k y ⊥ Sky_\\perp Sky 20 , 000 20,000 20,000 25 , 000 25,000 25,000 9 , 000 9,000 9,000
S u n ⊥ Sun_\\perp Sun 100 , 000 100,000 100,000 105 , 000 105,000 105,000 81 , 000 81,000 81,000

满月则近似为 1 l x 1\\mathrmlx 1lx

精确光

精确光包括点光源和聚光灯。

为了模拟平方衰减定律,其照度计算公式为:
E = I d 2 ⟨ n , l ⟩ \\mathrmE=\\cfrac\\mathrmId^2\\langle n, l\\rangle E=d2In,l
其中点光源和聚光灯的光度 I \\mathrmI I的计算方式有所区别; d d d为被照射点到光源点的距离。
此时的计算结果单位是照度( l x \\mathrmlx lx),与方向光的单位相同,为照度 l x \\mathrmlx lx(注:光度仅用于描述光源信息,所以有立体角概念,但是对于受照射物体,则只考虑接收到的光通量,所以此处的单位忽略的每立体角)。

最终计算亮度的公式则和方向光类似: L o u t = f ( v , l ) I d 2 ⟨ n , l ⟩ \\mathrmL_out=f(v,l)\\cfrac\\mathrmId^2\\langle n, l\\rangle Lout=f(v,l)d2In,l

IBL

在现实世界中,光线会从四面八方照射到物体表面,并且还有一些经过弹射后,间接照射到物体表面的光;一般情况下,渲染引擎会用立方体贴图来描述这类光,称为基于图像光照(Image Based Lighting, IBL)或间接光照(Indirect Lighting)。

整个环境光对给定物体表面点的整体贡献的光照,称为辐照度(Irradiance),用 E \\mathrmE E来表示,单位是 l x \\mathrmlx lx;而从物体表面弹射出的光称为辐亮度(Radiance),用 L o u t \\mathrmL_out Lout来表示,单位是 n i t \\mathrmnit nit。计算公式如下:
L o u t ( n , v ) = ∫ Ω f ( l , v , Θ ) L ⊥ ( l ) ⟨ n , l ⟩ d l \\mathrmL_out(n,v)=\\int_\\Omegaf(l,v,\\Theta)\\mathrmL_\\perp(l)\\langle n,l\\rangle dl Lout(n,v)=Ωf(l,v,Θ)L(l)n,ldl

其中,IBL所使用的物理单位是 n i t \\mathrmnit nit,即 c d / m 2 \\mathrmcd/m^2 cd/m2
对于HDR图像,情况会有些复杂。相机不能记录辐亮度,但是可以记录依赖于设备的,仅和场景辐亮度想过的值,所以需要提供一个乘数用于重建原本的绝对辐亮度。


相机

使用基于物理相机来对场景输出亮度正确的曝光,是图像处理的第一步。
光照管线输出的结果,到达相机时,使用亮度(Luminace)表示,单位是 c d / m 2 \\mathrmcd/m^2 cd/m2。场景亮度值会有一个极大的范围,比如星空的亮度近似为 1 0 − 5 c d / m 2 10^-5\\mathrmcd/m^2 105cd/m2;而太阳能够达到 1 0 9 c d / m 2 10^9\\mathrmcd/m^2 109cd/m2。所以需要对其进行重映射。

为了最大化的利用相机记录范围,将光集中到“中灰”附近;可通过手动或自动地改变三个参数来实现:光圈、快门速度、感光度。

  • 感光度

ISO感光度表示了胶片的感光速度,即银元素与光线的光化学反应速度;数码相机套用了这个感光度标准,代表了感光元器件的感光速度。感光度每提高一倍,感光速度也相应提高一倍。
低ISO值适合清晰、柔和的图片;而高的ISO值,则可以补偿灯光不足的场景。
感光度用 S \\mathrmS S表示。

  • 光圈

光圈决定了同一时间通过的光线多少,用 N \\mathrmN N来标记,以f-stop单位表示。越高的值表示光圈越小,而越低的值则表示更大的光圈,例如 f / 16 f/16 f/16 f / 1.4 f/1.4 f/1.4

  • 快门速度

快门速度控制光圈快门开启持续的时间。

曝光度

曝光度是通过以2为底的对数表示的:
E V = log ⁡ 2 ( N 2 t ) EV=\\log_2(\\cfracN^2t) EV=log2(tN2)
1 E V 1 EV 1EV的差异表示1 stop, + 1 E V +1EV +1EV表示亮度翻倍,相应的 − 1 E V -1EV 1EV则表示亮度减半。
业界惯例是使用感光度为100ISO的基础上进行度量,以100ISO为基准的曝光度可以记为 E V 100 EV_100 EV100。在改变感光度的情况下,可以得到以下公式:
E V S = E V 100 − log ⁡ 2 ( S 100 ) EV_S=EV_100 -\\log_2(\\cfracS100) EVS=EV100log2(100S)
可转换为:
E V 100 = E V S − log ⁡ 2 ( S 100 ) = log ⁡ 2 ( N 2 t ) − log ⁡ 2 ( S 100 ) EV_100=EV_S-\\log_2(\\cfracS100)=\\log_2(\\cfracN^2t)-\\log_2(\\cfracS100) EV100=EVS以上是关于从零开始的跨平台渲染引擎(番外一)——光和相机的主要内容,如果未能解决你的问题,请参考以下文章

从零开始的跨平台渲染引擎(番外一)——光和相机

从零开始学深度学习编译器番外一,Data Flow和Control Flow

从零开始的跨平台渲染引擎——OpenGL基础环境搭建

从零开始的跨平台渲染引擎——OpenGL基础环境搭建

从零开始的跨平台渲染引擎——OpenGL基础环境搭建

从零开始的跨平台渲染引擎(零)——基础架构分析与设计