Cook-Torrance光照模型
Cook-Torrance光照模型将物体粗糙表面看作由很多微平面组成,每一个微平面都可以看成一个理想的镜面反射体,物体表面粗糙程度由微平面斜率的变化来表示。越粗糙的表面由斜率变化越大,反之越小。
Cook-Torrance模型将光分为两个方面考虑,漫反射光强和镜面反射光强:Ic-t=Idiff+Ispec。
Idiff是漫反射光强,计算方式参照理想漫反射体(Lambert模型)的计算方式。Ispec是镜面反射光强,Ispec=KsIlRs。Cook-Torrance模型与phong、blinn-phong 模型的不同之处在于 Rs 的计算方法。Cook-Torrance的Rs计算公式如下:

F是菲涅尔反射系数。真实世界中,当视线和表面的夹角不同时,反射效果会有差别。例如,站在湖边上,自己脚边的水面,反射不明显,可以看到水下的东西;远处的水面,反射则十分明显。
D表示微平面分布函数。该项模拟物体表面是由无数微小的像镜子一样的平面组成,每一个微平面对于光线会根据自身的方向反射光线。最常使用的微平面分布函是 Backmann 分布函数:

m值用于度量表面的粗糙程度,较大的m 值对应于粗糙平面,较小的m 值对应与较光滑的表面;α 是顶点法向量 N 和半角向量 H 的夹角。其中可推导:

所以最终可得:

G是遮挡项。微平面间会出现三种情况:部分入射光被遮挡;部分反射光被遮挡;入射光反射光都没有被遮挡。
G=min(1,G1,G2)


