Phong和Blinn-Phong光照模型

Phong和Blinn-Phong是计算镜面反射光的两种光照模型,两者仅仅有很小的不同之处。

1.Phong模型

Phone模型计算中的一个关键步骤就是反射向量R的计算:

上图中的位于表面“下面”的向量 ‘I’ 是原始 ‘I’ 向量的拷贝,并且二者是一样的,现在我们的目标计算出向量 ‘R’ 。根据向量相加原则,向量 ‘R’ 等于 ‘I‘ + ‘V‘,‘I’ 是已知的,所以我们需要做的就是找出向量 ‘V’。注意法向量 ‘N’ 的负方向就是 ‘-N’,我们可以在 ‘I’ 和 ‘-N’ 之间使用一个点乘运算就能得到 ‘I’ 在 ‘-N’ 上面的投影的模。这个模正好是 ‘V’ 的模的一半,由于 ‘V’ 与 ‘N’ 有相同的方向,我们可以将这个模乘上 ‘N’ (其模为 1 )再乘上 2 即可得到 ‘V’。总结一下就是下面的公式:

2.Blinn-Phong模型

Phong模型中计算反射光线的向量是一件相对比较耗时的任务,因此Blinn-Phong对这一点进行了改进。

Ks:物体对于反射光线的衰减系数

N:表面法向量

H:光入射方向L和视点方向V的中间向量

Shininess:高光系数

可见,通过该式计算镜面反射光是符合基本规律的,当视点方向和反射光线方向一致时,计算得到的H与N平行,dot(N,H)取得最大;当视点方向V偏离反射方向时,H也偏离N。

同时H的计算比起反射向量R的计算简单的多,R向量的计算需要若干次的向量乘法与加法,而H的计算仅仅需要一次加法。

下面是用cg着色语言书写的Phong和Blinn-Phong的顶点和片段着色程序

Phong_FragmentLighting_v.cg
 1 struct V2F{
 2     float4 position:POSITION;
 3     float3 worldPosition: TEXCOORD0;
 4     float3 worldNormal :TEXCOORD1;
 5 };
 6 void Phong_FragmentLighting_v(float4 position :POSITION,
 7                               float4 normal:NORMAL,
 8                               uniform float4x4 modelMatrix,
 9                               uniform float4x4 modelMatrix_IT,
10                               uniform float4x4 modelViewProj,
11                               out V2F O){
12     O.position=mul(modelViewProj,position);
13     O.worldPosition=mul(modelMatrix,position).xyz;
14     O.worldNormal=normalize(mul(modelMatrix_IT,normal)).xyz;
15 }
Phong_FragmentLighting_f.cg
 1 void Phong_FragmentLighting_f(float3 position :TEXCOORD0,
 2                                float3 normal: TEXCOORD1,
 3                                uniform float3 globalAmbient,
 4                                uniform float3 lightColor,
 5                                uniform float3 lightPosition,
 6                                uniform float3 eyePosition,
 7                                uniform float3 Ke,
 8                                uniform float3 Ka,
 9                                uniform float3 Kd,
10                                uniform float3 Ks,
11                                uniform float  shininess,
12                                out float4 color:COLOR)
13               {
14                   float3 N=normalize(normal);
15                   float3 L=normalize(lightPosition-position);
16                   float3 V=normalize(eyePosition-position);
17
18                   float3 R=reflect(-L,N);
19                   R=normalize(R);
20
21                   // Compute emissive term
22                   float3 emissive = Ke;
23
24                  // Compute ambient term
25                  float3 ambient = Ka * globalAmbient;
26
27                 // Compute the diffuse term
28                 float diffuseLight = max(dot(N, L), 0);
29                 float3 diffuse = Kd * lightColor * diffuseLight;
30
31                 // Compute the specular term
32                 float specularLight = pow(max(dot(V, R), 0), shininess);
33                 if (diffuseLight <= 0) specularLight = 0;
34                 float3 specular = Ks * lightColor * specularLight;
35
36                 //color.xyz = emissive + ambient + diffuse + specular;
37                 color.xyz=ambient + diffuse + specular;
38                 color.w = 1;
39               }
BlinnPhong_FragmentLighting_v.cg
 1 struct V2F{
 2     float4 position:POSITION;
 3     float3 worldPosition: TEXCOORD0;
 4     float3 worldNormal :TEXCOORD1;
 5 };
 6 void BlinnPhong_FragmentLighting_v(float4 position :POSITION,
 7                               float4 normal:NORMAL,
 8                               uniform float4x4 modelMatrix,
 9                               uniform float4x4 modelMatrix_IT,
10                               uniform float4x4 modelViewProj,
11                               out V2F O){
12     O.position=mul(modelViewProj,position);
13     O.worldPosition=mul(modelMatrix,position).xyz;
14     O.worldNormal=normalize(mul(modelMatrix_IT,normal)).xyz;
15 }
 
