Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,9 @@ bool init_opengl() {
glCullFace(GL_BACK);
glEnable(GL_CULL_FACE);

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

glClearColor(0.529f, 0.808f, 0.922f, 0.0f);

glEnable(GL_MULTISAMPLE);
Expand All @@ -116,6 +119,7 @@ float last_y = 0.0f;
enum class MESH_TYPE : int {
SPHERE,
TERRAIN,
TRANSPARENT_TERRAIN,
RANDOM,
CHECKERBOARD,
EMPTY,
Expand Down Expand Up @@ -189,13 +193,19 @@ void createTestChunk() {
uint8_t* voxels = new uint8_t[CS_P3] { 0 };
memset(voxels, 0, CS_P3);
memset(mainThreadMeshData.opaqueMask, 0, CS_P2 * sizeof(uint64_t));
memset(mainThreadMeshData.transparentMask, 0, CS_P2 * sizeof(uint64_t));

switch (mesh_type) {
case (int) MESH_TYPE::TERRAIN: {
noise.generateTerrainV1(voxels, mainThreadMeshData.opaqueMask, 30);
break;
}

case (int) MESH_TYPE::TRANSPARENT_TERRAIN: {
noise.generateTerrainV1Transparent(voxels, mainThreadMeshData.transparentMask, 30);
break;
}

case (int) MESH_TYPE::RANDOM: {
noise.generateWhiteNoiseTerrain(voxels, mainThreadMeshData.opaqueMask, 30);
break;
Expand Down Expand Up @@ -285,6 +295,7 @@ void createTestChunk() {
auto meshLambda = [](ChunkTableEntry* tableEntry, ThreadData* threadData) -> MeshingResponse {
Timer decompressionTimer("", true);
memset(threadData->meshData->opaqueMask, 0, CS_P2 * sizeof(uint64_t));
memset(threadData->meshData->transparentMask, 0, CS_P2 * sizeof(uint64_t));
rle::decompressToVoxelsAndOpaqueMask(levelFile.buffer.data() + tableEntry->rleDataBegin, tableEntry->rleDataSize, threadData->voxels, threadData->meshData->opaqueMask);
auto decompressionDurationUs = decompressionTimer.end();

Expand Down Expand Up @@ -319,6 +330,7 @@ int main(int argc, char* argv[]) {
}

mainThreadMeshData.opaqueMask = new uint64_t[CS_P2] { 0 };
mainThreadMeshData.transparentMask = new uint64_t[CS_P2] { 0 };
mainThreadMeshData.faceMasks = new uint64_t[CS_2 * 6] { 0 };
mainThreadMeshData.forwardMerged = new uint8_t[CS_2] { 0 };
mainThreadMeshData.rightMerged = new uint8_t[CS] { 0 };
Expand Down Expand Up @@ -347,6 +359,7 @@ int main(int argc, char* argv[]) {
for (int i = 0; i < MAX_MESHING_FUTURES; i++) {
auto meshData = new MeshData();
meshData->opaqueMask = new uint64_t[CS_P2] { 0 };
meshData->transparentMask = new uint64_t[CS_P2] { 0 };
meshData->faceMasks = new uint64_t[CS_2 * 6] { 0 };
meshData->forwardMerged = new uint8_t[CS_2] { 0 };
meshData->rightMerged = new uint8_t[CS] { 0 };
Expand Down Expand Up @@ -440,6 +453,7 @@ int main(int argc, char* argv[]) {

memset(voxels->data(), 0, CS_P3);
memset(mainThreadMeshData.opaqueMask, 0, CS_P2 * sizeof(uint64_t));
memset(mainThreadMeshData.transparentMask, 0, CS_P2 * sizeof(uint64_t));

noise.generateTerrainV2(voxels->data(), mainThreadMeshData.opaqueMask, x, z, 30);

Expand Down
67 changes: 54 additions & 13 deletions src/mesher.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ static constexpr int CS_P3 = CS_P * CS_P * CS_P;
struct MeshData {
uint64_t* faceMasks = nullptr; // CS_2 * 6
uint64_t* opaqueMask = nullptr; //CS_P2
uint64_t* transparentMask = nullptr; //CS_P2
uint8_t* forwardMerged = nullptr; // CS_2
uint8_t* rightMerged = nullptr; // CS
BM_VECTOR<uint64_t>* vertices = nullptr;
Expand Down Expand Up @@ -109,27 +110,67 @@ void mesh(const uint8_t* voxels, MeshData& meshData) {
int vertexI = 0;

uint64_t* opaqueMask = meshData.opaqueMask;
uint64_t* transparentMask = meshData.transparentMask;
uint64_t* faceMasks = meshData.faceMasks;
uint8_t* forwardMerged = meshData.forwardMerged;
uint8_t* rightMerged = meshData.rightMerged;

// Hidden face culling
for (int a = 1; a < CS_P - 1; a++) {
const int aCS_P = a * CS_P;
const int a_ = a * CS_P;

for (int b = 1; b < CS_P - 1; b++) {
const uint64_t columnBits = opaqueMask[(a * CS_P) + b] & P_MASK;
const int baIndex = (b - 1) + (a - 1) * CS;
const int abIndex = (a - 1) + (b - 1) * CS;

faceMasks[baIndex + 0 * CS_2] = (columnBits & ~opaqueMask[aCS_P + CS_P + b]) >> 1;
faceMasks[baIndex + 1 * CS_2] = (columnBits & ~opaqueMask[aCS_P - CS_P + b]) >> 1;

faceMasks[abIndex + 2 * CS_2] = (columnBits & ~opaqueMask[aCS_P + (b + 1)]) >> 1;
faceMasks[abIndex + 3 * CS_2] = (columnBits & ~opaqueMask[aCS_P + (b - 1)]) >> 1;

faceMasks[baIndex + 4 * CS_2] = columnBits & ~(opaqueMask[aCS_P + b] >> 1);
faceMasks[baIndex + 5 * CS_2] = columnBits & ~(opaqueMask[aCS_P + b] << 1);
const int ab = a_ + b;
const uint64_t opaque_col = opaqueMask[ab] & P_MASK;
const int ba_index = (b - 1) + (a - 1) * CS;
const int ab_index = (a - 1) + (b - 1) * CS;
const int up_faces = ba_index + 0 * CS_2;
const int down_faces = ba_index + 1 * CS_2;
const int right_faces = ab_index + 2 * CS_2;
const int left_faces = ab_index + 3 * CS_2;
const int front_faces = ba_index + 4 * CS_2;
const int back_faces = ba_index + 5 * CS_2;

// Opaque face culling
faceMasks[up_faces] = (opaque_col & ~opaqueMask[ab + CS_P]) >> 1;
faceMasks[down_faces] = (opaque_col & ~opaqueMask[ab - CS_P]) >> 1;

faceMasks[right_faces] = (opaque_col & ~opaqueMask[ab + 1]) >> 1;
faceMasks[left_faces] = (opaque_col & ~opaqueMask[ab - 1]) >> 1;

faceMasks[front_faces] = opaque_col & ~(opaqueMask[ab] >> 1);
faceMasks[back_faces] = opaque_col & ~(opaqueMask[ab] << 1);

// Transparent face culling
uint64_t bits_here = transparentMask[ab] & P_MASK;
if(bits_here == 0) continue;

const int ab_ = ab * CS_P;
while (bits_here)
{
unsigned long bitPos;
#ifdef _MSC_VER
_BitScanForward64(&bitPos, bits_here);
#else
bitPos = __builtin_ctzll(bits_here);
#endif
bits_here &= ~(1ull << bitPos);

if (bitPos == 0 || bitPos >= CS+1) continue;

const int abc = ab_ + bitPos;
const uint8_t v1 = voxels[abc];
// The transparent step is slower than the opaque step
// because we need to check if neighboring transparent blocks are differents (we don't care about that for opaque blocks)
faceMasks[up_faces] |= (static_cast<uint64_t>(!(opaqueMask[ab + CS_P] & (1ull << bitPos)) && v1 != voxels[abc + CS_P2]) << (bitPos - 1));
faceMasks[down_faces] |= (static_cast<uint64_t>(!(opaqueMask[ab - CS_P] & (1ull << bitPos)) && v1 != voxels[abc - CS_P2]) << (bitPos - 1));

faceMasks[right_faces] |= (static_cast<uint64_t>(!(opaqueMask[ab + 1] & (1ull << bitPos)) && v1 != voxels[abc + CS_P]) << (bitPos - 1));
faceMasks[left_faces] |= (static_cast<uint64_t>(!(opaqueMask[ab - 1] & (1ull << bitPos)) && v1 != voxels[abc - CS_P]) << (bitPos - 1));

faceMasks[front_faces] |= (static_cast<uint64_t>(!(opaqueMask[ab] & (1ull << (bitPos + 1))) && v1 != voxels[abc + 1]) << bitPos);
faceMasks[back_faces] |= (static_cast<uint64_t>(!(opaqueMask[ab] & (1ull << (bitPos - 1))) && v1 != voxels[abc - 1]) << bitPos);
}
}
}

Expand Down
28 changes: 28 additions & 0 deletions src/misc/noise.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,34 @@ class Noise {
}
}

void generateTerrainV1Transparent(uint8_t* voxels, uint64_t* transparentMask, int seed) {
noise1.SetSeed(seed);

for (int x = 0; x < CS_P; x++) {
for (int y = CS_P - 1; y--;) {
for (int z = 0; z < CS_P; z++) {
float val = ((noise1.GetSimplexFractal(x, y, z)) + 1.0f) / 2.0f;

if (val > glm::smoothstep(0.15f, 1.0f, (float) y / (float) CS_P)) {
int i = get_zxy_index(x, y, z);
int i_above = get_zxy_index(x, y + 1, z);

transparentMask[(y * CS_P) + x] |= 1ull << z;

switch (voxels[i_above]) {
case 0:
voxels[i] = 10;
break;
default:
voxels[i] = 9;
break;
}
}
}
}
}
}

void generateTerrainV2(uint8_t* voxels, uint64_t* opaqueMask, int offsetX, int offsetZ, int seed) {
noise2.SetSeed(seed);

Expand Down
9 changes: 5 additions & 4 deletions src/shaders/main.fs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
#version 460 core

layout(location=0) out vec3 out_color;
layout(location=0) out vec4 out_color;

in VS_OUT {
vec3 pos;
flat vec3 normal;
flat vec3 color;
flat vec4 color;
} fs_in;

uniform vec3 eye_position;
Expand All @@ -22,8 +22,9 @@ void main() {
rim = smoothstep(0.6, 1.0, rim);

out_color =
fs_in.color +
vec4(vec3(fs_in.color.rgb +
(diffuse_color * max(0, dot(L, fs_in.normal))) +
(rim_color * vec3(rim, rim, rim))
(rim_color * vec3(rim, rim, rim))),
fs_in.color.a)
;
}
24 changes: 14 additions & 10 deletions src/shaders/main.vs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ uniform ivec3 eye_position_int;
out VS_OUT {
out vec3 pos;
flat vec3 normal;
flat vec3 color;
flat vec4 color;
} vs_out;

const vec3 normalLookup[6] = {
Expand All @@ -29,15 +29,19 @@ const vec3 normalLookup[6] = {
vec3( 0, 0, -1 )
};

const vec3 colorLookup[8] = {
vec3(0.2, 0.659, 0.839),
vec3(0.302, 0.302, 0.302),
vec3(0.278, 0.600, 0.141),
vec3(0.1, 0.1, 0.6),
vec3(0.1, 0.6, 0.6),
vec3(0.6, 0.1, 0.6),
vec3(0.6, 0.6, 0.1),
vec3(0.6, 0.1, 0.1)
const vec4 colorLookup[10] = {
// Opaque colors
vec4(0.2, 0.659, 0.839, 1.0),
vec4(0.302, 0.302, 0.302, 1.0),
vec4(0.278, 0.600, 0.141, 1.0),
vec4(0.1, 0.1, 0.6, 1.0),
vec4(0.1, 0.6, 0.6, 1.0),
vec4(0.6, 0.1, 0.6, 1.0),
vec4(0.6, 0.6, 0.1, 1.0),
vec4(0.6, 0.1, 0.1, 1.0),
// Transparent colors
vec4(0.302, 0.302, 0.302, 0.5),
vec4(0.278, 0.600, 0.141, 0.5),
};

const int flipLookup[6] = int[6](1, -1, -1, 1, -1, 1);
Expand Down