Cook Torrance 模型将物体粗糙表面看做很多微小平面组成,每一个微小平面都被看做一个理想的镜面反射,物体表面粗糙程度由微平面斜率的变化来衡量,一个粗糙表面由一些列斜率变化很大的微平面组成,而相对平滑的微平面斜率变化很小,
Vertex shader:
1
uniform vec3 lightposition;//光源为位置
2
uniform vec3 eyeposition;//相机位置
3
varying float NdotL, NdotH, NdotV, VdotH ;
4
void main(void)
{
5
6
vec3 objPosition = vec3 (gl_ModelViewMatrix * gl_Vertex);
7
vec3 Normal = normalize (gl_NormalMatrix * gl_Normal);
8
vec3 LightDir = normalize (lightposition - objPosition);
9
vec3 EyeDir = normalize (eyeposition - objPosition);
10
vec3 HalfVec = normalize (LightDir + EyeDir);
11
12
NdotL = max(dot(Normal, LightDir), 0.0);
13
NdotH = max(dot(Normal, HalfVec), 0.0);
14
NdotV = max(dot(Normal, EyeDir), 0.0);
15
VdotH = max(dot(EyeDir, HalfVec), 0.0);
16
17
gl_Position = ftransform();
18
} Frag Shader:
1
uniform sampler2D tex;
2
uniform vec4 ambient;//环境光颜色
3
uniform vec4 DiffuseLightColor;//漫反射光源颜色
4
uniform vec4 SpecularLightColor;//specular光源颜色
5
varying float NdotL, NdotH, NdotV, VdotH ;
6
float diff=0.1;
7
float spec=1.0;
8
void main(void)
{
9
float m = 0.6;//物体表面粗超程度
10
float f0 = 0.9;//入射角接近0时候的菲涅尔反射系数
11
12
float Fresnel = f0 + (1.0 - f0) * pow((1.0 - VdotH), 5.0);
13
float Droughness = (pow(NdotH, 2.0)-1.0) / (m * m * pow(NdotH,2.0));
14
float Drough = (1.0 / m * m * pow(NdotH,4.0)) * exp(Droughness);
15
float G1 = (2.0 * NdotH * NdotL) / VdotH;
16
float G2 = (2.0 * NdotH * NdotV) / VdotH;
17
float Geometric= min(1.0, min(G1, G2));
18
19
float Rs = (Fresnel * Drough * Geometric) / (NdotV * NdotL);
20
21
vec3 diffuse = diff * vec3(DiffuseLightColor) * NdotL;
22
vec3 specular = spec * vec3(SpecularLightColor) * Rs;
23
24
vec4 Color = vec4((diffuse + specular),1.0);
25 gl_FragColor = Color;
26
} f0系数的设置对反射的亮度有一定的影响。 此处设置的比较大,一般近似取f0=
pow((1.0 - VdotH), 4.0);
Effect:
Object1