聚光灯下的黑色边框伪影(OpenGL)

时间:2018-09-14 08:59:48

标签: opengl glsl rendering fragment-shader spotlight

我尝试使用OpenGL和Fragment Shader实现基本的聚光灯。但是,我注意到聚光灯的外围有明显的黑色边框伪影。我希望在聚光灯圆圈内和聚光灯圆圈外的颜色之间会出现硬性分界线。

茶壶的颜色为纯灰色(0.75,0.75,0.75),其照明方式为:

  1. 身体和手柄之间的蓝点灯
  2. 从右上方指向茶壶中心的红色定向灯
  3. 从相机朝向身体的绿色聚光灯

这是片段着色器代码(假设在顶点着色器和CPU端正确完成了转换):

#version 330 compatibility
#extension GL_ARB_separate_shader_objects : enable

in vec3   oNormal;
in vec3   oPos;
out vec4  Color;

uniform vec3 light0Pos;
uniform vec3 light0Color;
uniform vec3 light1Dir;
uniform vec3 light1Color;
uniform vec3 light2Pos;
uniform vec3 light2Color;
uniform vec3 light2SpotDir;
uniform float light2SpotExp;
uniform float light2SpotCut;

void main()
{
  vec3 nNormal = normalize(oNormal);
  vec3 surfaceColor = vec3(0.75, 0.75, 0.75);
  vec3 tempColor = vec3 (0.0, 0.0, 0.0);

  //first light: point light
  float w = max(dot(nNormal, normalize(light0Pos - oPos)), 0.0);
  tempColor = surfaceColor * vec3(w) * light0Color.xyz;

  //second light: directional light
  w = max(dot(nNormal, normalize(light1Dir) * vec3(-1.0)), 0.0);
  tempColor = tempColor + max(vec3(0.0),surfaceColor * vec3(w) * light1Color.xyz);

  //third light: spotlight
  vec3 spotDir = normalize(vec3(light2SpotDir));
  vec3 light2Dir = normalize(oPos - light2Pos);
  w = dot(spotDir, light2Dir);
  float c = step(cos(radians(light2SpotCut * 0.5)),w);
  w = c * pow(w,light2SpotExp) * max(dot(nNormal, normalize(light2Dir) * vec3(-1.0)), 0.0);
  tempColor = tempColor + max(vec3(0.0),surfaceColor * vec3(w) * light2Color.xyz);

  Color = vec4(tempColor, 1.0);
}

我怀疑存在插值问题。如果我检查像素值,则聚光灯外且靠近边框的红色像素的颜色为(87、0、0),聚光灯内且靠近边框的绿色/黄色像素的颜色为(83、66、0) 。如果是由于插值,则边框的颜色应为(80,30,0)。但是,边框的颜色改为(17,9,0)。。。红色通道不应插入。

谢谢!

0 个答案:

没有答案