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

, когда вы видите, что свет, движущийся вокруг эффекта, очень поразителен;там много шума с фрагментами, которые становятся черно-белыми все время.Это может быть несколько уменьшено при использовании minvariance (таким образом игнорируя что-либо ниже определенного порога), но тогда мы получим еще худшие эффекты с неправильным падением (см. Мой другой пост).
Я использую GLSL 1.2, потому что я нахожусь наMac, поэтому у меня нет доступа к функции modf, чтобы разделить точность по двум каналам, как описано в Gem 3 GPU, глава 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);
}
Затенение карты теней
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.