Hi,
I believe a major problem with the attempt to do the handmade resolve is that the depth buffer is disabled with glDisable(GL_DEPTH_TEST). But this also disables the depth write and therefore messes up all the following peels. Before using the handmade resolve the blit framebuffer would fill the depth buffer, but now this should be done manually.
A good way to demonstrate the bug is to only use Peel1 or higher for the FinalStretch shader. This will not display anything.
So a better way is this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 | internal void
ResolveMultisample(opengl_framebuffer *From, opengl_framebuffer *To,
u32 Width, u32 Height)
{
glBindFramebuffer(GL_FRAMEBUFFER, To->FramebufferHandle);
glViewport(0, 0, Width, Height);
glScissor(0, 0, Width, Height);
//Realized after posting only one of glDepthFunc and glClear is needed.
//glClear(GL_DEPTH_BUFFER_BIT);
glDepthFunc(GL_ALWAYS);
...
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glDepthFunc(GL_LEQUAL);
}
|
I found this out while trying to improve the manual resolve shader. I believed the DepthMin/Max range would give good results. But ran into the depth issue while debugging it. After that the DepthMin/Max worked ok if I also used the UsedSampleCount/SampleCount fraction to set the alpha value of the CombinedColor (line 44 below) and a #define DepthThreshold 0.001f:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47 | f32 DepthMin = texelFetch(DepthSampler, ivec2(gl_FragCoord.xy), 0).r;
f32 DepthMax = DepthMin;
for(s32 SampleIndex = 1;
SampleIndex < SampleCount;
++SampleIndex)
{
f32 Depth = texelFetch(DepthSampler, ivec2(gl_FragCoord.xy), SampleIndex).r;
if (Depth < DepthMin) {
f32 Diff = (DepthMin - Depth);
if (Diff >= DepthThreshold) {
DepthMax = Depth;
}
DepthMin = Depth;
} else if (Depth > DepthMax) {
f32 Diff = (Depth - DepthMax);
if (Diff < DepthThreshold) {
DepthMax = Depth;
}
}
}
gl_FragDepth = DepthMax;
v4 CombinedColor = V4(0, 0, 0, 0);
s32 UsedSampleCount = 0;
for(s32 SampleIndex = 0;
SampleIndex < SampleCount;
++SampleIndex)
{
f32 Depth = texelFetch(DepthSampler, ivec2(gl_FragCoord.xy), SampleIndex).r;
if(Depth >= DepthMin && Depth <= DepthMax)
{
v4 Color = texelFetch(ColorSampler, ivec2(gl_FragCoord.xy), SampleIndex);
#if ShaderSimTexReadSRGB
Color.rgb *= Color.rgb;
#endif
CombinedColor += Color;
UsedSampleCount += 1;
}
}
f32 InvSampleCount = 1.0f / f32(UsedSampleCount);
ResultColor = InvSampleCount*CombinedColor;
ResultColor *= f32(UsedSampleCount)/f32(SampleCount);
#if ShaderSimTexWriteSRGB
ResultColor.rgb = sqrt(ResultColor.rgb);
#endif
|
I hope to point these problems out in the prestream tonight, but being in Europe I don't know if I can make it ;)
-----
Some more tweaking:
-----
After a bit more fidgeting, and actually watching the rest of the episode I saw that you where also using centroid to get better depth per resolved pixel. With the centroid still used, some edges won't get smoothed (the 'connection' of a lower block against a higher block).
But disabling the centroid gave weird results along other edges. So I also tried collecting all the samples without respect for the depth they have and only setting the glFragDepth to the DepthMax of the tested range by commenting line 31 to disable the range test. I think this emulates the normal resolve as far as selecting colors the best, but still has the upside of controlling the depth buffer output.
That combined with disabling the centroid and a DepthThreshold of 0.0025f gave the best result. A bit hacky, but it seems to give nice results :)
Happy coding,
Mox