GSoC 2014 - Voxel Terrain System

Hi, I’m interested in adding a voxel terrain system to jME for this years GSoC. I know I’m a bit late to the game but I was wonder what people wanted to see from this technology.

I know for me the stuff that Miguel Cepero builds at VoxelFarm (see http://voxelfarm.com/vfweb/index.html) is truly awe inspiring.
I’m not new to voxel systems and I’ve built a small engine that utilized a more primitive form the the same technology.

Here’s a trailer of some the stuff I’ve created in the pasted related to this:
[video]http://youtu.be/qishGOl-iHw?t=1m13s[/video]

So I guess I’m looking to see what interest there is in such technology as well as any suggestions for mentors i should get in touch with.

4 Likes

Cool! I’ve been following Miguel Cepero’s stuff for awhile, it’s awesome =D

There’s a dual marching cubes implementation running around on here (http://hub.jmonkeyengine.org/forum/topic/marching-cubes-co/), but unfortunately it doesn’t support sharp edges, so I’d like to see maybe a cubical marching squares implementation (http://graphics.csie.ntu.edu.tw/CMS/) or a dual contouring one (http://www.cs.rice.edu/~jwarren/papers/dualcontour.pdf)…

For me, I’d like to see a fast update speed for shaping the terrain, savability, voxel types (grass, dirt, etc.), networkability, lod (so you can have mountains in the distance or something), sharp edge support, bakeable ambient occlusion, maybe implementing libnoise (http://libnoise.sourceforge.net/)?

These are ideas/suggestions, not expectations :wink: Don’t feel the need to do all of them or whatevs; even just a simple and easily modifiable marching cubes base would be cool to see.
If I knew more about the stuff, I would try to help out, but I haven’t found the time to, and you probably know far more than I do on the subject :wink: but voxel engines are always fun to see! Good luck!

Well I guess there would be interest, as this can be usefull for quite some different stuff in games :slight_smile:

For me an important factor (for any kind of terrain system) would be the ability for lod, and some ind of chunk support.
Aka in a higher level logic it is possible to say I load a range of 3 blocks, the 9 inner are high detail, the rest low detail. This allows then to make whatever is necessary in whatever context without forcing many thins to the developers.

Aynway I’m not in any position to decide on anything GSOc related , just showing my interest :slight_smile:

1 Like

So since you’ve started an open dialog (which is a plus!), I hope you don’t mind if we discuss your project out here in the open, seeing as it seems to extend beyond the confines of GSoC anyhow.

  • Your demo, which looks great, is it already based on jME3 or is it all custom?
  • Are you planning to create something that can be used with other engines besides jME3?
  • Any plans for real-time terrain editing?
@erlend_sh said: - Your demo, which looks great, is it already based on jME3 or is it all custom?

To clarify, I’m pretty sure that demo is someone else’s. OP can confirm I guess.

Thanks for your replies.

@nomnom
So at its core a volumetric terrain system revolves around the concept of a density function. This function describes a density at some location and looks like this f(x,y,z).
All this really means is at some position x,y,z there is a value that represents the distance from the surface.

The papers and techniques that are being mentioned are different ways to extract triangle data from this density function.

A lot of these algorithms build off each other in one way or another.

Marching Cubes [1987] -> Was really the foundational algorithm on creating smooth surfaces from a density function.

Extended Marching Cubes [2001] -> Sharp edges was a real problem for marching cubes so this algorithm described a method for finding where these sharp edges should be. It also provided a method to correct for these sharp edges.

Dual Contour[2002] → Improved on extended marching cubes by utilizing octree’s. It also shows to in general to be more flexible than that of extended marching cubes.

Dual Marching Cubes [2004] → Better utilized octree’s and in general has a lower polygon output than that of dual contour method.

Cubical Marching Squares[2005] → One of the newest method and I’ve seen and doesn’t build off the original marching cubes. It looks at cube face’s rather the contents of the cube. To be honest I still don’t know a lot about it but I’ll do some more digging.

Implementing one of these algorithms is only one part of making a good volumetric terrain system. These algorithms only define what kind of geometry the system is capable of representing. It doesn’t solve problems around multi-material terrain or level of detail.

A list of volume extraction methods:
http://swiftcoder.wordpress.com/planets/isosurface-extraction/

@pspeed/erlend_sh/Empire Phoenix
The video I posted is of a game me and my friend made over the last couple of years.
Our game was made in a home brewed engine built around multiplayer.
Our terrain system was only based off marching cubes.

My plans are to build a voxel terrain system specifically for jME.
I’m looking for it to support the following things:
-Real time editing
-Multi-material
-Level of Detail (LOD)
-Physics
-Shadows and other lighting effects

As of right now I’m planning on using some form of dual marching cubes.
Cubical marching squares and dual contour are still possibilities as well.

One of the things that I’ll really focus on is ease to use API’s.

1 Like

Update
I thought i’d throw together a little demo of marching cubes (seems like there’s been a lot of that lately :wink: ).
My laptop isn’t very good but here’s a video anyway.
[video]http://youtu.be/SBysKUD5hYs[/video]

And an image as well.

Here is a link to the jME3 project/code if you want to run it or see how it works:
https://dl.dropboxusercontent.com/u/41648603/BasicGameGSOC.zip

I tried to keep it pretty simple.

For a much nicer demo see pspeed’s stuff:
http://hub.jmonkeyengine.org/forum/topic/marching-cubes-triplanar-mapping-multires-textures-and-lemur/

References:
http://paulbourke.net/geometry/polygonise/
http://http.developer.nvidia.com/GPUGems3/gpugems3_ch01.html

4 Likes

Awesome! Dude, thanks for the code! =D it’ll be fun to play around with and learn from…
I quickly tried to open it in jME and got this error when I went to look at the mesh:

[java]WARNING: Bad compile of:
1 uniform mat4 g_WorldViewProjectionMatrix;
2 uniform mat3 g_NormalMatrix;
3 uniform mat3 g_ViewMatrix;
4 uniform vec4 g_LightPosition;
5 //attribute vec3 inPosition;
6 uniform vec4 m_Color;
7
8
9 attribute vec3 inPosition;
10 attribute vec2 inTexCoord;
11 attribute vec3 inNormal;
12 out vec3 normal,vNormal, lightDir;
13 out float NdotL;
14 out vec4 vertex;
15
16 void main() {
17
18 vertex = vec4(inPosition,1);
19 normal = inNormal;
20 vNormal = gl_NormalMatrix * inNormal;
21 lightDir = normalize(g_LightPosition.xyz);
22
23 /* Compute the diffuse term */
24 NdotL = max(dot(vNormal, lightDir), 0.2);
25 gl_Position = g_WorldViewProjectionMatrix * vec4(inPosition, 1.0);
26 }

Mar 28, 2014 3:53:49 PM com.jme3.app.Application handleError
SEVERE: Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]
com.jme3.renderer.RendererException: compile error in:ShaderSource[name=Shaders/triplaner.vert, defines, type=Vertex, language=GLSL100] error:0(12) : error C5060: out can’t be used with non-varying normal
0(12) : error C5060: out can’t be used with non-varying vNormal
0(12) : error C5060: out can’t be used with non-varying lightDir
0(13) : error C5060: out can’t be used with non-varying NdotL
0(14) : error C5060: out can’t be used with non-varying vertex
[/java]

I’ll take a look at it when I have some more free time, but I thought I’d just let you know about it. Thanks!

out is a “new” keyword, and requires a higher GLSL version than the default (but graphics drivers act differently, so it will fail on some and not on others). Go to the MatDef, and change the GLSL version to a higher one (not sure what the minimum is). Or change it to varying instead (also need to change the .frag)

In the matdef, try GLSL130… according to a quick google search that’s when “out” was added as a replacement for varying.

By default same error for me. (GLSL100, 110 or 120)

setting GLSL130 gets a different error:

[java]
SEVERE: Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]
com.jme3.renderer.RendererException: compile error in:ShaderSource[name=Shaders/triplaner.frag, defines, type=Fragment, language=GLSL130] error:0(2) : warning C7555: ‘varying’ is deprecated, use ‘in/out’ instead
0(3) : warning C7555: ‘varying’ is deprecated, use ‘in/out’ instead
0(6) : warning C7555: ‘varying’ is deprecated, use ‘in/out’ instead
0(13) : error C7505: OpenGL does not allow swizzles on scalar expressions
0(28) : warning C7533: global variable gl_FragColor is deprecated after version 120
[/java]

I’m using Win7 32-bit with latest JDK and updates ( no nightlies ) and nVidia GT630 gfx

;(

Cheers,
-Radan.

Well seems like you do swizzeling, find out what it means, and remove it.

Removing this line from the supplied triplanar.frag file fixed it…

line 12: blending /= (blending.x + blending.y + blending.z ).xxx;

Shader code is something I’m yet to really learn, but this gets the sample code running…
(ie that line makes no sense to me)

Cheers,
-Radan.

edit: removing the “.xxx” from the end of that line also fixed it…

what does triplanar.frag look like? swizzles is like aVector4.xyz (the .xyz part). From the error, it looks like it’s trying to use them on a primitive type (float or something), I guess

Edit: ninjaed, (blending.x + blending.y + blending.z ) will return a float

the original triplaner.frag file:

[java]
varying vec3 normal, vNormal, lightDir;
varying float NdotL;
uniform sampler2D m_ColorMap1;
uniform sampler2D m_ColorMap2;
varying vec4 vertex;

void main()
{
//Triplaner time. Pulled directly from http://http.developer.nvidia.com/GPUGems3/
vec3 blending = (abs( normal ) - 0.1) * 2.0;
blending = normalize(max(blending, 0)); // Force weights to sum to 1.0 (very important!)
blending /= (blending.x + blending.y + blending.z ).xxx;
vec4 coords = vertex *0.5;

vec4 col1 = texture2D( m_ColorMap2, coords.yz );//x dom
vec4 col2; //y dom
if(normal.y > 0){
    col2 = texture2D( m_ColorMap1, coords.zx ); //This is what gives us the grass on top effect.
}else{
    col2 = texture2D( m_ColorMap2, coords.zx );
}
vec4 col3 = texture2D( m_ColorMap2, coords.xy );//z dom


vec4 colBlended = (col1 * blending.x + col2 * blending.y + col3 * blending.z)*NdotL;//diffuse
gl_FragColor =  colBlended;

}
[/java]

Actually this is allowed in Opengl 4.2:
https://www.opengl.org/wiki/Data_Type_(GLSL)

In OpenGL 4.2 or shading_language_420pack_extref, scalars can be swizzled as well. They obviously only have one source component, but it is legal to do this: float aFloat; vec4 someVec = aFloat.xxxx;

so if you up the GLSL version to 150 (assuming you support it, it should work), or just remove the .xxx should work as well

Heh, GLSL150 brings in a new error… guess my cheapo card is a stickler for glsl code…

[java]
SEVERE: Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]
com.jme3.renderer.RendererException: compile error in:ShaderSource[name=Shaders/triplaner.vert, defines, type=Vertex, language=GLSL150] error:0(10) : warning C7555: ‘attribute’ is deprecated, use ‘in/out’ instead
0(11) : warning C7555: ‘attribute’ is deprecated, use ‘in/out’ instead
0(12) : warning C7555: ‘attribute’ is deprecated, use ‘in/out’ instead
0(21) : error C7533: global variable gl_NormalMatrix is deprecated after version 120
[/java]

removing the .xxx works for me (and setting GSSL130) so I’ll stick with that.

Cheers,
-Radan.

gl_NormalMatrix looks like a typo, should be g_NormalMatrix

@radanz said: Heh, GLSL150 brings in a new error... guess my cheapo card is a stickler for glsl code...

[java]
SEVERE: Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]
com.jme3.renderer.RendererException: compile error in:ShaderSource[name=Shaders/triplaner.vert, defines, type=Vertex, language=GLSL150] error:0(10) : warning C7555: ‘attribute’ is deprecated, use ‘in/out’ instead
0(11) : warning C7555: ‘attribute’ is deprecated, use ‘in/out’ instead
0(12) : warning C7555: ‘attribute’ is deprecated, use ‘in/out’ instead
0(21) : error C7533: global variable gl_NormalMatrix is deprecated after version 120
[/java]

removing the .xxx works for me (and setting GSSL130) so I’ll stick with that.

Cheers,
-Radan.

Be happy your configuration is so strict about errors, nothing is more annoying than a error ignoring driver, and then on some other computer you get random crashes.

** Update 2**
Fixed shaders (I think)
Added Physics
Controls:
w,a,s,d,q -> movement
t -> Shoots balls
Left Mouse -> Adds terrain
Right Mouse -> Removes terrain
Left Shift -> Run/Faster move speed
Video:

[video]http://youtu.be/vdj7adtGdKk[/video]

Demo Links:
Demo_Linux
Demo_Mac
Demo_Windows

Source/SDK project:
https://dl.dropboxusercontent.com/u/41648603/jME_GSoC/BasicGameGSOC.zip

To edit how the world gets changed look in simpleUpdate() function.
[java]
HitData hd = Physics.collideRay(vw, cam.getLocation(),cam.getDirection(), 50);
if(hd.impact!=null){
vw.modVoxelSphere(hd.impact, radius, .3f);
}
[/java]

Let me know if anything doesn’t work.

2 Likes