我在SAVSM设置中遇到精度损失的问题。
当你看到光线移动时效果非常惊人;有很多噪音,碎片一直在黑白分明。通过使用微分方程(因此忽略低于某个阈值的任何东西)可以稍微减少这一点,但是随着不正确的衰减,我们会得到更糟糕的效果(参见我的其他帖子)。
我正在使用GLSL 1.2,因为我在Mac上,所以我无法访问modf函数,以便在GPU Gems 3第8章中描述的两个通道之间分割精度。
我将GL_RGBA32F_ARB纹理与Framebuffer对象一起使用,然后ping两个纹理来生成一个求和区域表,我将其用于VSM算法。
Moments / Depth Shader为表创建基础
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);
}
Summed表似乎确实有效。我知道这是因为我有一个函数可以从求和表转换回原始深度图,这两个图像看起来几乎相同。我也使用-0.5 + 0.5技巧以获得更高的精度但它似乎没有帮助
我的问题是这个,鉴于im只在一个只有GLSL 1.2的mac上,如何在两个通道上分割精度?如果我可以在求和表中使用这些额外的通道空间,那么这可能会起作用吗?我见过一些使用modf的东西,但我不能使用。
另外,人们建议使用32位整数缓冲区,但我不认为我在macbook pro上支持这些缓冲区。