Code Monkey home page Code Monkey logo

Comments (12)

bonsairobo avatar bonsairobo commented on May 21, 2024

I think having a way to generate skirts would be a good addition, even if we eventually have something that's more "correct."

I only worry that skirts would cause overlapping meshes and Z fighting. Apparently this can be remedied with shaders, but it's something to remember.

from building-blocks.

Dimev avatar Dimev commented on May 21, 2024

I haven't had issues with overlapping/z-fighting with it, as it's only against the edge of the chunk face, and generates "downwards", so it doesn't generate a skirt into a space where the other mesh would be, but instead generates it downwards.

I have a demo program under this video if you want to look at it in detail: https://www.youtube.com/watch?v=Wz-tX8SKgYo

from building-blocks.

bonsairobo avatar bonsairobo commented on May 21, 2024

generates "downwards", so it doesn't generate a skirt into a space where the other mesh would be

I'm not sure what you mean by this.

from building-blocks.

Dimev avatar Dimev commented on May 21, 2024

Sorry if I suck at explaining it. I think the demo can show it best if you go below the terrain

For marching cubes I generate the extra skirt faces on the chunk faces as well, that way they don't overlap and cause Z-fighting.
Viewed from below:
image

My idea with surface nets was to do roughly the same: generate an extra vertice on the face of the chunk, and connect the regular vertices to that.

This would make the mesh generated perfectly fit within the chunk, and make it touch the chunk faces, like so (although with proper triangle orientation and normals):
image

Then from there it's possible to hide the last bit of lod cracks by generating an extra bit of mesh that extends "downwards" (Towards where the cell is full)

from building-blocks.

Dimev avatar Dimev commented on May 21, 2024

I also found this, which describes a way to do it in a bit more detail: https://www.reddit.com/r/VoxelGameDev/comments/5uzics/how_to_generate_continuous_levels_of_detail_for_a/ddz4t9o/?context=3

from building-blocks.

bonsairobo avatar bonsairobo commented on May 21, 2024

The reddit link doesn't actually mention skirts at all. They're talking about continuous level of detail using mesh decimation.

If I understand you correctly, the way you intend to avoid z fighting is to make sure that skirts are always placed on the interior of the isosurface. If you can actually do that, I think it would look OK is most cases. But it seems difficult to ensure that property, and I bet it would also have edge cases where you can still see through the cracks.

from building-blocks.

Dimev avatar Dimev commented on May 21, 2024

Yeah, here they don't mention skirts, but they do have this picture
image

That's basically how I would ensure the vertices would be on the face of the chunk, then from there you can generate the skirts to sit on the face of the chunk and inside the isosurface

I'm sure there would be some edge cases where you can see the cracks, but for the marching cubes variant of skirts I haven't found them/seen them yet

from building-blocks.

bonsairobo avatar bonsairobo commented on May 21, 2024

I want to a quick brain dump on the "multiresolution surface nets" issue in general...

Surface Nets Background

Surface Nets is essentially a form of dual contouring without hermite data. The canonical dual contouring algorithm for an octree will create a quad for each "minimal" edge being intersected by the isosurface. By minimal, I mean the edge can't be subdivided further in the octree. I've observed that doing this traversal on a hashed octree can be difficult to optimize (see the adf-experiment branch of this repo). This is partly because of the way a node must store redundant samples that all adjacent (parent, sibling, child) nodes also store. Maybe there is a better way to do this, but I haven't seen it.

In contrast, running surface nets on a regular grid is pretty fast. I've even seen multiple examples of "fast dual contouring" on the internet which tend to use a uniform grid. And uniform grids also lend themselves to being meshed on the GPU. So the octree ADF scheme seems like a tough sell for me.

LOD Stitching for Surface Nets

Here's my current idea for using chunks of at different resolutions.

surface_nets_lod_transition

In this picture we've got a chunk of LOD N and some adjacent chunks of LOD N+1. Note that every chunk actually has the same number of samples, but a chunk of LOD N+1 covers a larger region than a chunk of LOD N. (The entirety of LOD N+1 chunks is not shown). This is totally compatible with the existing ChunkMap structure.

The picture is trying to illustrate how we could generate a boundary mesh between chunks of different levels of detail. The core idea is to use stitching quad elements that look like this:

v-------v
| \   / |
|  \ /  |
v---v---v

with LOD N+1 vertices at the top and LOD N vertices at the bottom.

Here's a plan for how we could implement this:

Right now, we always copy voxels from a chunk and its neighbors while generating a chunk's mesh. We could change this so that we have two kinds of meshes: a "core" chunk mesh and a "boundary" mesh. While generating a core mesh would only require voxels from a single chunk, generating a boundary mesh would require voxels from multiple chunks (I think at most 9 for a single chunk face). Then we can have two kinds of boundary mesh:

  • LOD N to LOD N
  • LOD N to LOD N + 1

The picture above highlights the LOD N to LOD N + 1 boundary mesh; it's the blue vertices and any vertices adjacent to a blue vertex.

I am a little less clear on how we would actually generate this mesh. I think it would look nearly identical to surface nets, except when you create a quad, you'd have to know if you need a regular quad or a transition quad.

Transvoxel

Another option that is probably easier is to just implement marching cubes and transvoxel. This is a proven algorithm for LOD. There a some downsides though:

  • lower quality meshes (more triangles)
  • giant lookup tables are somewhat magical
  • easier to extend surface nets for sharp features

from building-blocks.

Dimev avatar Dimev commented on May 21, 2024

I also found this, which generates a lower detail version along with the high detail one, and then just blends between the meshes: PorkStudios/FarPlaneTwo#49

I haven't actually done anything with getting data from other chunks, how hard is it to do that (assuming the octree does not have any chunk getting implemented yet)?

from building-blocks.

bonsairobo avatar bonsairobo commented on May 21, 2024

I haven't actually done anything with getting data from other chunks, how hard is it to do that (assuming the octree does not have any chunk getting implemented yet)?

If all chunks are at the same LOD, then you can use copy_extent on the ChunkMap and it will figure out which chunks need to be accessed for you.

If you want to access chunks at different LODs, there is currently no "high level" operation for this.

from building-blocks.

bonsairobo avatar bonsairobo commented on May 21, 2024

Another option that sounds a bit simpler than stitching...

If we had a vertex hierarchy, similar to an octree, where each vertex had up to 8 child vertices, then we could blend the vertices based on distance from the camera.

This does rely on specific shading techniques to be efficient though. It would also require more GPU memory on LOD boundaries, I think twice as much since each vertex also needs a parent to blend with.

But as a bonus, it removes the popping issue and gives smooth LOD transitions.

This is roughly what's done in Galaxia: https://dexyfex.com/2016/07/14/voxels-and-seamless-lod-transitions/

from building-blocks.

jedjoud10 avatar jedjoud10 commented on May 21, 2024

I actually have managed to implement multi-resolution surface nets in my custom engine, however the "skirts" methods does produce some very odd results (due to the clamping of the vertices to the edges of the volumes). However, when using derived normals from the density field, these artefacts disappear completely.

This is when using derived normals inside the fragment shader (which clearly allows you to see the "edge" between the chunks)
image

And this is when you use derived normals (though with the use of the "flat" shader to make it lowpoly)
image

Another potential problem that might arise with skirts is self shadowing issues in case it's 3D
image
though that might simply be due to my bad octree heuristic.

from building-blocks.

Related Issues (18)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.