Messin' around with the GL renderer
First of all, lil' status update. Things are nearly ready for the 0.9 release, we are mostly busy ironing out small issues here and there to ensure everything is good. Nobody would want something big like that 0.9 release to end up being a total flop.

Also, if you ever wondered why progress is slow: an emulator project is like a tree in that once you're done with the trunk, it branches off in a billion different directions. At this point, melonDS is too big to be a one-man show. There are a few people working on it now, but there's only so much we can do with our time and motivation.

Anyway, while Generic is busy polishing the JIT, I figured I'd go around and try fixing some of the issues on the issue tracker.

This one, Deformed floor textures in the Celestial Tower (Pokemon Black/White) (OpenGL only), is an interesting problem. The base issue is that, if you happen to remember, the DS can draw quads natively, while modern GPUs can't. Actually, it's even worse: clipping on the DS cuts through polygons but doesn't create more polygons, which means that you can end up with a maximum of 10 vertices per polygon. For example, a triangle that sticks out of the view volume can become a quad, a pentagon, or more.

The base issue here is faulty rendering of these polygons that have more than 3 vertices. The DS employs a scanline-based convex polygon renderer, so it doesn't care how many vertices your polygon has. Software renderers used in DS emulators use similar filling algorithms, so no problem there either. However, when you use OpenGL, it's another deal entirely -- modern OpenGL-compatible GPUs are very good at drawing triangles, but... that's about it.

So, what do you do when you need to render a quad? Easy, split it into two triangles!

Suppose the quad below.



All fine and dandy. Now we split this, like this:



You can notice that, compared to the original quad, it looks distorted now. Maybe if we try splitting it in the other direction?



... well, yeah. There's only so much we can do with this.

Enter Arisotura. I've always found this to be an interesting problem, and had a few ideas to alleviate it. There isn't going to be a perfect fix, short of implementing custom interpolation somehow, but we can try to reduce the distortion by dividing these polygons more. We can't overdo it either, lest it kill performance.

A simple way to do it is the following:



It's still not perfect, but somewhat better. Keep in mind that this is an extreme example to show the issue at hand. In real-world cases, polygons are going to be smaller, and the distortion generally more subtle.

Speaking of which:



The polygon right under the bridge is a quad and exhibits the issue we're talking about. For reference, here's how it looks with the software renderer:



So I tried implementing the polygon splitting algorithm shown above. The idea is simple: find the center of the polygon, calculate the color/texcoord/depth attributes at that point, and create triangles around it. In practice, it isn't always easy to get these things working.



Once the bugs were fixed, it started looking more promising.



Not perfect, but it looks much better this way.

Still got some testing to do, and considering whether I should add an option for this, but I'm confident this will make it in 0.9. We have been neglecting the OpenGL renderer since the day it was created, it's more than time to give it some love.
Arisotura says:
Aug 25th 2020
the bit that got me stuck was how to calculate proper barycentric coordinates, but I got another idea. since the DS does twofold interpolation (first along the edges, then along each scanline), I think we can replicate that in the shaders without too much trouble.

I'd have to give it a good try. but I was onto another problem recently: GL_EQUAL depth test mode.
anon says:
Aug 31st 2020
Are there long-term plans for Vulkan support?
Generic aka RSDuck says:
Sep 1st 2020
> Are there long-term plans for Vulkan support?

there's little to no reason for us to put the effort necessary into writing a Vulkan renderer. While we do rely heavily on some "modern" (as in modern 10 years ago) GPU features, the DS's GPU is relatively inflexible thus translating the graphics work to modern GPUs is relatively straightforward (with the exception of quirks like this where Vulkan wouldn't help neither). We would probably gain nothing from the additional flexibilities Vulkan provides.

And except for Apple which never really cared about OpenGL anyway it's here too stay.
Nine says:
Sep 16th 2020
I know it's rude to needle for a vk renderer, but it does have the flexibility to implement and offload the software renderer onto the gpu.
Generic aka RSDuck says:
Sep 22nd 2020
OpenGL supports compute shaders as well (admittedly there are some Vulkan specific extensions which can be beneficial for software renderers)
Post a comment
Name:
DO NOT TOUCH