sezero / quakespasm

QuakeSpasm -- A modern, cross-platform Quake game engine based on FitzQuake.
https://sourceforge.net/projects/quakespasm/
GNU General Public License v2.0
244 stars 97 forks source link

Geometry Rendering Distortion (Mac) #80

Open timbergeron opened 1 year ago

timbergeron commented 1 year ago

On Mac at FOVs > 100 get rendering artifacts exiting teleporter on e4m3 on MacBook Pro 14 M1 QuakeSpasm-0.96.0-osx-SDL2. See below.

spasm0000

sezero commented 1 year ago

Can't reproduce on i686-linux with fov 110 at 1920x1080 fullscreen after a quick run to the spot with notarget on. Maybe something mac/driver specific. @ericwa might have an idea..

timbergeron commented 1 year ago

https://github.com/sezero/quakespasm/assets/68674590/30ee7040-e7a3-4d15-80ba-38c60a453303

Here's a video. More noticable the higher the FOV

timbergeron commented 1 year ago

spasm0001 Even at FOV 90 I just type kill on dm3 until I get to RL spawn and I see this before moving.

timbergeron commented 1 year ago

Does not happen on my Intel Mac.

ericwa commented 1 year ago

I can't repro this on Windows either; I don't have access to any M1 macs unfortunately.

Here's a r_drawflat 1 + r_showtris 1 + fov 130 screenshot of the same scene in dm3 (0.96.0, Win11, x64 build):

spasm0107

Blended over @timbergeron 's screenshot we can see it's just 1 triangle in the middle of a face that's missing: 271142398-69391589-bf81-4a20-9b12-30b1ad5e035b

So, definitely not a vis culling related issue, since that would happen at a face granularity.

I don't really have any ideas of how to fix this. OpenGL implementation bug? Is QS running on ARM macs under the x86_64 -> arm emulation layer?

Edit: I'm assuming launching with -noglsl will work around the bug?

timbergeron commented 1 year ago

Same issue with -noglsl

sezero commented 1 year ago

Is QS running on ARM macs under the x86_64 -> arm emulation layer?

If he is using our release builds, then yes (because while I can actually build arm versions I can't sign/notarize them.)

dsvensson commented 2 months ago

I wonder if I'm getting the same with ezQuake on my MacBook. I'm using native arm builds though, so if so it's not arch-dependent. A Mac user reported this a while back, and it was pretty easy to reproduce on dm6 in ezQuake.

What's similar in both the cases earlier in this thread, and in the ezQuake bug reports is that two vertices are behind the near plane.

Can easily reproduce it in ezQuake at the same place in dm3 as above. But with a different set of vertices, but that might just be due to different iteration order.

image image

dsvensson commented 2 months ago

Same rendering issues with FTE on macOS arm64,

image

Yet another piece of the puzzle is that it's not an issue on macOS arm64 when FTE runs as WASM/WebGL in the browser. https://hub.quakeworld.nu/games/?gameId=83873 ... but WebGL is OpenGL ES, so perhaps that's why it works there as it's different driver code and likely something Apple cares more about compared to desktop OpenGL... if it's driver related rather than engine related.

timbergeron commented 2 months ago

image333 image2

adding this here for reference

sezero commented 2 months ago

This feels more and more like a driver bug every day? Closing..

Feel free to re-open if proven otherwise and have patch to fix it.

dsvensson commented 2 months ago

@sezero Not sure it's a driver bug, but rather a quirk in an undefined corner,

https://gamedev.net/forums/topic/609483-ipadopengl-es-20-a-triangle-disappears-at-particlular-camera-view/

"Finally I have noticed that after perspective transform, if there are two points with negative w in a triangle, and xy value of them are equal respectively, the triangle will be discarded"

http://web.archive.org/web/20150908203347/http://fly.srk.fer.hr/~unreal/theredbook/appendixg.html

"OpenGL might not handle homogeneous clip coordinates with w < 0 correctly. To be sure that your code is portable to all OpenGL systems, use only nonnegative w values."

If so, then perhaps it's not the only hardware this happens on.

Talked to a guy yesterday with the same rendering bug in a standalone Metal application. He had a triangle affeced by this, where two vertices shared the same coordinates, both with a negative w component which at least matches the iPad bug mentioned in the first link above. And I suppose the MacBook GPU is an enlarged evolution of the iPad GPU.

Haven't had time to dig out the data from any Quake engine yet, but it sounds likely to find such vertices there as well.

dsvensson commented 2 months ago

@sezero The cause of this bug is that QuakeSpasm, FTE and ezQuake all produce degenerate triangles. As a quick experiment I added detection and pruning of such in ezQuake which avoids clipping of nearby non-degenerate triangles that are partially out of view. Guess it's a quirk of the hardware, but the solution is easy, just don't produce such triangles. Probably not the only hardware affected by weird side effects due to this.

sezero commented 2 months ago

@sezero The cause of this bug is that QuakeSpasm, FTE and ezQuake all produce degenerate triangles. As a quick experiment I added detection and pruning of such in ezQuake which avoids clipping of nearby non-degenerate triangles that are partially out of view. Guess it's a quirk of the hardware, but the solution is easy, just don't produce such triangles. Probably not the only hardware affected by weird side effects due to this.

If you have a well-tested patch, please post it.

dsvensson commented 2 months ago

Nopes, just a quick hack to verify the cause of the bug. I'll change the tesselation in ezQuake to not produce degenerates rather than producing them as filtering them out is a bit nasty. But now it's clear why it happens, so I suggest you reopen the issue.

sezero commented 2 months ago

OK, re-opened. If someone has a patch for this, it would be welcomed.

dsvensson commented 2 months ago

Here's the crude workaround experiment in ezQ from earlier today. It will introduce some blinking pixel unless gl_clear 1 as it's ~0 rather than 0 area. A solution is probably to identify collinear triangles and try to reshuffle the iteration order in hope of finding a non-collinear solution to the problem, and failing to do so, introducing a vertex in the middle of the polygon and tesselate with that as a start. In practice polygon vertex count seem to be fairly small, and the number of polygons causing collinear triangles from the natural iteration order all engines seem to use is relatively small in various maps I've tried, so probably not a huge penalty.

https://github.com/qw-ctf/ezquake-source/commit/22f39e2a79bd7dcb35ba2f320b344c860c1639ca

timbergeron commented 2 months ago

applied this to qss(m) to test and it worked