WebGL多个光源创建黑暗边缘

时间:2014-03-14 17:49:49

标签: javascript webgl lighting

修改

问题结果是事情的组合,但最重要的是我错误计算了照明强度,因为我没有正确计算我的正常矩阵。从现在开始,这个修复程序已经留下了我的记忆,但是我记得我没有采用转置反转,这对解决这个问题有很大的帮助。


我已经花了一些时间研究这个问题,但是我无法解决这个问题。

我发现,当将多个光源应用到物体时,必须在将它们相加后将最终颜色值钳制起来,但是当灯光相互作用时,我仍然会得到奇怪的暗边缘。

这是我所描述的截图:

Lighting problem screenshot (it's a teapot)

头灯朝向当前相机的方向,另一个光源朝向场景的最左侧。目前大灯正好位于茶壶旋钮/手柄的右侧,正如您所看到的,还有一些非常奇怪的互动。

这是我的着色器来源:

顶点着色器

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);
}

片段着色器

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);


}

非常感谢任何帮助。谢谢!

1 个答案:

答案 0 :(得分:0)

问题结果是事情的组合,但最重要的是我错误计算了照明强度,因为我没有正确计算我的正常矩阵。从现在开始,这个修复程序已经留下了我的记忆,但是我记得我没有采用转置反转,这对解决这个问题有很大的帮助。

所以......问题甚至不在我提供的代码中。我的错。