Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mario Kart DS decal graphic glitch #19

Closed
ppsspp-gamer opened this issue Dec 17, 2016 · 9 comments
Closed

Mario Kart DS decal graphic glitch #19

ppsspp-gamer opened this issue Dec 17, 2016 · 9 comments
Assignees
Labels

Comments

@ppsspp-gamer
Copy link

This bug is related to the commit " OpenGL Renderer: Allow all opaque non-shadow polygons to write to depth buffer"

Before this commit:
before

After this commit:
after

@rogerman rogerman self-assigned this Dec 17, 2016
@rogerman rogerman added the bug label Dec 17, 2016
@rogerman
Copy link
Collaborator

Well that sucks. Looks like there are limitations to this shadow polygon hack, which really is a variation over a previous hack, which was a slight improvement over a previous hack.

Looks like the only real way to solve all rendering cases at the same time is to handle shadow polygons perfectly, which is not an easy feat. (Hence the need for the silly hacks to get partial functionality in the first place.)

I'll take another look at it, but I make no guarantees that this issue can be truly fixed in the OpenGL renderer, due to some programming limitations that OpenGL imposes that makes emulating the special NDS conditions much harder than it needs to be.

@ppsspp-gamer
Copy link
Author

Before perfect fix come out, is it worthy to give this hack an option to switch old and new behaviors?

@rogerman
Copy link
Collaborator

@ppsspp-gamer
I was pretty skeptical about the decal-polygon-check hack in the first place, and the issue with Golden Sun: Dark Dawn only gave me the excuse to go back to something that closer resembles real NDS behavior (hence commit 49309fb).

So to answer your question: Unless you can show me a specific instance where the new behavior causes a game-breaking bug (like the completely missing keyboard in Golden Sun: Dark Dawn), I will not be considering any game-specific option hacks in the meantime.

@ppsspp-gamer
Copy link
Author

I have one question about commit 49309fb:

Render3DError OpenGLRenderer_3_2::SetupPolygon(const POLY &thePoly)
{
GLboolean enableDepthWrite = GL_TRUE;

if (attr.polygonMode == POLYGON_MODE_SHADOW)
{
         .......................
}
else if ( attr.isTranslucent || (std::find(this->_shadowPolyID.begin(), this->_shadowPolyID.end(), attr.polygonID) == this->_shadowPolyID.end()) )
{
	glDisable(GL_STENCIL_TEST);
	glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
	enableDepthWrite = (!attr.isTranslucent || attr.isOpaque || attr.enableAlphaDepthWrite) ? GL_TRUE : GL_FALSE;
}
else 
{
           .............
}
   ...........

}



After your code change, if a polygon is opaque but with translucent texture (format TEXMODE_A3I5 or TEXMODE_A5I3) will still write to z-buffer when rendering the polygon.

But shouldn't render a translucent polygon only do z-testing without write to z-buffer? Otherwise, pixels behind a transparent polygon won't rendering?

@zeromus
Copy link
Contributor

zeromus commented Dec 19, 2016

the nds doesn't consider whether a polygon is translucent when writing depth, but whether the fragment is. opaque fragments write their depth; and translucent fragments write their depth (if the game has selected it.) Games can select PER POLY whether that's the case. The code you pasted references that idea with 'enableAlphaDepthWrite'

You can always check softrasterizer (line 598) or gbatek for a reference--the opengl renderer is at best an approximation of the correct functionality.

@ppsspp-gamer
Copy link
Author

@zeromus thanks for your explaination.

@rogerman
Copy link
Collaborator

New progress: I've rewritten the algorithm for rendering shadow polygons to be more accurate than ever before in commit 5285131. This has allowed me to reorganize the code in such a way where this issue is now isolated down to a single line of code in SetupPolygon().

The exact problem is this: Like you and zeromus have already mentioned, this issue is caused by the fact that the NDS can control writing to the depth buffer on a PER FRAGMENT basis. However, OpenGL has limitations where it only allows us to control writing to the depth buffer on a PER POLYGON basis. This becomes an issue with A5I3 and A3I5 formatted textures, which can have a mix of both opaque and transparent pixels that require PER FRAGMENT control of the depth buffer in order to render properly.

For polygons with A5I3/A3I5 textures, if you assume such polygons as transparent, and therefore disable depth buffer writes, then opaque fragments might fail to render. This can be game-breaking for the many games that rely on such polygons, since critical objects might disappear in this case.

But If you assume that such polygons are not transparent, and therefore enable depth buffer writes, then opaque fragments will render fine, but existing fragments behind transparent fragments may render as fully opaque (ignoring the transparent fragments). While this situation may not cause game-breaking issues like disappearing polygons, it does make things look a lot uglier.

Now that shadow polygon rendering is finally resolved, this puts us into a position where we can try to emulate controlling per-fragment depth writes in OpenGL. This will most likely involve adding a full rendering pass, which will surely cause a performance hit. Now... how much of a performance hit remains to be seen.

rogerman added a commit that referenced this issue Dec 22, 2016
…5 and A5I3 textures would fail to render correctly.

Fixes issue #19.
@rogerman
Copy link
Collaborator

Fixed in commit 7b13501.

It looks like I didn't have to use a separate full rendering pass after all -- I simply rendered the A5I3/A3I5 textured polygon twice. The first pass renders the polygon assuming that it is transparent and discards all opaque fragments, and then the second pass renders the polygon assuming that it is opaque and discards all transparent fragments.

I also had to bring back the opaque-decal-polygon check because Picross 3D needs the check for correct rendering. Now that the previous shadow polygon hacks have been eliminated in commit 5285131, the opaque-decal-polygon check is necessary once again.

@ppsspp-gamer
Copy link
Author

Thanks, great fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants