Rendering issues - some help?

Started by namida, August 28, 2022, 10:36:39 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

geoo

QuoteI've been thinking this over for a while and the only obvious downside I can see is that it will mark a lot of pairs of faces as having one that must come first, even when it actually doesn't matter. However, this would only result in a performance penalty, rather than a failure - it might be acceptable, would have to test (and possibly optimize) before I could say for sure.
Actually, if you mark dependencies where there are none, you add additional edges to your graph, and making it more likely to get cycles.

I think the many cyclic dependencies you see are exactly a result of this. There may be instances where you legitimately get cyclic dependencies, but these should be rare in practice (e.g. the lemming intersecting with the diagonal block).

I don't really have time to think through your outlined algorithm in detail, but you should have as few extraneous dependencies as possible.
Newell's algorithm (linked in my previous post, and the linked stack overflow post also has a link to the Wikipedia article) claims to take care of this, maybe worth having a look at.

namida

#16
So I managed to think of a case where my idea (which I had partially, but nowhere near fully, implemented) would fail. See attached sketch. The black lines are intended to represent billboard sprites (perhaps lemmings), although pretty much the same thing would arise even from them merely being the front face of a block.

There is an objectively correct answer to the rendering order here. First, note that the two non-diagonal faces of the deflector block would not be rendered anyway due to facing away from the camera. With this in mind, the correct ordering for the remaining pieces is that the deflector block's diagonal face must be drawn before the billboard on the right; while it doesn't matter which order those two are drawn in relative to the billboard on the left. However, my idea would create a cyclic result here.

Newell's algorithm specifically relies on splitting polygons. This in turn would produce the appearance of lemmings disappearing into corner blocks that they're very close to (much like Z-buffering also does). Discarding the polygon splitting aspect and simply doing the overlap detection, my hunch is that this would not eliminate cases where cyclic results emerge in cases that do have a correct draw order. If this result were going to be accepted, it would be less effort (and better performance-wise) to at least have another go at resolving the Z-buffering issues - perhaps by trying the "render only a subset of Z depths at a time" approach.

Maybe it's worth giving that a go anyway. It shouldn't be particularly time-consuming to implement.
My projects
2D Lemmings: NeoLemmix (engine) | Lemmings Plus Series (level packs) | Doomsday Lemmings (level pack)
3D Lemmings: Loap (engine) | L3DEdit (level / graphics editor) | L3DUtils (replay / etc utility) | Lemmings Plus 3D (level pack)
Non-Lemmings: Commander Keen: Galaxy Reimagined (a Commander Keen fangame)

namida

Okay, so I tried a hybrid approach here - keeping the existing code for rendering the blocks (and cracks on them etc), but using Z buffer for sprites. Although it does have the "sprite partially disappears into deflector / slope" issue, this is not too severe and I think it's better than the downright odd stuff that was happening with the existing code.

The code for blocks seems to mostly get things right - it's when sprites (which can be taller than blocks) get thrown into the mix that things get weird, generally. However if there are still issues, I can look at going into a full BSP tree approach for the blocks.

There's also one special case, to avoid Z-fighting - when hatch flaps are completely closed, they get treated as block faces rather than sprites. Similar special cases need to be added for a few other things too; namely teleporters, spring landing pads, and trampolines; but this is trickier to do as they'd need to be seperated out from other objects during the rendering.
My projects
2D Lemmings: NeoLemmix (engine) | Lemmings Plus Series (level packs) | Doomsday Lemmings (level pack)
3D Lemmings: Loap (engine) | L3DEdit (level / graphics editor) | L3DUtils (replay / etc utility) | Lemmings Plus 3D (level pack)
Non-Lemmings: Commander Keen: Galaxy Reimagined (a Commander Keen fangame)

namida

#18
I've gotten the new rendering code to a state where I'm comfortable merging it into master. It's not perfect yet - there's some cases (in particular, with the smaller segment of 22.5 degree slopes) where there's still issues, but those are issues that already existed prior to these changes. A whole lot of issues on the other hand were improved. Compare the attached screenshots (default camera on Fun 1 of L3D).

Regarding performance, on LP3D Mayhem 19 "Power Distribution", with FPS limiter turned off, I get around 210 FPS on the preview screen and 190 FPS in-game with the new code. On the old code, I get 205 FPS on the preview screen (so the new code actually performs better, somehow) and 195 FPS in-game (so the new code is about 2% slower).
My projects
2D Lemmings: NeoLemmix (engine) | Lemmings Plus Series (level packs) | Doomsday Lemmings (level pack)
3D Lemmings: Loap (engine) | L3DEdit (level / graphics editor) | L3DUtils (replay / etc utility) | Lemmings Plus 3D (level pack)
Non-Lemmings: Commander Keen: Galaxy Reimagined (a Commander Keen fangame)

namida

I've been working on code that uses Z buffering for the blocks too, using some trickery to avoid Z-fighting. Namely, when each face is drawn, the Z buffer is read to determine where to draw as usual, but it's not written to. Thus, multiple graphics on the same face won't Z-fight, and which one is in front is determined by rendering order. Then, after this, it draws them again in a second pass, this time *only* writing the Z buffer (but not drawing the actual pixels).

This somewhat works (and eliminates the remaining issues with the current code), but Z-fighting can still occur in some cases, such as if we have two blocks next to each other A B where both the right face of A, and the left face of B, have a graphic to draw (due to one having a double-sided graphic on that face). To address this, I need to modify the code to handle paired faces together. Not too hard to do in and of itself, but a bit trickier to optimize - my initial attempts at this method of rendering the blocks had utterly awful frame rates, but I managed to hugely optimize it; the existing optimization wouldn't work well when working with pairs of faces, so I'd need to find another way.
My projects
2D Lemmings: NeoLemmix (engine) | Lemmings Plus Series (level packs) | Doomsday Lemmings (level pack)
3D Lemmings: Loap (engine) | L3DEdit (level / graphics editor) | L3DUtils (replay / etc utility) | Lemmings Plus 3D (level pack)
Non-Lemmings: Commander Keen: Galaxy Reimagined (a Commander Keen fangame)