Отложенный рендер с легкими объемами производит странную полосу

У меня есть отложенный рендер, который вычисляет только уравнения освещения, когда текущий фрагмент находится в диапазоне источника света. Я делаю это, вычисляя размер светового объема в моем приложении и отправляю это вместе с другой световой информацией в шейдеры. Затем я проверяю расстояние между фрагментом и lightPos (на свет) и использую громкость света в качестве порога.

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

Отложенное отображение рендерера

Код фрагмента шейдера выглядит следующим образом:

vec3 position = texture(worldPos, fs_in.TexCoords).rgb;
vec3 normal = texture(normals, fs_in.TexCoords).rgb;
normal = normalize(normal * 2.0 - 1.0);
vec3 color = texture(albedo, fs_in.TexCoords).rgb;
float depth = texture(worldPos, fs_in.TexCoords).a;
// Add global ambient value
fragColor = vec4(vec3(0.1) * color, 0.0);
for(int i = 0; i < NR_LIGHTS; ++i)
{
float distance = abs(length(position - lights[i].Position.xyz));
if(distance <= lights[i].Size)
{
vec3 lighting;
// Ambient
lighting += lights[i].Ambient * color;
// Diffuse
vec3 lightDir = normalize(lights[i].Position.xyz - position);
float diffuse = max(dot(normal, lightDir), 0.0);
lighting += diffuse * lights[i].Diffuse * color;
// Specular
vec3 viewDir = normalize(viewPos - position);
vec3 reflectDir = reflect(-lightDir, normal);
float spec = pow(max(dot(viewDir, reflectDir), 0.0), 8);
lighting += spec * lights[i].Specular;

// Calculate attenuation
float attenuation = max(1.0f - lights[i].Linear * distance, 0.0);
lighting *= attenuation;
fragColor += vec4(lighting, 0.0);
}
}
fragColor.a = 1.0;

Функция затухания является линейной функцией расстояния между положением фрагмента и каждым источником света.

В этой конкретной сцене я использую линейное значение ослабления 0.075 из которых я генерирую размер / радиус источника света как:

Size = 1.0 / Linear;

некоторые наблюдения

Когда я снимаю проверку расстояния if(distance <= lights[i].Size) Я не понимаю странной проблемы с границей.

Если я визуализирую значение освещения одного источника света и визуализирую расстояние как distance/lights.Size Я получаю следующие 2 изображения:

Отложенное отображение рендерера

который выглядит так, как будто расчеты радиуса / расстояния света и ослабления света одинаковы по радиусу.

Когда я изменяю уравнение проверки расстояния на if(distance <= lights[i].Size * 2.0f) (радикально увеличивая радиус света), я получаю значительно меньше полосы границ, но если я смотрю достаточно близко, я время от времени вижу их, так что даже это не устраняет проблему полностью.

Я понятия не имею, что вызывает это, и у меня нет вариантов на данный момент.

4

Решение

Эта секция:

    vec3 lighting;
// Ambient
lighting += lights[i].Ambient * color;

Вы никогда не инициализируете освещение, прежде чем добавить его. Я думаю, что это может вызвать неопределенное поведение. Попробуйте изменить это на:

    // Ambient
vec3 lighting = lights[i].Ambient * color;
3

Другие решения


По вопросам рекламы [email protected]