渲染管线中光照的计算

文章目录

  • 渲染管线中光照的计算
    • 前言
    • 法向量
    • 朗伯余弦定律
    • 漫反射
    • 环境光照
    • 镜面光照
      • 菲涅尔效应
    • 表面粗糙度
    • 光照模型
    • 平行光源
    • 点光源
      • 衰减
    • 聚光灯

渲染管线中光照的计算

前言

首先我们来看一下同一个模型在有光与无光下的区别:

无光:
在这里插入图片描述
有光
在这里插入图片描述
很明显的感知就是无光下渲染的模型,给人的感受是扁平化,不像一个模型,但是在经过光照渲染之后,就可以感受出立体效果。光照下的模型经过光照(lighting)与阴影(shading)的叠加,给我们展现出了很好的立体效果。而我们所看到的颜色,是依靠模型的材质呈现的。

看下图,在同一个平行光源(后面会讲解)下,同一个物体,不同材质下所呈现的结果不同,材质呢,有粗糙度,如石头,与瓷砖,当然还有金属度、折射率、透明度等。A球就是带透明的,因此,他在光照的影响下产生了折射,所以我们能看见它背后的物体,而B球则不能。人眼看见光的原因是因为光照射到物体上时候,一部分会被吸收,一部分会被反射,反射的光进入人眼,光受体感受到刺激,将信号传入大脑,也就是我们所能看到颜色的原因。
在这里插入图片描述

法向量

法向量是指垂直于给定曲面、曲线或几何体的向量(对于曲面就是垂直于切线空间)。下图就是相对于A点的法向量
在这里插入图片描述

朗伯余弦定律

光可以看作是光子的集合,在空间中按特定的方向传播。每个光子都载有(光)能量。光源每
秒发出的(光)能量称为辐射通量(radiant flux)。而单位面积上的辐射通量密度(irradiance,称为辐(射)
照度)。我们将辐射通量用来确定表面某区域所接收到的光量(即眼晴感受到的明亮度)。

一个面元的辐亮度或光亮度在其表面上半球的所有方向相等时,则有 E θ = E n c o s θ = E n ( n ⋅ L ) E_θ=E_ncosθ = E_n(n·L) Eθ=Encosθ=En(nL)
式中, E θ E_θ Eθ E n E_n En分别表示面元在 θ 角(与表面法线夹角)方向及其法线方向的辐射强度或光强度, n n n是法向量, L L L光向量
(可以理解越接近于垂直照射的光,能量越强)
考虑到 ( n ⋅ L ) = c o s θ (n·L) =cosθ (nL)=cosθ 这值是有可能小于0的,因此,给它限定了一下范围
f ( θ ) = m a x ( c o s θ , 0 ) = m a x ( n ⋅ L , 0 ) ( 也就是要求它大于等于 0 ) f(θ) = max(cosθ,0)=max(n·L,0) (也就是要求它大于等于0) f(θ)=max(cosθ,0)=max(nL,0)(也就是要求它大于等于0)
这部分建议大家参考百度文库的资料

漫反射

当光照射到物体表面上某个点时候,一部分会被吸收,一部分会被四处反弹。(因为看似是平面的物体,其实放大之后,是凹凸不平的)
在这里插入图片描述
假设一点的有80%白光的入射光量,而这点的漫反射率是50%的红光,100%的绿光,75%的蓝光,则入射光量值 B L = ( 0.8 , 0.8 , 0.8 ) B_L=(0.8,0.8,0.8) BL=(0.8,0.8,0.8),漫反射率为 m d = ( 0.5 , 1.0 , 0.75 ) m_d=(0.5,1.0,0.75) md=(0.5,1.0,0.75)则这个点的反射光量是:
c d = B L ⊙ m d = ( 0.8 , 0.8 , 0.8 ) ⊙ ( 0.5 , 1.0 , 0.75 ) = ( 0.4 , 0.8 , 0.6 ) ( ⊙ 对应元素相乘 ) c_d =B_L⊙\\ m_d = (0.8,0.8,0.8)⊙(0.5,1.0,0.75)\\ = (0.4,0.8,0.6)\\ \quad\\ (⊙对应元素相乘) cd=BLmd=(0.8,0.8,0.8)(0.5,1.0,0.75)=(0.4,0.8,0.6)(对应元素相乘)
根据朗伯余弦定律就有了:
c d = m a x ( L ⋅ n , 0 ) ⋅ ( B L ⊙ m d ) c_d =max(L·n,0) ·(B_L⊙m_d) cd=max(Ln0)(BLmd)

