voxel biomes and CPU pushed blocks
This commit is contained in:
parent
7fda2614d7
commit
a0b00b0f1c
24 changed files with 1007 additions and 91 deletions
BIN
resources/EngineResources/Texture/blueleaf_set.png
Normal file
BIN
resources/EngineResources/Texture/blueleaf_set.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.6 KiB |
BIN
resources/EngineResources/Texture/blueleaf_set_2.png
Normal file
BIN
resources/EngineResources/Texture/blueleaf_set_2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.9 KiB |
BIN
resources/EngineResources/Texture/blueleaf_set_2_translucent.png
Normal file
BIN
resources/EngineResources/Texture/blueleaf_set_2_translucent.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.6 KiB |
BIN
resources/EngineResources/Texture/blueleaf_set_translucent.png
Normal file
BIN
resources/EngineResources/Texture/blueleaf_set_translucent.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2 KiB |
BIN
resources/EngineResources/Texture/test_cube_translucency.png
Normal file
BIN
resources/EngineResources/Texture/test_cube_translucency.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.2 KiB |
|
|
@ -32,11 +32,26 @@ layout(std430, binding = 3) buffer Counters {
|
||||||
uint faceCount;
|
uint faceCount;
|
||||||
} counters;
|
} counters;
|
||||||
|
|
||||||
|
struct Voxel {
|
||||||
|
uint MaterialIndex;
|
||||||
|
uint BlockType;
|
||||||
|
uvec2[2] UpIndex;
|
||||||
|
uvec2[2] DownIndex;
|
||||||
|
uvec2[2] NorthIndex;
|
||||||
|
uvec2[2] SouthIndex;
|
||||||
|
uvec2[2] EastIndex;
|
||||||
|
uvec2[2] WestIndex;
|
||||||
|
};
|
||||||
|
|
||||||
|
layout(std430, set = 1, binding = 0) readonly buffer VoxelUniform {
|
||||||
|
Voxel materials[];
|
||||||
|
} voxelReg;
|
||||||
|
|
||||||
layout(push_constant) uniform ChunkInfo {
|
layout(push_constant) uniform ChunkInfo {
|
||||||
ivec3 chunkPos;
|
ivec3 chunkPos;
|
||||||
int slot;
|
int slot;
|
||||||
uint faceOffset;
|
uint faceOffset;
|
||||||
uint unused0;
|
uint voxelTypeCount;
|
||||||
uint indirectCommandIndex;
|
uint indirectCommandIndex;
|
||||||
uint padding0;
|
uint padding0;
|
||||||
};
|
};
|
||||||
|
|
@ -44,7 +59,10 @@ layout(push_constant) uniform ChunkInfo {
|
||||||
uint flatten(ivec3 pos) {
|
uint flatten(ivec3 pos) {
|
||||||
return uint((pos.x * CHUNK_AREA) + (pos.y * CHUNK_SIZE) + pos.z);
|
return uint((pos.x * CHUNK_AREA) + (pos.y * CHUNK_SIZE) + pos.z);
|
||||||
}
|
}
|
||||||
|
bool isSeeThrough(Voxel voxel, uint type) {
|
||||||
|
if (type == 0u || voxel.BlockType == 3u || type > voxelTypeCount) return true;
|
||||||
|
return voxelReg.materials[type - 1u].BlockType >= 1u;
|
||||||
|
}
|
||||||
uint getVoxel(ivec3 pos) {
|
uint getVoxel(ivec3 pos) {
|
||||||
if (pos.x < 0 || pos.x >= CHUNK_SIZE) return 0u;
|
if (pos.x < 0 || pos.x >= CHUNK_SIZE) return 0u;
|
||||||
if (pos.y < 0 || pos.y >= CHUNK_SIZE) return 0u;
|
if (pos.y < 0 || pos.y >= CHUNK_SIZE) return 0u;
|
||||||
|
|
@ -58,7 +76,16 @@ uint hash21(uvec2 p) {
|
||||||
p.y += p.x * 1664525u;
|
p.y += p.x * 1664525u;
|
||||||
return p.x ^ (p.x >> 16);
|
return p.x ^ (p.x >> 16);
|
||||||
}
|
}
|
||||||
|
uint pcg_hash(uint seed) {
|
||||||
|
uint state = seed * 747796405u + 289133645u;
|
||||||
|
uint word = ((state >> ((state >> 28u) + 4u)) ^ state) * 277803737u;
|
||||||
|
return (word >> 22u) ^ word;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint randomRangeUint(uint seed, uint minVal, uint maxVal) {
|
||||||
|
uint range = maxVal - minVal + 1u;
|
||||||
|
return minVal + (pcg_hash(seed) % range);
|
||||||
|
}
|
||||||
uint random_1_to_3(vec2 uv, uint customSeed) {
|
uint random_1_to_3(vec2 uv, uint customSeed) {
|
||||||
uvec2 p = uvec2(floatBitsToUint(uv.x), floatBitsToUint(uv.y));
|
uvec2 p = uvec2(floatBitsToUint(uv.x), floatBitsToUint(uv.y));
|
||||||
p.x ^= customSeed;
|
p.x ^= customSeed;
|
||||||
|
|
@ -66,6 +93,31 @@ uint random_1_to_3(vec2 uv, uint customSeed) {
|
||||||
return (randInt % 3u) + 1u;
|
return (randInt % 3u) + 1u;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint packFace(uvec3 voxelPos, uint faceIndex, Voxel voxel) {
|
||||||
|
uint randomSeed = uint(voxelPos.x) * 73856093u ^ uint(voxelPos.z) * 19349663u;
|
||||||
|
uvec2 UpIndex = uvec2(randomRangeUint(randomSeed,voxel.UpIndex[0].x,voxel.UpIndex[1].x),randomRangeUint(randomSeed,voxel.UpIndex[0].y,voxel.UpIndex[1].y));
|
||||||
|
uvec2 DownIndex = uvec2(randomRangeUint(randomSeed,voxel.DownIndex[0].x,voxel.DownIndex[1].x),randomRangeUint(randomSeed,voxel.DownIndex[0].y,voxel.DownIndex[1].y));
|
||||||
|
uvec2 NorthIndex = uvec2(randomRangeUint(randomSeed,voxel.NorthIndex[0].x,voxel.NorthIndex[1].x),randomRangeUint(randomSeed,voxel.NorthIndex[0].y,voxel.NorthIndex[1].y));
|
||||||
|
uvec2 SouthIndex = uvec2(randomRangeUint(randomSeed,voxel.SouthIndex[0].x,voxel.SouthIndex[1].x),randomRangeUint(randomSeed,voxel.SouthIndex[0].y,voxel.SouthIndex[1].y));
|
||||||
|
uvec2 EastIndex = uvec2(randomRangeUint(randomSeed,voxel.EastIndex[0].x,voxel.EastIndex[1].x),randomRangeUint(randomSeed,voxel.EastIndex[0].y,voxel.EastIndex[1].y));
|
||||||
|
uvec2 WestIndex = uvec2(randomRangeUint(randomSeed,voxel.WestIndex[0].x,voxel.WestIndex[1].x),randomRangeUint(randomSeed,voxel.WestIndex[0].y,voxel.WestIndex[1].y));
|
||||||
|
|
||||||
|
uvec2 textureIndices[8] = uvec2[8](UpIndex, DownIndex, NorthIndex,
|
||||||
|
SouthIndex, EastIndex, WestIndex, NorthIndex,SouthIndex);
|
||||||
|
uvec2 tex = textureIndices[faceIndex];
|
||||||
|
uint textureIndexX = tex.x;
|
||||||
|
uint textureIndexY = tex.y;
|
||||||
|
uint materialId = voxel.MaterialIndex;
|
||||||
|
|
||||||
|
return (voxelPos.x & 0xFu) |
|
||||||
|
((voxelPos.y & 0xFu) << 4u) |
|
||||||
|
((voxelPos.z & 0xFu) << 8u) |
|
||||||
|
((faceIndex & 0x7u) << 12u) |
|
||||||
|
((materialId & 0x7FFu) << 15u) |
|
||||||
|
((textureIndexX & 0x7u) << 26u) |
|
||||||
|
((textureIndexY & 0x7u) << 29u);
|
||||||
|
}
|
||||||
|
|
||||||
uint packFace(uvec3 voxelPos, uint faceIndex, uint materialId) {
|
uint packFace(uvec3 voxelPos, uint faceIndex, uint materialId) {
|
||||||
uint randomFaceValue = random_1_to_3(vec2(voxelPos.x, voxelPos.z),faceOffset);
|
uint randomFaceValue = random_1_to_3(vec2(voxelPos.x, voxelPos.z),faceOffset);
|
||||||
uint textureIndexX = 0u;
|
uint textureIndexX = 0u;
|
||||||
|
|
@ -107,23 +159,28 @@ uint packFace(uvec3 voxelPos, uint faceIndex, uint materialId) {
|
||||||
textureIndexY = 0u;
|
textureIndexY = 0u;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (voxelPos.x & 0x1Fu) |
|
return (voxelPos.x & 0xFu) |
|
||||||
((voxelPos.y & 0x1Fu) << 5u) |
|
((voxelPos.y & 0xFu) << 4u) |
|
||||||
((voxelPos.z & 0x1Fu) << 10u) |
|
((voxelPos.z & 0xFu) << 8u) |
|
||||||
((faceIndex & 0x7u) << 15u) |
|
((faceIndex & 0x7u) << 12u) |
|
||||||
((materialId & 0xFFu) << 18u) |
|
((materialId & 0x7FFu) << 15u) |
|
||||||
((textureIndexX & 0x7u) << 26u) |
|
((textureIndexX & 0x7u) << 26u) |
|
||||||
((textureIndexY & 0x7u) << 29u);
|
((textureIndexY & 0x7u) << 29u);
|
||||||
}
|
}
|
||||||
|
|
||||||
void emitFace(ivec3 voxelPos, uint faceIndex, uint voxelType) {
|
void emitFace(ivec3 voxelPos, uint faceIndex, uint voxelType) {
|
||||||
|
if (voxelType == 0u || voxelType > voxelTypeCount) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
uint localFace = atomicAdd(counters.faceCount, 1u);
|
uint localFace = atomicAdd(counters.faceCount, 1u);
|
||||||
|
|
||||||
if (localFace >= MAX_VISIBLE_FACES_PER_CHUNK) {
|
if (localFace >= MAX_VISIBLE_FACES_PER_CHUNK) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
faces[faceOffset + localFace] = packFace(uvec3(voxelPos), faceIndex, voxelType);
|
Voxel voxel = voxelReg.materials[voxelType - 1u];
|
||||||
|
faces[faceOffset + localFace] = packFace(uvec3(voxelPos), faceIndex, voxel);
|
||||||
|
|
||||||
atomicAdd(drawCmds[indirectCommandIndex].vertexCount, VERTICES_PER_FACE);
|
atomicAdd(drawCmds[indirectCommandIndex].vertexCount, VERTICES_PER_FACE);
|
||||||
}
|
}
|
||||||
|
|
@ -136,21 +193,20 @@ void main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
uint current = getVoxel(pos);
|
uint current = getVoxel(pos);
|
||||||
|
if (current == 0u || current > voxelTypeCount) {
|
||||||
if (current == 0u) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Voxel voxel = voxelReg.materials[current - 1u];
|
||||||
if (current == 4u) {
|
if (voxel.BlockType == 1u) {
|
||||||
emitFace(pos, 6u, current);
|
emitFace(pos, 6u, current);
|
||||||
emitFace(pos, 7u, current);
|
emitFace(pos, 7u, current);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getVoxel(pos + ivec3( 0, 1, 0)) == 0u || getVoxel(pos + ivec3( 0, 1, 0)) == 4u) emitFace(pos, 0u, current);
|
if (isSeeThrough(voxel,getVoxel(pos + ivec3( 0, 1, 0)))) emitFace(pos, 0u, current);
|
||||||
if (getVoxel(pos + ivec3( 0, -1, 0)) == 0u || getVoxel(pos + ivec3( 0, -1, 0)) == 4u) emitFace(pos, 1u, current);
|
if (isSeeThrough(voxel,getVoxel(pos + ivec3( 0, -1, 0)))) emitFace(pos, 1u, current);
|
||||||
if (getVoxel(pos + ivec3( 1, 0, 0)) == 0u || getVoxel(pos + ivec3( 1, 0, 0)) == 4u) emitFace(pos, 2u, current);
|
if (isSeeThrough(voxel,getVoxel(pos + ivec3( 1, 0, 0)))) emitFace(pos, 2u, current);
|
||||||
if (getVoxel(pos + ivec3(-1, 0, 0)) == 0u || getVoxel(pos + ivec3( -1, 0, 0)) == 4u) emitFace(pos, 3u, current);
|
if (isSeeThrough(voxel,getVoxel(pos + ivec3(-1, 0, 0)))) emitFace(pos, 3u, current);
|
||||||
if (getVoxel(pos + ivec3( 0, 0, 1)) == 0u|| getVoxel(pos + ivec3( 0, 0, 1)) == 4u) emitFace(pos, 4u, current);
|
if (isSeeThrough(voxel,getVoxel(pos + ivec3( 0, 0, 1)))) emitFace(pos, 4u, current);
|
||||||
if (getVoxel(pos + ivec3( 0, 0, -1)) == 0u || getVoxel(pos + ivec3( 0, 0, -1)) == 4u) emitFace(pos, 5u, current);
|
if (isSeeThrough(voxel,getVoxel(pos + ivec3( 0, 0, -1)))) emitFace(pos, 5u, current);
|
||||||
}
|
}
|
||||||
|
|
@ -8,6 +8,19 @@ const int CHUNK_AREA = CHUNK_SIZE * CHUNK_SIZE;
|
||||||
layout(std430, binding = 0) buffer VoxelData {
|
layout(std430, binding = 0) buffer VoxelData {
|
||||||
uint voxels[];
|
uint voxels[];
|
||||||
};
|
};
|
||||||
|
struct Biome {
|
||||||
|
uint surfaceBlock;
|
||||||
|
uint dirtBlock;
|
||||||
|
uint stoneBlock;
|
||||||
|
uint grassFoliage;
|
||||||
|
uint[4] flowers;
|
||||||
|
uint[4] tallBlocks;
|
||||||
|
uint[4] otherFoliage;
|
||||||
|
};
|
||||||
|
|
||||||
|
layout(std430, set = 1, binding = 0) readonly buffer BiomeUniform {
|
||||||
|
Biome biomes[];
|
||||||
|
} BiomeReg;
|
||||||
|
|
||||||
layout(push_constant) uniform ChunkInfo {
|
layout(push_constant) uniform ChunkInfo {
|
||||||
ivec3 chunkPos;
|
ivec3 chunkPos;
|
||||||
|
|
@ -15,15 +28,8 @@ layout(push_constant) uniform ChunkInfo {
|
||||||
uint faceOffset;
|
uint faceOffset;
|
||||||
uint unused0;
|
uint unused0;
|
||||||
uint indirectCommandIndex;
|
uint indirectCommandIndex;
|
||||||
uint padding0;
|
uint biomeCount;
|
||||||
};
|
};
|
||||||
vec3 random3(vec3 st) {
|
|
||||||
return fract(sin(vec3(
|
|
||||||
dot(st, vec3(127.1, 311.7, 74.7)),
|
|
||||||
dot(st, vec3(269.5, 183.3, 246.1)),
|
|
||||||
dot(st, vec3(113.5, 271.9, 124.6))
|
|
||||||
)) * 43758.5453123);
|
|
||||||
}
|
|
||||||
|
|
||||||
float random3to1(vec3 st) {
|
float random3to1(vec3 st) {
|
||||||
return fract(sin(dot(st, vec3(127.1, 311.7, 74.7))) * 43758.5453123);
|
return fract(sin(dot(st, vec3(127.1, 311.7, 74.7))) * 43758.5453123);
|
||||||
|
|
@ -88,6 +94,29 @@ float valueNoise(vec2 st) {
|
||||||
(c - a) * u.y * (1.0 - u.x) +
|
(c - a) * u.y * (1.0 - u.x) +
|
||||||
(d - b) * u.x * u.y;
|
(d - b) * u.x * u.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint pcg_hash(uint seed) {
|
||||||
|
uint state = seed * 747796405u + 289133645u;
|
||||||
|
uint word = ((state >> ((state >> 28u) + 4u)) ^ state) * 277803737u;
|
||||||
|
return (word >> 22u) ^ word;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint randomRangeUint(uint seed, uint minVal, uint maxVal) {
|
||||||
|
uint range = maxVal - minVal + 1u;
|
||||||
|
return minVal + (pcg_hash(seed) % range);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint GetBiome(vec3 worldPos, uint MaxBiomes) {
|
||||||
|
if (MaxBiomes == 0u) return 0u;
|
||||||
|
vec3 X = vec3(worldPos);
|
||||||
|
X = mat3(
|
||||||
|
0.788675134594813, -0.211324865405187, -0.577350269189626,
|
||||||
|
-0.211324865405187, 0.788675134594813, -0.577350269189626,
|
||||||
|
0.577350269189626, 0.577350269189626, 0.577350269189626) * X;
|
||||||
|
float n = clamp(cubicNoise(X), 0.0, 0.9999);
|
||||||
|
uint Biome = uint(floor(n * float(MaxBiomes)));
|
||||||
|
return min(Biome, MaxBiomes - 1u);
|
||||||
|
}
|
||||||
bool isCave(vec3 worldPos) {
|
bool isCave(vec3 worldPos) {
|
||||||
vec3 X = vec3(worldPos);
|
vec3 X = vec3(worldPos);
|
||||||
X = mat3(
|
X = mat3(
|
||||||
|
|
@ -102,32 +131,40 @@ void main() {
|
||||||
ivec3 localPos = ivec3(gl_GlobalInvocationID.xyz);
|
ivec3 localPos = ivec3(gl_GlobalInvocationID.xyz);
|
||||||
ivec3 worldPos = chunkPos * CHUNK_SIZE + localPos;
|
ivec3 worldPos = chunkPos * CHUNK_SIZE + localPos;
|
||||||
|
|
||||||
|
uint biome = GetBiome(vec3(worldPos.z, worldPos.y, worldPos.x) * 0.05, biomeCount);
|
||||||
|
Biome currentBiome = BiomeReg.biomes[biome];
|
||||||
|
|
||||||
float YZone = floor(worldPos.y/150.0)*150.0;
|
float YZone = floor(worldPos.y/150.0)*150.0;
|
||||||
float SurfaceHeight = valueNoise(vec2(worldPos.x + YZone * 2, worldPos.z + YZone * 2) * 0.005) * 100 +
|
float SurfaceHeight = valueNoise(vec2(worldPos.x + YZone * 2, worldPos.z + YZone * 2) * 0.005) * 100 +
|
||||||
|
|
||||||
valueNoise(vec2(worldPos.x + YZone * 2, worldPos.z + YZone * 2) * 0.01) * 10 +
|
valueNoise(vec2(worldPos.x + YZone * 2, worldPos.z + YZone * 2) * 0.01) * 10 +
|
||||||
valueNoise(vec2(worldPos.x + YZone * 2, worldPos.z + YZone * 2) * 0.1) * 5 +
|
valueNoise(vec2(worldPos.x + YZone * 2, worldPos.z + YZone * 2) * 0.1) * 5 +
|
||||||
valueNoise(vec2(worldPos.x + YZone * 2, worldPos.z + YZone * 2)) * 0.5 + YZone;
|
valueNoise(vec2(worldPos.x + YZone * 2, worldPos.z + YZone * 2)) * 0.5 + YZone;
|
||||||
|
|
||||||
|
uint RandomBlockVal = randomRangeUint(uint(worldPos.x) * 73856093u ^ uint(worldPos.z) * 19349663u,0u ,3u);
|
||||||
float IslandUnderneathHeight = valueNoise(vec2(worldPos.x + YZone * 2, worldPos.z + YZone * 2) * 0.005) * 100 +
|
float IslandUnderneathHeight = valueNoise(vec2(worldPos.x + YZone * 2, worldPos.z + YZone * 2) * 0.005) * 100 +
|
||||||
|
|
||||||
valueNoise(vec2(worldPos.x + YZone * 2, worldPos.z + YZone * 2) * 0.1) * 20 +
|
valueNoise(vec2(worldPos.x + YZone * 2, worldPos.z + YZone * 2) * 0.1) * 20 +
|
||||||
valueNoise(vec2(worldPos.x + YZone * 2, worldPos.z + YZone * 2) * 0.1) * 5 +
|
valueNoise(vec2(worldPos.x + YZone * 2, worldPos.z + YZone * 2) * 0.1) * 5 +
|
||||||
valueNoise(vec2(worldPos.x + YZone * 2, worldPos.z + YZone * 2)) * 0.5 - 15 + YZone;
|
valueNoise(vec2(worldPos.x + YZone * 2, worldPos.z + YZone * 2)) * 0.5 - 15 + YZone;
|
||||||
|
|
||||||
float grassNoise = valueNoise(vec2(worldPos.z + YZone * 2, worldPos.x + YZone * 2));
|
float grassNoise = valueNoise(vec2(worldPos.z * 0.5 - YZone * 2, worldPos.x * 0.5 - YZone * 2));
|
||||||
|
|
||||||
uint voxelType = 0u;
|
uint voxelType = 0u;
|
||||||
|
|
||||||
if (float(worldPos.y) <= SurfaceHeight && float(worldPos.y) >= IslandUnderneathHeight) {
|
if (float(worldPos.y) <= SurfaceHeight && float(worldPos.y) >= IslandUnderneathHeight) {
|
||||||
float depthBelowSurface = SurfaceHeight - float(worldPos.y);
|
float depthBelowSurface = SurfaceHeight - float(worldPos.y);
|
||||||
if (depthBelowSurface < 0.5) {
|
if (depthBelowSurface < 0.5) {
|
||||||
if(grassNoise < 0.65) voxelType = 4u; // Grass foliage
|
if(grassNoise < 0.65) voxelType = currentBiome.grassFoliage; // Grass foliage
|
||||||
|
else if (grassNoise < 0.75) voxelType = currentBiome.flowers[RandomBlockVal];
|
||||||
|
else if (grassNoise < 0.85) voxelType = currentBiome.otherFoliage[RandomBlockVal];
|
||||||
else voxelType = 0u;
|
else voxelType = 0u;
|
||||||
}else if (depthBelowSurface < 2.5) {
|
}else if (depthBelowSurface < 2.5) {
|
||||||
voxelType = 1u; // Grass
|
voxelType = currentBiome.surfaceBlock; // Grass
|
||||||
} else if (depthBelowSurface < 6.0) {
|
} else if (depthBelowSurface < 6.0) {
|
||||||
voxelType = 2u; // Dirt(also stone rn)
|
voxelType = currentBiome.dirtBlock; // Dirt(also stone rn)
|
||||||
} else {
|
} else {
|
||||||
voxelType = 3u; // Stone
|
voxelType = currentBiome.stoneBlock; // Stone
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
|
|
@ -145,14 +182,16 @@ void main() {
|
||||||
float depthBelowSurface = height2 - float(worldPos.y);
|
float depthBelowSurface = height2 - float(worldPos.y);
|
||||||
|
|
||||||
if (depthBelowSurface < 0.5) {
|
if (depthBelowSurface < 0.5) {
|
||||||
if (grassNoise < 0.65) voxelType = 4u; // Grass foliage
|
if (grassNoise < 0.65) voxelType = currentBiome.grassFoliage; // Grass foliage
|
||||||
|
else if (grassNoise < 0.75) voxelType = currentBiome.flowers[RandomBlockVal];
|
||||||
|
else if (grassNoise < 0.85) voxelType = currentBiome.otherFoliage[RandomBlockVal];
|
||||||
else voxelType = 0u;
|
else voxelType = 0u;
|
||||||
} else if (depthBelowSurface < 1.5) {
|
} else if (depthBelowSurface < 1.5) {
|
||||||
voxelType = 1u; // Grass
|
voxelType = currentBiome.surfaceBlock; // Grass
|
||||||
} else if (depthBelowSurface < 6.0) {
|
} else if (depthBelowSurface < 6.0) {
|
||||||
voxelType = 2u; // Dirt(also stone rn)
|
voxelType = currentBiome.dirtBlock; // Dirt(also stone rn)
|
||||||
} else {
|
} else {
|
||||||
voxelType = 3u; // Stone
|
voxelType = currentBiome.stoneBlock; // Stone
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
88
resources/EngineResources/shaders/packed_scene_fragment.glsl
Normal file
88
resources/EngineResources/shaders/packed_scene_fragment.glsl
Normal file
|
|
@ -0,0 +1,88 @@
|
||||||
|
#version 450
|
||||||
|
#extension GL_EXT_nonuniform_qualifier : require
|
||||||
|
|
||||||
|
const int MAX_TEXTURES = 128;
|
||||||
|
|
||||||
|
layout(location = 0) in vec4 inPos;
|
||||||
|
layout(location = 1) in vec3 inNormal;
|
||||||
|
layout(location = 2) in vec3 inTangent;
|
||||||
|
layout(location = 3) in vec3 inBitangent;
|
||||||
|
layout(location = 4) in vec2 inTextCoords;
|
||||||
|
layout(location = 5) in mat4 viewMatrix;
|
||||||
|
layout(location = 9) in flat uint textureIndex;
|
||||||
|
|
||||||
|
layout(location = 0) out vec4 outAlbedo;
|
||||||
|
layout(location = 1) out vec4 outViewPos;
|
||||||
|
|
||||||
|
struct Material {
|
||||||
|
vec4 diffuseColor; //16
|
||||||
|
uint hasTexture; //20
|
||||||
|
uint textureIdx; //24
|
||||||
|
uint hasNormalMap; //28
|
||||||
|
uint normalMapIdx; //32
|
||||||
|
uint hasRoughMap; //36
|
||||||
|
uint roughMapIdx; //40
|
||||||
|
float roughnessFactor; //44
|
||||||
|
float metallicFactor; //48
|
||||||
|
vec4 emissiveColour; //64
|
||||||
|
uint hasEmissiveMap; //68
|
||||||
|
uint emissiveMapIdx; //72
|
||||||
|
uint hasTranslucencyMap; //76
|
||||||
|
uint translucencyMapIdx; //80
|
||||||
|
float translucencyFactor; //84
|
||||||
|
uint hasOpacityMap; //88
|
||||||
|
uint OpacityMapIdx; //92
|
||||||
|
float OpacityFactor; //96
|
||||||
|
float reflectiveness; //100
|
||||||
|
float refractiveness; //104
|
||||||
|
float Padding1; //108
|
||||||
|
float Padding2; //112
|
||||||
|
};
|
||||||
|
|
||||||
|
layout(set = 2, binding = 0) readonly buffer MaterialUniform{
|
||||||
|
Material materials[];
|
||||||
|
} matUniform;
|
||||||
|
|
||||||
|
layout(set = 3, binding = 0) uniform sampler2D textSampler[MAX_TEXTURES];
|
||||||
|
|
||||||
|
|
||||||
|
layout(push_constant) uniform pc{
|
||||||
|
layout(offset = 64) uint materialIdx;
|
||||||
|
} push_constants;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec4 viewPos = vec4(viewMatrix * inPos);
|
||||||
|
outViewPos = viewPos;
|
||||||
|
|
||||||
|
Material material = matUniform.materials[textureIndex];
|
||||||
|
|
||||||
|
uint albedoTextureIndex = material.textureIdx;
|
||||||
|
if (albedoTextureIndex >= MAX_TEXTURES){
|
||||||
|
outAlbedo = vec4(0.0,0.0,1.0,1.0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(material.hasTexture == 1){
|
||||||
|
vec4 texColor = texture(textSampler[nonuniformEXT(albedoTextureIndex)], inTextCoords);
|
||||||
|
outAlbedo = texColor;
|
||||||
|
} else{
|
||||||
|
outAlbedo = material.diffuseColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 Opacity = vec4(outAlbedo.a, outAlbedo.a, outAlbedo.a, 1.0);
|
||||||
|
|
||||||
|
if (material.OpacityFactor > 0.0 && material.OpacityFactor < 1.0) {
|
||||||
|
Opacity = vec4(material.OpacityFactor, material.OpacityFactor, material.OpacityFactor, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (material.hasOpacityMap > 0 && material.OpacityMapIdx < MAX_TEXTURES) {
|
||||||
|
Opacity = texture(textSampler[nonuniformEXT(material.OpacityMapIdx)], inTextCoords);
|
||||||
|
}
|
||||||
|
|
||||||
|
float opacityf = Opacity.x + Opacity.y + Opacity.z;
|
||||||
|
opacityf = opacityf / 3;
|
||||||
|
if(opacityf < 0.4){ discard; }
|
||||||
|
|
||||||
|
outAlbedo = vec4(outAlbedo.rgb, opacityf);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,149 @@
|
||||||
|
#version 450
|
||||||
|
#extension GL_EXT_nonuniform_qualifier : require
|
||||||
|
|
||||||
|
const int MAX_TEXTURES = 128;
|
||||||
|
|
||||||
|
|
||||||
|
layout(location = 0) in vec4 inPos;
|
||||||
|
layout(location = 1) in vec3 inNormal;
|
||||||
|
layout(location = 2) in vec3 inTangent;
|
||||||
|
layout(location = 3) in vec3 inBitangent;
|
||||||
|
layout(location = 4) in vec2 inTextCoords;
|
||||||
|
layout(location = 5) in mat4 viewMatrix;
|
||||||
|
layout(location = 9) in flat uint MaterialID;
|
||||||
|
|
||||||
|
layout(location = 1) out vec4 outAlbedo ;
|
||||||
|
layout(location = 0) out vec4 outPos;
|
||||||
|
layout(location = 2) out vec4 outNormal;
|
||||||
|
layout(location = 3) out vec4 outPBR;
|
||||||
|
layout(location = 4) out vec4 outEmissive;
|
||||||
|
layout(location = 5) out vec4 outTranslucency;
|
||||||
|
layout(location = 6) out vec4 outOpacity;
|
||||||
|
layout(location = 7) out vec4 outViewPos;
|
||||||
|
|
||||||
|
struct Material {
|
||||||
|
vec4 diffuseColor; //16
|
||||||
|
uint hasTexture; //20
|
||||||
|
uint textureIdx; //24
|
||||||
|
uint hasNormalMap; //28
|
||||||
|
uint normalMapIdx; //32
|
||||||
|
uint hasRoughMap; //36
|
||||||
|
uint roughMapIdx; //40
|
||||||
|
float roughnessFactor; //44
|
||||||
|
float metallicFactor; //48
|
||||||
|
vec4 emissiveColour; //64
|
||||||
|
uint hasEmissiveMap; //68
|
||||||
|
uint emissiveMapIdx; //72
|
||||||
|
uint hasTranslucencyMap; //76
|
||||||
|
uint translucencyMapIdx; //80
|
||||||
|
float translucencyFactor; //84
|
||||||
|
uint hasOpacityMap; //88
|
||||||
|
uint OpacityMapIdx; //92
|
||||||
|
float OpacityFactor; //96
|
||||||
|
float reflectiveness; //100
|
||||||
|
float refractiveness; //104
|
||||||
|
float Padding1; //108
|
||||||
|
float Padding2; //112
|
||||||
|
};
|
||||||
|
layout(set = 2, binding = 0) readonly buffer MaterialUniform {
|
||||||
|
Material materials[];
|
||||||
|
} matUniform;
|
||||||
|
layout(set = 3, binding = 0) uniform sampler2D textSampler[MAX_TEXTURES];
|
||||||
|
|
||||||
|
vec3 calcNormal(Material material, vec3 normal, vec2 textCoords, mat3 TBN)
|
||||||
|
{
|
||||||
|
vec3 newNormal = normal;
|
||||||
|
if (material.hasNormalMap > 0 && material.normalMapIdx < MAX_TEXTURES)
|
||||||
|
{
|
||||||
|
newNormal = texture(textSampler[nonuniformEXT(material.normalMapIdx)], textCoords).rgb;
|
||||||
|
newNormal = normalize(newNormal * 2.0 - 1.0);
|
||||||
|
newNormal = normalize(TBN * newNormal);
|
||||||
|
}
|
||||||
|
return newNormal;
|
||||||
|
}
|
||||||
|
|
||||||
|
layout(push_constant) uniform pc {
|
||||||
|
layout(offset = 64) uint materialIdx;
|
||||||
|
} push_constants;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
outPos = inPos;
|
||||||
|
|
||||||
|
vec4 viewPos = vec4(viewMatrix * vec4(inPos.xyz, 1.0));
|
||||||
|
outViewPos = viewPos;
|
||||||
|
|
||||||
|
Material material = matUniform.materials[MaterialID];
|
||||||
|
|
||||||
|
uint albedoTextureIndex = material.textureIdx;
|
||||||
|
if (albedoTextureIndex >= MAX_TEXTURES) {
|
||||||
|
outAlbedo = vec4(0.0,0.0,1.0,1.0);
|
||||||
|
outOpacity = vec4(0.0,0.0,1.0,1.0);
|
||||||
|
outNormal = vec4(0.0,0.0,1.0,1.0);
|
||||||
|
outEmissive = vec4(0.0,0.0,1.0,1.0);
|
||||||
|
outTranslucency = vec4(0.0,0.0,1.0,1.0);
|
||||||
|
outPBR = vec4(0.0,0.0,1.0,1.0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (material.hasTexture == 1) {
|
||||||
|
outAlbedo = texture(textSampler[nonuniformEXT(albedoTextureIndex)], inTextCoords);
|
||||||
|
} else {
|
||||||
|
outAlbedo = material.diffuseColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 Opacity = vec4(outAlbedo.a, outAlbedo.a, outAlbedo.a, 1.0);
|
||||||
|
|
||||||
|
if (material.OpacityFactor > 0.0 && material.OpacityFactor < 1.0) {
|
||||||
|
Opacity = vec4(material.OpacityFactor, material.OpacityFactor, material.OpacityFactor, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (material.hasOpacityMap > 0 && material.OpacityMapIdx < MAX_TEXTURES) {
|
||||||
|
outOpacity = texture(textSampler[nonuniformEXT(material.OpacityMapIdx)], inTextCoords);
|
||||||
|
} else {
|
||||||
|
outOpacity = Opacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
Opacity = outOpacity;
|
||||||
|
|
||||||
|
float opacityf = Opacity.x + Opacity.y + Opacity.z;
|
||||||
|
opacityf = opacityf / 3;
|
||||||
|
|
||||||
|
outAlbedo = vec4(outAlbedo.rgb, opacityf);
|
||||||
|
|
||||||
|
if(outAlbedo.a < 0.5) discard;
|
||||||
|
|
||||||
|
mat3 TBN = mat3(inTangent, inBitangent, inNormal);
|
||||||
|
vec3 newNormal = calcNormal(material, inNormal, inTextCoords, TBN);
|
||||||
|
|
||||||
|
float ao = 0.5f;
|
||||||
|
float roughnessFactor = 0.0f;
|
||||||
|
float metallicFactor = 0.0f;
|
||||||
|
|
||||||
|
if (material.hasRoughMap > 0 && material.roughMapIdx < MAX_TEXTURES) {
|
||||||
|
vec4 metRoughValue = texture(textSampler[nonuniformEXT(material.roughMapIdx)], inTextCoords);
|
||||||
|
roughnessFactor = metRoughValue.g;
|
||||||
|
metallicFactor = metRoughValue.b;
|
||||||
|
} else {
|
||||||
|
roughnessFactor = material.roughnessFactor;
|
||||||
|
metallicFactor = material.metallicFactor;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 emissive = material.emissiveColour;
|
||||||
|
if (material.hasEmissiveMap > 0 && material.emissiveMapIdx < MAX_TEXTURES) {
|
||||||
|
emissive = texture(textSampler[nonuniformEXT(material.emissiveMapIdx)], inTextCoords);
|
||||||
|
}
|
||||||
|
outEmissive = emissive;
|
||||||
|
|
||||||
|
vec4 Translucency = vec4(material.translucencyFactor, material.translucencyFactor, material.translucencyFactor, 1);
|
||||||
|
if(material.hasTranslucencyMap > 0 && material.translucencyMapIdx < MAX_TEXTURES){
|
||||||
|
Translucency = texture(textSampler[nonuniformEXT(material.translucencyMapIdx)], inTextCoords);
|
||||||
|
}
|
||||||
|
outTranslucency = Translucency;
|
||||||
|
|
||||||
|
float Refractiveness = material.refractiveness;
|
||||||
|
float Reflectiveness = material.reflectiveness;
|
||||||
|
|
||||||
|
outNormal = vec4(newNormal, Refractiveness);
|
||||||
|
outPBR = vec4(ao, roughnessFactor, metallicFactor, Reflectiveness);
|
||||||
|
}
|
||||||
|
|
@ -6,6 +6,7 @@ layout(location = 2) out vec3 outTangent;
|
||||||
layout(location = 3) out vec3 outBitangent;
|
layout(location = 3) out vec3 outBitangent;
|
||||||
layout(location = 4) out vec2 outTextCoords;
|
layout(location = 4) out vec2 outTextCoords;
|
||||||
layout(location = 5) out mat4 viewMatrix;
|
layout(location = 5) out mat4 viewMatrix;
|
||||||
|
layout(location = 9) out flat uint outMaterialID;
|
||||||
|
|
||||||
layout(set = 0, binding = 0) uniform ProjUniform { mat4 matrix; } projUniform;
|
layout(set = 0, binding = 0) uniform ProjUniform { mat4 matrix; } projUniform;
|
||||||
layout(set = 1, binding = 0) uniform ViewUniform { mat4 matrix; } viewUniform;
|
layout(set = 1, binding = 0) uniform ViewUniform { mat4 matrix; } viewUniform;
|
||||||
|
|
@ -93,17 +94,13 @@ void main() {
|
||||||
uint triangleVertex = (uint(gl_VertexIndex))% 6u;
|
uint triangleVertex = (uint(gl_VertexIndex))% 6u;
|
||||||
uint cornerIndex = TRI_TO_CORNER[triangleVertex];
|
uint cornerIndex = TRI_TO_CORNER[triangleVertex];
|
||||||
|
|
||||||
//uint faceRecordIndex = uint(gl_VertexIndex) / 6u;
|
|
||||||
//uint triangleVertex = uint(gl_VertexIndex) % 6u;
|
|
||||||
//uint cornerIndex = TRI_TO_CORNER[triangleVertex];
|
|
||||||
|
|
||||||
uint packedFace = faces[faceRecordIndex];
|
uint packedFace = faces[faceRecordIndex];
|
||||||
|
|
||||||
uint voxelX = packedFace & 0x1Fu;
|
uint voxelX = packedFace & 0xFu;
|
||||||
uint voxelY = (packedFace >> 5u) & 0x1Fu;
|
uint voxelY = (packedFace >> 4u) & 0xFu;
|
||||||
uint voxelZ = (packedFace >> 10u) & 0x1Fu;
|
uint voxelZ = (packedFace >> 8u) & 0xFu;
|
||||||
uint faceId = (packedFace >> 15u) & 0x7u;
|
uint faceId = (packedFace >> 12u) & 0x7u;
|
||||||
uint matId = (packedFace >> 18u) & 0xFFu;
|
uint matId = (packedFace >> 15u) & 0x7FFu;
|
||||||
uint texIdxX = (packedFace >> 26u) & 0x7u;
|
uint texIdxX = (packedFace >> 26u) & 0x7u;
|
||||||
uint texIdxY = (packedFace >> 29u) & 0x7u;
|
uint texIdxY = (packedFace >> 29u) & 0x7u;
|
||||||
|
|
||||||
|
|
@ -111,7 +108,6 @@ void main() {
|
||||||
vec2 scalar = vec2(1.0/4.0,1.0/4.0);
|
vec2 scalar = vec2(1.0/4.0,1.0/4.0);
|
||||||
|
|
||||||
faceId = min(faceId, 7u);
|
faceId = min(faceId, 7u);
|
||||||
matId = min(matId, 4u);
|
|
||||||
|
|
||||||
vec3 localPos = vec3(voxelX, voxelY, voxelZ) + FACE_CORNERS[faceId][cornerIndex];
|
vec3 localPos = vec3(voxelX, voxelY, voxelZ) + FACE_CORNERS[faceId][cornerIndex];
|
||||||
vec3 worldPos = localPos + push_constants.ModelOffset.xyz * 16.0;
|
vec3 worldPos = localPos + push_constants.ModelOffset.xyz * 16.0;
|
||||||
|
|
@ -119,10 +115,14 @@ void main() {
|
||||||
vec4 worldPosVec4 = vec4(worldPos, 1.0);
|
vec4 worldPosVec4 = vec4(worldPos, 1.0);
|
||||||
|
|
||||||
gl_Position = projUniform.matrix * viewUniform.matrix * worldPosVec4;
|
gl_Position = projUniform.matrix * viewUniform.matrix * worldPosVec4;
|
||||||
|
|
||||||
outPos = worldPosVec4;
|
outPos = worldPosVec4;
|
||||||
outNormal = NORMALS[faceId];
|
outNormal = NORMALS[faceId];
|
||||||
outTangent = TANGENTS[faceId];
|
outTangent = TANGENTS[faceId];
|
||||||
outBitangent = BITANGENTS[faceId];
|
outBitangent = BITANGENTS[faceId];
|
||||||
outTextCoords = CORNER_UVS_GRASS_BLOCK[faceId][cornerIndex] * scalar + texID;
|
vec2 atlasSize = vec2(64, 64);
|
||||||
|
vec2 texel = 0.5 / atlasSize;
|
||||||
|
vec2 tileMin = vec2(texIdxX, texIdxY) * scalar + texel;
|
||||||
|
vec2 tileMax = vec2(texIdxX + 1u, texIdxY + 1u) * scalar - texel;
|
||||||
|
outTextCoords = mix(tileMin, tileMax, CORNER_UVS_GRASS_BLOCK[faceId][cornerIndex]);
|
||||||
|
outMaterialID = matId;
|
||||||
}
|
}
|
||||||
|
|
@ -17,6 +17,69 @@ layout(location = 1) out flat uint outMaterialIdx;
|
||||||
|
|
||||||
const uint TRI_TO_CORNER[6] = uint[6](0u, 1u, 2u, 0u, 2u, 3u);
|
const uint TRI_TO_CORNER[6] = uint[6](0u, 1u, 2u, 0u, 2u, 3u);
|
||||||
|
|
||||||
|
const vec3 NORMALS[8] = vec3[8](
|
||||||
|
vec3( 0.0, 1.0, 0.0), // Face 0 (+Y)
|
||||||
|
vec3( 0.0, -1.0, 0.0), // Face 1 (-Y)
|
||||||
|
vec3( 1.0, 0.0, 0.0), // Face 2 (+X)
|
||||||
|
vec3(-1.0, 0.0, 0.0), // Face 3 (-X)
|
||||||
|
vec3( 0.0, 0.0, 1.0), // Face 4 (+Z)
|
||||||
|
vec3( 0.0, 0.0, -1.0), // Face 5 (-Z)
|
||||||
|
vec3(-0.7071, 0.0, 0.7071), // Face 6
|
||||||
|
vec3( 0.7071, 0.0, 0.7071) // Face 7
|
||||||
|
);
|
||||||
|
|
||||||
|
const vec3 TANGENTS[8] = vec3[8](
|
||||||
|
vec3( 1.0, 0.0, 0.0), // Face 0
|
||||||
|
vec3( 1.0, 0.0, 0.0), // Face 1
|
||||||
|
vec3( 0.0, 0.0, -1.0), // Face 2
|
||||||
|
vec3( 0.0, 0.0, 1.0), // Face 3
|
||||||
|
vec3( 1.0, 0.0, 0.0), // Face 4
|
||||||
|
vec3(-1.0, 0.0, 0.0), // Face 5
|
||||||
|
vec3( 0.7071, 0.0, 0.7071), // Face 6
|
||||||
|
vec3( 0.7071, 0.0,-0.7071) // Face 7
|
||||||
|
);
|
||||||
|
|
||||||
|
const vec3 BITANGENTS[8] = vec3[8](
|
||||||
|
vec3( 0.0, 0.0, 1.0), // Face 0
|
||||||
|
vec3( 0.0, 0.0, -1.0), // Face 1
|
||||||
|
vec3( 0.0, 1.0, 0.0), // Face 2
|
||||||
|
vec3( 0.0, 1.0, 0.0), // Face 3
|
||||||
|
vec3( 0.0, 1.0, 0.0), // Face 4
|
||||||
|
vec3( 0.0, 1.0, 0.0), // Face 5
|
||||||
|
vec3( 0.0, 1.0, 0.0), // Face 6
|
||||||
|
vec3( 0.0, 1.0, 0.0) // Face 7
|
||||||
|
);
|
||||||
|
|
||||||
|
const vec2 CORNER_UVS[5][4] = vec2[5][4](
|
||||||
|
vec2[4](vec2(0.5, 0.0), vec2(0.5, 0.5), vec2(1.0, 0.5), vec2(1.0, 0.0)),
|
||||||
|
vec2[4](vec2(0.0, 0.5), vec2(0.0, 1.0), vec2(0.5, 1.0), vec2(0.5, 0.5)),
|
||||||
|
vec2[4](vec2(0.5, 0.0), vec2(0.5, 0.5), vec2(1.0, 0.5), vec2(1.0, 0.0)),
|
||||||
|
vec2[4](vec2(0.5, 0.0), vec2(0.5, 0.5), vec2(1.0, 0.5), vec2(1.0, 0.0)),
|
||||||
|
vec2[4](vec2(1.0, 1.0), vec2(1.0, 0.5), vec2(0.5, 0.5), vec2(0.5, 1.0))
|
||||||
|
);
|
||||||
|
const vec2 CORNER_UVS_GRASS_BLOCK[8][4] = vec2[8][4](
|
||||||
|
vec2[4](vec2(0.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 1.0), vec2(1.0, 0.0)),
|
||||||
|
vec2[4](vec2(0.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 1.0), vec2(1.0, 0.0)),
|
||||||
|
vec2[4](vec2(1.0, 1.0), vec2(1.0, 0.0),vec2(0.0, 0.0), vec2(0.0, 1.0)),
|
||||||
|
vec2[4]( vec2(0.0, 1.0),vec2(1.0, 1.0), vec2(1.0, 0.0),vec2(0.0, 0.0)),
|
||||||
|
vec2[4]( vec2(0.0, 1.0),vec2(1.0, 1.0), vec2(1.0, 0.0),vec2(0.0, 0.0)),
|
||||||
|
vec2[4](vec2(1.0, 1.0), vec2(1.0, 0.0),vec2(0.0, 0.0), vec2(0.0, 1.0)),
|
||||||
|
vec2[4](vec2(1.0, 1.0), vec2(1.0, 0.0), vec2(0.0, 0.0), vec2(0.0, 1.0)),
|
||||||
|
vec2[4](vec2(1.0, 1.0), vec2(1.0, 0.0), vec2(0.0, 0.0), vec2(0.0, 1.0))
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
const vec3 FACE_CORNERS[8][4] = vec3[8][4](
|
||||||
|
vec3[4](vec3(0.0, 1.0, 0.0), vec3(0.0, 1.0, 1.0), vec3(1.0, 1.0, 1.0), vec3(1.0, 1.0, 0.0)), // Face 0 (+Y)
|
||||||
|
vec3[4](vec3(0.0, 0.0, 0.0), vec3(1.0, 0.0, 0.0), vec3(1.0, 0.0, 1.0), vec3(0.0, 0.0, 1.0)), // Face 1 (-Y)
|
||||||
|
vec3[4](vec3(1.0, 0.0, 0.0), vec3(1.0, 1.0, 0.0), vec3(1.0, 1.0, 1.0), vec3(1.0, 0.0, 1.0)), // Face 2 (+X)
|
||||||
|
vec3[4](vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 1.0), vec3(0.0, 1.0, 1.0), vec3(0.0, 1.0, 0.0)), // Face 3 (-X)
|
||||||
|
vec3[4](vec3(0.0, 0.0, 1.0), vec3(1.0, 0.0, 1.0), vec3(1.0, 1.0, 1.0), vec3(0.0, 1.0, 1.0)), // Face 4 (+Z)
|
||||||
|
vec3[4](vec3(0.0, 0.0, 0.0), vec3(0.0, 1.0, 0.0), vec3(1.0, 1.0, 0.0), vec3(1.0, 0.0, 0.0)), // Face 5 (-Z)
|
||||||
|
vec3[4](vec3(0.0, 0.0, 0.0), vec3(0.0, 1.0, 0.0), vec3(1.0, 1.0, 1.0), vec3(1.0, 0.0, 1.0)), // Face 6 (cross model pane 1)
|
||||||
|
vec3[4](vec3(0.0, 0.0, 1.0), vec3(0.0, 1.0, 1.0), vec3(1.0, 1.0, 0.0), vec3(1.0, 0.0, 0.0)) // Face 7 (cross model pane 2)
|
||||||
|
);
|
||||||
|
|
||||||
vec3 buildFaceCornerPosition(uvec3 voxelPos, uint faceId, uint cornerIndex) {
|
vec3 buildFaceCornerPosition(uvec3 voxelPos, uint faceId, uint cornerIndex) {
|
||||||
vec3 p = vec3(voxelPos);
|
vec3 p = vec3(voxelPos);
|
||||||
|
|
||||||
|
|
@ -63,21 +126,40 @@ vec3 buildFaceCornerPosition(uvec3 voxelPos, uint faceId, uint cornerIndex) {
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
uint faceRecordIndex = uint(gl_VertexIndex) / 6u;
|
uint faceRecordIndex = uint(gl_VertexIndex) / 6u;
|
||||||
uint triangleVertex = uint(gl_VertexIndex) % 6u;
|
uint triangleVertex = (uint(gl_VertexIndex))% 6u;
|
||||||
uint cornerIndex = TRI_TO_CORNER[triangleVertex];
|
uint cornerIndex = TRI_TO_CORNER[triangleVertex];
|
||||||
|
|
||||||
|
//uint faceRecordIndex = uint(gl_VertexIndex) / 6u;
|
||||||
|
//uint triangleVertex = uint(gl_VertexIndex) % 6u;
|
||||||
|
//uint cornerIndex = TRI_TO_CORNER[triangleVertex];
|
||||||
|
|
||||||
uint packedFace = faces[faceRecordIndex];
|
uint packedFace = faces[faceRecordIndex];
|
||||||
|
|
||||||
uint voxelX = packedFace & 0x1Fu;
|
uint voxelX = packedFace & 0xFu;
|
||||||
uint voxelY = (packedFace >> 5u) & 0x1Fu;
|
uint voxelY = (packedFace >> 4u) & 0xFu;
|
||||||
uint voxelZ = (packedFace >> 10u) & 0x1Fu;
|
uint voxelZ = (packedFace >> 8u) & 0xFu;
|
||||||
uint faceId = (packedFace >> 15u) & 0x7u;
|
uint faceId = (packedFace >> 12u) & 0x7u;
|
||||||
uint matId = (packedFace >> 18u) & 0xFFu;
|
uint matId = (packedFace >> 15u) & 0x7FFu;
|
||||||
|
uint texIdxX = (packedFace >> 26u) & 0x7u;
|
||||||
|
uint texIdxY = (packedFace >> 29u) & 0x7u;
|
||||||
|
|
||||||
vec3 localPos = buildFaceCornerPosition(uvec3(voxelX, voxelY, voxelZ), faceId, cornerIndex);
|
// (voxelPos.x & 0xFu) |
|
||||||
|
// ((voxelPos.y & 0xFu) << 4u) |
|
||||||
|
// ((voxelPos.z & 0xFu) << 8u) |
|
||||||
|
// ((faceIndex & 0x7u) << 12u) |
|
||||||
|
// ((materialId & 0x7FFu) << 15u) |
|
||||||
|
// ((textureIndexX & 0x7u) << 26u) |
|
||||||
|
// ((textureIndexY & 0x7u) << 29u);
|
||||||
|
|
||||||
|
vec2 texID = vec2((texIdxX)/4.0,(texIdxY)/4.0);
|
||||||
|
vec2 scalar = vec2(1.0/4.0,1.0/4.0);
|
||||||
|
|
||||||
|
faceId = min(faceId, 7u);
|
||||||
|
|
||||||
|
vec3 localPos = vec3(voxelX, voxelY, voxelZ) + FACE_CORNERS[faceId][cornerIndex];
|
||||||
vec3 worldPos = localPos + push_constants.ModelOffset.xyz * 16.0;
|
vec3 worldPos = localPos + push_constants.ModelOffset.xyz * 16.0;
|
||||||
|
|
||||||
outTextCoord = vec2(0.0);
|
outTextCoord = CORNER_UVS_GRASS_BLOCK[faceId][cornerIndex] * scalar + texID;
|
||||||
outMaterialIdx = matId;
|
outMaterialIdx = matId;
|
||||||
|
|
||||||
gl_Position = vec4(worldPos, 1.0);
|
gl_Position = vec4(worldPos, 1.0);
|
||||||
|
|
|
||||||
51
resources/EngineResources/shaders/water_frag.glsl
Normal file
51
resources/EngineResources/shaders/water_frag.glsl
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
#version 460 core
|
||||||
|
|
||||||
|
in vec3 FragPos;
|
||||||
|
in vec2 TexCoords;
|
||||||
|
in vec3 Normal;
|
||||||
|
|
||||||
|
out vec4 FragColor;
|
||||||
|
|
||||||
|
uniform vec3 cameraPos;
|
||||||
|
uniform vec3 lightPos;
|
||||||
|
|
||||||
|
// Material constants
|
||||||
|
const vec3 waterShallowColor = vec3(0.0, 0.6, 0.7);
|
||||||
|
const vec3 waterDeepColor = vec3(0.05, 0.15, 0.3);
|
||||||
|
const vec3 sunColor = vec3(1.0, 0.95, 0.8);
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
// Normalize vectors
|
||||||
|
vec3 n = normalize(Normal);
|
||||||
|
vec3 viewDir = normalize(cameraPos - FragPos);
|
||||||
|
vec3 lightDir = normalize(lightPos - FragPos);
|
||||||
|
|
||||||
|
// 1. Ambient Lighting
|
||||||
|
vec3 ambient = 0.3 * waterShallowColor;
|
||||||
|
|
||||||
|
// 2. Diffuse Shading
|
||||||
|
float diff = max(dot(n, lightDir), 0.0);
|
||||||
|
vec3 diffuse = diff * sunColor * 0.4;
|
||||||
|
|
||||||
|
// 3. Specular Highlights (Blinn-Phong)
|
||||||
|
vec3 halfwayDir = normalize(lightDir + viewDir);
|
||||||
|
float spec = pow(max(dot(n, halfwayDir), 0.0), 64.0); // High shininess for water glaze
|
||||||
|
vec3 specular = spec * sunColor * 0.8;
|
||||||
|
|
||||||
|
// 4. Fresnel Approximation (Schlick's approximation)
|
||||||
|
// Water has a base reflectivity of roughly 0.02 at a perpendicular view angle
|
||||||
|
float F0 = 0.02;
|
||||||
|
float fresnel = F0 + (1.0 - F0) * pow(1.0 - max(dot(n, viewDir), 0.0), 5.0);
|
||||||
|
|
||||||
|
// Mix deep and shallow water colors based on the normal angle
|
||||||
|
vec3 baseWaterColor = mix(waterShallowColor, waterDeepColor, max(dot(n, vec3(0.0, 1.0, 0.0)), 0.0));
|
||||||
|
|
||||||
|
// Combine lighting results
|
||||||
|
vec3 lightingResult = ambient + diffuse + specular;
|
||||||
|
|
||||||
|
// Blend final look with Fresnel reflection dominance
|
||||||
|
vec3 finalColor = mix(baseWaterColor + specular, lightingResult + vec3(fresnel * 0.5), fresnel);
|
||||||
|
|
||||||
|
// Output final color with subtle translucency opacity
|
||||||
|
FragColor = vec4(finalColor, 0.85);
|
||||||
|
}
|
||||||
46
resources/EngineResources/shaders/water_vert.glsl
Normal file
46
resources/EngineResources/shaders/water_vert.glsl
Normal file
|
|
@ -0,0 +1,46 @@
|
||||||
|
#version 450
|
||||||
|
|
||||||
|
layout (location = 0) in vec3 aPos;
|
||||||
|
layout (location = 1) in vec2 aTexCoords;
|
||||||
|
|
||||||
|
out vec3 FragPos;
|
||||||
|
out vec2 TexCoords;
|
||||||
|
out vec3 Normal;
|
||||||
|
|
||||||
|
uniform mat4 model;
|
||||||
|
uniform mat4 view;
|
||||||
|
uniform mat4 projection;
|
||||||
|
uniform float uTime;
|
||||||
|
|
||||||
|
// Wave configuration constants
|
||||||
|
const float AMPLITUDE = 0.15;
|
||||||
|
const float FREQUENCY = 1.5;
|
||||||
|
const float SPEED = 2.0;
|
||||||
|
|
||||||
|
// Simple wave function that modifies elevation based on position and time
|
||||||
|
float calculateWave(vec3 pos, float time, vec2 direction) {
|
||||||
|
return AMPLITUDE * sin(dot(pos.xz, direction) * FREQUENCY + time * SPEED);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Derivative of the wave function to calculate accurate dynamic surface normals
|
||||||
|
vec3 calculateWaveNormal(vec3 pos, float time) {
|
||||||
|
float dx = AMPLITUDE * FREQUENCY * cos(pos.x * FREQUENCY + time * SPEED);
|
||||||
|
float dz = AMPLITUDE * FREQUENCY * cos(pos.z * FREQUENCY + time * SPEED);
|
||||||
|
return normalize(vec3(-dx, 1.0, -dz));
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec3 displacedPos = aPos;
|
||||||
|
|
||||||
|
// Combine two wave directions for a less predictable, more organic look
|
||||||
|
displacedPos.y += calculateWave(aPos, uTime, vec2(1.0, 0.0));
|
||||||
|
displacedPos.y += calculateWave(aPos, uTime * 1.2, vec2(0.5, 0.8));
|
||||||
|
|
||||||
|
FragPos = vec3(model * vec4(displacedPos, 1.0));
|
||||||
|
TexCoords = aTexCoords;
|
||||||
|
|
||||||
|
// Pass transformed normals and position to the fragment shader
|
||||||
|
Normal = mat3(transpose(inverse(model))) * calculateWaveNormal(displacedPos, uTime);
|
||||||
|
|
||||||
|
gl_Position = projection * view * model * vec4(displacedPos, 1.0);
|
||||||
|
}
|
||||||
|
|
@ -5,6 +5,8 @@ import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance;
|
||||||
import net.halbear.Terrain4J.EngineCore.Logic.InitData;
|
import net.halbear.Terrain4J.EngineCore.Logic.InitData;
|
||||||
import net.halbear.Terrain4J.EngineCore.Logic.Rendering.SkyBox;
|
import net.halbear.Terrain4J.EngineCore.Logic.Rendering.SkyBox;
|
||||||
import net.halbear.Terrain4J.EngineCore.Logic.Rendering.VulkanContext;
|
import net.halbear.Terrain4J.EngineCore.Logic.Rendering.VulkanContext;
|
||||||
|
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Computing.VoxelTerrainGeneration.Biome;
|
||||||
|
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Computing.VoxelTerrainGeneration.Voxel;
|
||||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Computing.VoxelTerrainGeneration.VoxelChunkGenerator;
|
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Computing.VoxelTerrainGeneration.VoxelChunkGenerator;
|
||||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Computing.VoxelTerrainGeneration.VoxelWorldManager;
|
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Computing.VoxelTerrainGeneration.VoxelWorldManager;
|
||||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.RenderPasses.GUI.GuiRenderer;
|
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.RenderPasses.GUI.GuiRenderer;
|
||||||
|
|
@ -30,6 +32,7 @@ import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.SwapChain.
|
||||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.SwapChain.SwapChainRender;
|
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.SwapChain.SwapChainRender;
|
||||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Util.VulkanUtils;
|
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Util.VulkanUtils;
|
||||||
import net.halbear.Terrain4J.EngineCore.Threads.RenderThread;
|
import net.halbear.Terrain4J.EngineCore.Threads.RenderThread;
|
||||||
|
import org.joml.Vector2i;
|
||||||
import org.joml.Vector3f;
|
import org.joml.Vector3f;
|
||||||
import org.joml.Vector3i;
|
import org.joml.Vector3i;
|
||||||
import org.lwjgl.system.MemoryStack;
|
import org.lwjgl.system.MemoryStack;
|
||||||
|
|
@ -188,6 +191,190 @@ public class VulkanRenderer implements Renderer {
|
||||||
GuiRender.LoadTextures(RendererContext,initData.GuiTextures(),textureCache);
|
GuiRender.LoadTextures(RendererContext,initData.GuiTextures(),textureCache);
|
||||||
//VoxelWorldManager.Init(RendererContext);
|
//VoxelWorldManager.Init(RendererContext);
|
||||||
// VoxelWorldManager.GenerateChunks(new Vector3i(0,0,0), new Vector3i(16,0,16));
|
// VoxelWorldManager.GenerateChunks(new Vector3i(0,0,0), new Vector3i(16,0,16));
|
||||||
|
Vector2i positionArr[][] = new Vector2i[4][4];
|
||||||
|
for(int x = 0; x < 4; x++){
|
||||||
|
for(int y = 0; y < 4; y++){
|
||||||
|
positionArr[x][y] = new Vector2i(x,y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int Index = materialsCache.GetPosition("VoxelTerrain");
|
||||||
|
int Index2 = materialsCache.GetPosition("Blueleaf");
|
||||||
|
int Index3 = materialsCache.GetPosition("Blueleaf2");
|
||||||
|
Voxel grassVoxel = new Voxel(Index, 0,
|
||||||
|
new Vector2i[]{positionArr[0][1], positionArr[0][3]},
|
||||||
|
new Vector2i[]{positionArr[1][0], positionArr[1][0]},
|
||||||
|
new Vector2i[]{positionArr[0][0], positionArr[0][0]},
|
||||||
|
new Vector2i[]{positionArr[0][0], positionArr[0][0]},
|
||||||
|
new Vector2i[]{positionArr[0][0], positionArr[0][0]},
|
||||||
|
new Vector2i[]{positionArr[0][0], positionArr[0][0]});
|
||||||
|
|
||||||
|
Voxel stoneVoxel = new Voxel(Index, 0,
|
||||||
|
new Vector2i[]{positionArr[1][0], positionArr[1][0]},
|
||||||
|
new Vector2i[]{positionArr[1][0], positionArr[1][0]},
|
||||||
|
new Vector2i[]{positionArr[1][0], positionArr[1][0]},
|
||||||
|
new Vector2i[]{positionArr[1][0], positionArr[1][0]},
|
||||||
|
new Vector2i[]{positionArr[1][0], positionArr[1][0]},
|
||||||
|
new Vector2i[]{positionArr[1][0], positionArr[1][0]});
|
||||||
|
|
||||||
|
Voxel grassSideVoxel = new Voxel(Index, 1,
|
||||||
|
new Vector2i[]{positionArr[1][1], positionArr[1][3]},
|
||||||
|
new Vector2i[]{positionArr[1][1], positionArr[1][3]},
|
||||||
|
new Vector2i[]{positionArr[1][1], positionArr[1][3]},
|
||||||
|
new Vector2i[]{positionArr[1][1], positionArr[1][3]},
|
||||||
|
new Vector2i[]{positionArr[1][1], positionArr[1][3]},
|
||||||
|
new Vector2i[]{positionArr[1][1], positionArr[1][3]});
|
||||||
|
Voxel Mushroom = new Voxel(Index, 1,
|
||||||
|
new Vector2i[]{positionArr[2][3], positionArr[2][3]},
|
||||||
|
new Vector2i[]{positionArr[2][3], positionArr[2][3]},
|
||||||
|
new Vector2i[]{positionArr[2][3], positionArr[2][3]},
|
||||||
|
new Vector2i[]{positionArr[2][3], positionArr[2][3]},
|
||||||
|
new Vector2i[]{positionArr[2][3], positionArr[2][3]},
|
||||||
|
new Vector2i[]{positionArr[2][3], positionArr[2][3]});
|
||||||
|
|
||||||
|
Voxel Log = new Voxel(Index, 0,
|
||||||
|
new Vector2i[]{positionArr[2][1], positionArr[2][1]},
|
||||||
|
new Vector2i[]{positionArr[2][1], positionArr[2][1]},
|
||||||
|
new Vector2i[]{positionArr[2][2], positionArr[2][2]},
|
||||||
|
new Vector2i[]{positionArr[2][2], positionArr[2][2]},
|
||||||
|
new Vector2i[]{positionArr[2][2], positionArr[2][2]},
|
||||||
|
new Vector2i[]{positionArr[2][2], positionArr[2][2]});
|
||||||
|
|
||||||
|
Voxel Leaves = new Voxel(Index, 2,
|
||||||
|
new Vector2i[]{positionArr[2][0], positionArr[2][0]},
|
||||||
|
new Vector2i[]{positionArr[2][0], positionArr[2][0]},
|
||||||
|
new Vector2i[]{positionArr[2][0], positionArr[2][0]},
|
||||||
|
new Vector2i[]{positionArr[2][0], positionArr[2][0]},
|
||||||
|
new Vector2i[]{positionArr[2][0], positionArr[2][0]},
|
||||||
|
new Vector2i[]{positionArr[2][0], positionArr[2][0]});
|
||||||
|
|
||||||
|
Voxel bluegrassVoxel = new Voxel(Index2, 0,
|
||||||
|
new Vector2i[]{positionArr[0][1], positionArr[1][3]},
|
||||||
|
new Vector2i[]{positionArr[1][0], positionArr[1][0]},
|
||||||
|
new Vector2i[]{positionArr[0][0], positionArr[0][0]},
|
||||||
|
new Vector2i[]{positionArr[0][0], positionArr[0][0]},
|
||||||
|
new Vector2i[]{positionArr[0][0], positionArr[0][0]},
|
||||||
|
new Vector2i[]{positionArr[0][0], positionArr[0][0]});
|
||||||
|
|
||||||
|
Voxel blueDirtVoxel = new Voxel(Index2, 0,
|
||||||
|
new Vector2i[]{positionArr[1][0], positionArr[1][0]},
|
||||||
|
new Vector2i[]{positionArr[1][0], positionArr[1][0]},
|
||||||
|
new Vector2i[]{positionArr[1][0], positionArr[1][0]},
|
||||||
|
new Vector2i[]{positionArr[1][0], positionArr[1][0]},
|
||||||
|
new Vector2i[]{positionArr[1][0], positionArr[1][0]},
|
||||||
|
new Vector2i[]{positionArr[1][0], positionArr[1][0]});
|
||||||
|
|
||||||
|
Voxel bluegrassSideVoxel = new Voxel(Index3, 1,
|
||||||
|
new Vector2i[]{positionArr[0][0], positionArr[1][2]},
|
||||||
|
new Vector2i[]{positionArr[0][0], positionArr[1][2]},
|
||||||
|
new Vector2i[]{positionArr[0][0], positionArr[1][2]},
|
||||||
|
new Vector2i[]{positionArr[0][0], positionArr[1][2]},
|
||||||
|
new Vector2i[]{positionArr[0][0], positionArr[1][2]},
|
||||||
|
new Vector2i[]{positionArr[0][0], positionArr[1][2]});
|
||||||
|
|
||||||
|
Voxel blueFlower1 = new Voxel(Index2, 1,
|
||||||
|
new Vector2i[]{positionArr[2][0], positionArr[2][0]},
|
||||||
|
new Vector2i[]{positionArr[2][0], positionArr[2][0]},
|
||||||
|
new Vector2i[]{positionArr[2][0], positionArr[2][0]},
|
||||||
|
new Vector2i[]{positionArr[2][0], positionArr[2][0]},
|
||||||
|
new Vector2i[]{positionArr[2][0], positionArr[2][0]},
|
||||||
|
new Vector2i[]{positionArr[2][0], positionArr[2][0]});
|
||||||
|
|
||||||
|
Voxel blueFlower2 = new Voxel(Index2, 1,
|
||||||
|
new Vector2i[]{positionArr[2][1], positionArr[2][1]},
|
||||||
|
new Vector2i[]{positionArr[2][1], positionArr[2][1]},
|
||||||
|
new Vector2i[]{positionArr[2][1], positionArr[2][1]},
|
||||||
|
new Vector2i[]{positionArr[2][1], positionArr[2][1]},
|
||||||
|
new Vector2i[]{positionArr[2][1], positionArr[2][1]},
|
||||||
|
new Vector2i[]{positionArr[2][1], positionArr[2][1]});
|
||||||
|
|
||||||
|
Voxel blueFlower3 = new Voxel(Index2, 1,
|
||||||
|
new Vector2i[]{positionArr[2][2], positionArr[2][2]},
|
||||||
|
new Vector2i[]{positionArr[2][2], positionArr[2][2]},
|
||||||
|
new Vector2i[]{positionArr[2][2], positionArr[2][2]},
|
||||||
|
new Vector2i[]{positionArr[2][2], positionArr[2][2]},
|
||||||
|
new Vector2i[]{positionArr[2][2], positionArr[2][2]},
|
||||||
|
new Vector2i[]{positionArr[2][2], positionArr[2][2]});
|
||||||
|
|
||||||
|
Voxel blueFlower4 = new Voxel(Index2, 1,
|
||||||
|
new Vector2i[]{positionArr[2][3], positionArr[2][3]},
|
||||||
|
new Vector2i[]{positionArr[2][3], positionArr[2][3]},
|
||||||
|
new Vector2i[]{positionArr[2][3], positionArr[2][3]},
|
||||||
|
new Vector2i[]{positionArr[2][3], positionArr[2][3]},
|
||||||
|
new Vector2i[]{positionArr[2][3], positionArr[2][3]},
|
||||||
|
new Vector2i[]{positionArr[2][3], positionArr[2][3]});
|
||||||
|
|
||||||
|
Voxel blueFlower5 = new Voxel(Index2, 1,
|
||||||
|
new Vector2i[]{positionArr[3][0], positionArr[3][0]},
|
||||||
|
new Vector2i[]{positionArr[3][0], positionArr[3][0]},
|
||||||
|
new Vector2i[]{positionArr[3][0], positionArr[3][0]},
|
||||||
|
new Vector2i[]{positionArr[3][0], positionArr[3][0]},
|
||||||
|
new Vector2i[]{positionArr[3][0], positionArr[3][0]},
|
||||||
|
new Vector2i[]{positionArr[3][0], positionArr[3][0]});
|
||||||
|
|
||||||
|
Voxel blueFlower6 = new Voxel(Index2, 1,
|
||||||
|
new Vector2i[]{positionArr[3][1], positionArr[3][1]},
|
||||||
|
new Vector2i[]{positionArr[3][1], positionArr[3][1]},
|
||||||
|
new Vector2i[]{positionArr[3][1], positionArr[3][1]},
|
||||||
|
new Vector2i[]{positionArr[3][1], positionArr[3][1]},
|
||||||
|
new Vector2i[]{positionArr[3][1], positionArr[3][1]},
|
||||||
|
new Vector2i[]{positionArr[3][1], positionArr[3][1]});
|
||||||
|
|
||||||
|
Voxel blueFlower7 = new Voxel(Index2, 1,
|
||||||
|
new Vector2i[]{positionArr[3][2], positionArr[3][2]},
|
||||||
|
new Vector2i[]{positionArr[3][2], positionArr[3][2]},
|
||||||
|
new Vector2i[]{positionArr[3][2], positionArr[3][2]},
|
||||||
|
new Vector2i[]{positionArr[3][2], positionArr[3][2]},
|
||||||
|
new Vector2i[]{positionArr[3][2], positionArr[3][2]},
|
||||||
|
new Vector2i[]{positionArr[3][2], positionArr[3][2]});
|
||||||
|
|
||||||
|
Voxel blueFlower8 = new Voxel(Index2, 1,
|
||||||
|
new Vector2i[]{positionArr[3][3], positionArr[3][3]},
|
||||||
|
new Vector2i[]{positionArr[3][3], positionArr[3][3]},
|
||||||
|
new Vector2i[]{positionArr[3][3], positionArr[3][3]},
|
||||||
|
new Vector2i[]{positionArr[3][3], positionArr[3][3]},
|
||||||
|
new Vector2i[]{positionArr[3][3], positionArr[3][3]},
|
||||||
|
new Vector2i[]{positionArr[3][3], positionArr[3][3]});
|
||||||
|
Voxel blueLeaves1 = new Voxel(Index3, 2,
|
||||||
|
new Vector2i[]{positionArr[0][3], positionArr[0][3]},
|
||||||
|
new Vector2i[]{positionArr[0][3], positionArr[0][3]},
|
||||||
|
new Vector2i[]{positionArr[0][3], positionArr[0][3]},
|
||||||
|
new Vector2i[]{positionArr[0][3], positionArr[0][3]},
|
||||||
|
new Vector2i[]{positionArr[0][3], positionArr[0][3]},
|
||||||
|
new Vector2i[]{positionArr[0][3], positionArr[0][3]});
|
||||||
|
Voxel blueLeaves2 = new Voxel(Index3, 2,
|
||||||
|
new Vector2i[]{positionArr[1][3], positionArr[1][3]},
|
||||||
|
new Vector2i[]{positionArr[1][3], positionArr[1][3]},
|
||||||
|
new Vector2i[]{positionArr[1][3], positionArr[1][3]},
|
||||||
|
new Vector2i[]{positionArr[1][3], positionArr[1][3]},
|
||||||
|
new Vector2i[]{positionArr[1][3], positionArr[1][3]},
|
||||||
|
new Vector2i[]{positionArr[1][3], positionArr[1][3]});
|
||||||
|
|
||||||
|
VoxelWorldManager.AddVoxel(grassVoxel, "grass");//1
|
||||||
|
VoxelWorldManager.AddVoxel(stoneVoxel, "DirtVoxel");//2
|
||||||
|
VoxelWorldManager.AddVoxel(stoneVoxel, "StoneVoxel");//3
|
||||||
|
VoxelWorldManager.AddVoxel(grassSideVoxel, "grassSideVoxel");//4
|
||||||
|
VoxelWorldManager.AddVoxel(Mushroom, "mushroom");//5
|
||||||
|
VoxelWorldManager.AddVoxel(Log, "log");//6
|
||||||
|
VoxelWorldManager.AddVoxel(Leaves, "leaves");//7
|
||||||
|
VoxelWorldManager.AddVoxel(bluegrassVoxel, "bluegrassVoxel");//8
|
||||||
|
VoxelWorldManager.AddVoxel(blueDirtVoxel, "blueDirtVoxel");//9
|
||||||
|
VoxelWorldManager.AddVoxel(bluegrassSideVoxel, "bluegrassSideVoxel");//10
|
||||||
|
VoxelWorldManager.AddVoxel(blueFlower1, "blueFlower1");//11
|
||||||
|
VoxelWorldManager.AddVoxel(blueFlower2, "blueFlower2");//12
|
||||||
|
VoxelWorldManager.AddVoxel(blueFlower3, "blueFlower3");//13
|
||||||
|
VoxelWorldManager.AddVoxel(blueFlower4, "blueFlower4");//14
|
||||||
|
VoxelWorldManager.AddVoxel(blueFlower5, "blueFlower5");//15
|
||||||
|
VoxelWorldManager.AddVoxel(blueFlower6, "blueFlower6");//16
|
||||||
|
VoxelWorldManager.AddVoxel(blueFlower7, "blueFlower7");//17
|
||||||
|
VoxelWorldManager.AddVoxel(blueFlower8, "blueFlower8");//18
|
||||||
|
VoxelWorldManager.AddVoxel(blueLeaves1, "blueLeaves1");//19
|
||||||
|
VoxelWorldManager.AddVoxel(blueLeaves2, "blueLeaves2");//20
|
||||||
|
|
||||||
|
Biome GreenBiome = new Biome(1,2,3,4,new int[]{5,6,7,4},new int[]{4,4,4,4},new int[]{4,18,16,17});
|
||||||
|
Biome Blueleaf = new Biome(8,9,3,10,new int[]{11,19,20,14},new int[]{5,6,7,8},new int[]{15,16,17,18});
|
||||||
|
|
||||||
|
VoxelWorldManager.AddBiome(Blueleaf, "blueleaf");
|
||||||
|
VoxelWorldManager.AddBiome(GreenBiome, "greenBiome");
|
||||||
}
|
}
|
||||||
|
|
||||||
public GuiRenderer GetGUIRenderer(){return GuiRender;}
|
public GuiRenderer GetGUIRenderer(){return GuiRender;}
|
||||||
|
|
|
||||||
|
|
@ -163,8 +163,14 @@ public class GameCore implements GameLogic {
|
||||||
boolean createOfflinePlayer = !PrimaryRuntime.IsServer && !ClientSideNetworkUtils.Connected;
|
boolean createOfflinePlayer = !PrimaryRuntime.IsServer && !ClientSideNetworkUtils.Connected;
|
||||||
|
|
||||||
MaterialData VoxelMat = new MaterialData("VoxelTerrain","resources/EngineResources/Texture/test_cube.png","","",new Vector4f(1,1,1,1),
|
MaterialData VoxelMat = new MaterialData("VoxelTerrain","resources/EngineResources/Texture/test_cube.png","","",new Vector4f(1,1,1,1),
|
||||||
0,0,"",new Vector4f(),"",0,"",1,new Vector4f(),1.0f,0);
|
0,0,"",new Vector4f(),"resources/EngineResources/Texture/test_cube_translucency.png",0,"",1,new Vector4f(),1.0f,0);
|
||||||
|
MaterialData BlueleafMat = new MaterialData("Blueleaf","resources/EngineResources/Texture/blueleaf_set.png","","",new Vector4f(1,1,1,1),
|
||||||
|
0,0,"",new Vector4f(),"resources/EngineResources/Texture/blueleaf_set_translucent.png",0,"",1,new Vector4f(),1.0f,0);
|
||||||
|
MaterialData BlueleafMat2 = new MaterialData("Blueleaf2","resources/EngineResources/Texture/blueleaf_set_2.png","","",new Vector4f(1,1,1,1),
|
||||||
|
0,0,"",new Vector4f(),"resources/EngineResources/Texture/blueleaf_set_2_translucent.png",0,"",1,new Vector4f(),1.0f,0);
|
||||||
materials.add(VoxelMat);
|
materials.add(VoxelMat);
|
||||||
|
materials.add(BlueleafMat);
|
||||||
|
materials.add(BlueleafMat2);
|
||||||
materials.addAll(MelonaMat);
|
materials.addAll(MelonaMat);
|
||||||
materials.addAll(CollisionVisualisationMat);
|
materials.addAll(CollisionVisualisationMat);
|
||||||
materials.addAll(MelonaMaterial);
|
materials.addAll(MelonaMaterial);
|
||||||
|
|
@ -681,11 +687,11 @@ public class GameCore implements GameLogic {
|
||||||
Vector3f CamRot = cam.GetRotation();
|
Vector3f CamRot = cam.GetRotation();
|
||||||
Vector3i ChunkPos = new Vector3i((int)Math.floor(CamPos.x/ (float) VoxelChunkGenerator.CHUNK_SIZE),(int)Math.floor(CamPos.y/ (float)VoxelChunkGenerator.CHUNK_SIZE),(int)Math.floor(CamPos.z/ (float)VoxelChunkGenerator.CHUNK_SIZE));
|
Vector3i ChunkPos = new Vector3i((int)Math.floor(CamPos.x/ (float) VoxelChunkGenerator.CHUNK_SIZE),(int)Math.floor(CamPos.y/ (float)VoxelChunkGenerator.CHUNK_SIZE),(int)Math.floor(CamPos.z/ (float)VoxelChunkGenerator.CHUNK_SIZE));
|
||||||
if(ChunkPos.x != VoxelWorldManager.LastPosition.x || ChunkPos.y != VoxelWorldManager.LastPosition.y || ChunkPos.z != VoxelWorldManager.LastPosition.z || CamRot.x != LastCamRotation.x || CamRot.y != LastCamRotation.y || CamRot.z != LastCamRotation.z) {
|
if(ChunkPos.x != VoxelWorldManager.LastPosition.x || ChunkPos.y != VoxelWorldManager.LastPosition.y || ChunkPos.z != VoxelWorldManager.LastPosition.z || CamRot.x != LastCamRotation.x || CamRot.y != LastCamRotation.y || CamRot.z != LastCamRotation.z) {
|
||||||
VoxelWorldManager.UnloadFarChunks(ChunkPos, 12,cam.GetViewMatrix(),projection.GetProjectionMatrix());
|
VoxelWorldManager.UnloadFarChunks(ChunkPos, 16,cam.GetViewMatrix(),projection.GetProjectionMatrix());
|
||||||
VoxelWorldManager.GenerateChunks(ChunkPos, new Vector3i(12,8,12),cam.GetViewMatrix(),projection.GetProjectionMatrix());
|
VoxelWorldManager.GenerateChunks(ChunkPos, new Vector3i(16,16,16),cam.GetViewMatrix(),projection.GetProjectionMatrix());
|
||||||
} else {
|
} else {
|
||||||
VoxelWorldManager.UnloadFarChunks(ChunkPos, 24,cam.GetViewMatrix(),projection.GetProjectionMatrix());
|
VoxelWorldManager.UnloadFarChunks(ChunkPos, 96,cam.GetViewMatrix(),projection.GetProjectionMatrix());
|
||||||
VoxelWorldManager.GenerateChunks(ChunkPos, new Vector3i(24,12,24),cam.GetViewMatrix(),projection.GetProjectionMatrix());
|
VoxelWorldManager.GenerateChunks(ChunkPos, new Vector3i(48,16,48),cam.GetViewMatrix(),projection.GetProjectionMatrix());
|
||||||
}
|
}
|
||||||
LastCamRotation.set(CamRot);
|
LastCamRotation.set(CamRot);
|
||||||
if(PrimaryRuntime.IsServer){
|
if(PrimaryRuntime.IsServer){
|
||||||
|
|
|
||||||
|
|
@ -163,9 +163,9 @@ CreateNewClientConnection();
|
||||||
Logger.debug("UnThrottlingEngine");
|
Logger.debug("UnThrottlingEngine");
|
||||||
FrameAccuracy= OriginalFrameAccuracy;
|
FrameAccuracy= OriginalFrameAccuracy;
|
||||||
}
|
}
|
||||||
PrimaryThread.UpdateFrameAccuracy();
|
if(PrimaryThread != null)PrimaryThread.UpdateFrameAccuracy();
|
||||||
DrawingThread.UpdateFrameAccuracy();
|
if(DrawingThread != null)DrawingThread.UpdateFrameAccuracy();
|
||||||
FastThread.UpdateFrameAccuracy();
|
if(FastThread != null)FastThread.UpdateFrameAccuracy();
|
||||||
}
|
}
|
||||||
public void UpdateTickRateThreshold(){
|
public void UpdateTickRateThreshold(){
|
||||||
CappedToTickRate = EngineConfig.getInstance().GetPrimaryTickCap();
|
CappedToTickRate = EngineConfig.getInstance().GetPrimaryTickCap();
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
package net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Computing.VoxelTerrainGeneration;
|
||||||
|
|
||||||
|
public record Biome(int surfaceBlock, int dirtBlock, int stoneBlock, int grassFoliage, int[] foliageBlocks, int[] tallBlocks, int[] otherFoliage) {
|
||||||
|
}
|
||||||
|
|
@ -8,8 +8,13 @@ import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.P
|
||||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Shader.*;
|
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Shader.*;
|
||||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DeviceLayers.Device;
|
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DeviceLayers.Device;
|
||||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Util.VulkanBuffer;
|
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Util.VulkanBuffer;
|
||||||
|
import org.lwjgl.system.MemoryUtil;
|
||||||
import org.lwjgl.util.shaderc.Shaderc;
|
import org.lwjgl.util.shaderc.Shaderc;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.lwjgl.util.vma.Vma.VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT;
|
||||||
import static org.lwjgl.util.vma.Vma.VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE;
|
import static org.lwjgl.util.vma.Vma.VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE;
|
||||||
import static org.lwjgl.vulkan.VK13.*;
|
import static org.lwjgl.vulkan.VK13.*;
|
||||||
|
|
||||||
|
|
@ -22,20 +27,31 @@ public class SharedVoxelTerrainResources {
|
||||||
|
|
||||||
public static final int TERRAIN_GENERATION_PUSH_CONSTANT_SIZE = Integer.BYTES * 8;
|
public static final int TERRAIN_GENERATION_PUSH_CONSTANT_SIZE = Integer.BYTES * 8;
|
||||||
|
|
||||||
|
public static final int MAX_VOXEL_TYPES = 256;
|
||||||
|
public static final int MAX_BIOME_TYPES = 256;
|
||||||
|
public static final int VOXEL_REG_DATA_SIZE = 104;
|
||||||
|
public static final int BIOME_REG_DATA_SIZE = 64;
|
||||||
|
|
||||||
private static final String DESC_ID_VOXEL_GENERATION = "VOXEL_SHARED_DESC_GENERATION";
|
private static final String DESC_ID_VOXEL_GENERATION = "VOXEL_SHARED_DESC_GENERATION";
|
||||||
private static final String DESC_ID_RESET = "VOXEL_SHARED_DESC_RESET";
|
private static final String DESC_ID_RESET = "VOXEL_SHARED_DESC_RESET";
|
||||||
private static final String DESC_ID_MESH = "VOXEL_SHARED_DESC_MESH";
|
private static final String DESC_ID_MESH = "VOXEL_SHARED_DESC_MESH";
|
||||||
private static final String DESC_ID_FACE_GRAPHICS = "VOXEL_SHARED_DESC_FACE_GRAPHICS";
|
private static final String DESC_ID_FACE_GRAPHICS = "VOXEL_SHARED_DESC_FACE_GRAPHICS";
|
||||||
|
private static final String DESC_ID_VOXEL_REG = "VOXEL_REGISTRY";
|
||||||
|
private static final String DESC_ID_BIOME_REG = "BIOME_REGISTRY";
|
||||||
|
|
||||||
private final VoxelMeshPool meshPool;
|
private final VoxelMeshPool meshPool;
|
||||||
|
|
||||||
private final VulkanBuffer voxelData;
|
private final VulkanBuffer voxelData;
|
||||||
private final VulkanBuffer counters;
|
private final VulkanBuffer counters;
|
||||||
|
private final VulkanBuffer voxelRegistryBuffer;
|
||||||
|
private final VulkanBuffer biomeRegistryBuffer;
|
||||||
|
|
||||||
private final DescriptorSetLayout voxelGenerationLayout;
|
private final DescriptorSetLayout voxelGenerationLayout;
|
||||||
private final DescriptorSetLayout resetLayout;
|
private final DescriptorSetLayout resetLayout;
|
||||||
private final DescriptorSetLayout meshGenerationLayout;
|
private final DescriptorSetLayout meshGenerationLayout;
|
||||||
private final DescriptorSetLayout faceGraphicsLayout;
|
private final DescriptorSetLayout faceGraphicsLayout;
|
||||||
|
private final DescriptorSetLayout voxelDeclarationLayout;
|
||||||
|
private final DescriptorSetLayout biomeDeclarationLayout;
|
||||||
|
|
||||||
private static final String MESH_GENERATION_GLSL = "resources/EngineResources/VoxelComputeShaders/meshGenerationShared.glsl";
|
private static final String MESH_GENERATION_GLSL = "resources/EngineResources/VoxelComputeShaders/meshGenerationShared.glsl";
|
||||||
private static final String VOXEL_GENERATION_GLSL = "resources/EngineResources/VoxelComputeShaders/voxelGenerationShared.glsl";
|
private static final String VOXEL_GENERATION_GLSL = "resources/EngineResources/VoxelComputeShaders/voxelGenerationShared.glsl";
|
||||||
|
|
@ -58,6 +74,15 @@ public class SharedVoxelTerrainResources {
|
||||||
counters = new VulkanBuffer(VkCtx, COUNTER_BUFFER_SIZE, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
|
counters = new VulkanBuffer(VkCtx, COUNTER_BUFFER_SIZE, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
|
||||||
VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE, 0, 0);
|
VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE, 0, 0);
|
||||||
|
|
||||||
|
voxelRegistryBuffer = new VulkanBuffer(VkCtx, (long) MAX_VOXEL_TYPES * VOXEL_REG_DATA_SIZE,
|
||||||
|
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE,
|
||||||
|
VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT,
|
||||||
|
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
|
||||||
|
biomeRegistryBuffer = new VulkanBuffer(VkCtx, (long) MAX_BIOME_TYPES * BIOME_REG_DATA_SIZE,
|
||||||
|
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE,
|
||||||
|
VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT,
|
||||||
|
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
|
||||||
|
|
||||||
voxelGenerationLayout = new DescriptorSetLayout(VkCtx, new DescriptorSetLayout.LayoutInformation[]{
|
voxelGenerationLayout = new DescriptorSetLayout(VkCtx, new DescriptorSetLayout.LayoutInformation[]{
|
||||||
new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 0, 1, VK_SHADER_STAGE_COMPUTE_BIT)
|
new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 0, 1, VK_SHADER_STAGE_COMPUTE_BIT)
|
||||||
});
|
});
|
||||||
|
|
@ -78,6 +103,13 @@ public class SharedVoxelTerrainResources {
|
||||||
new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,0,1,VK_SHADER_STAGE_VERTEX_BIT )
|
new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,0,1,VK_SHADER_STAGE_VERTEX_BIT )
|
||||||
});
|
});
|
||||||
|
|
||||||
|
voxelDeclarationLayout = new DescriptorSetLayout(VkCtx, new DescriptorSetLayout.LayoutInformation[]{
|
||||||
|
new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 0, 1, VK_SHADER_STAGE_COMPUTE_BIT)
|
||||||
|
});
|
||||||
|
biomeDeclarationLayout = new DescriptorSetLayout(VkCtx, new DescriptorSetLayout.LayoutInformation[]{
|
||||||
|
new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 0, 1, VK_SHADER_STAGE_COMPUTE_BIT)
|
||||||
|
});
|
||||||
|
|
||||||
createDescriptorSets(VkCtx);
|
createDescriptorSets(VkCtx);
|
||||||
|
|
||||||
PushConstantsRange[] generationPushConstants = new PushConstantsRange[]{
|
PushConstantsRange[] generationPushConstants = new PushConstantsRange[]{
|
||||||
|
|
@ -90,9 +122,11 @@ public class SharedVoxelTerrainResources {
|
||||||
|
|
||||||
resetPipeline = new ComputePipeline(VkCtx,resetShader,new DescriptorSetLayout[]{resetLayout},generationPushConstants);
|
resetPipeline = new ComputePipeline(VkCtx,resetShader,new DescriptorSetLayout[]{resetLayout},generationPushConstants);
|
||||||
|
|
||||||
voxelGenerationPipeline = new ComputePipeline(VkCtx,voxelShader, new DescriptorSetLayout[]{voxelGenerationLayout},generationPushConstants);
|
voxelGenerationPipeline = new ComputePipeline(VkCtx,voxelShader,
|
||||||
|
new DescriptorSetLayout[]{voxelGenerationLayout,biomeDeclarationLayout},generationPushConstants);
|
||||||
|
|
||||||
meshGenerationPipeline = new ComputePipeline( VkCtx,meshShader, new DescriptorSetLayout[]{meshGenerationLayout},generationPushConstants );
|
meshGenerationPipeline = new ComputePipeline(VkCtx, meshShader,
|
||||||
|
new DescriptorSetLayout[]{meshGenerationLayout, voxelDeclarationLayout}, generationPushConstants);
|
||||||
|
|
||||||
resetShader.CleanUp(VkCtx);
|
resetShader.CleanUp(VkCtx);
|
||||||
voxelShader.CleanUp(VkCtx);
|
voxelShader.CleanUp(VkCtx);
|
||||||
|
|
@ -126,6 +160,71 @@ public class SharedVoxelTerrainResources {
|
||||||
|
|
||||||
DescriptorSet faceGraphicsSet = allocator.AddDescriptorSet(device, DESC_ID_FACE_GRAPHICS, faceGraphicsLayout);
|
DescriptorSet faceGraphicsSet = allocator.AddDescriptorSet(device, DESC_ID_FACE_GRAPHICS, faceGraphicsLayout);
|
||||||
faceGraphicsSet.SetBuffer(device, meshPool.facePool(), meshPool.facePool().GetRequestedSize(), 0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
|
faceGraphicsSet.SetBuffer(device, meshPool.facePool(), meshPool.facePool().GetRequestedSize(), 0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
|
||||||
|
|
||||||
|
DescriptorSet voxelDeclareDescriptorSet = allocator.AddDescriptorSet(device, DESC_ID_VOXEL_REG, voxelDeclarationLayout);
|
||||||
|
voxelDeclareDescriptorSet.SetBuffer(device, voxelRegistryBuffer, voxelRegistryBuffer.GetRequestedSize(), 0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
|
||||||
|
DescriptorSet biomeDeclareDescriptorSet = allocator.AddDescriptorSet(device, DESC_ID_BIOME_REG, biomeDeclarationLayout);
|
||||||
|
biomeDeclareDescriptorSet.SetBuffer(device, biomeRegistryBuffer, biomeRegistryBuffer.GetRequestedSize(), 0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UploadBiomeRegistry(VulkanContext VkCtx, List<Biome> biomeReg) {
|
||||||
|
int count = Math.min(biomeReg.size(), MAX_BIOME_TYPES);
|
||||||
|
long memoryAddr = biomeRegistryBuffer.MapMemory(VkCtx);
|
||||||
|
ByteBuffer buffer = MemoryUtil.memByteBuffer(memoryAddr, (int) biomeRegistryBuffer.GetRequestedSize());
|
||||||
|
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
Biome biome = biomeReg.get(i);
|
||||||
|
int base = i * BIOME_REG_DATA_SIZE;
|
||||||
|
buffer.putInt(base + 0, biome.surfaceBlock());
|
||||||
|
buffer.putInt(base + 4, biome.dirtBlock());
|
||||||
|
buffer.putInt(base + 8, biome.stoneBlock());
|
||||||
|
buffer.putInt(base + 12, biome.grassFoliage());
|
||||||
|
for (int j = 0; j < 4; j++) {
|
||||||
|
buffer.putInt(base + 16 + j * 4, biome.foliageBlocks()[j]);
|
||||||
|
buffer.putInt(base + 32 + j * 4, biome.tallBlocks()[j]);
|
||||||
|
buffer.putInt(base + 48 + j * 4, biome.otherFoliage()[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
biomeRegistryBuffer.UnMapMemory(VkCtx);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UploadVoxelRegistry(VulkanContext VkCtx, List<Voxel> voxelReg) {
|
||||||
|
int count = Math.min(voxelReg.size(), MAX_VOXEL_TYPES);
|
||||||
|
long memoryAddr = voxelRegistryBuffer.MapMemory(VkCtx);
|
||||||
|
ByteBuffer buffer = MemoryUtil.memByteBuffer(memoryAddr, (int) voxelRegistryBuffer.GetRequestedSize());
|
||||||
|
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
Voxel voxel = voxelReg.get(i);
|
||||||
|
int base = i * VOXEL_REG_DATA_SIZE;
|
||||||
|
buffer.putInt(base + 0, voxel.MaterialID());
|
||||||
|
buffer.putInt(base + 4, voxel.BlockType());
|
||||||
|
buffer.putInt(base + 8, voxel.UpUV()[0].x);
|
||||||
|
buffer.putInt(base + 12, voxel.UpUV()[0].y);
|
||||||
|
buffer.putInt(base + 16, voxel.UpUV()[1].x);
|
||||||
|
buffer.putInt(base + 20, voxel.UpUV()[1].y);
|
||||||
|
buffer.putInt(base + 24, voxel.DownUV()[0].x);
|
||||||
|
buffer.putInt(base + 28, voxel.DownUV()[0].y);
|
||||||
|
buffer.putInt(base + 32, voxel.DownUV()[1].x);
|
||||||
|
buffer.putInt(base + 36, voxel.DownUV()[1].y);
|
||||||
|
buffer.putInt(base + 40, voxel.NorthUV()[0].x);
|
||||||
|
buffer.putInt(base + 44, voxel.NorthUV()[0].y);
|
||||||
|
buffer.putInt(base + 48, voxel.NorthUV()[1].x);
|
||||||
|
buffer.putInt(base + 52, voxel.NorthUV()[1].y);
|
||||||
|
buffer.putInt(base + 56, voxel.SouthUV()[0].x);
|
||||||
|
buffer.putInt(base + 60, voxel.SouthUV()[0].y);
|
||||||
|
buffer.putInt(base + 64, voxel.SouthUV()[1].x);
|
||||||
|
buffer.putInt(base + 68, voxel.SouthUV()[1].y);
|
||||||
|
buffer.putInt(base + 72, voxel.EastUV()[0].x);
|
||||||
|
buffer.putInt(base + 76, voxel.EastUV()[0].y);
|
||||||
|
buffer.putInt(base + 80, voxel.EastUV()[1].x);
|
||||||
|
buffer.putInt(base + 84, voxel.EastUV()[1].y);
|
||||||
|
buffer.putInt(base + 88, voxel.WestUV()[0].x);
|
||||||
|
buffer.putInt(base + 92, voxel.WestUV()[0].y);
|
||||||
|
buffer.putInt(base + 96, voxel.WestUV()[1].x);
|
||||||
|
buffer.putInt(base + 100, voxel.WestUV()[1].y);
|
||||||
|
}
|
||||||
|
voxelRegistryBuffer.UnMapMemory(VkCtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
public DescriptorSetLayout faceGraphicsLayout() {
|
public DescriptorSetLayout faceGraphicsLayout() {
|
||||||
|
|
@ -163,6 +262,12 @@ public class SharedVoxelTerrainResources {
|
||||||
public String voxelGenerationDescriptorId() {
|
public String voxelGenerationDescriptorId() {
|
||||||
return DESC_ID_VOXEL_GENERATION;
|
return DESC_ID_VOXEL_GENERATION;
|
||||||
}
|
}
|
||||||
|
public String voxelRegDescriptorID() {
|
||||||
|
return DESC_ID_VOXEL_REG;
|
||||||
|
}
|
||||||
|
public String biomeRegDescriptorID() {
|
||||||
|
return DESC_ID_BIOME_REG;
|
||||||
|
}
|
||||||
|
|
||||||
public String resetDescriptorId() {
|
public String resetDescriptorId() {
|
||||||
return DESC_ID_RESET;
|
return DESC_ID_RESET;
|
||||||
|
|
@ -181,9 +286,13 @@ public class SharedVoxelTerrainResources {
|
||||||
voxelGenerationLayout.CleanUp(VkCtx);
|
voxelGenerationLayout.CleanUp(VkCtx);
|
||||||
meshGenerationLayout.CleanUp(VkCtx);
|
meshGenerationLayout.CleanUp(VkCtx);
|
||||||
faceGraphicsLayout.CleanUp(VkCtx);
|
faceGraphicsLayout.CleanUp(VkCtx);
|
||||||
|
voxelDeclarationLayout.CleanUp(VkCtx);
|
||||||
|
biomeDeclarationLayout.CleanUp(VkCtx);
|
||||||
|
|
||||||
voxelData.cleanup(VkCtx);
|
voxelData.cleanup(VkCtx);
|
||||||
counters.cleanup(VkCtx);
|
counters.cleanup(VkCtx);
|
||||||
|
voxelRegistryBuffer.cleanup(VkCtx);
|
||||||
|
biomeRegistryBuffer.cleanup(VkCtx);
|
||||||
meshPool.cleanup(VkCtx);
|
meshPool.cleanup(VkCtx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
package net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Computing.VoxelTerrainGeneration;
|
||||||
|
|
||||||
|
import org.joml.Vector2i;
|
||||||
|
|
||||||
|
public record Voxel(int MaterialID, int BlockType, Vector2i[] UpUV, Vector2i[] DownUV, Vector2i[] NorthUV, Vector2i[] SouthUV, Vector2i[] EastUV, Vector2i[] WestUV) {
|
||||||
|
}
|
||||||
|
|
@ -38,16 +38,18 @@ public class VoxelChunkGenerator {
|
||||||
pushConstants.putInt(8, chunk.position().z);
|
pushConstants.putInt(8, chunk.position().z);
|
||||||
pushConstants.putInt(12, chunk.slot());
|
pushConstants.putInt(12, chunk.slot());
|
||||||
pushConstants.putInt(16, faceOffset);
|
pushConstants.putInt(16, faceOffset);
|
||||||
pushConstants.putInt(20, 0);
|
pushConstants.putInt(20, VoxelWorldManager.GetVoxelTypeCount());
|
||||||
pushConstants.putInt(24, indirectCommandIndex);
|
pushConstants.putInt(24, indirectCommandIndex);
|
||||||
pushConstants.putInt(28, 0);
|
pushConstants.putInt(28, VoxelWorldManager.GetBiomeTypeCount());
|
||||||
|
|
||||||
LongBuffer resetDescriptorSet = stack.longs(allocator.GetDescriptorSet(
|
LongBuffer resetDescriptorSet = stack.longs(allocator.GetDescriptorSet(
|
||||||
resources.resetDescriptorId()).GetVkDescriptorSet());
|
resources.resetDescriptorId()).GetVkDescriptorSet());
|
||||||
LongBuffer voxelDescriptorSet = stack.longs(allocator.GetDescriptorSet(
|
LongBuffer voxelDescriptorSet = stack.longs(allocator.GetDescriptorSet(
|
||||||
resources.voxelGenerationDescriptorId()).GetVkDescriptorSet());
|
resources.voxelGenerationDescriptorId()).GetVkDescriptorSet(),
|
||||||
LongBuffer meshDescriptorSet = stack.longs(allocator.GetDescriptorSet(
|
allocator.GetDescriptorSet(resources.biomeRegDescriptorID()).GetVkDescriptorSet());
|
||||||
resources.meshDescriptorId()).GetVkDescriptorSet());
|
LongBuffer meshDescriptorSet = stack.longs(
|
||||||
|
allocator.GetDescriptorSet(resources.meshDescriptorId()).GetVkDescriptorSet(),
|
||||||
|
allocator.GetDescriptorSet(resources.voxelRegDescriptorID()).GetVkDescriptorSet());
|
||||||
|
|
||||||
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_COMPUTE,resources.resetPipeline().GetVulkanPipeline());
|
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_COMPUTE,resources.resetPipeline().GetVulkanPipeline());
|
||||||
vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_COMPUTE,resources.resetPipeline().GetVulkanPipelineLayout(),0, resetDescriptorSet,null );
|
vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_COMPUTE,resources.resetPipeline().GetVulkanPipelineLayout(),0, resetDescriptorSet,null );
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,8 @@ import org.lwjgl.vulkan.VkCommandBuffer;
|
||||||
import org.tinylog.Logger;
|
import org.tinylog.Logger;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
|
|
||||||
|
|
@ -17,7 +19,7 @@ import static org.lwjgl.vulkan.VK13.*;
|
||||||
|
|
||||||
public class VoxelWorldManager {
|
public class VoxelWorldManager {
|
||||||
public static final int CHUNK_SIZE = 16;
|
public static final int CHUNK_SIZE = 16;
|
||||||
private static final int MAX_RESIDENT_CHUNKS = 8192 * 2;
|
private static final int MAX_RESIDENT_CHUNKS = 8192 * 3;
|
||||||
private static final int MAX_CHUNK_GENERATIONS_PER_FRAME = 128;
|
private static final int MAX_CHUNK_GENERATIONS_PER_FRAME = 128;
|
||||||
|
|
||||||
private static final ConcurrentLinkedQueue<Vector3i> RequestedChunks = new ConcurrentLinkedQueue<>();
|
private static final ConcurrentLinkedQueue<Vector3i> RequestedChunks = new ConcurrentLinkedQueue<>();
|
||||||
|
|
@ -25,6 +27,71 @@ public class VoxelWorldManager {
|
||||||
private static final ConcurrentHashMap<Vector3i, Boolean> KnownChunks = new ConcurrentHashMap<>();
|
private static final ConcurrentHashMap<Vector3i, Boolean> KnownChunks = new ConcurrentHashMap<>();
|
||||||
private static final ConcurrentHashMap<Vector3i, VoxelChunkVisibility> CulledChunks = new ConcurrentHashMap<>();
|
private static final ConcurrentHashMap<Vector3i, VoxelChunkVisibility> CulledChunks = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
private static final List<Voxel> VoxelRegistry = new java.util.concurrent.CopyOnWriteArrayList<>();
|
||||||
|
private static final ConcurrentHashMap<String, Integer> VoxelNameToIndex = new ConcurrentHashMap<>();
|
||||||
|
private static volatile boolean RegistryDirty = false;
|
||||||
|
|
||||||
|
private static final List<Biome> BiomeRegistry = new java.util.concurrent.CopyOnWriteArrayList<>();
|
||||||
|
private static final ConcurrentHashMap<String, Integer> BiomeNameToIndex = new ConcurrentHashMap<>();
|
||||||
|
private static volatile boolean BiomeRegistryDirty = false;
|
||||||
|
|
||||||
|
public static synchronized void AddVoxel(Voxel voxel, String name) {
|
||||||
|
Integer existing = VoxelNameToIndex.get(name);
|
||||||
|
if (existing != null) {
|
||||||
|
VoxelRegistry.set(existing, voxel);
|
||||||
|
} else {
|
||||||
|
VoxelNameToIndex.put(name, VoxelRegistry.size());
|
||||||
|
VoxelRegistry.add(voxel);
|
||||||
|
}
|
||||||
|
RegistryDirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<Voxel> GetVoxelRegistry() {
|
||||||
|
return new ArrayList<>(VoxelRegistry);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Voxel GetVoxel(String name) {
|
||||||
|
Integer idx = VoxelNameToIndex.get(name);
|
||||||
|
return idx == null ? null : VoxelRegistry.get(idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int GetVoxelTypeID(String name) {
|
||||||
|
Integer idx = VoxelNameToIndex.get(name);
|
||||||
|
return idx == null ? -1 : idx + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int GetVoxelTypeCount() {
|
||||||
|
return VoxelRegistry.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static synchronized void AddBiome(Biome biome, String name) {
|
||||||
|
Integer existing = BiomeNameToIndex.get(name);
|
||||||
|
if (existing != null) {
|
||||||
|
BiomeRegistry.set(existing, biome);
|
||||||
|
} else {
|
||||||
|
BiomeNameToIndex.put(name, BiomeRegistry.size());
|
||||||
|
BiomeRegistry.add(biome);
|
||||||
|
}
|
||||||
|
BiomeRegistryDirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<Biome> GetBiomeRegistry() {
|
||||||
|
return new ArrayList<>(BiomeRegistry);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Biome GetBiome(String name) {
|
||||||
|
Integer idx = BiomeNameToIndex.get(name);
|
||||||
|
return idx == null ? null : BiomeRegistry.get(idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int GetBiomeTypeID(String name) {
|
||||||
|
Integer idx = BiomeNameToIndex.get(name);
|
||||||
|
return idx == null ? -1 : idx + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int GetBiomeTypeCount() {
|
||||||
|
return BiomeRegistry.size();
|
||||||
|
}
|
||||||
|
|
||||||
private static SharedVoxelTerrainResources Resources;
|
private static SharedVoxelTerrainResources Resources;
|
||||||
private static VoxelChunkGenerator Generator;
|
private static VoxelChunkGenerator Generator;
|
||||||
|
|
@ -59,7 +126,7 @@ public class VoxelWorldManager {
|
||||||
public static int GenerationOffset = 0;
|
public static int GenerationOffset = 0;
|
||||||
public static Vector3i LastPosition = new Vector3i(0, 0, 0);
|
public static Vector3i LastPosition = new Vector3i(0, 0, 0);
|
||||||
|
|
||||||
static int IterationX = 0;
|
static volatile int IterationX = 0;
|
||||||
static Vector3i ChunkPos = new Vector3i(0, 0, 0);
|
static Vector3i ChunkPos = new Vector3i(0, 0, 0);
|
||||||
static Vector3i ChunkPos2 = new Vector3i(0, 0, 0);
|
static Vector3i ChunkPos2 = new Vector3i(0, 0, 0);
|
||||||
|
|
||||||
|
|
@ -70,6 +137,11 @@ public class VoxelWorldManager {
|
||||||
private static Vector3f min = new Vector3f();
|
private static Vector3f min = new Vector3f();
|
||||||
private static Vector3f min2 = new Vector3f();
|
private static Vector3f min2 = new Vector3f();
|
||||||
|
|
||||||
|
public static synchronized void ResetIterationX()
|
||||||
|
{
|
||||||
|
IterationX = 0;
|
||||||
|
}
|
||||||
|
|
||||||
public static synchronized void GenerateChunks(Vector3i Position, Vector3i Radius, Matrix4f cameraView,Matrix4f projectionMatrix) {
|
public static synchronized void GenerateChunks(Vector3i Position, Vector3i Radius, Matrix4f cameraView,Matrix4f projectionMatrix) {
|
||||||
|
|
||||||
projectionMatrix.mul(cameraView, viewProjectionMatrix);
|
projectionMatrix.mul(cameraView, viewProjectionMatrix);
|
||||||
|
|
@ -118,6 +190,20 @@ public class VoxelWorldManager {
|
||||||
Init(VkCtx);
|
Init(VkCtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (RegistryDirty) {
|
||||||
|
RegistryDirty = false;
|
||||||
|
Resources.UploadVoxelRegistry(VkCtx, GetVoxelRegistry());
|
||||||
|
}
|
||||||
|
if (BiomeRegistryDirty) {
|
||||||
|
BiomeRegistryDirty = false;
|
||||||
|
Resources.UploadBiomeRegistry(VkCtx, GetBiomeRegistry());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (VoxelRegistry.isEmpty()) {
|
||||||
|
return; // nothing to mesh against yet
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int generatedThisFrame = 0;
|
int generatedThisFrame = 0;
|
||||||
|
|
||||||
while (!RequestedChunks.isEmpty() && generatedThisFrame < MAX_CHUNK_GENERATIONS_PER_FRAME) {
|
while (!RequestedChunks.isEmpty() && generatedThisFrame < MAX_CHUNK_GENERATIONS_PER_FRAME) {
|
||||||
|
|
@ -206,19 +292,19 @@ public class VoxelWorldManager {
|
||||||
KnownChunks.remove(pos);
|
KnownChunks.remove(pos);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
int dx = pos.x - centerChunk.x;
|
// int dx = pos.x - centerChunk.x;
|
||||||
int dy = pos.y - centerChunk.y;
|
// int dy = pos.y - centerChunk.y;
|
||||||
int dz = pos.z - centerChunk.z;
|
// int dz = pos.z - centerChunk.z;
|
||||||
|
//
|
||||||
int distSq = dx * dx + dy * dy + dz * dz;
|
// int distSq = dx * dx + dy * dy + dz * dz;
|
||||||
if (distSq > maxDistSq) {
|
// if (distSq > maxDistSq) {
|
||||||
RenderChunk chunk = entry.getValue();
|
// RenderChunk chunk = entry.getValue();
|
||||||
|
//
|
||||||
Resources.meshPool().free(chunk);
|
// Resources.meshPool().free(chunk);
|
||||||
KnownChunks.remove(pos);
|
// KnownChunks.remove(pos);
|
||||||
|
//
|
||||||
return true;
|
// return true;
|
||||||
}
|
// }
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -82,6 +82,8 @@ public class DeferredSceneRender implements SceneRenderer {//dynamic rendering
|
||||||
private static final String FRAGMENT_OPAQUE_SHADER_FILE_SPV = FRAGMENT_OPAQUE_SHADER_FILE_GLSL + ".spv";
|
private static final String FRAGMENT_OPAQUE_SHADER_FILE_SPV = FRAGMENT_OPAQUE_SHADER_FILE_GLSL + ".spv";
|
||||||
private static final String VERTEX_SHADER_FILE_GLSL = "resources/EngineResources/shaders/scene_vertex.glsl";
|
private static final String VERTEX_SHADER_FILE_GLSL = "resources/EngineResources/shaders/scene_vertex.glsl";
|
||||||
private static final String VERTEX_SHADER_FILE_SPV = VERTEX_SHADER_FILE_GLSL + ".spv";
|
private static final String VERTEX_SHADER_FILE_SPV = VERTEX_SHADER_FILE_GLSL + ".spv";
|
||||||
|
private static final String PACKED_FRAGMENT_SHADER_FILE_GLSL = "resources/EngineResources/shaders/packed_scene_fragment_deferred.glsl";
|
||||||
|
private static final String PACKED_FRAGMENT_SHADER_FILE_SPV = PACKED_FRAGMENT_SHADER_FILE_GLSL + ".spv";
|
||||||
private static final String PACKED_VERTEX_SHADER_FILE_GLSL = "resources/EngineResources/shaders/packed_scene_vertex.glsl";
|
private static final String PACKED_VERTEX_SHADER_FILE_GLSL = "resources/EngineResources/shaders/packed_scene_vertex.glsl";
|
||||||
private static final String PACKED_VERTEX_SHADER_FILE_SPV = PACKED_VERTEX_SHADER_FILE_GLSL + ".spv";
|
private static final String PACKED_VERTEX_SHADER_FILE_SPV = PACKED_VERTEX_SHADER_FILE_GLSL + ".spv";
|
||||||
private Pipeline VkVoxelPipeline;
|
private Pipeline VkVoxelPipeline;
|
||||||
|
|
@ -246,11 +248,11 @@ public class DeferredSceneRender implements SceneRenderer {//dynamic rendering
|
||||||
private static ShaderModule[] CreateShaderModules(VulkanContext VkCtx, int Translucent){
|
private static ShaderModule[] CreateShaderModules(VulkanContext VkCtx, int Translucent){
|
||||||
if(EngineConfig.getInstance().RecompileShaders()){
|
if(EngineConfig.getInstance().RecompileShaders()){
|
||||||
ShaderCompiler.CompileGLSLShaderOnChange(Translucent > 2 ? PACKED_VERTEX_SHADER_FILE_GLSL : VERTEX_SHADER_FILE_GLSL, Shaderc.shaderc_glsl_vertex_shader);
|
ShaderCompiler.CompileGLSLShaderOnChange(Translucent > 2 ? PACKED_VERTEX_SHADER_FILE_GLSL : VERTEX_SHADER_FILE_GLSL, Shaderc.shaderc_glsl_vertex_shader);
|
||||||
ShaderCompiler.CompileGLSLShaderOnChange( Translucent == 2 ? FRAGMENT_TRANSLUCENT_SHADER_FILE_GLSL : Translucent == 1 ? FRAGMENT_OPAQUE_SHADER_FILE_GLSL : FRAGMENT_SHADER_FILE_GLSL, Shaderc.shaderc_glsl_fragment_shader);
|
ShaderCompiler.CompileGLSLShaderOnChange( Translucent > 2 ? PACKED_FRAGMENT_SHADER_FILE_GLSL : Translucent == 2 ? FRAGMENT_TRANSLUCENT_SHADER_FILE_GLSL : Translucent == 1 ? FRAGMENT_OPAQUE_SHADER_FILE_GLSL : FRAGMENT_SHADER_FILE_GLSL, Shaderc.shaderc_glsl_fragment_shader);
|
||||||
}
|
}
|
||||||
return new ShaderModule[]{
|
return new ShaderModule[]{
|
||||||
new ShaderModule(VkCtx, VK_SHADER_STAGE_VERTEX_BIT, Translucent > 2 ? PACKED_VERTEX_SHADER_FILE_SPV :VERTEX_SHADER_FILE_SPV,null),
|
new ShaderModule(VkCtx, VK_SHADER_STAGE_VERTEX_BIT, Translucent > 2 ? PACKED_VERTEX_SHADER_FILE_SPV :VERTEX_SHADER_FILE_SPV,null),
|
||||||
new ShaderModule(VkCtx, VK_SHADER_STAGE_FRAGMENT_BIT, Translucent == 2 ? FRAGMENT_TRANSLUCENT_SHADER_FILE_SPV : Translucent == 1 ? FRAGMENT_OPAQUE_SHADER_FILE_SPV : FRAGMENT_SHADER_FILE_SPV,null)
|
new ShaderModule(VkCtx, VK_SHADER_STAGE_FRAGMENT_BIT, Translucent > 2 ? PACKED_FRAGMENT_SHADER_FILE_SPV : Translucent == 2 ? FRAGMENT_TRANSLUCENT_SHADER_FILE_SPV : Translucent == 1 ? FRAGMENT_OPAQUE_SHADER_FILE_SPV : FRAGMENT_SHADER_FILE_SPV,null)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,8 @@ public class ForwardSceneRender implements SceneRenderer {//dynamic rendering
|
||||||
public static String SkyBoxID = "SKYBOX_TEXTURE";
|
public static String SkyBoxID = "SKYBOX_TEXTURE";
|
||||||
private static final int PUSH_CONSTANTS_SIZE = VulkanUtils.MATRIX4X4_SIZE + VulkanUtils.INT_SIZE;
|
private static final int PUSH_CONSTANTS_SIZE = VulkanUtils.MATRIX4X4_SIZE + VulkanUtils.INT_SIZE;
|
||||||
private final VulkanBuffer BufferProjectionMatrix;
|
private final VulkanBuffer BufferProjectionMatrix;
|
||||||
|
private static final String PACKED_FRAGMENT_SHADER_FILE_GLSL = "resources/EngineResources/shaders/packed_scene_fragment.glsl";
|
||||||
|
private static final String PACKED_FRAGMENT_SHADER_FILE_SPV = PACKED_FRAGMENT_SHADER_FILE_GLSL + ".spv";
|
||||||
private static final String PACKED_VERTEX_SHADER_FILE_GLSL = "resources/EngineResources/shaders/packed_scene_vertex.glsl";
|
private static final String PACKED_VERTEX_SHADER_FILE_GLSL = "resources/EngineResources/shaders/packed_scene_vertex.glsl";
|
||||||
private static final String PACKED_VERTEX_SHADER_FILE_SPV = PACKED_VERTEX_SHADER_FILE_GLSL + ".spv";
|
private static final String PACKED_VERTEX_SHADER_FILE_SPV = PACKED_VERTEX_SHADER_FILE_GLSL + ".spv";
|
||||||
private Pipeline VkVoxelPipeline;
|
private Pipeline VkVoxelPipeline;
|
||||||
|
|
@ -293,11 +295,11 @@ public class ForwardSceneRender implements SceneRenderer {//dynamic rendering
|
||||||
private static ShaderModule[] CreateShaderModules(VulkanContext VkCtx, int Translucent){
|
private static ShaderModule[] CreateShaderModules(VulkanContext VkCtx, int Translucent){
|
||||||
if(EngineConfig.getInstance().RecompileShaders()){
|
if(EngineConfig.getInstance().RecompileShaders()){
|
||||||
ShaderCompiler.CompileGLSLShaderOnChange(Translucent > 2 ? PACKED_VERTEX_SHADER_FILE_GLSL :VERTEX_SHADER_FILE_GLSL, Shaderc.shaderc_glsl_vertex_shader);
|
ShaderCompiler.CompileGLSLShaderOnChange(Translucent > 2 ? PACKED_VERTEX_SHADER_FILE_GLSL :VERTEX_SHADER_FILE_GLSL, Shaderc.shaderc_glsl_vertex_shader);
|
||||||
ShaderCompiler.CompileGLSLShaderOnChange( Translucent == 2 ? FRAGMENT_TRANSLUCENT_SHADER_FILE_GLSL : Translucent == 1 ? FRAGMENT_OPAQUE_SHADER_FILE_GLSL : FRAGMENT_SHADER_FILE_GLSL, Shaderc.shaderc_glsl_fragment_shader);
|
ShaderCompiler.CompileGLSLShaderOnChange(Translucent > 2 ? PACKED_FRAGMENT_SHADER_FILE_GLSL : Translucent == 2 ? FRAGMENT_TRANSLUCENT_SHADER_FILE_GLSL : Translucent == 1 ? FRAGMENT_OPAQUE_SHADER_FILE_GLSL : FRAGMENT_SHADER_FILE_GLSL, Shaderc.shaderc_glsl_fragment_shader);
|
||||||
}
|
}
|
||||||
return new ShaderModule[]{
|
return new ShaderModule[]{
|
||||||
new ShaderModule(VkCtx, VK_SHADER_STAGE_VERTEX_BIT, Translucent > 2 ? PACKED_VERTEX_SHADER_FILE_SPV : VERTEX_SHADER_FILE_SPV,null),
|
new ShaderModule(VkCtx, VK_SHADER_STAGE_VERTEX_BIT, Translucent > 2 ? PACKED_VERTEX_SHADER_FILE_SPV : VERTEX_SHADER_FILE_SPV,null),
|
||||||
new ShaderModule(VkCtx, VK_SHADER_STAGE_FRAGMENT_BIT, Translucent == 2 ? FRAGMENT_TRANSLUCENT_SHADER_FILE_SPV : Translucent == 1 ? FRAGMENT_OPAQUE_SHADER_FILE_SPV : FRAGMENT_SHADER_FILE_SPV,null)
|
new ShaderModule(VkCtx, VK_SHADER_STAGE_FRAGMENT_BIT,Translucent > 2 ? PACKED_FRAGMENT_SHADER_FILE_SPV : Translucent == 2 ? FRAGMENT_TRANSLUCENT_SHADER_FILE_SPV : Translucent == 1 ? FRAGMENT_OPAQUE_SHADER_FILE_SPV : FRAGMENT_SHADER_FILE_SPV,null)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,7 @@ public class Device {
|
||||||
}
|
}
|
||||||
var features12 = VkPhysicalDeviceVulkan12Features.calloc(MemStack)
|
var features12 = VkPhysicalDeviceVulkan12Features.calloc(MemStack)
|
||||||
.sType$Default()
|
.sType$Default()
|
||||||
|
.shaderSampledImageArrayNonUniformIndexing(true)
|
||||||
.scalarBlockLayout(true);
|
.scalarBlockLayout(true);
|
||||||
|
|
||||||
var features13 = VkPhysicalDeviceVulkan13Features.calloc(MemStack)
|
var features13 = VkPhysicalDeviceVulkan13Features.calloc(MemStack)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue