参考:http://www.codinglabs.net/article_physically_based_rendering_cook_torrance.aspx
这个函数是关于microfacet方面的。
roughness为0时如图:
roughness为0.2时如图:
roughness为0.5时如图:
roughness为0.8时如图:
roughness为1时如图:
最后是代码:
这个代码也只是拿来测试一下。
Shader "Custom/GeometryShader"
{
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;
}
//Geometry函数
//alpha就是roughness
float GGX_PartialGeometryTerm(vec3 v, vec3 n, vec3 h, float alpha)
{
float VoH2 = clamp(dot(v, h), 0.0, 1.0);
float chi = chiGGX(VoH2 / clamp(dot(v, n), 0.0, 1.0));
VoH2 = VoH2 * VoH2;
float tan2 = (1 - VoH2) / VoH2;
return (chi * 2) / (1 + sqrt(1 + alpha * alpha * tan2));
}
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 Geo = GGX_PartialGeometryTerm(viewDirection, normalDirection, halfVector, _Roughness);
float kS = Geo * Geo;
float kD = 1 - kS;
gl_FragColor = vec4(kD *(ambientLighting) + kS *specularReflection, 1.0);
}
#endif
ENDGLSL
}
}
}