Числовая стабильность с таблицами суммированной области в теневом отображении

#macos #opengl #glsl #shadow

#macos #opengl #glsl #тень

Вопрос:

У меня возникла проблема с потерей точности в моей настройке SAVSM.

введите описание изображения здесь

когда вы видите движущийся свет, эффект очень поразительный; возникает много шума, фрагменты постоянно становятся черно-белыми. Это может быть несколько уменьшено с помощью minvariance (таким образом, игнорируя все, что ниже определенного порога), но тогда мы получаем еще худшие эффекты с неправильным уменьшением (см. Мой другой пост).

Я использую GLSL 1.2, потому что я на Mac, поэтому у меня нет доступа к функции modf, чтобы разделить точность по двум каналам, как описано в GPU Gems 3, глава 8.

Я использую текстуры GL_RGBA32F_ARB с объектом Framebuffer и подключаю две текстуры для генерации таблицы суммированной области, которую я использую с алгоритмом VSM.

Моменты / Шейдер глубины для создания основы для таблиц

 varying vec4 v_position;
varying float tDepth;


float g_DistributeFactor = 1024.0;  


void main()
{
    // Is this linear depth? I would say yes but one can't be utterly sure.
    // Could try a divide by the far plane?

    float depth = v_position.z / v_position.w ;
    depth = depth * 0.5   0.5;          //Don't forget to move away from unit cube ([-1,1]) to [0,1] coordinate system

    vec2 moments = vec2(depth, depth * depth);


    // Adjusting moments (this is sort of bias per pixel) using derivative
    float dx = dFdx(depth);
    float dy = dFdy(depth);
    moments.y  = 0.25 * (dx*dx dy*dy);

    // Subtract 0.5 off now so we can get this into our summed area table calc

    //moments -= 0.5;

    // Split the moments into rg and ba for EVEN MORE PRECISION

//  float FactorInv = 1.0 / g_DistributeFactor;

//  gl_FragColor = vec4(floor(moments.x) * FactorInv, fract(moments.x ) * g_DistributeFactor, 
//                  floor(moments.y)  * FactorInv, fract(moments.y)  * g_DistributeFactor);


    gl_FragColor = vec4(moments,0.0,0.0);
}
  

Шейдер shadowmap

 varying vec4 v_position;
varying float tDepth;


float g_DistributeFactor = 1024.0;  


void main()
{
    // Is this linear depth? I would say yes but one can't be utterly sure.
    // Could try a divide by the far plane?

    float depth = v_position.z / v_position.w ;
    depth = depth * 0.5   0.5;          //Don't forget to move away from unit cube ([-1,1]) to [0,1] coordinate system

    vec2 moments = vec2(depth, depth * depth);


    // Adjusting moments (this is sort of bias per pixel) using derivative
    float dx = dFdx(depth);
    float dy = dFdy(depth);
    moments.y  = 0.25 * (dx*dx dy*dy);

    // Subtract 0.5 off now so we can get this into our summed area table calc

    //moments -= 0.5;

    // Split the moments into rg and ba for EVEN MORE PRECISION

//  float FactorInv = 1.0 / g_DistributeFactor;

//  gl_FragColor = vec4(floor(moments.x) * FactorInv, fract(moments.x ) * g_DistributeFactor, 
//                  floor(moments.y)  * FactorInv, fract(moments.y)  * g_DistributeFactor);


    gl_FragColor = vec4(moments,0.0,0.0);
}
  

Похоже, что суммированные таблицы действительно работают. Я знаю это, потому что у меня есть функция, которая преобразует обратно из суммированной таблицы в исходную карту глубины, и два изображения выглядят практически одинаково. Я также использую трюк -0,5 0,5, чтобы добиться большей точности, но, похоже, это не помогает

Мой вопрос заключается в следующем, учитывая, что я на Mac, который имеет только GLSL 1.2, как я могу разделить точность по двум каналам? Если бы я мог использовать эти дополнительные каналы для пространства в суммированной таблице, то, возможно, это сработало бы? Я видел кое-что, использующее modf, но это недоступно для меня.

Кроме того, люди предложили 32-разрядные целочисленные буферы, но я не думаю, что у меня есть поддержка для них на моем macbook pro.

Комментарии:

1. Вы нашли хорошее решение для этого в конце? В настоящее время я нахожусь в начале своего путешествия по текстурам глубины суммированной области и уже сталкиваюсь с похожими проблемами.