mirror of
https://github.com/CrispyPin/crispypin.cc.git
synced 2024-11-10 04:00:27 +01:00
56 lines
No EOL
3.3 KiB
HTML
56 lines
No EOL
3.3 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<link rel="stylesheet" href="/style.css">
|
|
<link rel="icon" type="image/x-icon" href="/icons/favicon.png">
|
|
<title>Voxel engine</title>
|
|
</head>
|
|
<body>
|
|
<header>
|
|
<a href="/" id="logo"><img src="/icons/logo.png" alt=""></a>
|
|
</header>
|
|
<main>
|
|
<h1>Godot-Rust Voxel Engine</h1>
|
|
<a href="https://github.com/CrispyPin/gd-voxel-rs">https://github.com/CrispyPin/gd-voxel-rs</a>
|
|
<p>
|
|
I made a voxel engine in rust to learn rust and godot-rust as well as explore voxel systems. It has (practically) infinite terrain generation, lets you place and remove voxels and supports transparent voxel types. The main point was to develop an optimised meshing algorithm.
|
|
</p>
|
|
<video src="demo.mp4" controls>video not supported :(</video>
|
|
<p>Demo of fast terrain generation</p>
|
|
<video src="demo2.mp4" controls>video not supported :(</video>
|
|
<p>Optimised mesh visualisation</p>
|
|
|
|
<h2 id="greedy-mesh" class="title-link"><a href="#greedy-mesh">Optimised/greedy mesh algorithm</a></h2>
|
|
<p>Disclaimer: this is not done. <b>I will write the rest of this soon™</b></p>
|
|
|
|
<p>The algorithm I'm using is one I made myself, inspired by a few others. I could not find an easy to understand explanation of how to do it but <a href="https://vercidium.com/blog/voxel-world-optimisations/">this artice</a> and <a href="https://0fps.net/2012/06/30/meshing-in-a-minecraft-game/">this article</a> gave me somewhere to start.</p>
|
|
|
|
<p>In this explanation I will assume basic knowledge of how meshes work and how to do the simplest form of culling for voxel meshes.</p>
|
|
|
|
<img src="fig1.png" alt="">
|
|
<p>fig. 1: example set of voxels, with the simplest form of mesh generation applied.</p>
|
|
|
|
<p>To start off, we can break down the problem to 2 dimensions by recognising that each direction along the axis as well as each layer along those directions is independent. We then only have to process a single 2D slice of the voxel domain at once.
|
|
</p>
|
|
|
|
<img src="fig2.png" alt="">
|
|
<p>fig. 2: The algorithm only needs to consider one layer and direction at a time, highlighted in green</p>
|
|
|
|
<p>The first step is to generate "strips", essentially create long quads that cover connected voxels. We can loop through the plane and keep track of at most one active strip. The active strip is the last one started and we grow it as more voxels under it are traversed. In the inner loop we check the voxel at that position as well as the one above. With this we can determine if we need to stop the current strip, start a new one or do nothing. If there is not currently an active strip, a new one should be created when the voxel below is filled and the one above is empty (an exposed surface). </p>
|
|
|
|
<img src="fig3.png" alt="">
|
|
<p>fig.3: Long strips of adjacent voxels can be merged into fewer, long quads.</p>
|
|
</main>
|
|
<footer>
|
|
<p>You can find me here:</p>
|
|
<div class="links">
|
|
<a href="https://github.com/CrispyPin"><img src="/icons/github.png" alt="" width=32px></a>
|
|
<a href="https://crispypin.itch.io/"><img src="/icons/itch.io.svg" alt="" width=32px></a>
|
|
<a href="https://www.youtube.com/CrispyPin42"><img src="/icons/youtube.png" alt="" width=32px></a>
|
|
</div>
|
|
</footer>
|
|
</body>
|
|
</html> |