BlinnPhong_FragmentLighting_f.cg
 1 void BlinnPhong_FragmentLighting_f(float3 position :TEXCOORD0,
 2                                float3 normal: TEXCOORD1,
 3                                uniform float3 globalAmbient,
 4                                uniform float3 lightColor,
 5                                uniform float3 lightPosition,
 6                                uniform float3 eyePosition,
 7                                uniform float3 Ke,
 8                                uniform float3 Ka,
 9                                uniform float3 Kd,
10                                uniform float3 Ks,
11                                uniform float  shininess,
12                                out float4 color:COLOR)
13               {
14                   float3 N=normalize(normal);
15                   float3 L=normalize(lightPosition-position);
16                   float3 V=normalize(eyePosition-position);
17
18                  float3 H=normalize(L+V);
19
20                   // Compute emissive term
21                   float3 emissive = Ke;
22
23                  // Compute ambient term
24                  float3 ambient = Ka * globalAmbient;
25
26                 // Compute the diffuse term
27                 float diffuseLight = max(dot(N, L), 0);
28                 float3 diffuse = Kd * lightColor * diffuseLight;
29
30                 // Compute the specular term
31                 float specularLight = pow(max(dot(H, N), 0), shininess);
32                 if (diffuseLight <= 0) specularLight = 0;
33                 float3 specular = Ks * lightColor * specularLight;
34
35                 color.xyz=ambient + diffuse + specular;
36                 color.w = 1;
37               }
效果对比:

Phong光照模型Blinn-Phong光照模型

通过简单的对比发现,在相同条件下Blinn-Phong的高光范围要比Phong更大,写实效果Phong光照模型更好。但算法简单,运行速度快是Blinn-Phong光照模型的优点。
时间: 2024-10-12 20:37:45

Phong和Blinn-Phong光照模型的相关文章

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

[旧博客转移 - 2016年4月4日 13:13 ] 油腻的师姐: 以前玩过一款很火热的端游<剑灵>,剑灵刚出来的时候,某网页游戏广告视频中有句台词:"我不断的在寻找,有你的世界在哪里",该广告中的人物,音效都模仿了剑灵,而<剑灵>中的人物模型表面看上去油光发亮,所以就被网友改成了:"我不断的洗澡,油腻的师姐在哪里" 像这样(皮肤表面的高光) 这样 还有~ 这样 其实这是使用了镜面反射着色,除了剑灵,其他很多高品质的AAA级游戏也都使用了不同

TeaPot 用webgl画茶壶(2) Phong Shading

在Fragment Shader里应用Phong Shading使得茶壶更逼真.即使是单一颜色的茶壶,只要光源的位置变化,或眼睛的位置变化,看到的茶壶的各个部分的颜色明暗是不一定一样的.所谓Phong Shading就是Phong这个人提出的一种决定每个像素颜色的方法. 总的来说,我们希望看到怎样的茶壶?我们希望它跟真的一样,有光照着它,所以照到的地方亮,照不到的地方暗,迎着光的地方还有高亮反射光. 点e看到点p有颜色,是因为有光子从p跑到了e.点p有光子,除非p是光源,不然光子肯定是从别的地方

【DirectX11】第九篇 光照模型——高光

本系列文章主要翻译和参考自<Real-Time 3D Rendering with DirectX and HLSL>一书(感谢原书作者),同时会加上一点个人理解和拓展,文章中如有错误,欢迎指正. 这里是书中的代码和资源. 本文所有的环境和工具使用都基于之前的文章,如有不明白的地方请先参考本系列之前的几篇文章. 本文索引: 关于灯光 Specular Highlights 高光 1 Phong 冯氏光照模型 2 Phong Preamble 冯氏光照模型变量准备 3 Phong Vertex