环境光照

我们不仅要考虑光源的影响,还需要考虑间接光照的影响,比如,太阳光照射到水面,然后水面反射到镜子里,镜子再反射到某个物体上,其实真实世界中,间接光照是很多的,就比如。下方是环境光照的方程:
c a = A L ⊙ m d c_a =A_L⊙m_d ca=ALmd
A L A_L AL指定了表面接收到的间接光量(环境光量), m a m_a ma依旧是漫反射率。对于环境光照的计算,是在当前的光照模型中,都按照统一的环境光照计算,并没有进行真实的物理世界的模拟,光照计算,是耗性能的过程。

镜面光照

镜面反射是指光线在平滑表面上的反射,使得反射光线与入射光线在同一平面内,并且入射角等于反射角。
镜面反射通常发生在光线从一个介质进入另一个折射率较小(折射率指介质对光的折射程度)的介质时,比如从空气进入玻璃或水中时。
在这里插入图片描述

菲涅尔效应

菲涅尔效应描述了光线从一个介质进入另一个介质时,由于折射率的不同而产生的反射现象。
菲涅尔效应的主要表现是入射光线部分反射和部分折射,即一部分光线通过介质界面进入另一个介质,另一部分光线则反射回原介质。

下图一个由近到远的过程,可以看到近处的石头清晰,远处的石头看不清,因为在远处的石头,几乎不发生折射。
在这里插入图片描述

菲涅尔效应的强度取决于入射角、介质的折射率差异以及极化状态等因素。

由于光照过程的复杂性,我们一般不会将完整的菲涅耳方程用于实时渲染,而是采用石里克近似
Schlick approximation)法
来代替:
R F ( θ i ) = R F ( 0 ○ ) + ( 1 − R F ( 0 ○ ) ) ( 1 − c o s θ i ) 5 R_F(θ_i) = R_F(0^○) +(1-R_F(0^○))(1-cosθ_i)^5 RF(θi)=RF(0)+1RF(0)(1cosθi)5
R F R_F RF是反射光量, 1 − R F ( 0 ○ ) 1-R_F(0^○) 1RF(0)是折射光量, R F R_F RF的值是一个RGB的向量,即颜色反应了反射光量。
下面是场景的一些材质对应的属性值:

介质 R F ( 0 ○ ) R_F(0^○) RF(0)
(0.02,0.02,0.02)
玻璃(0.08,0.08,0.08)
塑料(0.05,0.05,0.05)
(1.0,0.71,0.29)
(0.95,0.93,0.88)
(0.95,0.64,0.54)

表面粗糙度

真实世界的反射物体表面不是理想镜面,而是在微观下具有一定的粗糙度。理想转态下的镜面粗糙度是0,它的宏观与微观的法向方向是相同的,但是真实世界下不是。
在这里插入图片描述
我们定义归一化分布函数 ρ ( θ h ) ∈ [ 0 , 1 ] \rho(θ_h)∈[0,1] ρ(θh)[01],用来表示微观表面法线h与宏观表面法线n之间夹角为 θ h θ_h θh
函数公式:
ρ ( θ h ) = c o s m ( θ h ) = c o s m ( n ⋅ h ) \rho(θ_h)=cos^m(θ_h)=cos^m(n·h) ρ(θh)=cosm(θh)=cosm(nh)

在这里插入图片描述
我们将 ρ ( θ h ) \rho(θ_h) ρ(θh)与某种归一化因子进行融合,从而获得基于粗糙度来模拟镜面反射光量的新函数:
S ( θ h ) = m + 8 8 c o s m ( θ h ) = m + 8 8 ( n ⋅ h ) m S(θ_h) = \frac{ m+8}{8}cos^m(θ_h) \\ = \frac{ m+8}{8}(n·h)^m S(θh)=8m+8cosm(θh)=8m+8(nh)m
经过菲涅尔效应计算,镜面反射进入观察者眼的光量为:

