在说光照之前,有必要先弄清法线的变换,假设Mworld 将物体的定点一一变换到世界空间,如果我们对法线实施同样的变化,,以为能将法线变换到世界空间,但世界上变换之后的法线不再与表面垂直,就像下图:

    

    这意味着变换并不维持正交的性质,当然,不是所有的矩阵都会出现这种情况,只有当转换操作中包含非均匀缩放操作(XYZ各个方向缩放量不一样)时,这时候就不会再正交,这也意味着大部分的平移操作,旋转操作,均匀缩放操作或者上述组合都是能直接变换得,如何推导这个矩阵,方法有很多,(数学家们并未找出一个非常优雅的证明,我就从书上挪用下好了)

    显然,变换之前 : (V1 – V0)*n = 0;我们将其n转置,写成矩阵乘法((V1 – V0)*
nT = 0;),就是一个 1 * 2的矩阵 乘上一个 2*1的矩阵 ,为了简单起见,将V1 – V0 记做U,那么就是U* nT = 0

    好了,开始推导,其实我们事先可以知道要求的目标矩阵是(Mworld )-1 T

我们要找一个矩阵B 能使 (U* Mworld) * ( n * B) = 0,即维持正交特性,简单起见,将Mworld 记做A

    首先,由于要加入A的逆,我们便可以在原式里面插入 A-1 *A ,(注意,A总是可逆的) ,这样并不影响原式A-1 *A = I ,:即式子变成这样:u(AA-1) nT = 0

    注意,矩阵满足结合律,这样我们变可以将U与A结合尽量朝目标式子靠近 ,即: (uA)(A-1 nT) = 0

    由于我们还需要一次转置,于是我们对(A-1 nT)
实施两次转置,这样并不 改变结果,于是得到下式: (uA) ((A-1 nT)T)T = 0

    我们这下消去一些T,利用 (AB)T = BT AT ,于是变成:
(uA) (n(A-1)T)T

注意这是个矩阵乘法,现在我们需要变换回来,又将其变回点积,即去掉最外面的那个T就行了:

        uA*n(A-1)T = 0

    结果已经出来了,即 B = (A-1)T

这是个证明而不是求导,希望读者注意到这一点,如何求导出来,读者自行研究吧

正题:光照

    现实中的光照何其炫丽,当然.这一切离不开物理学,首先进入Lamberat 余弦定理(定律?) 这是个很常见的现象,光照强度与法线和光照方向成的角度的余弦成正比,即:

        

    θ指的是L与N所成角度,L指光照方向,n是物体(表面)的法线方向,如果L,N都是标准化的那么 cosθ = L*n 很显然的,因为模长为1

    这个定理暂时放在这里,先简易介绍下Phong光照模型:

        事实上,光是非常复杂的,因为他具有波粒二向性,不考虑如此复杂的情况,也需要考虑对象表面处的入射辐射度已经抵达眼睛的出射辐射度,两者之间的关系可用BRDF描述,但是还是太复杂了(对于我来说).BRDF的简化版本并可通过Phong光照来模拟,实际上,实时光照效果伴随着GPU的发展已经逐渐脱离了Phong光照模型,尽管如此,从基础开始总是最好不过的了.

    Phong光照中,对象表面上一点的颜色由四项定义,即 漫反射(diffuse) ,镜面反射(specular),环境光(ambient)以及反射光.其中,漫反射和镜面反射来源于光源的光线,环境光用于模拟间接光照,发射光则是自发光对象了.接下来让我详细说之:

漫反射

    考虑一个粗糙的表面,考虑最简单的光照情况,光照强度不随距离缩减,并到达一个表面时,沿着各个方向 均匀反射,由于反射光沿所有方向均匀反射,无论从那个方向观察,表面亮度均相同,使用时,无需考虑观测者的位置,至于Lamberat定理有关联(漫反射计算是视角独立的).一般的,将漫反射拆成两部分,一部分是光源的漫反射系数,一部分是材质的漫反射系数.将光照的记成Ld,材质的记为Md,那么反射光等于:

        C = Ld * Md * f(θ) = Ld * Md * max(L.n,0)

    各个方向均匀反射,所以不用考虑视点(相机)的位置

    环境光

    考虑到某些物体并没有处于光照的直接照射下,却某些部分会被照亮,因为其他物体对光的反射,想要模仿这类反射光,环境光是个不错的选择,由于光在场景中经多次反射并从各个方向抵达表明最终点,那么在各个方向上的以都是等强度的(这并不符合物理),这意味着,该光照与法线无关,也与视见方向无关,直接可以简单的写成 Sa * Ma

    镜面光

    前面已经说过粗糙平面,如果是光滑的如同镜子了,这个时候遵循反射定理,入射光和反射光与法线所成角度相等,但是值得注意的是,反射光不一定会朝着眼睛(相机)的方向,如下图

    

    这说明计算是视角依赖的,与角度的余弦成正比(反射方向与视角方向的夹角),为了更加健康的模拟此光照,当达到一定角度时,这种光照不贡献任何强度,有个近似的模拟强度的函数,函数如下

    (r*v) sh ,r为反射方向,v为眼睛和顶点所成的方向,sh表示对象表面的光滑程度,即模拟了达到一定角度时,强度贡献的衰弱,当然,只写成这样是有问题的,因为l,n的方向所成不一定是锐角,成〉=90度时是下面这种情况,还有就是r*v 小于0也是不正确的,所以,公式

    

    这是系数,然后再乘上Ss*Ms即得出了镜面反射

    至于发射光,可简单的定义为Me

