Ashikhmin-Shirley模型实施:丑陋的结果

时间:2013-11-25 14:07:22

标签: glsl shader fragment-shader

我正在尝试使用这些公式实现Ashikhmin-Shirley模型:

enter image description here

这是GLSL 1.2片段着色器代码:

uniform vec4 materialAmbient, materialDiffuse, materialSpecular;
uniform float materialShininess;
uniform vec4 lightAmbient, lightDiffuse, lightSpecular, lightPosition;

varying vec3 P,N;


float pi= 3.1415926535;


vec4 Fd(float NdotV, float NdotL) {
    vec4 fd= (28.0 * materialDiffuse * lightDiffuse) / (23.0 * pi) * (1.0 - materialSpecular * lightSpecular);
    fd*= 1.0 - pow(1.0-NdotV/2.0,5.0);
    fd*= 1.0 - pow(1.0-NdotL/2.0, 5.0);
    return fd;
}

vec4 Fr(float u, vec4 specular) {
    return specular + (1.0-specular) * pow(1.0 - u, 5.0);
}

// f= phi
vec4 Fs(float VdotH, float NdotH, float NdotL, float NdotV, float et, float eb, float f) {
    vec4 fs= Fr(VdotH, materialSpecular * lightSpecular);
    fs*= sqrt((et+1.0) * (eb+1.0)) / (8.0 * pi);
    fs*=  pow(NdotH, et*pow(cos(f),2.0) + eb*pow(sin(f),2.0)) / (VdotH * max(NdotL, NdotV));
    return fs;
}


void main(void) {
    vec3 L= normalize(vec3(lightPosition) - P);
    vec3 V= cameraPosition;
    vec3 H= normalize(L+V);
    float NdotL= max(dot(N,L),0.0);
    float NdotV= max(dot(N,V),0.0);
    float NdotH= max(dot(N,H),0.0);
    float VdotH= max(dot(V,H),0.0);
    gl_FragColor= Fd(NdotV, NdotL) + Fs(VdotH, NdotH, NdotL, NdotV, 128.0,128.0,1.0);
}

我已经检查过,似乎所有的制服和变化都以正确的方式传递,我从顶点着色器传递P和N.变量是:

  1. 光线方向:L;
  2. 表面法线:N;
  3. 摄像头方向:V;
  4. 半矢量:H;
  5. 片段位置:P。
  6. 我通过的制服是:

    1. light {高光|漫反射| Ambient}:0xffffff(当然转换为rgba向量);
    2. materialAmbient:0x543807;
    3. materialDiffuse:0xc6901d;
    4. materialSpecular:0xfdefce;
    5. materialShininess:27.8974。
    6. 这是我得到的结果:

      enter image description here

      这对我来说似乎很奇怪,我在网上看到过Ashkhmin-Shirley实施的其他图片,但它们并不相似。这是一个例子:

      enter image description here

      我想要一个这样的!!也许我使用错误的phi值和其他值?或者配方中出现了什么问题?

1 个答案:

答案 0 :(得分:0)

我想你可能会错过括号:

vec4 fd= (28.0 * materialDiffuse * lightDiffuse) / (23.0 * pi) * (1.0 - materialSpecular * lightSpecular);

vec4 fd= ((28.0 * materialDiffuse * lightDiffuse) / (23.0 * pi)) * (1.0 - materialSpecular * lightSpecular);

代替。