Comments (16)
Also, turns out my fear really happens: I found a case where the sphere is larger than a voxel, but small enough to make nothing generate because it doesnt affect corners of the whole volume.
For holes, I found they appear in very specific grid locations, no matter where I put the sphere. DualCells don't generate there for some reason, causing 1-voxel size holes.
Edit: fixed :)
So here is the current status:
I've got it to "work", but there are several problems with it.
1) I use a constrained 8-bit distance field.
So far, to represent smooth voxel data, I used only 8 bits per voxel to store the isolevel. So in about 2 units of space among the surface normal, it goes from -1 (inside the object) to 1 (outside the object), where the intersection with 0 defines the surface. Any voxel beyond this area will either always be 1 or -1, regardless of how further away they are.
A slice of the volume looks like this:
Pros:
- Most of the voxel data will happen to be either -1 or 1, which means it can be compressed very well with RLE
- Editing the data can stay relatively local, since changing the isolevel to add a sphere on the terrain only requires to modify voxels around in a distance of 2 units.
Cons:
- LOD is probably less straightforward than a true distance field
The problem is, it breaks part of the Dual Marching Cubes approach, which is assuming an actual distance field. For this reason I tried to reverse the way the octree is built. It succeeds at subdividing where the surface is, but it fails to simplify it further than 2 cells. For example, if I give the algorithm a flat plane, it will still generate plenty of quads (regardless of building top-down or bottom-up):
Something to do with the octree's split policy? At this point, having an octree and a dual grid before using marching cubes isn't very useful.
In the case simplification of dual marching cubes isn't good, I don't know how I could go about simplify meshes. I don't have much experience in this area, and if there is an algorithm fast enough for voxel surface extraction, it would need to spare chunk borders so that they can still connect seamlessly etc.
2) If I had to use a true distance field
Pros:
- Dual Marching Cubes would work?
- LOD becomes simpler
Cons:
- I would have at least to double memory required, for example using 16-bit floats to store the isolevel
- It would no longer compress well to RLE as the values change all the way to the end of the volume (because it's a distance)
- Editing the volume would become much more expensive, because adding even a tiny sphere requires to update the distance to the surface in the whole volume rather than locally. Removing matter would be even worse, in fact I don't even know how to do it properly.
A sparse voxel octree could be used (currently I only have a "sparse voxel" structure), but I'm not sure which approach is best to handle real-time edits across LODs.
So I'm unsure at this point. Is a true distance field really the way to go? How would these concerns would be solved?
Now this mesher is pushed to the master branch, under the meshers/dmc
folder. The main routine is found in VoxelMesherDMC::build()
. I added several options to choose how adaptivity is done, including disabling it, which then provides regular marching cubes (faster to build, but more polygons).
from godot_voxel.
I would tend to prefer a solution with LOD, but I have no dedicated time to work on this at the moment.
from godot_voxel.
Well, the implementation in Ogre3D's VolumeComponent does have a LOD mechanism, but yeah, can't work on stuff if you don't have the time for it :-/
from godot_voxel.
I started investigating this algorithm, but I have a questionning about the way it uses the octree in a top-down way to detect surface features. Let's say you have an empty volume, and the player places a small sphere in the middle:
The algorithm goes by checking the corners of the octree node, and if they differ by some policy, splits the node recursively. But in that situation I can see it won't detect anything, because it starts at the boundaries of the whole terrain, and that sphere is small in comparison. No voxels will be polygonized...
from godot_voxel.
Maybe the paper's explanation was vague? I think it's not checking the actual corners, but rather checking to see if there is any geometry within the volume of the cube, and then subdividing.
Though, that portion of the algorithm I think is for voxelizing an existing mesh. For terrain, that probably won't be needed except maybe when the player is digging or building. Generating the terrain from noise or existing data, you'd basically be able to just generate a chunk of terrain data as a 3D array, and build the octree in a "bottoms up" fashion.
from godot_voxel.
@zauberparacelsus I'm actually not using the paper much, I'm following the explanations from volume-gfx.com
(which doesn't use QEF), in parallel with Ogre's implementation and so far that's what I realized from it. So I wonder if indeed a bottom-up construction would make more sense to catch this kind of situation.
from godot_voxel.
Yeah, I had been attempting to write a custom voxel algorithm a while back, not going off of references to anything else (so probably a lot of mistakes and way too many ifs). I was using an octree just for storage rather than using it to generate the mesh, though when I was generating the octree I did it purely by "bottoms up" from an input 3D array.
from godot_voxel.
One additional thought: I don't know if the algorithm is designed to handle volumes containing multiple materials. Like, if you have a large flat area with nothing but dirt except for one block of stone. Would the algorithm ensure that the single bit of stone was preserved, or would it get optimized out? If the latter, the algorithm might need to be coded to handle volumes with multiple materials.
from godot_voxel.
@zauberparacelsus my guess is, it will probably have two material IDs and a blend value, and the shader will use a texture array with triplanar sampling. But like heightmap rendering, and due to how Godot rendering works, having two actual materials will be quite hard without splitting the mesh.
from godot_voxel.
Another thing I'm not used to, is the use of Hermite data. So far my voxels only needed 8 quantified bytes per value, which worked OK with Transvoxel.
Now, they need WAY more, like 64 bytes (if using 16-bit floats), for the value and the gradient's X, Y and Z, which appears to not even be a normalized vector. I can still quantify that in 8-bit channels but I'm unsure of the result. I could compute it on the fly, though.
from godot_voxel.
Ok, that doesn't look too bad for a sphere placed in a corner
from godot_voxel.
Oh, by material I hadn't meant in the sense of a 3D shader, but rather in a more conventional sense. Like, dirt, clay, stone, and wood are all different materials in the perspective of the player.
from godot_voxel.
Got to the stage of deriving the dual grid, using very similar code to Ogre. I have a hunch something isn't right... not sure if that's just the debug rendering or an actual grid problem
I submitted my WIP on the dmc
branch
from godot_voxel.
Might have been the debug draw, it wasn't making cubes properly
from godot_voxel.
Making good progress, finally got a mesh :) But it has holes in it, I don't understand why
from godot_voxel.
I'll close this, as I don't plan to work more on the DMC implementation for now (default got replaced with Transvoxel). More specific issues or PRs can still be opened later.
from godot_voxel.
Related Issues (20)
- Question: Enclosing and texturing underneath isosurface when using transvoxels HOT 2
- GDExtension API dump wrong type for enum VoxelInstancer::UpMode HOT 3
- So... quick question how would I make the noise larger? HOT 1
- VoxelMeshSDF partition_subdiv description missing info about BAKE_MODE_APPROX_FLOODFILL HOT 1
- VoxelMeshSDF get_aabb() mentions non existant margin property HOT 1
- Dummy page "2" not needed anymore HOT 1
- Assertion printed when previewing last VoxelMeshSDF layer in editor HOT 1
- VoxelModifier preview mesh has gaps with smoothness HOT 3
- Toggling visibility of VoxelModifier does nothing HOT 1
- VoxelModifierMesh changing isolevel does not update preview HOT 1
- Is the VoxelGraphGenerator usable as a base for the generation in a VoxelGenerationScript? HOT 10
- VoxelMeshSDF incorrect BAKE_MODE_ACCURATE_NAIVE description about sign calculation HOT 2
- VoxelMeshSDF BAKE_MODE_ACCURATE_PARTITIONED does not accurately bake PrismMesh HOT 3
- VoxelModifierMesh does not show up under VoxelTerrain HOT 2
- Performing edit on VoxelTerrain that hasn't loaded yet silently fails HOT 6
- Voxel Cubes not texturing. and meshes laggy and unpreforment. HOT 4
- Godot crashes when trying to add any element to the VoxelBlockyTypeLibrary HOT 2
- Error reported using '_GenerateBlock' of 'C #' HOT 3
- VoxelTool.do_* functions do not ignore VoxelModifier on terrain HOT 4
- VoxelModifier get cutout around edited regions HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from godot_voxel.