常用光照类型基本概念工作原理及其计算公式
在三维场景中,原理上物体的渲染效果取决于光照与物体表面的相互作用,对于渲染程序而言,可以通过把一些数学公式应用于像素着色来实现,从而模拟出真实生活中的各种材质效果。比如金属、玻璃、木质或石刻效果等。
本文做如下假定:
我们讨论的是基于像素着色(per-pixel basis),每个pixel有它自己的位置向量,法线向量以及表面颜色(Surface color,在这里可以是来自纹理的颜色,也可以是RGB颜色(flat color));
表面颜色(Surface color)通常是由R,G,B三部分组成,在这个教程中,我们把它当作一个向量看待;
输入表面颜色(光照处理前的表面颜色,这里的“输入”可以理解为函数的输入参数的“输入”)只是普通的颜色(单纯的纹理颜色或者RGB颜色),而输出表面颜色(光照处理后的表面颜色)是光照作用于表面的合成颜色,如可以是有阴影,高光等效果的颜色。
这个教程中假设每个场景中只有一个灯光。对于多灯光的场合,对每一个灯光循环进行这些运算(环境光除外)。
Ambient Lighting 环境光
在真实生活里,有光源的房子里的物体不会是全黑的,即使这个表面是背对光源的,这是因为有环境光(可看作是光线在环境中经过充分传播后所形成的一种无方向的全局均匀光照)。我们认为场景中的物体,不论它在什么位置,总会受到一定数量的环境光照射。环境光照算法如下:
输入 | 输出 |
Col – 物体原表面颜色 AmbAmount – 场景中环境光的强弱程度 (介于0 到 1之间) | SurfaceColor – 环境光照作用之后的表面颜色 SurfaceColor = Col*AmbAmount |
环境光照效果图:
Lambert Shading 漫射光
现在我们真正开始考虑一束光照射在物体表面上的作用过程,我们使用最常见的光照算法-------漫反射光照着色(或者说郎伯特余弦定律或郎伯特着色),这个算法是将入射光与表面法线向量的点积当作漫反射光照强度因子,下面我们看看环境光照与漫射光照共同作用的算法:
输入 | 输出 |
LCol – 照射在表面上的漫射光 Pos – 表面上被照射的位置 LPos – 漫射光源的位置 N -表面上被照射的位置处的法向量 Col –物体原表面颜色 AmbAmount -场景中环境光的强弱程度 (0 to 1) | SurfaceColor -环境光照与漫射光照共同作用之后的表面颜色 VectorToLight = Normalise(LPos - Pos); DiffuseFactor = Dot(VectorToLight, Normal); //DiffuseFactor ranges from 0 to 1 //光线与表面法线夹角大于90度,想像下光线在背面射过来,正面肯定没有光照 if(DiffuseFactor < 0) then DiffuseFactor = 0; //环境光照与漫射光照共同作用 SurfaceColor = Col*AmbAmount + Col*DiffuseFactor*LCol; |
环境光与漫射光共同作用效果
Specular Highlights 镜面高光
现在我们考虑物体表面有光泽的效果,这种效果是将Phong反射模型,结合前面两个光照作用而成。这中光照效果计算需要知道观察者在场景中的位置,而先前的环境光照与漫射光照效果计算都与观察者所在位置无关的。
这种光照计算是这样的,首先我们计算入射光在表面处的反射光线,然后再将反射光线与视线(观察者的眼睛与表面观察点的连线)之间的点积值当作反射到观察者眼中的光照强度因子,因为表面上高亮的部分是反射光线反射到观察者眼睛或照相机中较多的地方,这些地方的反射光线与视线之间的夹角非常小,点积值就越大。
输入 | 输出 |
ViewPos – 观察者的位置 SpecAmount – 镜面光强弱. (from 0 to about 200) SpecCol – 镜面光颜色(通常为白色). LCol – 照射在表面上的漫射光 Pos – 表面上被照射的位置 LPos – 漫射光源的位置 N -表面上被照射的位置处的法向量 Col –物体原表面颜色 AmbAmount -场景中环境光的强弱程度 (0 to 1) | SurfaceColor -环境光照,漫射光照与镜面光共同作用之后的表面颜色 DiffuseFactor = ... //经前两个光照作用得来的颜色 DirectionToViewer = Normalise(ViewPos - Pos); VectorToLight = Normalise(LPos - Pos); //计算反射光 ReflectanceRay = 2 * Dot(N, VectorToLight) * N - VectorToLight; //计算镜面光照因子. 数学公式 SpecFac = (R dot N)^Spec SpecularFactor = Pow(Dot(ReflectanceRay, DirectionToViewer), SpecAmount); //环境光照,漫射光照与镜面光共同作用 SurfaceColor = Col*AmbFactor + Col*DiffuseFactor*LCol + SpecCol*SpecularFactor; |
环境光照,漫射光照与镜面光共同作用
[ 注意:可以在一个场景中使用多个漫射光照与镜面光作用 ]
Fresnel Term 菲涅尔准则
菲涅尔效果是根据观察者的观察表面来调整反射率来实现的。比如你从水面,油漆表面或者丝绸的正上方看,反射光泽的柔和效果基本没有,如果侧着或平着看的话,反射光泽的柔和效果就很明显,这就是菲涅尔效果。我们简单地通过点积操作计算表明法线与视线之间夹角的余弦值,再将这个值加权。对于较平滑表面,加权系数设置在1.0-5.0之间(油漆效果,丝绸等),对于比较凹凸的表面,加权系数设置为8.0或更高(水波,液体等)
输入 | 输出 |
ViewPos – 观察者的位置 FresAmount – 边缘或表面的尖锐程度. (油漆丝绸:1,液体: 2-8) FresCol - frenel 反射光 (通常使用reflection map or 类似的东西). LCol – 照射在表面上的漫射光 Pos – 表面上被照射的位置 LPos – 漫射光源的位置 N -表面上被照射的位置处的法向量 Col –物体原表面颜色 AmbAmount -场景中环境光的强弱程度 (0 to 1 | SurfaceColor -环境光照,漫射光照与镜面光,菲涅尔反射共同作用之后的表面颜色 DiffuseFactor = ... //环境光照,漫射光照作用得来的颜色 SpecularFactor = ... //镜面高光作用得来的颜色 DirectionToViewer = Normalise(ViewPos - Pos); //计算fresnel因子. 我们计算视线与表面法向量间夹角的余弦值(在[-1..1]之间),然后加一,移动到区间[0..2],然后再加权。 FresnelTerm = Pow(Dot(N, DirectionToViewer)+1, FresAmount); //确保因子的在正常范围内 if (FresnelTerm > 1) then FresnelTerm = 1; //无菲涅尔反射的场合: Ambient light, Diffuse Light and Specular Light NonReflective = Col*AmbFactor + Col*DiffuseFactor*LCol + SpecCol*SpecularFactor; Reflective = FresCol; //环境光照,漫射光照与镜面光,菲涅尔反射共同作用 SurfaceColor = NonReflective*(1-FresnelTerm) + Reflective*FresnelTerm; |
漫射无菲涅尔反射时效果
漫射有菲涅尔反射时效果
- 相关文章
CentOS6 Apache2.2多站点HTTPS配置
可以使用letsencrypt(certbot)免费证书服务。支持多系统、多站点和多目录,支持wildcard(通配符域名),90天生效,可用定时任务自动更新。需要注意一点的是apache2.4以下版本需要在默认的ssl配置中添加如下的指令:NameVirtualHost
WebAssembly工作原理和JavaScript语言性能对比分析
本文简单说明WebAssembly(简称wasm)工作原理和高性能的原由(和JavaScript相比)。不过需要提醒的是Wasm并非设计来完全替代JS,而是对JS的一个强大补充,JS中...
Web界面编程状态变化和JS开发框架(React/Angular/Ember)
UI编程中的一个关键课题就是界面组件化(可复用)以及组件状态管理。稍早一些的windows程序员可能接触过MFC,其界面编程中有一个DDX(DoDataExchange)的机制,...
CSS3弹性布局弹性流(flex-flow)属性详解和实例
弹性布局是CSS3引入的强大的布局方式,用来替代以前Web开发人员使用的一些复杂而易错hacks方法(如使用float进行类似流式布局)。其中flex-flow是flex-direction...
如何使用CSS3合成模式(blend-mode)和滤镜(filter)实现彩色蜡笔(时光机)照片特效
在之前的文章中我们已经详细讲解过CSS3滤镜(filter,也可称之为过滤器)的工作方式,本文将实现一个当下流行的时光机相片特效实例来说明其实际用途。
我们...深入理解CSS3滤镜(filter)功能和实例详解
CSS3滤镜功能源自SVG滤镜规范,SVG滤镜最早用来给矢量图添加类似PS中像素图的一些特效。
把这个滤镜功能引入到普通HTML元素中可以带来很有趣的效果(模糊、...HTML5、Hybrid APP、Native APP对比和技术选型
HTML5和Native APP都很容易理解。为了获得HTML5的移植性和移动本地应用的高性能,搞出来一些混合APP的解决方案。比如Apache的Cordova(也就是以前的PhoneGap),...
Babylon.js入门教程和开发实例
Babylon.js是一款WebGL开发框架。和Three.js类似。主要的技术区别是Three.js还试图回退兼容CSS 3D。Three.js是完全社区推动的,比Babylon.js要成熟些,而Babylon...
Three.js入门教程5 - 10个必须知道的编程技巧
作者为Google的Paul,关于如何写出好的WebGL代码的文章。和很多开发者一样,我通过实践学习,但同时我也向其他更有经验的开发者们学习。在过去的几个月中,我在c...
HTML网页布局:静态、自适应、流式、响应式
静态布局(Static Layout)即传统Web设计,对于PC设计一个Layout,在屏幕宽高有调整时,使用横向和竖向的滚动条来查阅被遮掩部分;对于移动设备,单独设计一个布...
jQuery Ribbles - 基于WebGL的水面涟漪动效插件
使用jQuery
使用纯CSS3实现一个3D旋转的书本
有一些前沿的电商网站已经开始使用3D模型来展示商品并支持在线定制,而其中图书的展示是最为简单的一种,无需复杂的建模过程,使用图片和CSS3的一些变换即可实现...
如何使用CSS3实现书页(书本)卷角效果
我们有时候想在页面显示一个公告或用户提示信息。一个常用设计是使用书签形状。我们可以给书签添加卷角效果,以使其更为逼真。所谓的“卷角”实际上可以用小角度...
更多...