局部光照模型

提要 常见的光照模型一般包括四个部分ambient, diffuse, specular, 和emitted light. 即: vertex color = ambient + diffuse + specular + emitted light 当有多个光源的时候,最后的颜色就是多个结果的叠加. Ambient light:环境光,通常定义在光源的中,注意每个光源的衰减量. Diffuse:漫反射部分,光照找到物体的表面,由于物体的表面凹凸不平而反射到各个方向的光. Specular :相比

4种基本光照模型

1.Lambert模型(漫反射) 环境光: Iambdiff = Kd*Ia 其中Ia 表示环境光强度,Kd(0<K<1)为材质对环境光的反射系数,Iambdiff是漫反射体与环境光交互反射的光强. 方向光: Ildiff = Kd * Il * Cos(θ) 其中Il是点光源强度,θ是入射光方向与顶点法线的夹角,称入射角(0<=A<=90°),Ildiff是漫反射体与方向光交互反射的光强,若 N为顶点单位法向量,L表示从顶点指向光源的单位向量(注意顶点指向光源),则Cos(θ)等

Opengl 4种光照模型

https://blog.csdn.net/ym19860303/article/details/25545933 1.Lambert模型(漫反射) 环境光: Iambdiff = Kd*Ia 其中Ia 表示环境光强度,Kd(0<K<1)为材质对环境光的反射系数,Iambdiff是漫反射体与环境光交互反射的光强. 方向光: Ildiff = Kd * Il * Cos(θ) 其中Il是点光源强度,θ是入射光方向与顶点法线的夹角,称入射角(0<=A<=90°),Ildiff是漫反射体

Unity shader教程-第六课:Ramp Texture

本文首发地址:http://98jy.net/article/25 更多文章,请入传送门 ---------------------------------------------- Ramp Texture在Valve公司的军团要塞2后开始成为一种控制漫反射的方法. Ramp Texture是类似下图的一张贴图: 在一般的Blinn/Phong模型中,我们对漫反射的系数是基于入射光和击中的点的法线的角度.在这种情况下,系数的计算代码大致如下: float DiffuseCoeff(in flo

合金装备V 幻痛 制作技术特辑

合金装备V:幻痛 制作特辑 资料原文出自日版CGWORLD2015年10月号 在[合金装备4(Metal Gear Solid IV)]7年后,序章作品[合金装备5 :原爆点 (Metal Gear Solid V: Ground Zeroes)]1年半后,合金装备(MGS)系列的最新作[合金装备5 幻痛(METAL GEAR SOLID V: THE PHANTOM PAIN)]发售了.游戏上做最新的挑战,一直走在这个时代的游戏图形最前端的开发团队,在本作中是以什么为目标,为了这个目标加入了何

Unity 图形学 基础知识总结

1. 渲染流水线 三大块:应用阶段,几何阶段,光栅化阶段 渲染图元   顶点信息 GPU流水线 顶点数据=> 顶点着色器;曲面细分着色器;几何着色器;裁剪;屏幕映射=> 三角形设置;三角形遍历;片元着色器;逐片元操作=> 屏幕图像 裁剪:可配置的,摄像机属性 逐片元操作:模板测试,深度测试,混合(不可编程,可以配置) 为了优化,Unity的Ztest是在片元着色器之前; 但是如果使用了clip(值为负数,丢弃像素信息 discard)函数,会关闭提前测试,导致需要处理的片元增加 2. 数

【转载】计算机图形学框架

原文: 计算机图形学框架 应用 基本图形生成算法 图元光栅化标准 直线要直 图元终点要准 图元生成的亮度.色泽粗细要均匀 快速计算 直线光栅化算法 逐点比较法 数值微分法 中点Bresenham算法 圆的光栅化算法 简单方程产生圆弧 Bresenham算法产生圆弧 多边形填充 扫描线填充 宽图元 复制像素画宽图元 移动画笔画宽图元 3D数学基础 坐标系 向量 矩阵 空间集合运算 集合形体的表达 几何体之间的关系 图形变换 二维及三维图形几何变换 二维图形几何变换 平移变换 比例变换 旋转变换 错