Я пытаюсь реализовать базовый прожектор, используя OpenGL и Fragment Shader. Тем не менее, я замечаю, что на периферии прожектора есть отчетливый артефакт с черной каймой. Я ожидаю увидеть резкую границу между цветом внутри круга прожектора и снаружи круга прожектора.
.
Чайник имеет простой серый цвет (0,75,0,75,0,75), он подсвечивается:
- синий точечный светильник между корпусом и ручкой
- красный направленный свет сверху справа, указывающий на центр чайника
- зеленый прожектор от камеры к корпусу
Вот код фрагмента шейдера (при условии, что преобразования выполняются правильно в вершинном шейдере и на стороне процессора):
#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) ... Красный канал не должен быть интерполирован.
Спасибо!