finish article on old voxel engine
2
.domains
|
@ -1,3 +1,3 @@
|
|||
www.emamaker.com
|
||||
emamaker.com
|
||||
www.emamaker.com
|
||||
emamaker.codeberg.page
|
||||
|
|
|
@ -2,6 +2,8 @@ Title: Developing a Voxel Engine
|
|||
|
||||
# Developing a Voxel Engine
|
||||
|
||||
<img src="/resources/projects/voxel-engine-1/voxelengine1-1.png" />
|
||||
|
||||
Almost two years ago I decided to start working on a Voxel Engine --
|
||||
knowing almost nothing about voxel engines.
|
||||
This is not a guide to voxel engines nor a tutorial about making one,
|
||||
|
@ -13,13 +15,12 @@ I decided to go with
|
|||
rel="noopener"}, as Java was the only language I knew two years ago and I didn't want to start from raw [LWJGL](http://lwjgl.org), and this engine was easy enough to use for me.
|
||||
Nothing excludes that the code can't be ported to other languages, and it's probably something I'll do to learn new languages quickly. Maybe in the future I can port this engine to other languages or rewrite it using OpenGL with [LWJGL](http://lwjgl.org).
|
||||
|
||||
## Image here
|
||||
|
||||
All my code is available on my [GitHub profile:
|
||||
https://github.com/EmaMaker](https://github.com/EmaMaker)
|
||||
<img src="/resources/projects/voxel-engine-1/voxelengine1-2.png" />
|
||||
|
||||
[The my code is available on my github:](https://github.com/EmaMaker)
|
||||
|
||||
|
||||
**Face Culling**
|
||||
## Face Culling
|
||||
My first test worked using strange formula to have less cubes as position on the y axis increased and used full cubes with a yellow-purple texture to test the borders. This is the first big error when making a voxel engine.
|
||||
Even if you see a world made out of cubes, in reality there are any. All the "cubes" are made of simple quads that appear or disappear based on what you need. For example, if you have two adjacent cubes with each cube touching a single face of the other, both cubes will have a face that won't be seen by the user, so the simplest thing to do is just not rendering them and save workload on the GPU. This method is called Face Culling.
|
||||
You can read more about rendering methods for voxel engines [in this very interesting article by 0fps](https://0fps.net/2012/06/30/meshing-in-a-minecraft-game/){target="_blank" rel="noopener"}.
|
||||
|
@ -31,36 +32,34 @@ But there were still some problems with this: the *Cell* generated six different
|
|||
100fps on my Dell XPS M1330, which now is a 12-years-old laptop.
|
||||
But when it came to generate new parts of the world, the Java Garbage Collector started crying for all the mess it had to clean.
|
||||
|
||||
## Other image here
|
||||
<img src="/resources/projects/voxel-engine-1/voxelengine1-3.jpg" />
|
||||
<img src="/resources/projects/voxel-engine-1/voxelengine1-4.jpg" />
|
||||
|
||||
**Greedy Meshing to overcome perfomance issues**
|
||||
## Greedy Meshing to overcome perfomance issues
|
||||
|
||||
Speaking with some folks on the [jMonkeyEngine Forums](https://hub.jmonkeyengine.org), I got the advice to abandon the six-objects method I had been using, in favour of GreedyMeshing. As you can read from [in the 0fps article](https://0fps.net/2012/06/30/meshing-in-a-minecraft-game/){target="_blank" rel="noopener"}, greedy meshing constructs a single mesh for the cubes faces with same texture that are next to each other.
|
||||
I didn't really understand the maths that 0fps did, as I'm still in high school and I haven't studies most of the concepts he used yet, but I was successfull in writing my own. It's quite dumb code, as it's mostly made of if statements and while cycle with mostly no Maths in it, but it works well, and I'm happy with it.
|
||||
|
||||
## Other image here
|
||||
<img src="/resources/projects/voxel-engine-1/voxelengine1-5.jpg" />
|
||||
|
||||
[[This is a wirefram of a chunk mesh generated with greedy
|
||||
meshing]{.small}]{.small}
|
||||
<h4> This is a wirefram of a chunk mesh generated with greedy meshing </h4>
|
||||
|
||||
|
||||
**Smooth world generation using Simplex Noise**
|
||||
## Smooth world generation using Simplex Noise
|
||||
|
||||
As I mentioned before, the early tests used a strange formula to generate less cubes on each layer as the position on the y-axis increased. This was abandoned in less than a couple of weeks, and I tried to have a smooth terrain generating ellipses starting for a center point, with the radius decreasing as the position on the position on the y-axis increased.
|
||||
But I started reading more and more about smooth pseudo-random number generation and I came across [Perlin Noise](https://en.wikipedia.org/wiki/Perlin_noise), which sounded really interesting.
|
||||
I tried to implement Perlin Noise by myself, but after a couple of unsuccesfull tries, I found this [Simplex Noise java implentation by SRombauts](https://github.com/SRombauts/SimplexNoise/blob/master/references/SimplexNoise.java).
|
||||
[Simplex Noise](https://en.wikipedia.org/wiki/Simplex_noise) is computationally less expensive than Perlin Noise, which is can be really useful in this situation. I then adapted the Simplex Noise to my needs, added a couple of features for saving and loading the permutation table to and from file and the world generated was much more beatiful than before.
|
||||
|
||||
## Other image
|
||||
[[The first working test with Simplex Noise (left) and the first test
|
||||
ever with Simplex Noise (right)]{.small}]{.small}
|
||||
<img src="/resources/projects/voxel-engine-1/voxelengine1-6.jpg" />
|
||||
<img src="/resources/projects/voxel-engine-1/voxelengine1-7.jpg" />
|
||||
|
||||
At this point of the development, I decided to not use the *Cell* object
|
||||
anymore and replace them with simple integers inside the
|
||||
three-dimensional array. This saved up to 200MB of RAM when the player
|
||||
is still.
|
||||
<h4> The first working test with Simplex Noise (left) and the first test ever with Simplex Noise (right) </h4>
|
||||
|
||||
**Saving and Loading from file**
|
||||
At this point of the development, I decided to not use the *Cell* object anymore and replace them with simple integers inside the three-dimensional array. This saved up to 200MB of RAM when the player is still.
|
||||
|
||||
## Saving and Loading from file
|
||||
|
||||
As I wanted to preserve the world when I closed the engine, I implemented a basic Chunk load/save system to save RAM by not keeping loaded *Chunks* that are very far apart from the player.
|
||||
This is also used to save the world when the game windows is closed and load it again when it's reopened. The *Chunks* are saved in a plain text file, with each line corresponding to a single index of the 3d-array in the *Chunk,* with the x position, y position, z position and the id integer separated by spaces.
|
||||
|
@ -70,7 +69,7 @@ Along with the *Chunks,* also the *Simplex Noise Permutation Table* and the game
|
|||
This system is absolutely bad, saving lots of *Chunks* requires even gigabytes of space on the disk, which is really insane.
|
||||
|
||||
|
||||
**MultiThreading*,* Block Picking and Customization.**
|
||||
## MultiThreading, Block Picking and Customization.
|
||||
|
||||
Greedy Meshing and Loading *Chunks* from files require some time, which depends on the CPU and disk speed of the Computer. To remove this delay, which blocked the entire Main Thread of the game, I decided to load and generate *Chunks* in a separated thread, which doesn't affect the main one.
|
||||
This makes the engine really smooth to run and the *Chunks* generating in front of you is really nice.
|
||||
|
@ -90,5 +89,7 @@ At this point, I can declare my Voxel Engine completely working, and I'm really
|
|||
You can see all the history of the development on the [github
|
||||
repo](https://github.com/EmaMaker/voxel-engine-jme3.git).
|
||||
|
||||
<img src="/resources/projects/voxel-engine-1/voxelengine1-1.png" />
|
||||
|
||||
But my learning journey isn't finished yet, I still have tons of new things to learn.
|
||||
|
||||
|
|
After Width: | Height: | Size: 672 KiB |
After Width: | Height: | Size: 81 KiB |
After Width: | Height: | Size: 44 KiB |
After Width: | Height: | Size: 45 KiB |
After Width: | Height: | Size: 45 KiB |
After Width: | Height: | Size: 45 KiB |
After Width: | Height: | Size: 83 KiB |
After Width: | Height: | Size: 94 KiB |
After Width: | Height: | Size: 87 KiB |
After Width: | Height: | Size: 836 KiB |