Voxel Terrain System

Hey, quick update. I ended up using dual contour and a similar interface to pspeed’s. I’m still thinking through how to have a nice interface for multiple materials. Hoping to have a demo by next week.

1 Like

Btw, texture2DArray is deprecated, thats whats up with these previous errors. texture(…) takes sampler2DArray as parameter
(just found out myself)

Did this project fail the midterm evaluation?

Would also like to hear any updates on it.

Sorry about the long time period between updates. The project is still on going.
So right now I have the dual contour data structures and algorithms working.
I also have some primitive shapes and operations working.

So, here is some code and what it outputs:

[java]
Vector3f boxCenter = new Vector3f(0,2.5f,0);

BoxVolume box = new BoxVolume(boxCenter, 5, 5, 5);

BoxVolume box2 = new BoxVolume(new Vector3f(-2.5f,0,-2.5f), 5, 20, 5);

//Make a sphere
SphereVolume sphere= new SphereVolume(new Vector3f(0, 0, 0), 4f);
//Set type to rock
sphere.setSimpleType(0);

//Set type to lava
box.setSimpleType(2);

Volume newVolme = CSGOperators.union(false,sphere,box)
Volume finalVolume= CSGOperators.difference(newVolume, box2)
VoxelObject vo = new VoxelObject(bb,finalVolume, .25f);

//Extract Mesh Data:
List<Geometry> colorMesh = vo.extractGeometry(typeToMaterial);

[/java]

The code starts by initializing a sphere centered at the point (0,0,0) with radius 4. It then initializes a cube with length 5 centered at (0,2.5f,0).
The union operation’s first parameters determines if the box material should overwrite the sphere material. In this case it will not.
The difference operation takes our new volume of the sphere and box and removes a corner of it (the volume described by box2).
It then creates a a new VoxelObject that takes a bounding box, a volume and a voxel size.

The last line extracts a geometry object for each type of material in the voxel object. The typeToMaterial is a mapping from a material index to a proper JME material.

Here is the result:

Here is the same with with a quad’s showing (native output of dual contour):

Right now I’m still working on different operations (e.g. rotation/scale) and getting them to work properly.
I’m also working on a voxel object with support for real time operations.

How does it look performance wise?

Here’s the breakdown for that scene:

3.3 seconds to construct the geometry.
Voxel size .25f

40.5% of the time was spent getting voxel data from the union operation.
42% of the time was spent getting voxel data from the difference operation.
Creating the meshes took about 12.5% of the time.
The actual dual contouring (the bit where you find the vertex in the cube) was the rest.

Basically generating the voxel data is the slowest part. Even if it was just a simple sphere this would have been the case.

Would it allow for dynamic terrain modification on runtime? It doesn’t look like that big of a volume 64^3? 128^3? and it already has 3 seconds overhead. It would be painfull even if put to another thread.

It would be great if it was possibile to do modifications on a part of volume.

It’s a valid point. However the terrain is usually edited in relatively small area’s at a time.
In addition the voxel size can be adjusted which greatly increases runtime.
Voxels of size .25f or smaller are really for when you want a high degree of resolution.
I think we’ll find speeds comparable to marching cubes demo with a much higher modification accuracy.
Or at least that’s the hope =D

Hey, I just wanted to play around a bit with tihs, and wanted to ask if it is somewhere downloadable, like github ect?

(I know it’s not finished yet, but it will probably do fine to allow me a simple prototype for evaluating the use of voxels in my game without doing to much work :wink: )

Hi, as I saw your first posts about Dual Conturing I thought that I should give it a try =D That’s exactly that, what I have looked for my game. Here is my first screenshot of my implementation,

It’s amazing how fast that algorithm is and which results it could generate. :stuck_out_tongue_winking_eye:

3 Likes

That looks really good.
I’ve been using Leonardo Schmitz’s method to generate the iso-points.
http://www.inf.ufrgs.br/~comba/papers/thesis/diss-leonardo.pdf (pages 42-44)
Its implementation is a lot shorter then the implementation for the quadratic error function.

