参考http://www.codinglabs.net/article_physically_based_rendering_cook_torrance.aspx
这个分布函数其实就是靠roughness来改变高光分布的意思。
roughness为0.01时如图:
roughness为0.2时如图:
roughness为0.6时如图:
roughness为1时如图:
下面是代码:
这代码只是拿来测试一下这个分布函数的。
Shader "Custom/DistributionShader"
{
Properties
{
_DiffuseColor ("Diffuse Color", Color) = (1,1,1,1)
_SpecColor ("Specular Color", Color) = (1,1,1,1)
_Roughness ("Roughness", Float) = 10
}
SubShader
{
Pass
{
Tags { "LightMode" = "ForwardBase" }
GLSLPROGRAM
uniform vec4 _DiffuseColor;
uniform vec4 _SpecColor;
uniform float _Roughness;
uniform vec3 _WorldSpaceCameraPos;
uniform mat4 _Object2World;
uniform mat4 _World2Object;
uniform vec4 _WorldSpaceLightPos0;
uniform vec4 _LightColor0;
#ifdef VERTEX
//顶点着色器
out vec4 worldPosition;
out vec3 worldNormalDirection;
void main()
{
mat4 modelMatrix = _Object2World;
mat4 modelMatrixInverse = _World2Object;
worldPosition = modelMatrix * gl_Vertex;
worldNormalDirection = normalize(vec3(vec4(gl_Normal, 0.0) * modelMatrixInverse));
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}
#endif
#ifdef FRAGMENT
//片元着色器
in vec4 worldPosition;
in vec3 worldNormalDirection;
//工具函数
float chiGGX(float v)
{
return v > 0 ? 1 : 0;
}
//分布函数
//alpha就是roughness
float GGX_Distribution(vec3 n, vec3 h, float alpha)
{
float NoH = dot(n, h);
float alpha2 = alpha * alpha;
float NoH2 = NoH * NoH;
float den = NoH2 * alpha2 + (1 - NoH2);
return (chiGGX(NoH) * alpha2) / (3.1415926 * den * den);
}
void main()
{
vec3 normalDirection = normalize(worldNormalDirection);
vec3 viewDirection = normalize(_WorldSpaceCameraPos - vec3(worldPosition));
vec3 lightDirection = normalize(vec3(_WorldSpaceLightPos0));
vec3 ambientLighting = vec3(gl_LightModel.ambient) * vec3(_DiffuseColor);
vec3 diffuseReflection = vec3(_LightColor0) * vec3(_DiffuseColor)
* max(0.0, dot(normalDirection, lightDirection));
vec3 halfVector = normalize(lightDirection + viewDirection);
vec3 specularReflection;
//if (dot(normalDirection, lightDirection) < 0.0)
//{
// specularReflection = vec3(0.0, 0.0, 0.0);
//}
//else
//{
//specularReflection = vec3(_LightColor0) * vec3(_SpecColor)
// * pow(max(0.0, dot(reflect(-lightDirection, normalDirection), viewDirection)), _Roughness);
specularReflection = vec3(_LightColor0) * vec3(_SpecColor)
* pow(max(0.0, dot(halfVector, normalDirection)), _Roughness);
//}
float kS = GGX_Distribution(normalDirection, halfVector, _Roughness);
float kD = 1 - kS;
gl_FragColor = vec4(kD *(ambientLighting) + kS *specularReflection, 1.0);
}
#endif
ENDGLSL
}
}
}