您的位置:首页 > 其它

Cook-Torrance光照模型

2016-02-20 12:50 295 查看

 金属效果

Cook-Torrance光照模型

  该光照模型是基于物理材质的光照模型。光照射到物体表面发生漫反射、镜面反射、折射、透射等现象,在这里我们只考虑漫反射和镜面反射,Cook-Torrance是用来模拟不同材质的镜面反射效果。

  

    其中:

      ambient :环境光;

      K:决定高光部分和漫射的比例,一般而已,光复合能量守恒定律,即入射光的总能量和出射光的总能量相等;

      rs :镜面发射;

  

F项:菲涅尔反射

  即Fresnel,菲涅尔反射。我们在观察水面的时候,垂直看下去,清澈见底,看远处的水面,向镜子一样,这个就是菲涅尔效应。菲涅尔效应可以说是无处不在,不同的材质效果不同而已。

  

    v:视点的方向;

    h:半角向量,即视点和光线的中间向量;

D项:微平面法线分布函数

  该项模拟物体表面是由无数微小的像镜子一样的平面组成,每一个微平面对于光线会根据自身的方向反射光线,只有那些面向视点的平面贡献大。具体参见微平面法线分布的理论。

  

G项:几何项

   该项用于计算微平面中反射光重合部分的修正。

  

  

  

=============================================================================

 

Shader "JQM/Cook-Torrance"
{
Properties
{
_Color("Base Color",Color) = (1,1,1,1)
_MainTex ("Texture", 2D) = "white" {}

_Roughness("Roughness",Range(0,1)) = 1
_Fresnel("Fresnel",Range(0,1)) = 1
_K("K",Range(0,1)) = 1

_Environment ("Environment", Cube) = "white"
}

SubShader
{

Pass
{
Tags { "LightMode" = "ForwardBase"}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag

#include "UnityCG.cginc"

float4 _Color;
//使用Unity定义的变量:灯光
uniform float4 _LightColor0;

float _Roughness;
float _Fresnel;
float _K;
samplerCUBE _Environment;

struct VertexOutput
{
float4 pos : SV_POSITION;
float4 posWorld : TEXCOORD1;
float2 uv : TEXCOORD2;
float3 normal:Normal;

};

sampler2D _MainTex;
float4 _MainTex_ST;

VertexOutput vert (appdata_full v)
{
VertexOutput o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.posWorld = mul(_Object2World, v.vertex);
o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
o.normal = v.normal;

return o;
}

fixed4 frag (VertexOutput i) : COLOR
{
//将法线转到世界空间:乘以变换矩阵的逆的转置
//float3 normalWorld  = mul(_Object2World,i.normal);
float3 normalWorld  = mul(i.normal,_World2Object);

//观察者
float3 eyeDir = normalize(_WorldSpaceCameraPos -i.posWorld).xyz;

//光源
float3 lightDir = normalize(_WorldSpaceLightPos0).xyz;

fixed4 col = tex2D(_MainTex, i.uv);

///计算漫反射
float3 diffuse = _Color;

//计算天空盒
float3 r = reflect(-eyeDir,normalWorld);
float4 reflectiveColor = texCUBE(_Environment,r);

//计算高光
//float3 h = (eyeDir+lightDir)/2;
//float3 r = normalize(reflect(-lightDir,normalWorld));
//float3 specular = saturate(dot(lightDir,normalWorld))* _SpecularColor * pow(saturate(dot(r,eyeDir)),_SpecularPower);

//计算Cook-Torrance高光
float s;
float ln = saturate(dot(lightDir,normalWorld));

if(ln > 0.0)//在光照范围内
{
float3 h = normalize(eyeDir+lightDir);
float nh = saturate(dot(normalWorld, h));
float nv = saturate(dot(normalWorld, eyeDir));
float vh = saturate(dot(eyeDir, h));

//G项
float nh2 = 2.0*nh;
float g1 = (nh2*nv)/vh;
float g2 = (nh2*ln)/vh;
float g = min(1.0,min(g1,g2));

//D项:beckmann distribution function
float m2 = _Roughness*_Roughness;
float r1 = 1.0/(4.0 * m2 *pow(nh,4.0));
float r2 = (nh*nh -1.0)/(m2 * nh*nh);
float roughness = r1*exp(r2);

//F项
float fresnel = pow(1.0 - vh,5.0);
fresnel *= (1.0-_Fresnel);
fresnel += _Fresnel;
s = saturate((fresnel*g*roughness)/(nv*ln*3.14));

//reflectiveColor *= fresnel;
}

float3 final =_LightColor0*ln*(_K*diffuse*reflectiveColor*2 + s*(1-_K)*reflectiveColor*2) + UNITY_LIGHTMODEL_AMBIENT.xyz;
return float4(final,1);
}
ENDCG
}
}
}

 

 

  参考资料:

Google:http://ruh.li/GraphicsCookTorrance.html

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: