Domanda

EDIT

The problem turned out to be a combination of things, but most importantly I was miscalculating lighting intensities because I wasn't correctly calculating my normal matrix. The fix has left my memory since some time ago now, but I remember I was not taking the transpose-inverse, and that helped a great deal in solving the problem.


I've spent some time working on this problem, but I can't for the life of me figure it out.

I figured out that, when applying multiple light sources to an object, you must clamp the final color values after summing them together, but I'm still getting weirdly dark edges when the lights interact.

Here's a screenshot of what I'm describing:

Lighting problem screenshot (it

There's a head light that faces in the direction of the current camera and another light source to the far left of the scene. The headlight is currently centered just to the right of the teapot's knob/handle, and as you can see, there's some pretty strange interaction going on.

Here's my shader source:

vertex shader

attribute vec4 a_position;
attribute vec4 a_color;
attribute vec4 a_normals;
varying vec4 v_color_or_normal;
varying vec3 cam;
varying vec3 vert;
uniform mat4 u_xformMatrix;
uniform mat4 u_cameraMatrix;
void main() {
  gl_Position = u_cameraMatrix * u_xformMatrix * a_position;
  v_color_or_normal = a_color;
  cam = vec3(u_cameraMatrix * u_xformMatrix * a_position);
  vert = vec3(a_position);
}

fragment shader

precision mediump float;
varying vec4 v_color_or_normal;
varying vec3 cam; //modelview_mat*vertex
varying vec3 vert;//just the vertex
uniform int renderMode; //pass 0 when rendering the ground, 1 when rendering the teapot
uniform vec3 lookVec; //pass the vector representing the camera direction
uniform mat4 u_normalMatrix; //the normal matrix for calculating normals
    //I'm using
    //u_normalMatrix = modelMatrix.invert().transpose() (the transpose inverse)
uniform vec3 camCoords; //headlight origin
uniform vec3 worldLightCoords; //fixed light origin

void main() {
  vec3 emissive = vec3(0.0, 0.0, 0.0); //my professor requires this. Not sure why.
  vec3 ambient;
  vec3 diffuse;
  vec3 specular;
  float shiny;
  vec3 normal;

  if(renderMode == 0) { //render the ground colors
    ambient = vec3(v_color_or_normal - vec4(0.05, 0.3, 0.05, 0.0));
     diffuse = vec3(0.05, 0.3, 0.05);
     specular = vec3(0.22, 0.22, 0.22);
     shiny = 4.0;
    normal = vec3(normalize(u_normalMatrix * vec4(0.0, 1.0, 0.0, 1.0)));
  }

  if(renderMode == 1) { //render the teapot colors
    //do stuff for teapot
    ambient = vec3(0.105882, 0.58824, 0.113725);
    normal = vec3(normalize(u_normalMatrix * v_color_or_normal));
     diffuse = vec3(0.427451, 0.470588, 0.541176);
     specular = vec3(0.22, 0.22, 0.22);
     shiny = 9.0;
  }

  vec3 worldLightPos = worldLightCoords;
  vec3 camLightPos = camCoords;
  vec3 fixedLightDirection = normalize(worldLightPos - vert);
  vec3 camLightDirection = normalize(lookVec - vec3(0,0,10.0));

      //calculate diffuse/spec for fixed light source
  float lambertianFix = max(dot(fixedLightDirection, normal), 0.0);
  float specFix = 0.0;

  if(lambertianFix > 0.0) {
    vec3 R = reflect(-fixedLightDirection, normal);
    vec3 viewDirection = normalize(-vert);
    float specularAngle = max(dot(R, viewDirection), 0.0);
    specFix = pow(specularAngle, shiny);

  }

  vec3 total_diffuse = lambertianFix*diffuse;
  vec3 total_specular = specFix*specular;

      //calculate diffuse/spec for headlight
  float lambertianCam = max(dot(camLightDirection, normal), 0.0);
  float specCam = 0.0;

  if(lambertianCam > 0.0) { 
    vec3 R = reflect(-camLightDirection, normal);
    vec3 viewDirection = normalize(-cam);
    float specularAngle = max(dot(R, viewDirection), 0.0);
    specCam = pow(specularAngle, shiny);
  }

  total_diffuse += lambertianCam*diffuse;
  total_specular += specCam*specular;   

      //clamp values
  total_diffuse = clamp(total_diffuse, 0.0, 1.0);
  total_specular = clamp(total_specular, 0.0, 1.0);

      //put it all together
  gl_FragColor = vec4(emissive + ambient + total_diffuse + total_specular, 1.0);


}

Any help is much appreciated. Thanks!

È stato utile?

Soluzione

The problem turned out to be a combination of things, but most importantly I was miscalculating lighting intensities because I wasn't correctly calculating my normal matrix. The fix has left my memory since some time ago now, but I remember I was not taking the transpose-inverse, and that helped a great deal in solving the problem.

So... the problem wasn't even in the code I provided. My bad.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top