我尝试使用OpenGL和Fragment Shader实现基本的聚光灯。但是,我注意到聚光灯的外围有明显的黑色边框伪影。我希望在聚光灯圆圈内和聚光灯圆圈外的颜色之间会出现硬性分界线。
茶壶的颜色为纯灰色(0.75,0.75,0.75),其照明方式为:
这是片段着色器代码(假设在顶点着色器和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)。。。红色通道不应插入。
谢谢!