这个教程用到了向量数学知识,如果你对向量数学还不是很了解,请先阅读向量教程:read the tutorial。
光照与物体表面的相互作用可以通过将一些数学公式应用于基于per pixel(区别于基于顶点)的着色,从而模拟出真实生活中的各种材质效果。比如浮雕效果,波浪效果,油漆效果等。
在这个教程中,我们有如下假定:
第一,我们讨论的是基于像素着色(per-pixel basis),每个pixel有它自己的位置向量,法线向量以及表面颜色(Surface color,在这里可以是来自纹理的颜色,也可以是RGB颜色(flat color));
第二,表面颜色(Surface color)通常是由R,G,B三部分组成,在这个教程中,我们把它当作一个向量看待;
第三,输入表面颜色(光照处理前的表面颜色,这里的“输入”可以理解为函数的输入参数的“输入”)只是普通的颜色(单纯的纹理颜色或者RGB颜色),而输出表面颜色(光照处理后的表面颜色)是光照作用于表面的合成颜色,如可以是有阴影,高光等效果的颜色。
第四,这个教程中假设每个场景中只有一个灯光。对于多灯光的场合,对每一个灯光循环进行这些运算(环境光除外)。
好了,让我们开始讲解各种光照的算法原理
Ambient Lighting 环境光
在真实生活里,有光线的房子里的物体不会是全黑的,总有一些光量子照亮物体表面,即使这个表面是背对光源的,这就是环境光的原因。我们不考虑环境光的照射方向,我们总认为场景中的物体,不论它在什么位置,总会受到一定数量的环境光照射(全局照明)。环境光照算法如下:
Inputs:
Col – 物体原表面颜色
AmbAmount – 场景中环境光的强弱程度 (介于0 到 1之间)
Outputs:
SurfaceColor – 环境光照作用之后的表面颜色
SurfaceColor = Col*AmbAmount;
环境光照效果图:
Lambert Shading (郎伯特着色,郎伯特:物理上的亮度单位,在这里就是漫射光作用)
现在我们真正开始考虑一束光照射在物体表面上的作用过程,我们使用最常见的光照算法-------漫反射光照着色或者说郎伯特余弦定律或郎伯特着色(三个都一回事),这个算法是将入射光与表面法线向量的点积当作漫反射光照强度因子,下面我们看看环境光照与漫射光照共同作用的算法:
Inputs:
LCol – 照射在表面上的漫射光
Pos – 表面上被照射的位置
LPos – 漫射光源的位置
N -表面上被照射的位置处的法向量
Col –物体原表面颜色
AmbAmount -场景中环境光的强弱程度 (0 to 1)
Outputs:
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反射模型,结合前面两个光照作用而成。这中光照效果计算需要知道观察者在场景中的位置,而先前的环境光照与漫射光照效果计算都与观察者所在位置无关的。
这种光照计算是这样的,首先我们计算入射光在表面处的反射光线,然后再将反射光线与视线(观察者的眼睛与表面观察点的连线)之间的点积值当作反射到观察者眼中的光照强度因子,因为表面上高亮的部分是反射光线反射到观察者眼睛或照相机中较多的地方,这些地方的反射光线与视线之间的夹角非常小,点积值就越大。
Inputs:
ViewPos – 观察者的位置
SpecAmount – 镜面光强弱. (from 0 to about 200)
SpecCol – 镜面光颜色(通常为白色).
LCol – 照射在表面上的漫射光
Pos – 表面上被照射的位置
LPos – 漫射光源的位置
N -表面上被照射的位置处的法向量
Col –物体原表面颜色
AmbAmount -场景中环境光的强弱程度 (0 to 1)
Outputs:
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;
环境光照,漫射光照与镜面光共同作用
Note:可以在一个场景中使用多个漫射光照与镜面光作用
Fresnel Term 菲涅尔准则
菲涅尔效果是根据观察者的观察表面来调整反射率来实现的。比如你从水面,油漆表面或者丝绸的正上方看,反射光泽的柔和效果基本没有,如果侧着或平着看的话,反射光泽的柔和效果就很明显,这就是菲涅尔效果。我们简单地通过点积操作计算表明法线与视线之间夹角的余弦值,再将这个值加权。对于较平滑表面,加权系数设置在1.0-5.0之间(油漆效果,丝绸等),对于比较凹凸的表面,加权系数设置为8.0或更高(水波,液体等)
Inputs:
ViewPos – 观察者的位置
FresAmount – 边缘或表面的尖锐程度. (油漆丝绸:1,液体: 2-8)
FresCol - frenel 反射光 (通常使用reflection map or 类似的东西).
LCol – 照射在表面上的漫射光
Pos – 表面上被照射的位置
LPos – 漫射光源的位置
N -表面上被照射的位置处的法向量
Col –物体原表面颜色
AmbAmount -场景中环境光的强弱程度 (0 to 1)
Outputs:
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;
漫射无菲涅尔反射时效果 漫射有菲涅尔反射时效果
分享到:
相关推荐
非结构化网格的数据体光照计算是渲染这些复杂模型时的关键步骤,它涉及到对网格中的每个像素或样本点进行光照效果的精确计算。本文将探讨基于GPU(图形处理器)的非结构化网格数据体光照计算及其实现方法。 GPU,...
本资料提供的是关于点云法向量计算原理以及MATLAB实现的源码,对于学习和研究点云处理技术非常有帮助。 首先,我们需要了解什么是点云。点云是由一组三维坐标点构成的数据集,这些点在空间中分布,共同描述了一个...
HLSL是一种专门用于DirectX图形API的着色语言,它允许程序员在GPU上编写计算密集型代码,如光照计算,从而提高渲染性能。与传统的固定功能管线相比,使用HLSL的可编程管线提供了更大的灵活性和控制力。 1. **每顶点...
当所有几何信息存储完毕后,再根据G-Buffer的内容进行光照计算,一次性处理所有光源对每个像素的影响。 优点: - 高效处理大量光源:延迟渲染可以轻松应对成百上千的动态光源,因为光照计算是在像素级别上进行的。 ...
通过这个实验,你不仅能掌握光照传感器的工作原理和使用方法,还能深入理解Zigbee无线通信技术在传感器网络中的实际应用。这不仅是一项基础技能,也为未来在物联网(IoT)领域的发展打下坚实的基础。
微机原理与接口技术是计算机科学中的重要领域,它涉及到如何利用计算机系统处理各种外部设备的数据和控制。在这个课程设计中,我们面临的是一个光照强度测量仪的开发任务,这将涉及模拟信号到数字信号的转换,以及...
通过数学建模,不仅可以理解光照强度的计算原理,还可以为实际问题提供解决方案,如改善教室的照明环境,提高学生的舒适度。这个模型的建立和求解过程涉及到线性代数、微积分、优化理论等多个数学分支,充分体现了...
在OpenGL中,光照计算涉及以下步骤: 1. **漫反射**(Diffuse Reflection):这是最常见的一种反射类型,光线均匀地从物体表面散射。OpenGL使用`glLightModel`和`glMaterial`函数来设置漫反射颜色和系数。 2. **...
在OpenGL中,我们可以使用glLight和glMaterial函数来设置光源和物体材质,然后通过glEnable(GL_LIGHTING)启用光照计算。 为了构建3D模型,我们需要使用OpenGL的几何构造函数,如glBegin和glEnd,定义物体的基本形状...
本文将深入探讨Phong光照模型的核心原理、实现步骤以及如何在VC++中调整光强和光源位置。 Phong光照模型由Bui Tuong Phong在1975年提出,它包括了三个主要组成部分:环境光(Ambient Light)、漫反射光(Diffuse ...
4. **光照计算**:对于侧面光,我们需要计算入射光(光线与表面法线之间的角度)和观察者视角(表面点到观察者之间的角度)。这些角度用于计算漫射光照(基于入射角的余弦值)和可能的镜面高光(如果圆柱体具有镜面...
在这个实验中,CC2530可以用来读取光敏电阻的输出电压,然后根据电压变化计算出对应的光照度值,并通过无线网络将数据发送至中央数据收集点或者云端服务器。 实验步骤可能包括以下部分: 1. 连接光敏电阻:将光敏...
光照计算涉及到漫反射、镜面反射和环境光等几个方面,这些因素决定了物体表面颜色的最终呈现。 在描述中提到的“两个物体”,可能是指两个不同的3D模型,如立方体或者球体。每个物体的表面由多个多边形组成,每个...
冯氏光照模型是由物理学家彼特·冯(Peter Phong)提出的一种光照计算模型,它在OpenGL中被广泛应用来模拟现实世界中的光照效果,为3D物体赋予真实感。 冯氏光照模型主要包括三个主要部分:环境光、漫反射光和镜面...
使用`glEnable(GL_LIGHT0)`开启第一个光源,同时开启`GL_LIGHTING`来激活光照计算。 4. **模型视图和投影矩阵**: 光照效果的计算需要在正确的坐标系统下进行。因此,正确设置模型视图矩阵和投影矩阵是至关重要的...
6. **光照计算**:在OpenGL中,光照计算通常在顶点着色器和片段着色器中进行。顶点着色器处理每个顶点的光照,片段着色器则处理像素级别的光照,确保平滑过渡。 7. **光源位置和方向**:光源可以放置在场景中的任何...
平滑着色通过在每个像素上进行光照计算,生成更平滑的过渡效果,而平面着色则是在每个顶点处计算一次光照,然后将结果扩展到整个面片。在3D图形中,平滑着色通常能提供更高质量的视觉效果,尤其是在处理曲面时。 在...
法线向量决定了光线与表面的相对角度,进而影响光照计算。在OpenGL中,可以使用glNormal3f函数指定法线向量。 总结来说,本项目旨在通过OpenGL实现Bezier曲面的创建,并结合纹理和光照模型,为曲面添加丰富的视觉...
计算机图形学是信息技术领域的一个重要分支,主要研究如何在...实践中,你可能会遇到的问题包括光照计算的优化、阴影的软化、抗锯齿处理以及实时渲染中的性能瓶颈等,这些都是进一步提升图形质量需要考虑的技术点。
8. **着色器语言GLSL**:现代OpenGL使用GLSL(OpenGL Shading Language)编写更复杂的着色器,可以在GPU上进行更多的计算,包括光照计算。虽然这个例子可能不涉及GLSL,但了解其基本概念对深入学习OpenGL是必要的。 ...