Mirrors/portals don't render
Moderator: GZDoom Developers
Forum rules
Please don't bump threads here if you have a problem - it will often be forgotten about if you do. Instead, make a new thread here.
Please don't bump threads here if you have a problem - it will often be forgotten about if you do. Instead, make a new thread here.
- Marisa the Magician
- Posts: 3886
- Joined: Fri Feb 08, 2008 9:15 am
- Preferred Pronouns: She/Her
- Operating System Version (Optional): (btw I use) Arch
- Graphics Processor: nVidia with Vulkan support
- Location: Vigo, Galicia
- Contact:
Mirrors/portals don't render
It appears that mirrors just get cut off and draw the sky behind them when using softpoly, as seen by loading Kinsie's test map and turning around.
Not sure if this may be just mirrors, or portals in general.
Not sure if this may be just mirrors, or portals in general.
- drfrag
- Vintage GZDoom Developer
- Posts: 3141
- Joined: Fri Apr 23, 2004 3:51 am
- Location: Spain
- Contact:
Re: Mirrors don't render
It's not only mirrors but portals. I've tried infinity.wad.
viewtopic.php?f=3&t=52118#p909982
I don't think it's an easy fix.
viewtopic.php?f=3&t=52118#p909982
I don't think it's an easy fix.
Re: Mirrors/portals don't render
I have been reviewing and looking for a solution, but I have not succeeded, in my opinion the error must be in the depthbufer and stencilbuffer, which does not work properly.
But I've been doing some some strange tests, if I added the next line in the code.
the following happens:
the portal is seen, but only if the sky is present in the portal sector.
including mirrors:
now if I put all sectors with sky, all portals will be visible
which makes me think it occupies a base behind the entire map so that the portal is visible, as the sky does. but for this insurance modify the number of visible triangles in the sky to see what was going on.
and the following happens the portals are seen between cut.
forgiveness for the excessive amount of images but they are necessary.
But I've been doing some some strange tests, if I added the next line in the code.
the following happens:
the portal is seen, but only if the sky is present in the portal sector.
including mirrors:
now if I put all sectors with sky, all portals will be visible
which makes me think it occupies a base behind the entire map so that the portal is visible, as the sky does. but for this insurance modify the number of visible triangles in the sky to see what was going on.
and the following happens the portals are seen between cut.
forgiveness for the excessive amount of images but they are necessary.
- drfrag
- Vintage GZDoom Developer
- Posts: 3141
- Joined: Fri Apr 23, 2004 3:51 am
- Location: Spain
- Contact:
Re: Mirrors/portals don't render
Sorry no idea, hope that @dpJudas can help.
Re: Mirrors/portals don't render
Softpoly draws its triangles by first splitting them into line spans. Then for each line span it splits it into span segments by testing if fragments (pixels) in the span passes the depth and stencil tests. The function doing this is called TestSpan. TestSpan then calls DrawSpan for each span segment that passes the tests.
DrawSpan uses the fragment shader to generate the pixels for a span segment. Then DrawSpan copies or blends the result into the frame buffer. DrawSpan also writes the depth values to the depth buffer and updates the stencil buffer.
If the stencil buffer isn't working properly there are a couple of possibilities. It could be the WriteStencil function not writing correctly to the buffer (unlikely). It could be TestSpan not testing correctly from the buffer (more likely). Or it could be DepthTest, StencilTest, WriteStencil or WriteDepth on PolyTriangleThreadData not being correctly set up for the portal (most likely).
At the higher level the hardware renderer draws everything by setting up state using a class called FRenderState. Each backend has an implementation of this class that forwards this state to its rendering API. For example, for OpenGL the FRenderState::EnableStencil function calls glEnable(GL_STENCIL_TEST) in the FGLRenderState::EnableStencil function. For Softpoly this is the PolyRenderState::EnableStencil function. The functions controlling the depth/stencil state are: SetDepthClamp, SetDepthMask, SetDepthFunc, SetDepthRange, SetStencil and EnableStencil.
Softpoly delays forwarding those calls until PolyRenderState::Apply is called. Here it calls functions on mDrawCommands that eventually moves this state to PolyTriangleThreadData. So there's basically two possibilities here. Either this forwarding of state fails or is incomplete, resulting in the DepthTest+StencilTest+WriteStencil+WriteDepth booleans to be wrong in PolyTriangleThreadData. OR the error is in TestSpan or WriteStencil. Since I didn't write the portals in GZDoom I can't really say based on any screenshots which state is most likely wrong.
Note that your WriteDepth=true line seems to indicate maybe it always needs to be true when WriteStencil is also set to true by PolyRenderState::Apply.
DrawSpan uses the fragment shader to generate the pixels for a span segment. Then DrawSpan copies or blends the result into the frame buffer. DrawSpan also writes the depth values to the depth buffer and updates the stencil buffer.
If the stencil buffer isn't working properly there are a couple of possibilities. It could be the WriteStencil function not writing correctly to the buffer (unlikely). It could be TestSpan not testing correctly from the buffer (more likely). Or it could be DepthTest, StencilTest, WriteStencil or WriteDepth on PolyTriangleThreadData not being correctly set up for the portal (most likely).
At the higher level the hardware renderer draws everything by setting up state using a class called FRenderState. Each backend has an implementation of this class that forwards this state to its rendering API. For example, for OpenGL the FRenderState::EnableStencil function calls glEnable(GL_STENCIL_TEST) in the FGLRenderState::EnableStencil function. For Softpoly this is the PolyRenderState::EnableStencil function. The functions controlling the depth/stencil state are: SetDepthClamp, SetDepthMask, SetDepthFunc, SetDepthRange, SetStencil and EnableStencil.
Softpoly delays forwarding those calls until PolyRenderState::Apply is called. Here it calls functions on mDrawCommands that eventually moves this state to PolyTriangleThreadData. So there's basically two possibilities here. Either this forwarding of state fails or is incomplete, resulting in the DepthTest+StencilTest+WriteStencil+WriteDepth booleans to be wrong in PolyTriangleThreadData. OR the error is in TestSpan or WriteStencil. Since I didn't write the portals in GZDoom I can't really say based on any screenshots which state is most likely wrong.
Note that your WriteDepth=true line seems to indicate maybe it always needs to be true when WriteStencil is also set to true by PolyRenderState::Apply.
Re: Mirrors/portals don't render
Looking a bit further at this issue, it looks like the problem might actually be that HWPortal::DrawPortalStencil uses a very large quad to draw the portal and that softpoly may have trouble clipping it correctly. At least for portals.wad it fails to fill the portal with its intended depth values.
Edit: or maybe not. Not really sure I read the code in DrawPortalStencil right at all. Maybe it just draws the line faces by index and then sometimes does some bounding box voodoo whatever that might be about.
Edit: or maybe not. Not really sure I read the code in DrawPortalStencil right at all. Maybe it just draws the line faces by index and then sometimes does some bounding box voodoo whatever that might be about.
Re: Mirrors/portals don't render
Seems SetDepthRange wasn't implemented. Fixed it in https://github.com/coelckers/gzdoom/pull/1323.
- drfrag
- Vintage GZDoom Developer
- Posts: 3141
- Joined: Fri Apr 23, 2004 3:51 am
- Location: Spain
- Contact:
Re: Mirrors/portals don't render
@dpJudas: thanks very much for your help and the fix!
- drfrag
- Vintage GZDoom Developer
- Posts: 3141
- Joined: Fri Apr 23, 2004 3:51 am
- Location: Spain
- Contact:
Re: Mirrors/portals don't render
Now there's another problem but it's a minor thing. If you're at the entrance of the portal and move the mouse up and down or left and right some geometry appears and disappears inside of the portal (something you should not see). It also happens when you cross the portal. Seen in infinity.wad.
Re: Mirrors/portals don't render
If you mean standing so close to the portal that the portal line itself clips into the view near plane, then that's a known problem with portals that happens in both the software and hardware renderer. What you're seeing is the geometry behind the portal line. In portals.wad you see it as these red bricks that you are never meant to see.
Technically it might be avoidable by filling the stencil+depth buffer differently when the line clips into the near plane, but that's a fix needed for the hardware renderer and not softpoly.
Technically it might be avoidable by filling the stencil+depth buffer differently when the line clips into the near plane, but that's a fix needed for the hardware renderer and not softpoly.
- Graf Zahl
- Lead GZDoom+Raze Developer
- Posts: 49056
- Joined: Sat Jul 19, 2003 10:19 am
- Location: Germany
Re: Mirrors/portals don't render
The hardware renderer uses depth clamping to avoid this issue for the most part. Can't you do the same in softpoly?
Re: Mirrors/portals don't render
Ah, didn't know depth clamp was active. Also just tested portals.wad with the hardware renderer and indeed I don't see the red lines there in OpenGL and Vulkan. I guess my memory of portals.wad wasn't entirely accurate.
And yes, softpoly could then also just depth clamp.
And yes, softpoly could then also just depth clamp.
- drfrag
- Vintage GZDoom Developer
- Posts: 3141
- Joined: Fri Apr 23, 2004 3:51 am
- Location: Spain
- Contact:
Re: Mirrors/portals don't render
That was it. Thanks again, now it's mostly fine. When you cross some of them some junk geometry can flash but no big deal. For instance the leftmost portal on the map in infinity.wad or the green one in front of you at the start. But it's really a very minor thing now.