Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
November 11, 2020 05:53 am GMT

Making a voxel engine

Introduction

This series of posts will focus on creating a voxel engine, from scratch, based on BabylonJS for the low-level 3D routines support.

To begin, here is in the video below, the first target we will have to reach, in order to manage the rendering of the world.

So what is a voxel ?

To keep it simple, a voxel is in 3D what a pixel is in 2D. It is value in grid, in a 3D space.

Strictly speaking, the voxel is like a pixel, in the meaning that it has only one value, its color.

Voxel engines generally have a little more flexibility in the degree to which the display of a voxel is done. It can display a cube single colored, or textured as in Minecraft.

So displaying cubes is not a big deal, isn't it ?

Short answer : Yes... and no.

A 3D engine, in order to keep a good frame rate, can apply many optimizations to the 3D scene to render.

It can hide the non visible objects, or simplify the objects according to the camera distance.

The problem with voxels is that you will have a very large quantity of cube, so even if you try to hide some of them, you will quickly struggle in rendering speed.

Moreover, a cube is a simple geometric shape, and therefore, simplifying this object cannot be done without severely deforming it. Remove one node and the cube becomes anything you want except... a simpler cube.

So okay, but where to start then?

Let's start with something basic, which is to define some target functionalities that we are going to implement.

We're going to take our inspiration from the way Minecraft handles the rendering of worlds in the game, at least in the early versions of the game.

We will try to use as few technical terms as possible, just the bare minimum required, in order to keep all the explanations understandable to everyone.

World structure

The world

A world represents a set of voxels that it will be possible to display.The world is divided into regions.

The region

A region represents a piece of the world. Each region has the same number of voxels. A region is also represented by a 3D coordinate. A region is composed by a data chunk.

A chunk

A chunk is composed of a set of voxels, in a 3-dimensional grid, where each dimension is the same size. This can be simplified as a cube filled with small cubes.

Let's assume for example that a data chunk is composed of 3 dimensions of size 32. A region thus has 32*32*32 voxels, a total of 32768 voxels.

If our world has 100*100 regions per layer and let's say 3 layers of height, we will have a total of 100*100*3 regions, so 30000 regions.

Our world will thus have a total of 100*100*3*32768 = 983 040 000 voxels. Our very small world already has close to a billion potential voxels.

Block definition

Our voxel, in our engine, will be presented as a block, more complex in structure than a simple 3D point.

export type Block = {  name  : string; // Block name  guid  : string; // Unique global Id  uid   : number; // Unique local id  sidesTex : [ // Array of textures    string, // BACK    string, // FRONT    string, // RIGHT    string, // LEFT    string, // TOP    string  // BOTTOM  ];  size: [ // Edges size    number, // WIDTH    number, // HEIGHT    number  // DEPTH  ];  type    : string; // GAZ, LIQUID, BLOCK  opacity : number;  speed   : number; // 0 - 1};
Enter fullscreen mode Exit fullscreen mode

So we have the smallest usable unit.

Each block will need some data to represent each side, for optimization purpose. Let's define an enum to represents sides.

export enum Side {  Left     = 1  ,  Right    = 2  ,  Forward  = 4  ,  Backward = 8  ,  Top      = 16 ,  Bottom   = 32 ,  Z_Axis   = 3  ,  X_Axis   = 12 ,  Y_Axis   = 48 ,  All      = 63}
Enter fullscreen mode Exit fullscreen mode

Chunk definition

A chunk will store different kind of data, including the full and the optimized version of the blocks.

export type Chunk = {  position   : Vector3       ; // 3D position in the world  size       : number        ; // Size of the chunk, default will be 32  data       : Array<number> ; // The original data  dataSize   : number        ; // The number of non empty blocks  rcData     : Array<number> ; // An optimized version of visible only visible data  rcDataSize : number        ; // The number of visible blocks  hasRc      : boolean       ; // Define if a chunk has been optimized or not};
Enter fullscreen mode Exit fullscreen mode

1D array or the power of flattening everything

When dealing with Typescript / Javascript, it is easy to deal with array of array. It seems common to proceed like this.

But here, we need to keep in mind that performance will decrease rapidly as soon as we add new features, so we need to avoid wasting our precious frame per second by taking the easy way out.

Using a one-dimensional array to simulate a 3-dimensional access will always be faster. We will therefore use functions to simplify our work.

/** * Convert a vector 3 coordinate to a flat array index * @param x {number} The x coordinate * @param y {number} The y coordinate * @param z {number} The z coordinate * @param size {number} The size of each dimension, the size is the same for each one */export function vector3ToArrayIndex(x: number, y: number, z: number, size: number = 32) {  return (size * size * x) + (size * y) + z;}/** * Convert a flat array index to a 3D coordinate representation * @param index {number} The array index * @param size {number} The size of x,y,z dimension */export function arrayIndexToVector3(index: number, size: number = 32) {  return new BABYLON.Vector3(    (index / (size * size)) >> 0,    ((index / size) % size) >> 0,    (index % size) >> 0  );}
Enter fullscreen mode Exit fullscreen mode

This will conclude our introduction. In the next post, we will see how to render our blocks using Babylon Js, and the minimum of 3D terminology necessary to understand the next posts.

Enjoy !


Original Link: https://dev.to/nomoredeps/making-a-voxel-engine-46h8

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To