Артефакт с черной рамкой в ​​центре внимания (OpenGL) - PullRequest
0 голосов
/ 14 сентября 2018

Я пытаюсь реализовать базовый прожектор, используя OpenGL и Fragment Shader. Тем не менее, я замечаю, что на периферии прожектора есть отчетливый артефакт с черной каймой. Я ожидаю увидеть резкую границу между цветом внутри круга прожектора и снаружи круга прожектора.

.

Чайник имеет простой серый цвет (0,75,0,75,0,75), он подсвечивается:

  1. синий точечный светильник между корпусом и ручкой
  2. красный направленный свет сверху справа, указывающий на центр чайника
  3. зеленый прожектор от камеры к корпусу

Вот код фрагмента шейдера (при условии, что преобразования выполняются правильно в вершинном шейдере и на стороне процессора):

#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) ... Красный канал не должен быть интерполирован.

Спасибо!

...