代码实现如下:
Shader "Custom/Cook-Torrance" {
Properties {
mainTexture ("Texture", 2D) = "white" {}
specularColor("SpecularColor", Color) = (,,,)
fresnel0 ("Fresnel", Range(,)) = 0.5
roughness ("Roughness", Range(,)) = 0.5
ks("Ks",Range(,))=0.5
}
SubShader {
Tags { "LightMode"="ForwardBase" }
LOD
Pass{
CGPROGRAM
// Physically based Standard lighting model, and enable shadows on all light types
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
//#include "Light.cginc"
// Use shader model 3.0 target, to get nicer looking lighting
uniform float4 _LightColor0;
sampler2D mainTexture;
float4 mainTexture_ST;
uniform float4 specularColor;
uniform float fresnel0;
uniform float roughness;
uniform float ks;
struct v2f{
float4 pos:SV_POSITION;
float4 worldPos:TEXCOORD0;
float3 normal:NORMAL;
float2 uv:TEXCOORD1;
};
v2f vert(appdata_full v){
v2f o;
o.pos=mul(UNITY_MATRIX_MVP,v.vertex);
o.worldPos=mul(_Object2World,v.vertex);
o.normal=v.normal;
o.uv=TRANSFORM_TEX(v.texcoord, mainTexture);
return o;
}
float4 frag(v2f o):COLOR
{
float4 worldPos=o.worldPos;
float3 worldNormal=normalize(mul(float4(o.normal,),_World2Object).xyz);
float3 lightDir = normalize(_WorldSpaceLightPos0.xyz);
float3 viewDir=normalize(_WorldSpaceCameraPos-worldPos).xyz;
float3 halfAngleDir=normalize(viewDir+lightDir);
float vhDot=saturate( dot(viewDir,halfAngleDir));
float nhDot=saturate(dot(worldNormal,halfAngleDir));
float nlDot=saturate(dot(worldNormal,lightDir));
float nvDot=saturate(dot(worldNormal,viewDir));
float3 texColor= tex2D(mainTexture, o.uv);
float3 Ispec;
float3 Idiff=(_LightColor0*specularColor*nlDot).xyz*texColor;
if(nlDot>){
//F项
float F =pow((1.0-vhDot),5.0);
F *= (1.0-fresnel0);
F += fresnel0;
//D项
float d1=/(roughness*roughness*pow(nhDot,));
float d2=exp((nhDot*nhDot-)/(roughness*roughness*nhDot*nhDot));
float D=d1*d2;
//G项
float g1=*nhDot*nlDot/vhDot;
float g2=*nhDot*nvDot/vhDot;
float G=min(,min(g1,g2));
float Rs=saturate((F*D*G)/(nvDot*nlDot));
Ispec=(Rs*specularColor*ks).xyz;
}
else
return float4(Idiff,);
float3 finalColor=Idiff+Ispec;
return float4(finalColor,);
}
ENDCG
}
}
FallBack "Diffuse"
}
Cook-Torrance光照模型的更多相关文章
- 【Unity Shaders】学习笔记——SurfaceShader(十)镜面反射
[Unity Shaders]学习笔记——SurfaceShader(十)镜面反射 如果你想从零开始学习Unity Shader,那么你可以看看本系列的文章入门,你只需要稍微有点编程的概念就可以. 水 ...
- 由浅入深学习PBR的原理和实现
目录 一. 前言 1.1 本文动机 1.2 PBR知识体系 1.3 本文内容及特点 二. 初阶:PBR基本认知和应用 2.1 PBR的基本介绍 2.1.1 PBR概念 2.1.2 与物理渲染的差别 2 ...
- Opengles 管线编程介绍
OpenGL ES 2.0可编程管道 上图橙色部分(Vertex Shader和Fragment Shader)为此管道的可编程部分.整个管道包含以下两个规范: 1) OpenGL ...
- Cook-Torrence Illumination Model 的一些数学说明
Cook-Torrence 光照模型如下: 这个Io就是计算后最终的光强,主要是用来计算镜面反射光,漫反射和环境光的计算和Phong模型一致. F:Fresnel反射系数.主要用来说明反射光强度占入射 ...
- Lambert(朗伯)光照模型 和Half Lambert的区别
Lambert-它不包括任何任何镜面属性,对粗糙物体来说,这项属性是非常有用的,它不会反射出周围的环境.Lambert材质可以是透明的,在光线追踪渲染中发生折射,但是如果没有镜面属性,该类型就不会发生 ...
- [CG编程] 基本光照模型的实现与拓展以及常见光照模型解析
0.前言 这篇文章写于去年的暑假.大二的假期时间多,小组便开发一个手机游戏的项目,开发过程中忙里偷闲地了解了Unity的shader编写,而CG又与shaderLab相似,所以又阅读了<CG教程 ...
- Unity3D ShaderLab 车辆喷漆光照模型实战
这一篇,我们来创建一个车辆喷漆的光照模型.首先就是准备场景,新建Shader & Material. 过程比较简单,直接看完成的代码吧: Shader "91YGame/CarOut ...
- Unity3D ShaderLab 漫反射卷积光照模型
Unity3D ShaderLab 漫反射卷积光照模型 漫反射卷积[Diffuse convolution]是一个模糊立方体的过程,它保留了立方图的整体光照强度,只模糊了细节. 这种效果在我们要活得一 ...
- Unity3D ShaderLab 静态贴图光照模型
Unity3D ShaderLab 静态贴图光照模型 其实在unity的光照模型中,我们可以把光照讯息烘培进入一个2D贴图,来实现着色器的光照效果. 下面是在unity中关闭灯光和打开灯光的对比效果. ...
- Unity3D ShaderLab Half Lambert光照模型
Half Lambert光照模型 说到Half Lambert ,就不得不说反恐精英了,在制作反恐精英的过程中,为了防止物体的背面光丢失而显得太过平面化,就用了这个称之为half lambert的技术 ...
随机推荐
- 大前端涉猎之前后端交互总结2:使用PHP进行表单数据上传与更新
1:使用PHP进行表单上传 1.1 form表单的数据收集 HTML页面: 代码解释:核心模块是form的属性: --提交方式 : method="post" --指定 name ...
- Finding Memory Leaks with SAP Memory Analyzer
Introduction There is a common understanding that a single snapshot of the java heap is not enough f ...
- 简述各大 Linux 发行版,有主观,不完全,望见谅
只罗列当前热门的linux发行版 更多关于 Linux 以及 Linux 衍生版的内容可以参阅 中文wiki Debian 系 Debian:开源社区的代表性 linux 系统,每2年一次更新,现在的 ...
- Android-ContentProvider读取/新增/操作系统联系人数据
想要访问Android操作系统的ContentProvider就需要明白以下原理: 在Android操作系统里面的 /packsges/目录: apps: 很多的系统应用,例如:联系人,浏览器,音乐播 ...
- jquery库与其他库冲突的问题解决-jquery.noConflict()
在使用jQuery开发的时候,可能还会使用到其他的JS库,比如Prototype,但多库共存时可能会发生冲突:若是发生冲突后,可以通过以下几种方案进行解决: 一. jQuery库在其他库之前导入,直接 ...
- 系统数据库--恢复Master数据库
实现步骤:关闭SQL SERVER 服务,使用DAC登录 在cmd下还原master 重启SQL SERVER 服务
- js ~或者~~
问题:~是什么意思? 答:js中是对数字取反 var a = null; var b = '23' console.log(~~null) console.log(~~b)
- Ocelot Consul
1首先创建一个json的配置文件,文件名随便取,我取Ocelot.json 这个配置文件有两种配置方式,第一种,手动填写 服务所在的ip和端口:第二种,用Consul进行服务发现 第一种如下: { & ...
- 使用adb工具调试出现error:device offline
使用adb工具调试设备的时候会出现error:device offline,网上找了很多办法,最后终于解决了. 如果你也遇到这样的问题,先试试简单的办法,不行的话,试试这个..<.< ad ...
- maven+eclipse+ssm 环境搭建和启动
该类工程环境搭建和启动方法 ------------------------------------------------------------------------------- 配置 jdk ...