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
struct V2F{
float4 position:POSITION;
float3 worldPosition: TEXCOORD0;
float3 worldNormal :TEXCOORD1;
};
void Phong_FragmentLighting_v(float4 position :POSITION,
float4 normal:NORMAL,
uniform float4x4 modelMatrix,
uniform float4x4 modelMatrix_IT,
uniform float4x4 modelViewProj,
out V2F O){
O.position=mul(modelViewProj,position);
O.worldPosition=mul(modelMatrix,position).xyz;
O.worldNormal=normalize(mul(modelMatrix_IT,normal)).xyz;
}
Phong_FragmentLighting_f.cg
void Phong_FragmentLighting_f(float3 position :TEXCOORD0,
float3 normal: TEXCOORD1,
uniform float3 globalAmbient,
uniform float3 lightColor,
uniform float3 lightPosition,
uniform float3 eyePosition,
uniform float3 Ke,
uniform float3 Ka,
uniform float3 Kd,
uniform float3 Ks,
uniform float shininess,
out float4 color:COLOR)
{
float3 N=normalize(normal);
float3 L=normalize(lightPosition-position);
float3 V=normalize(eyePosition-position); float3 R=reflect(-L,N);
R=normalize(R); // Compute emissive term
float3 emissive = Ke; // Compute ambient term
float3 ambient = Ka * globalAmbient; // Compute the diffuse term
float diffuseLight = max(dot(N, L), );
float3 diffuse = Kd * lightColor * diffuseLight; // Compute the specular term
float specularLight = pow(max(dot(V, R), ), shininess);
if (diffuseLight <= ) specularLight = ;
float3 specular = Ks * lightColor * specularLight; //color.xyz = emissive + ambient + diffuse + specular;
color.xyz=ambient + diffuse + specular;
color.w = ;
}
BlinnPhong_FragmentLighting_v.cg
struct V2F{
float4 position:POSITION;
float3 worldPosition: TEXCOORD0;
float3 worldNormal :TEXCOORD1;
};
void BlinnPhong_FragmentLighting_v(float4 position :POSITION,
float4 normal:NORMAL,
uniform float4x4 modelMatrix,
uniform float4x4 modelMatrix_IT,
uniform float4x4 modelViewProj,
out V2F O){
O.position=mul(modelViewProj,position);
O.worldPosition=mul(modelMatrix,position).xyz;
O.worldNormal=normalize(mul(modelMatrix_IT,normal)).xyz;
}
BlinnPhong_FragmentLighting_f.cg
void BlinnPhong_FragmentLighting_f(float3 position :TEXCOORD0,
float3 normal: TEXCOORD1,
uniform float3 globalAmbient,
uniform float3 lightColor,
uniform float3 lightPosition,
uniform float3 eyePosition,
uniform float3 Ke,
uniform float3 Ka,
uniform float3 Kd,
uniform float3 Ks,
uniform float shininess,
out float4 color:COLOR)
{
float3 N=normalize(normal);
float3 L=normalize(lightPosition-position);
float3 V=normalize(eyePosition-position); float3 H=normalize(L+V); // Compute emissive term
float3 emissive = Ke; // Compute ambient term
float3 ambient = Ka * globalAmbient; // Compute the diffuse term
float diffuseLight = max(dot(N, L), );
float3 diffuse = Kd * lightColor * diffuseLight; // Compute the specular term
float specularLight = pow(max(dot(H, N), ), shininess);
if (diffuseLight <= ) specularLight = ;
float3 specular = Ks * lightColor * specularLight; color.xyz=ambient + diffuse + specular;
color.w = ;
}
效果对比:
Phong光照模型
Blinn-Phong光照模型 通过简单的对比发现,在相同条件下Blinn-Phong的高光范围要比Phong更大,写实效果Phong光照模型更好。但算法简单,运行速度快是Blinn-Phong光照模型的优点。
Phong和Blinn-Phong光照模型的更多相关文章
- 用DirectX12实现Blinn Phong
这次我们来用DirectX12实现一下基本的Blinn Phong光照模型.让我们再把这个光照模型的概念过一遍:一个物体的颜色由三个因素决定:ambient, diffuse, specular.am ...
- Unity-Shader-镜面高光Phong&BlinnPhong-油腻的师姐在哪里
[旧博客转移 - 2016年4月4日 13:13 ] 油腻的师姐: 以前玩过一款很火热的端游<剑灵>,剑灵刚出来的时候,某网页游戏广告视频中有句台词:"我不断的在寻找,有你的世界 ...
- Lambert漫反射.BLinnPhong及Phong模型 Unity自带的在Lighting.cginc里
1.漫反射 此模型属于经验模型,主要用来简单模拟粗糙物体表面的光照现象 此模型假设物体表面为理想漫反射体(也就是只产生漫反射现象,也成为Lambert反射体),同时,场景中存在两种光,一种为环境光,一 ...
- 如何在Unity中分别实现Flat Shading(平面着色)、Gouraud Shading(高洛德着色)、Phong Shading(冯氏着色)
写在前面: 先说一下为什么决定写这篇文章,我也是这两年开始学习3D物体的光照还有着色方式的,对这个特别感兴趣,在Wiki还有NVIDIA官网看了相关资料后,基本掌握了渲染物体时的渲染管道(The re ...
- 【Aladdin Unity3D Shader编程】之三 光照模型(二)
高光反射模型 Specular=直射光*pow(cosθ,高光的参数) θ:是反射光和视野方向的夹角 编写高光反射Shader Shader "AladdinShader/07 Specul ...
- 【Unity Shader】(三) ------ 光照模型原理及漫反射和高光反射的实现
[Unity Shader](三) ---------------- 光照模型原理及漫反射和高光反射的实现 [Unity Shader](四) ------ 纹理之法线纹理.单张纹理及遮罩纹理的实现 ...
- (转)光照模型及cg实现
经典光照模型(illumination model) 物体表面光照颜色由入射光.物体材质,以及材质和光的交互规律共同决定. 由于环境光给予物体各个点的光照强度相同,且没有方向之分,所以在只有环境光的情 ...
- 三种光照模型的shader实现
1.Lambert模型,公式为I=Kd*Il(N*L): Shader "Custom/Lambert_A" { Properties { _Diffuse(,,,) } SubS ...
- 合金装备V 幻痛 制作技术特辑
合金装备V:幻痛 制作特辑 资料原文出自日版CGWORLD2015年10月号 在[合金装备4(Metal Gear Solid IV)]7年后,序章作品[合金装备5 :原爆点 (Metal Gea ...
- 【Unity Shader】(六) ------ 复杂的光照(上)
笔者使用的是 Unity 2018.2.0f2 + VS2017,建议读者使用与 Unity 2018 相近的版本,避免一些因为版本不一致而出现的问题. [Unity Sha ...
随机推荐
- Hibernate 再接触 CRUD
1.save 一对多双向 package com.bjsxt.hibernate; import java.util.HashSet; import java.util.Set; import jav ...
- 利用原生态的(System.Web.Extensions)JavaScriptSerializer将mvc 前台提交到controller序列化复杂对象
主要代码如下: public JsonResult Test() { string s = Request.Form.ToString(); JavaScriptSerializer jss = ne ...
- Android Monkey: “No activities found to run, monkey aborted”错误原因
用monkey测试app时,输入命令adb shell monkey -p com.example.test -v -500 发现报错, 错误输入: :Monkey: seed=13 count=5 ...
- yii 定义场景
定义场景可以限制对字段的增删改查操作
- DM 9000网卡驱动移植
1. 由于内核已经带有DM9000 网卡的驱动,所以主要移植工作是在板文件中添加 platform_device 结构,并加入 ok6410_devices[] __initdata 数组. 代码如下 ...
- linux下arm汇编注释符
注意使用 @ 符 # 是整行注释符 @ 是行内注释符 以为 @ 是行内注释符,害我调试了半天.
- kotlin函数api
原 Kotlin学习(4)Lambda 2017年09月26日 21:00:03 gwt0425 阅读数:551 记住Lambda的本质,还是一个对象.和JS,Python等不同的是,Kotlin ...
- 判断元素16种方法expected_conditions
前言 标签(空格分隔): 判断元素 经常有小伙伴问,如何判断一个元素是否存在,如何判断alert弹窗出来了,如何判断动态的元素等等一系列的判断,在selenium的expected_condition ...
- Vi命令:如何删除全部内容
Vi命令:如何删除全部内容? 在命令模式下,输入:.,$d 一回车就全没了. 表示从当前行到末行全部删除掉. 用gg表示移动到首行.
- msf客户端渗透(二):PDF漏洞、恶意网站、flash漏洞、IE漏洞、java漏洞、android漏洞、VBScript感染payload
这个漏洞利用只在XP上有效 利用pdf漏洞利用payload exploit生成一个pdf文件 传到被攻击机上 启动msf侦听 exploit -j XP上双击运行这个pdf时,kali获取到一个sh ...

