Sep
30
2012

Marching Cubes Voxel Terrain

Marching cubes terrain sculpting v2.0 (this is also based to the earlier webgl port)

Current Features:
– Can add / remove ground
– Special shader for blending materials (based on world Y)
– Moved raycasting to camera, can add multiple chunks (but they are not “connected” to neighbours yet)
– Chunks are now connected to neighbours (bubblegum solution: each chunk has list of neighbours in array, based on name+x+y+z..)

TODO:
– Try INT version (creates blocky graphics like minecraft..?)
– Find better terrain UV mapping or shader techniques.. (texture atlas? texture painting? world slope based textures?)
– Custom collision system, instead of mesh collider?
– Save the mesh from play-mode to asset..
– Brush size adjusting..
– Display brush on terrain.. (using projector?)
– Try explosions? Dirtball?

References:
– Marching cube system is based on this earlier test: http://unitycoder.com/blog/2012/09/25/marching-cubes-javascript/
– Terrain shader is modified version of this: http://answers.unity3d.com/questions/54313/shader-rgb-colour-based-on-y-value-vertex.html
– Textures are from: http://opengameart.org

Webplayer:
http://unitycoder.com/upload/demos/VoxelTerrain1/ (v2.0)
http://unitycoder.com/upload/demos/VoxelTerrainUnity3/ (v3.0)

*Source is available here:
https://unitycoder.com/blog/2016/12/24/voxel-terrain-js/

Notes for 3.0:

worldroot (empty game object) has script CreateWorld
parameters:
Chunk: chunk prefab
size: (is actually resolution, if its too high will hit 65k vertices error), for example 16 seems fine.
axismin: 0 (chunk pivot from 0)
axismax:8 (chunk width 8 units)
sizex and sizez: 16×16 means 16*16 chunks side by side.

main terrain script is in the prefab VoxelMesh
“MarchingCubesJ.js”

some variables on the script:
noiseScale: adjust this when creating perlin terrains
strength, addStrength: digging and terrain adding strengths

functions:
– InitChunkPerlin() fills/creates the chunk, in this place you can create more interesting chunks.