我们已经简单的讲诉了光的几种成分,但没有区别光的不同类型,比如方向光,点关,聚光灯,下节再介绍了~

Phong光照以及其他的更多相关文章

  1. Unity-Shader-镜面高光Phong&BlinnPhong-油腻的师姐在哪里

    [旧博客转移 - 2016年4月4日 13:13 ] 油腻的师姐: 以前玩过一款很火热的端游<剑灵>,剑灵刚出来的时候,某网页游戏广告视频中有句台词:"我不断的在寻找,有你的世界 ...

  2. Obj模型功能完善(物体材质,光照,法线贴图).Cg着色语言+OpenTK+F#实现.

    这篇文章给大家讲Obj模型里一些基本功能的完善,包含Cg着色语言,矩阵转换,光照,多重纹理,法线贴图的运用. 在上篇中,我们用GLSL实现了基本的phong光照,这里用Cg着色语言来实现另一钟Blin ...

  3. Voreen(三) 光线投射参数介绍

    本篇介绍光线投射的第二个个制Pass,光线合成的参数,对应于第一篇总的流程介绍中的Processor SingleVolumeRaycaster.可设置的参数如下: 1,Sampling Rate 采 ...

  4. Opentk教程系列-1绘制一个三角形

    本系列教程翻译自Neo Kabuto's Blog.已经取得作者授权. 本文原文地址http://neokabuto.blogspot.com/2013/02/opentk-tutorial-1-op ...

  5. Qt3D

    ---------------------------------------------- 概述 - 请阅读QtHelp: Qt 3D Overview https://www.kdab.com/o ...

  6. OpenTK教程-1绘制一个三角形

    OpenTK的官方文档是真心的少,他们把怎么去安装OpenTK说的很清楚,但是也就仅限于此,这有一篇learn opentk in 15的教程(链接已经失效,译者注),但是并不完美.你可以在15分钟内 ...

  7. Shader开发之三大着色器

    固定功能管线着色器Fixed Function Shaders 固定功能管线着色器的关键代码一般都在Pass的材质设置Material{}和纹理设置SetTexture{}部分. Shader &qu ...

  8. 一步一步学RenderMonkey(4)--点光源光照模型 【转】

    转载请注明出处:http://blog.csdn.net/tianhai110 点光源光照模型: 公式: I = Icolor*attenuation;                        ...

  9. unity surface shader 1

    Unity ShaderLib :  CGPROGRAM  ENDCG之间是CG代码,之外的代码功能都由ShaderLib提供,CG中的一些方法比如tex2D(...)也是ShaderLib对CG进行 ...

随机推荐

  1. Windows Socket 最大连接数

    Socket 编程时,单机最多可以建立多少个 TCP 连接,受到操作系统的影响. Windows 下单机的TCP连接数受多个参数影响: 最大TCP连接数 [HKEY_LOCAL_MACHINE \Sy ...

  2. NSLog中的%@

    [NSLog中的%@] There is one additional substitution token available in Objective-C, %@, used to denote ...

  3. SpriteKit

    [SpriteKit] Sprite Kit provides a graphics rendering and animation infrastructure that you can use t ...

  4. hdu 1199 Color the Ball

    http://acm.hdu.edu.cn/showproblem.php?pid=1199 Color the Ball Time Limit: 2000/1000 MS (Java/Others) ...

  5. Xcode环境配置mysql

    本文默认mysql安装目录为/usr/local/mysql 在项目的header search paths中添加/usr/local/mysql/includ 2.在项目的library searc ...

  6. Python基础-函数(function)

    这里我们看看Python中函数定义的语法,函数的局部变量,函数的参数,Python中函数的形参可以有默认值,参数的传递是赋值操作,在函数调用时,可以对实参进行打包和解包  1,函数定义 关键字def引 ...

  7. AJAX制作JSON格式的实时更新数据的方法

    之前有写过这样的文章,但是出现了几个问题,第一,如果每秒都像数据库发送请求势必会造成服务器的压力过大,第二,如果使用JS的话,是不可以取得系统时间的,因为JS运行在客户端,所以只能取得客户端时间, 如 ...

  8. [添加用户]解决useradd 用户后没有添加用户Home目录的情况,Linux改变文件或目录的访问权限命令,linux修改用户密码

    将nobody用户添加到nogroup 组:usermod -g nogroup nobody cat /etc/passwd|grep nobodynobody:x:65534:65534:nobo ...

  9. libevent库的使用方法

    接写一个很简单的 Time Server 来当作例子:当你连上去以后 Server 端直接提供时间,然后结束连线.event_init() 表示初始化 libevent 所使用到的变数.event_s ...

  10. .NET企业轻量级开发框架(APS.NET+Spring.Net+NHibernate)

          在<企业级应用架构>系列文章发表之余,也得到了许多同行的反馈,有人说这套框架太重了或者技术学习太复杂了或者初学者不太好理解或者完全颠覆了传统APS.NET开发模式让人望而生畏. ...