I’m using the QR decomposition method to calculate the iso-points:

[java]/**
* Calculates the minimizer vertice for given normalMatrix and Normal*Point
* Vector
*
* @param N = normal matrixdata (normals of intersectionpoints)
* @param NxP = normal * point vectordata
* @param result = where it saves the result
*/
private void solveQRLeastSquares(double[][] N, double[] NxP, float[] result) {
Matrix a = new Basic1DMatrix(N);

    // A right hand side vector, which is simple dense vector
    Vector b = new BasicVector(NxP);


        // We will use Least Squares method,
        // which is based on QR decomposition and can be used with overdetermined systems
        LinearSystemSolver solver = a.withSolver(LinearAlgebra.LEAST_SQUARES);

        // The 'x' vector will be sparse
        Vector x = solver.solve(b, LinearAlgebra.DENSE_FACTORY);
        result[0] = (float) x.get(0);
        result[1] = (float) x.get(1);
        result[2] = (float) x.get(2);

}[/java]  

but the thing that it makes so fast is, I’m calculating the iso-points only once for the blueprint(ex. my sphere) and save the isopointpositions in hermitedatagrid from the blueprint. So if I build something there is no need to calculate the minimizerpoints again (copying it only). Only on edges where the blueprint intersects for example the box as shown on previous post I recalculate them to get smooth transitions.

[video]http://www.youtube.com/watch?v=RKyqeR4NuGo&feature=youtu.be[/video]
Quick Gallery:
http://imgur.com/a/yqhTV

Demo Packed as jar:
https://dl.dropboxusercontent.com/u/41648603/jME_GSoC/GSOC_DEMO2.zip

Eclipse Workspace Project folder:
https://dl.dropboxusercontent.com/u/41648603/jME_GSoC/Source.zip

Github:

Controls:
wasd - movement
Left Click - add
Right Click - remove
Left Arrow/Right Arrow - Change operations
Up Arrow/Down Arrow - Change materials
Scroll Wheel - Change Operation Size

Let me know if the shaders don’t compile for you.
The initial load might take a while. The noise function is particularly slow…
No doubt there are a lot of optimizations that would speed up the run time of the operations.

What’s next:

The world currently is stored in grid based chunks:

Next step is to move to an octree set up and use an adaptive version of dual contour:

Storing the voxel data in an octree will allow for speed up of operations and far less ram usage.

5 Likes

Hi, the shaders don’t compile for me. The problem was the varying specularSum, it’s not set in .vert shader.
But thank you for sharing your great work =D . After fixing the specularSum the demo runs very well.

Yeah i try to fix as many mistakes as I can with the shader but I always seem to miss a few. I wish my graphics card would be more strict about compilation -_-

Hello,
I am just wondering…

Can i use this yet? Like is the engine out somewhere(like on github) and if so Can i use it yet?

Because there is no level of detail its use is a bit limited.
If you go back to page 5 of this thread at the bottom there is the source and a github link.
I’m working on adding adaptive dual contour with an octree data layer.
This would increase the memory and processing efficiency by a huge factor.

Hey, I’m getting the following error,
is the library missing in the git?

Project ‘VoxelTerrain’ is missing required library: ‘jars/JavaFastPFOR-0.0.7.jar’ VoxelTerrain Build

Then for a second questions, since I build everything for me with gradle anyway, would you be interested if I create a buildscript, that behaves similar to the jme main build one?

Ok, I found the missing library via maven, then I got first shader problems.

Changing in the VoxelMaterial.j3md from GLSL150 to GLSL130 fixed those.
If this also works on other system this would be a good fix, as GLSL130 is supported by the mesa linux driver on ati apu’s.

VertexShader GLSL130: Shaders/VoxelMaterial.vert
FragmentShader GLSL130: Shaders/VoxelMaterial.frag