mattrdowney / planetaria

A Unity framework for Euclidean 2-sphere games (e.g. 2D virtual reality games) [quasi-MIT license]
Other
10 stars 2 forks source link

Use Unity's level-of-detail (LoD) system to render procedural meshes #91

Open mattrdowney opened 6 years ago

mattrdowney commented 6 years ago

This fix would be incredibly useful to "set and forget". It removes most burden from the user and generally makes the game better.

mattrdowney commented 6 years ago

Another interesting concept here is non-uniform/variable level-of-detail.

mattrdowney commented 5 years ago

Non-uniform world detail is covered in Unite 2013: Building a new universe in Kerbal Space Program ( https://m.youtube.com/watch?v=mXTxQko-JH0 ).

Basically, you create fanning between different regions to avoid seams, and you determine if you should subdivide a region based on distance from camera.

In practice, without zoom variable field of view is unnecessary. With zoom, you basically want to subdivide the four cells, adjacent to the z-axis the most (and the anti-podal ones the least). For this to work, I should switch to the recursive variant, since non-power-of-two variable tesselation would be hard to handle (if I 1:1 use the technique from the video). If I made my own technique, I would have an interesting time, but as long as I can get the UV coordinates, I can essentially do a UV sphere like technique with variable latitude changes. I would have to figure out how to create an equivalent fanning technique that avoids seams, but otherwise it seems promising.

mattrdowney commented 5 years ago

The hardest part is getting the level-of-detail to recalculate on its own (no user input) but also run quickly, so it doesn't cause loading screens (should use IEnumerator across multiple frames), change infrequently (e.g. on a 2x scale change), and should be fast (no steady performance hit).

Further notes: should support all sorts of UV mappings (e.g. octahedron sphere, 180 degree virtual reality cloth mapping, etc).

mattrdowney commented 5 years ago

UV seams are a tricky subject (vary depending on mapping), edge/vertex reuse is probably important for rendering (avoid artifacts, although Planetaria has fewer floating point problems because it's close to origin), any arbitrary point set can be used, so long as it uses the seam point set and maps UVs properly.

If zoom is zero, no detail is needed, but any amount of zoom means some tesselation should be performed (on close AND far hemispheres). You do need more tesselation, closer to camera, although this is mostly to make sure the camera isn't "past" edge of planetarium or to avoid the near clip plane.

I didn't fully mention the trickiness of the UV problem (I forgot this is why I originally thought the problem was difficult), and I may need to revisit/research&develop this with the new 180 degree virtual reality cloth mapping technique.

The octahedron UV projection cannot benefit from this technique, so I would need to 1) remap UVs each frame (not reasonable) or 2) find a new UV format.

mattrdowney commented 5 years ago

Upon thinking about it, if the 180 degree virtual reality cloth mapping technique works so well, why not use it?

(Disclaimer: I have a strong suspicion this is a logical fallacy based on non-distance/shape preservation in mapping / globe cartography. Even if it is, it may inspire a stupid yet creative solution (perhaps as an approximation).)

In theory, you would generate a flattened globe and repeat the space past the edge of the canvas. When you need to render, you find the orientation and send it to the renderer so it can compute the Matrix for changing the positions.

Which brings me to new ideas for implementation: performing extra work on GPU in the shader to avoid CPU-heavy work.

An ideal Planetaria texture would have all podal-antipodal pairs at a deterministic texture offset from one another (I would like .5 unit shift in both x/y in either direction). Not sure if that's possible (it sounds impossible, though).

mattrdowney commented 5 years ago

Notably, the UV problem was not as difficult as I believed it would be (even for #128).

My current version just tesselates a object in a basic way, but you can reuse that mesh for every object (assuming they use a Texture). I should still keep variable-tesselation on the to-do list, but runtime level-of-detail would rarely be useful for the games I am working on.

The level-of-detail system is not as useful for .svg files (as opposed to Textures), since you will likely convert the Unity .svg mesh into a tessellated sphere (and re-tessellating that would be debilitatingly expensive - and not as useful because Unity uses uniform-ish level-of-detail on .svg files).

Additionally, level-of-detail can be set to ~1000 vertices as a default. If a user wants more/less vertices they can do it themselves. Zooming in and out won't be too common in 2D virtual reality, and you can always go with worst-case tesselation as a default.