Cook Torrance 模型将物体粗糙表面看做很多微小平面组成,每一个微小平面都被看做一个理想的镜面反射,物体表面粗糙程度由微平面斜率的变化来衡量,一个粗糙表面由一些列斜率变化很大的微平面组成,而相对平滑的微平面斜率变化很小,
Vertex shader:
1uniform vec3 lightposition;//光源为位置
2uniform vec3 eyeposition;//相机位置
3varying float NdotL, NdotH, NdotV, VdotH ;
4void 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:
1uniform sampler2D tex;
2uniform vec4 ambient;//环境光颜色
3uniform vec4 DiffuseLightColor;//漫反射光源颜色
4uniform vec4 SpecularLightColor;//specular光源颜色
5varying float NdotL, NdotH, NdotV, VdotH ;
6float diff=0.1;
7float spec=1.0;
8void 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