For example can use this function instead (and change noiseScale to 0.1), (might need a 2 sided shader).

 function InitChunkPerlin3D()
 {
 var terrainHardness:int = 4; for (var z:int = 0; z lt; size; z++) // z - blue { for (var y:int = 0; y lt; size; y++) // y - green { for (var x:int = 0; x lt; size; x++) // x - red { var offX:int = x+offset.x; var offY:int = y+offset.y; var offZ:int = z+offset.z; var vx:float = axisMin + axisRange * x / (size -1); var vy:float = axisMin + axisRange * y / (size -1); var vz:float = axisMin + axisRange * z / (size -1); points.Add(Vector3(vx,vy,vz)); var value:float = p.Noise(offX*noiseScale,offY*noiseScale,offZ*noiseScale); if (y==0) value=terrainHardness*10000; // bottom is capped if (y==size-1) value=terrainHardness*10000; // top also values.Add(value); } } } }

Screenshot of what is included (v3.0)
< Click to view image

Info:
– Try the Webplayer demo 3.0 to see the current features (and bugs!)
– Main difference to that: This download version uses perlin noise terrain (Perlin.cs included)
– There are MANY bugs, for example: Setting chunk size & resolution only works with certain values..
– Feel free to ask more info

Image#2: Testing multiple chunks, somehow they should affect the neighbours (to connect the surfaces).. not sure yet how..

Image#3: Big Map (50 x 50 chunks, each chunk is 120 x 120 x 120 meters..) [click image to view full size]

Image#4: Current version (28.10.2012) (click to view full size)
– Chunks now connect properly, also while editing chunk borders
– Terrain can be generated with perlin noise

Image#5: Current version (3.11.2012) (click to view full size)
– This one is using 2D Mathf.PerlinNoise, instead of Perlin.cs, had some problems connecting chunks..

Image#6: Current version (3.11.2012) (click to view full size)
– Now its possible to use heightmap texture and build it as a voxel chunks terrain (still some leaks at chunk borders)

Image#7: Current version (4.11.2012) (click to view full size)


37 Comments + Add Comment

  • I don’t think the paypal link is working, seems to go to a sandbox paypal site (testing version).

    • Thanks for the info!..Seems to be a bug on that plugin, it should only use sandbox for single ip.. Disabled it now.

      • Cool thanks!

  • Next version (v3.0) is coming soon.. in a week or two.

    *Actually the main image refers to “v2.0” which is the current downloadable version,
    “v1.0” was the original test in previous marching cubes test.

    • Any chance to get it soon?

      • Hopefully this weekend!

  • Do you get the source code if you buy the Marching cubes terrain pack.
    Or do you have to donate to get the source code.

    • Yes, that 3eur download is with the source (js), terrain shader & example scene (same as the webplayer, minus those rain particles..)

      *The source is not optimized or very clean..

  • When you create terrain or edit terrain do the shapes have colliders so that I can put a character on the terrain without it falling through.

    • It uses/updates meshcollider (slow):
      GetComponent(MeshCollider).sharedMesh = null;
      GetComponent(MeshCollider).sharedMesh = geometry;

      I’ve tested with the default character controller, you can walk around the terrain just fine.

      Only problems are:
      – if you modify the ground where the rigidbody or player is, it falls through, since the terrain surface can go above the player..
      – Also currently the view rotation is done by rotating the terrain itself.. :)..so camera controls needs to be changed to something better: http://wiki.unity3d.com/index.php/Scripts/Controllers

      I’d suggest to check those free sources first:
      http://unitycoder.com/blog/2012/10/18/voxel-resources-engines-for-unity/

  • hi, Paypal does not support my country!

    • Any other online payment system that works? Or if you have some of your own asset/code to trade? 🙂

      • I don’t have any Assets to trade at the moment, at least not the one I have written my self. You can use eyowo.com or cashenvoy.com (They are localized to my country) or You can use http://chargify.com/payment-gateways/

        • it makes me think of the xolox developers, they had written. hello we are are setting up a new house, here is our address, send us anything as presents, vacuum cleaners, shelves, sauna, posters, anything. send something from your country! like there must be a million things there they dont have here, like crystals, bits of things. and old ring, hehe. easier to post than to log in to credit sites!

  • Can you send me the new one?
    I only have 1.0
    Very good work 🙂

  • Somehow I have to now get no mail.
    My English is not so good. :/
    here is from the goggle translator.
    Can you delete this. (The comment)

  • The shader does not work on my terrain-it just shows a black square when i enter the game view

    • What kind of graphics card you have? (type, memory)

      Does it work on the webplayer here?

      • It does not work on the webplayer either. I do have a mac that is older- a mac mini from early 2009, so that probably is the problem. Thanks!

  • Can you give me again the mail sending.
    I did not get.

    Could I have her address times (e-mail)?
    Then I do not always write in here

    good work

  • Thanks for the great work. I have been working on my own video system based on surface nets but was wondering how you handled the sculpting. Unfortunately I need to do some refactoring if I want to do it like yours, but it gave me some ideas. 🙂

    Looking forward to seeing more!

  • how do I implement using perlin.cs again and the heighthmap. I think ive gotten a pretty good understand of the mesh generation now. I am just having trouble with understanding how to use perlin noise for generation

    • Basically you can put some thresholds,
      – If perlin noise value for this grid position_xyz is > 0.3, then set grid value to 1
      – else set value to -1 (for example)

      Then you get a kind of “cheese” terrain with holes (with right values..)

      Or check these,
      https://sites.google.com/site/letsmakeavoxelengine/home/landcape-creation#TOC-Landscape

      • Thank you the “cheesy” terrain is exactly what im looking for. I also have one more question. I tried editing your shader to allow it to be affect by directional lights and shadows. I simply changed the lightmode from ‘always’ to ‘ForwardBase’. this allows the directional light to affect it, the only problem is that the shadows render in bright red for hard shadows and bright yellow or white for soft shadows. My knowledge of shader coding is very limited, but if you can point me in the right direction as to how to correct the problem with shadows Id greatly appreciate it.

  • Just bought the v3 source, freaking awesome work! Just what I was looking for. Now I can finally learn how this stuff works by example. 😀
    Thanks man!

    • thanks! (feel free to post questions/feedback here or to my email, since it doesnt have much instructions or comments)

      • Cool.:)
        Well I was wondering if you have any suggestions on how to go about placing trees on the generated terrain ? (tree prefabs, not necessarily voxel trees)

        • random ideas,

          For a quick test I would just raycast from above the chunk/area and plant trees on those..
          – could check hit face angle, so it doesnt place trees on too steep angles
          – could take perlin noise values as “density” maps, so some areas have more trees/grass..

          Or could just loop through all (or randomly picked) triangles/vertices from each mesh,
          if triangle face worldNormal is good (pointing upwards), place tree/grass/stone prefabs on that..

          this script sounds interesting also, maybe can get some ideas:
          “grass on mesh” script:
          http://forum.unity3d.com/threads/8659-nature-pack?p=63743&viewfull=1#post63743

          • I’ve been trying to wrap my head around it, but since I don’t understand big parts of the “level” generation scripts i’ve failed miserably.xD
            How would I go about looping thru the triangles of a mesh and then place something on it if the worldnormal is allright? Seems like the best way to go, but I’m really having trouble coding something like that.
            Would I add all the chunks to an array, and then use a “for” statement to loop thru them and add their triangles to an array, which I can then loop thru ?
            I’ve never coded/scripted anything regarding triangles and such in unity, and the stuff in API reference doesn’t really help that much.:s

          • Try the raycast only test to get started:
            http://docs.unity3d.com/Documentation/ScriptReference/Physics.Raycast.html

            You could try adding a new function call to after UpdateChunk(); in line 76 in MarchingCubesJ,
            at that point the mesh is already generated.

            And try with: Debug.Log(collider.bounds);
            You get the chunk size, then shoot raycasts from above the transform position.

            After that, raycast actually returns hit.normal,
            http://docs.unity3d.com/Documentation/ScriptReference/RaycastHit-normal.html

  • This is from google translator
    Where is v0.4? If I buy v0.3 can i get v0.4?

    • Hi,

      There is no v4.0 available, so the v3.0 is latest.

      (also there is no free update to next versions, half price would be possible,
      but there is no new version coming anytime soon)

      thanks!

  • Hey, I notice you have a screenshot from version 4 but you only have a download for version 3. What are the differences between the two and do you expect to release version 4 at any time?

    • That last image (#7) is only showing the seams fixed, which is included in the package.

      No new versions coming in near future at least..
      (also those free packages are much better)

Leave a comment

Connect

Twitter View LinkedIn profile Youtube Github Join Discord Twitch Instagram BlueSky

UnityLauncherPro

Get UnityLauncherPRO and work faster with Unity Projects!
*free unity hub alternative

@unitycoder_com

Subscribe to Blog via Email

Enter your email address to subscribe to this blog and receive notifications of new posts by email.