Модель освещения Phong на самом деле ничего не освещает - PullRequest
1 голос
/ 07 декабря 2011

В настоящее время у меня есть задание по внедрению модели освещения Phong в openGL / GLSL. Два шейдера, с которыми я сейчас работаю, приведены ниже. Проблема в том, что в фрагментном шейдере, если я не добавлю vColor к gl_FragColor, тогда вся фигура будет черной. Однако, если я действительно добавлю vColor, тогда вся форма будет того цвета без освещения. Я пытался решить это в течение нескольких часов, но не повезло. Что является причиной этого? Это проблема в моих шейдерах или проблема в коде openGL? Я использую один материал и один точечный источник света, который я покажу после шейдеров.

Редактировать: если я установлю gl_FragColor = vec4(N, 1.0), тогда объект выглядит так:

enter image description here

вершинный шейдер:

#version 150

in vec4 vPosition;
in vec3 vNormal;

uniform mat4 vMatrix;
uniform vec4 LightPosition;

out vec3 fNorm;
out vec3 fEye;
out vec3 fLight;

void main() {
  fNorm = vNormal;
  fEye = vPosition.xyz;
  fLight = LightPosition.xyz;

  if(LightPosition.w != 0.0) {
    fLight = LightPosition.xyz - vPosition.xyz;
  }

gl_Position = vMatrix * vPosition;
}

фрагментный шейдер:

#version 150

in vec3 fNorm;
in vec3 fLight;
in vec3 fEye;

uniform vec4 vColor;
uniform vec4 AmbientProduct, DiffuseProduct, SpecularProduct;
uniform mat4 vMatrix;
uniform vec4 LightPosition;
uniform float Shininess;

void main(){
    vec3 N = normalize(fNorm);
    vec3 E = normalize(fEye);
    vec3 L = normalize(fLight);
    vec3 H = normalize(L + E);

    vec4 ambient = AmbientProduct;

    float Kd = max(dot(L, N), 0.0);
    vec4 diffuse = Kd * DiffuseProduct;

    float Ks = pow(max(dot(N, H), 0.0), Shininess);
    vec4 specular = Ks * SpecularProduct;
    if(dot(L,N) < 0.0) 
        specular = vec4(0.0, 0.0, 0.0, 1.0); 

    gl_FragColor = vColor + ambient + diffuse + specular;
}

Установочные материалы и свет:

void init() {

    setMaterials(vec4(1.0, 0.0, 0.0, 0.0), //ambient
             vec4(1.0, 0.8, 0.0, 1.0), //diffuse
             vec4(1.0, 1.0, 1.0, 1.0), //specular
             100.0); //shine

    setLightSource(vec4(1.0, 0.0, 0.0, 1.0), //ambient
               vec4(1.0, 0.0, 0.0, 1.0), //diffuse
               vec4(1.0, 0.0, 0.0, 1.0), //specular
               vec4(1.0, 2.0, 3.0, 1.0)); //position

    setProducts();

    ....
}

/*
 * Sets the material properties for Phong lighting model.
 */
void setMaterials(vec4 amb, vec4 dif, vec4 spec, GLfloat s) {
    ambient = amb;
    diffuse = dif;
    specular = spec;
    shine = s;

    glUniform1f(vShininess, shine);
}

/*
 * Set light source properties.
 */
void setLightSource(vec4 amb, vec4 dif, vec4 spec, vec4 pos) {
    ambient0 = amb;
    diffuse0 = dif;
    specular0 = spec;
    light0_pos = pos;

    glUniform4fv(vLightPosition, 1, light0_pos);
}

/*
 * Find the products of materials components and light components.
 */
void setProducts(){
    vec4 ambientProduct = ambient * ambient0;
    vec4 diffuseProduct = diffuse * diffuse0;
    vec4 specularProduct = specular * specular0;

    glUniform4fv(vAmbientProduct, 1, ambientProduct);
    glUniform4fv(vDiffuseProduct, 1, diffuseProduct);
    glUniform4fv(vSpecularProduct, 1, specularProduct);

}

1 Ответ

0 голосов
/ 07 декабря 2011

Ваш окончательный состав освещения выглядит неправильно:

gl_FragColor = vColor + ambient + diffuse + specular;

Это должно быть что-то вроде

gl_FragColor = vColor * (ambient + diffuse) + specular;

т.е. освещение, модулированное альбедо объекта.

...