C s = m a x ( L ⋅ n , 0 ) ⋅ B L ⊙ R F ( a h ) m + 8 8 ( n ⋅ h ) m C_s=max(L·n,0)·B_L⊙R_F(a_h)\frac{ m+8}{8}(n·h)^m Cs=max(Ln,0)BLRF(ah)8m+8(nh)m
可以发现,如果 L ⋅ n ⩽ 0 L·n\leqslant0 Ln0那么所计算的结果是射向表面另一侧的光,因此此时正表面不会接收到任何光照。
在这里插入图片描述

光照模型

光照模型,是根据光学的有关定律,模拟自然界中光照明的物理过程的计算机模型。
我们所看到的光照,就是各种光的叠加,比如环境光,漫反射光、镜面反射光的叠加,在数学公式上,就这些公式的加法运算。
C o l o r = c a + c d + c s = A L ⊙ m d + m a x ( L ⋅ n , 0 ) ⋅ ( B L ⊙ m d ) + m a x ( L ⋅ n , 0 ) ⋅ B L ⊙ R F m + 8 8 ( n ⋅ h ) m = A L ⊙ m d + m a x ( L ⋅ n , 0 ) ⋅ B L ⊙ ( m d + R F ( a h ) m + 8 8 ( n ⋅ h ) m Color = c_a+c_d + c_s\\ = A_L⊙m_d +max(L·n,0) ·(B_L⊙m_d) + max(L·n,0)·B_L⊙R_F\frac{ m+8}{8}(n·h)^m \\ = A_L⊙m_d +max(L·n,0) ·B_L⊙(m_d +R_F(a_h)\frac{ m+8}{8}(n·h)^m Color=ca+cd+cs=ALmd+max(Ln0)(BLmd)+max(Ln,0)BLRF8m+8(nh)m=ALmd+max(Ln0)BL(md+RF(ah)8m+8(nh)m
L L L:指同光源的光同量。
n n n:表面法线。
h h h:列于光向量与观察向量(由表面点指向观察点的单位向量)之间的中间向量。
A L A_L AL:表示入射的环境光量。
B L B_L BL:表示入射的直射光量。
m d m_d md:指示根据表面漫反射率而反射的入射光量。
L ⋅ n L·n Ln:朗伯余弦定律。
a h a_h ah:中间向量 h h h与光向量 L L L之间的夹角。
R F ( a h ) R_F(a_h) RF(ah):根据菲涅耳效应,关于中间向量 h h h所反射到观察者眼中的光量。
m:控制表面的粗糙度。
( n ⋅ h ) m (n·h)^m (nh)m:指定法线h与宏观表面法线n之间夹角为B,的所有微平面片段。
\frac{ m+8}{8}:在镜面反射过程中,为模拟能量守恒所采用的归一化因子。

平行光源

平行光源(parallel light)也称方向光源(directional light,也译作定向光源),是一种距离目标物体
极远的光源(每个入射角与照射位置行成的夹角值近似)。因此,我们就可以将这种光源发出的所有入射光看作是彼此平行的光线。(如下图)
在这里插入图片描述

点光源

类似于一个灯泡,向四面八方照射。对于任意一点 P P P,光源 Q Q Q所发出的光源总有一束会经过词典,我们定义光向量与传播方向相反,即光向量的方向是由 P P P指向 Q Q Q
L = Q − P ∣ ∣ Q − P ∣ ∣ L=\frac{Q-P}{||Q-P||} L=∣∣QP∣∣QP
在这里插入图片描述

衰减

光强会随着距离的反比例平方而发生衰减,计算公式如下:
I ( d ) = I 0 d 2 I(d)= \frac{I_0}{d^{2}} I(d)=d2I0
I 0 I_0 I0为距离光源d=1处的光强

聚光灯

在这里插入图片描述
聚光灯在大于max angle的时候,点就不在灯的照射范围内了

与点光源计算一致,它的光向量:
L = Q − P ∣ ∣ Q − P ∣ ∣ L=\frac{Q-P}{||Q-P||} L=∣∣QP∣∣QP
聚光灯范围内的所有光线强度也不尽相同,位于Light到Center上的是最强的,也就是最中心的线,其他向量会随着距离中心线的角度变大而变小,而随着角度增加至max angle,光强将逐渐趋近于0。
具体计算与之前类似, k s p o t k_{spot} kspot表示聚光灯因子
k s p o t ( θ ) = m a x ( c o s θ , 0 ) x = m a x ( − L ⋅ d , 0 ) k_{spot}(\theta)=max(cos\theta,0)^x =max(-L·d,0) kspot(θ)=max(cosθ,0)x=max(Ld,0)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/9230.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

加速科技突破2.7G高速数据接口测试技术

随着显示面板分辨率的不断提升,显示驱动芯片(DDIC)的数据接口传输速率越来越高,MIPI、LVDS/mLVDS、HDMI等高速数据接口在DDIC上广泛应用。为满足高速数据接口的ATE测试需求,作为国内少数拥有完全自研的LCD Driver测试解…

【Web前端】定位_浮动_音视频

1、定位 1.1想对定位 相对定位,使用relative,参考点是标签之前的位置,不是相对于父节点、同级节点或浏览器。相对定位通过left、right进行水平偏移,通过top、bottom进行垂直偏移Ieft:表示相对于原本位置的左外边界右移的距离rig…

WebSocket 来单提醒和客户催单功能

一:WebSocket : WebSocket 是基于 TCP 的一种新的网络协议。它实现了浏览器与服务器全双工通信——浏览器和服务器只需要完成一次握手,两者之间就可以创建持久性的连接, 并进行双向数据传输。 HTTP协议和WebSocket协议对比&#…

算法提高之迷宫问题

算法提高之迷宫问题 核心思想&#xff1a;最短路问题 从(n-1,n-1)开始bfs 往前走一个就存入pre数组 之后再遍历pre数组输出 #include <iostream>#include <cstring>#include <algorithm>using namespace std;const int N 1010,M N*N;#define x first#def…

vue 代码样式问题

部分电脑存在样式错乱问题&#xff0c;部分电脑样式正常。最后发现是样式写在 el-col 里面导致的。 注意&#xff1a;写样式不要放在 el-row 或者 el-row &#xff0c;导致部分电脑会出现莫名其妙的样式问题 <el-row class"detail"><el-col class"it…

OSPF NSSA区域

原理概述 OSPF 协议定义了 Stub 区域和 Totally Stub 区域这两种特殊的非骨干区域&#xff0c;为的是精简 LSDB 中 LSA 的数量&#xff0c;同时也精简路由表中的路由条目数量&#xff0c;实现优化设备和网络性能的目的。根据定义&#xff0c; Stub 区域或 Totally Stub 区域中是…

Springboot项目使用redis实现session共享

1.安装redis&#xff0c;并配置密码 这里就不针对于redis的安装约配置进行说明了&#xff0c;直接在项目中使用。 redis在windows环境下安装&#xff1a;Window下Redis的安装和部署详细图文教程&#xff08;Redis的安装和可视化工具的使用&#xff09;_redis安装-CSDN博客 2…

PHP+MySQL组合开发 自定义商城系统源码 带完整的安装代码包以及安装部署教程

随着电子商务的蓬勃发展&#xff0c;越来越多的企业和个人希望拥有自己的在线商城系统。小编给大家分享一款基于PHP和MySQL技术栈&#xff0c;开发的一套自定义商城系统源码。该系统旨在帮助用户快速搭建稳定、高效的电子商务平台&#xff0c;并提供灵活的自定义功能&#xff0…

笨蛋学C++ 之 CMake的使用

笨蛋学C 之 CMake的使用 CMake生成可执行程序的流程CMake命令执行流程安装CMakelinux执行cpp文件运行删除 基本语法cmake命令构成运行.cmake文件&#xff0c;在CMake中如何打印信息变量操作set、listsetlist 流程控制条件流程控制循环流程控制forwhile 函数作用域全局作用域局部…

解读Inscode AI:开启代码智能化的新时代

导语&#xff1a; 近年来&#xff0c;人工智能技术的迅猛发展已经深刻地影响着各个行业&#xff0c;而在软件开发领域&#xff0c;Inscode AI的出现无疑将给代码智能化带来一场革命。本文将为大家解读Inscode AI的特点和应用&#xff0c;探索其如何改变我们的软件开发方式。 一…

java设计模式八 享元

享元模式&#xff08;Flyweight Pattern&#xff09;是一种结构型设计模式&#xff0c;它通过共享技术有效地支持大量细粒度的对象。这种模式通过存储对象的外部状态在外部&#xff0c;而将不经常变化的内部状态&#xff08;称为享元&#xff09;存储在内部&#xff0c;以此来减…

ORA-02020:过多的数据库链接在使用

一、问题描述 今天同事说&#xff0c;有一个查询功能&#xff0c;同时查了几个子平台的dblink&#xff0c;页面返回报错。 提示ORA-02020&#xff1a;过多的数据库链接在使用&#xff1b; bad SQL grammar 二、解决办法 1&#xff09;分析业务需求 分析业务场景 &#xff0c;发…

美食推荐网站设计

**中文摘要&#xff1a;**在当今信息化、网络化的时代背景下&#xff0c;美食文化正逐渐融入人们的日常生活&#xff0c;而网络平台成为人们获取美食信息、分享美食体验的重要途径。为了满足广大美食爱好者对美食信息的探索和推荐需求&#xff0c;本文提出了一种创新的美食推荐…

谷歌开源!用 js 编写 Shell 脚本! | 开源日报 No.247

google/zx Stars: 41.4k License: Apache-2.0 zx 是一个用于编写更好脚本的工具。 提供有用的包装器&#xff0c;简化了对 child_process 的操作转义参数并提供合理的默认值使用 JavaScript 编写复杂脚本时比 Bash 更方便可以直接使用 npm 安装 dani-garcia/vaultwarden St…

Nest 快速上手 —— (三)中间件 / 异常过滤器

一、 中间件&#xff08;Middleware&#xff09; 1.特点 中间件是一个在路由处理程序之前被调用的函数。中间件函数可以访问请求和响应对象&#xff0c;以及应用程序请求-响应周期中的next()中间件函数。下一个中间件函数通常由一个名为next的变量表示。 中间件函数可以执行以…

5.9gunplot绘图堆叠柱状图

gunplot绘图堆叠柱状图 plot"要用的数据&#xff08;后缀名是.dat)" using 2 t(或者title) 跟着是要命名的属性名称 这个名称可以用.dat里的每列列名&#xff0c;也可以直接在后面跟着定义 plot "data.dat" using 2 t columnheader(2), using 3 t column…

PyQt5 解决界面无响应方案

文章目录 前言版本案例解决方案QThreadQTimer 局部变量创建异步线程导致 UI 未响应如果 QTimer 不使用 self.time 写法 个人简介 前言 在PyQt5中&#xff0c;GUI线程通常指的是Qt的主事件循环线程&#xff0c;也称为主线程。主线程负责处理GUI事件、更新UI界面等任务。在PyQt5…

vue的组件库

作为一个Vue.js开发者&#xff0c;使用组件库是提高效率和代码重用的关键。Vue的组件库为开发者提供了一系列预先构建好的组件&#xff0c;可以在项目中直接引用和定制。以下是一些关于Vue组件库的知识点和用法&#xff1a; 常见的Vue组件库&#xff1a; Element UI&#xff…

如何通过OMS加快大表迁移至OceanBase

OMS&#xff0c;是OceanBase官方推出的数据迁移工具&#xff0c;能够满足众多数据迁移场景的需求&#xff0c;现已成为众多用户进行数据迁移同步的重要工具。OMS不仅支持多种数据源&#xff0c;还具备全量迁移、增量同步、数据校验等功能&#xff0c;并能够对分表进行聚合操作&…

系统运维(虚拟化)

1.VLAN VLAN&#xff08;Virtual Local Area Network&#xff09;即虚拟局域网&#xff0c;是将一个物理的LAN在逻辑上划分成多个广播域的通信技术。 每个VLAN是一个广播域&#xff0c;VLAN内的主机间可以直接通信&#xff0c;而VLAN间则不能直接互通。这样&#xff0c;广播报…