在说光照之前,有必要先弄清法线的变换,假设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. angular的directive笔记

    原贴地址 1,tansclude: 是指令能够能够把外部定义的内容传回指令模板内部(通过在内部标签使用ng-transclude).这个外部指定的内容是根据外部的作用域控制的,跟指令的作用域无关.这个 ...

  2. MYSQL数据库重点:流程控制语句

    1.BEGIN ... END复合语句:包含多个语句.statement_list 代表一个或多个语句的列表.statement_list之内每个语句都必须用分号(:)来结尾. [begin_labe ...

  3. HD1004Let the Balloon Rise

    Let the Balloon Rise Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others ...

  4. 在PhpStorm9中与Pi的xdebug进行调试

    PI的配置参考 http://www.cnblogs.com/yondy/archive/2013/05/01/3052687.html 在PhpStorm 9.0中参考下面的截图进行配置 配置完成以 ...

  5. python 前向引用

    即函数调用在函数定义之前 可以这样 def bbb(): print('this is b') aaa() def aaa(): print('this is a') bbb() ---------& ...

  6. Python基础 基本运算符

    什么是操作符 形如 1+1 = 2 这样的 1 就是操作数 + 就是操作符 python语言支持的操作符: 算数运算符 比较运算符(关系) 赋值运算符 逻辑运算符 位运算符 会员操作符 标志操作符 算 ...

  7. <!DOCTYPE> 标签的深度剖析以及使用选择

    前言: 今天被问道“有没有仔细了解过<!DOCTYPE>标签?”,愣了一下,因为一开始在W3cschool上看到过建议使用XHTML Transitional DTD,之后就很听话地把Dr ...

  8. OC:Block语法、Block使用、Block实现数组排序

    Block //定义一个求两个数最大值函数 int maxValue (int ,int); //函数的实现 int maxValue (int a, int b){ return  a > b ...

  9. 移动端轮播图插件(支持Zepto和jQuery)

    一. 效果图 二. 功能介绍 1. 支持图片自动轮播和非自动轮播 2. 支持点击和滑动. 三. 简单介绍 代码都有注释,逻辑简单,不做更多赘述. 1. 在你的html中添加一行. <sectio ...

  10. Jquery基础:append、prepend、after、before、appendTo的区别

    append() 是在被选元素的结束标签前面(即改被选元素的内部)插入指定内容. after() 是在被选元素的结束标签后面(即该被选元素的外部)插入指定的内容. appendTo() 仍然是在被选元 ...