使用MSAA出现了抗锯齿问题,在使用深度和FBO绘制CSG图形时。

7
我已经重新实现了OpenCSG,以适应现代OpenGL版本。
像素格式属性:
NSOpenGLPFAColorSize    , 24 ,
NSOpenGLPFAAlphaSize    , 8  ,
NSOpenGLPFADepthSize    , 32 ,
NSOpenGLPFAStencilSize  , 8  ,
NSOpenGLPFAAccelerated  ,
NSOpenGLPFADoubleBuffer ,
NSOpenGLPFASupersample  ,
NSOpenGLPFASampleBuffers, 1  ,
NSOpenGLPFASamples      , 4  ,

FBO规格:(尝试使用多重采样的FBO进行渲染,但是线条更加明显和可见,请查看底部的截图)
- 创建2次幂大小的纹理,GL_RGBA(尝试过GL_RGBA8和GL_RGBA32F)
- GL_DEPTH24_STENCIL8(尝试过GL_DEPTH32_STENCIL8,没有结果)
简单算法Goldfeather:
while (i < depth complexity) {
    take channel for render
       merge layers if no free channel 
    render each layer with stencil func, mask and depth params to channel (FBO)
}
merge layers (taking texture from FBO and render objects again with applying shader below)


在着色器中,我有合并代码(从FBO结果纹理重叠在渲染之上进行测试,在OpenCSG中设置投影纹理):

     vec2 ndcPos = gl_FragCoord.xy / sizetexture.xy;
     vec4 maskColor = texture2D(maskTexture, ndcPos.xy);
     if (maskColor[channel] < 0.5) {
        discard;
     }

enter image description here

看起来是因为FBO获取到了不够清晰的纹理或者大小不对。
编辑:
这些线条只出现在相交的减法网格上。 编辑2:
通过渲染到非MSAA FBO并在结果上应用FXAA进行修复。

32位色缓冲区+8位Alpha对我来说特别不寻常。通常像素格式设置为:32位(8位未使用)RGB + 0 A或24位RGB + 8位A,几乎从不是32位RGB + 8位A(这会产生40位色缓冲区)。虽然CGL将匹配最接近的格式,但您正在请求一些根本奇怪的东西,这应该没有影响。 - Andon M. Coleman
@AndonM.Coleman,使用该代码后,模型变成了蓝色,线条仍然可见,图片。在Mac OS X上,超采样比多重采样更优。我将尝试将其更改为MSAA,并查看GL_SAMPLE_ALPHA_TO_COVERAGE。 - Volodymyr B.
实际上,我关于多重采样的观点是,除非您在OS X上使用软件渲染器,否则您实际上不会得到超级采样。像素格式中的Supersample部分是一个提示,如果您期望它给您超级采样,则会遇到麻烦。您可能需要尝试超级采样+软件渲染,只是为了查看是否存在问题;如果是这样,您可能别无选择,只能使用单采样渲染。 - Andon M. Coleman
一定有办法在这个实现中使用多重采样。单采样留到最后。而且,我有这个代码在iOS上以单采样渲染运行。它有类似的非常奇怪的错误,在512x512平方渲染的角落是好的,但在屏幕的另一个部分,一切都有锯齿状的边缘和黑线,看起来像MSAA没有应用,但我在iOS上没有使用MSAA(不能在这里向您展示截图)。在iPad 3/4代中出现了问题,在iPad Air上一切正常。 - Volodymyr B.
@AndonM.Coleman 我已经改成了单采样渲染并应用了FXAA,虽然不如MSAA完美,但还可以。FXAA在某些地方会有点模糊。 - Volodymyr B.
显示剩余4条评论
1个回答

0

不确定我是否正确理解了您的解释。着色器中您正在采样的是什么类型的纹理?

我不知道您正在实现的算法的具体细节,但如果该纹理包含已经完成了多重采样收集的某些先前计算的结果,我真的不确定您是否可以将该结果用于整个片段(及其所有样本)。掩码在边缘处会逐渐消失,这似乎是问题所在。

也许您应该手动进行样本收集,例如在着色器中使用sampler2DMS并使用texelFetch读取单个样本。

另一种解决方案可能是在第一次传递中将gl_SampleMask设置为全部为1,以防止边界处的淡化。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接