Improved island generation

This commit is contained in:
Harrison Corlett 2026-09-17 11:31:52 +01:00
parent 8c301d0ac1
commit 4565188f15
5 changed files with 91 additions and 126 deletions

View file

@ -102,11 +102,16 @@ 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;
float islandheight = valueNoise(vec2(worldPos.z, worldPos.x) * 0.005) * 100 + valueNoise(vec2(worldPos.x, worldPos.z) * 0.1) * 20 + valueNoise(vec2(worldPos.x, worldPos.z) * 0.1) * 5+ valueNoise(vec2(worldPos.x, worldPos.z)) * 0.5 - 15; float YZone = floor(worldPos.y/150.0)*150.0;
float islandheight = 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) * 5+ valueNoise(vec2(worldPos.x + YZone * 2, worldPos.z + YZone * 2)) * 0.5 - 15 + YZone;
float height = 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.1) * 5+ valueNoise(vec2(worldPos.x + YZone * 2, worldPos.z + YZone * 2)) * 0.5 + YZone;
float height = valueNoise(vec2(worldPos.x, worldPos.z) * 0.005) * 100 + valueNoise(vec2(worldPos.x, worldPos.z) * 0.01) * 10 + valueNoise(vec2(worldPos.x, worldPos.z) * 0.1) * 5+ valueNoise(vec2(worldPos.x, worldPos.z)) * 0.5; float YZone2 = floor(worldPos.y/75.0)*75.0;
float height2 = valueNoise(vec2(-worldPos.x, -worldPos.z) * 0.005) * 100 + valueNoise(vec2(-worldPos.x, -worldPos.z) * 0.01) * 10 + valueNoise(vec2(-worldPos.x, -worldPos.z) * 0.1) * 5+ valueNoise(vec2(-worldPos.x, -worldPos.z)) * 0.5 + 100; float islandheight2 = valueNoise(vec2(worldPos.x - YZone2 * 2, worldPos.z -YZone2 * 2) * 0.005) * 60 + valueNoise(vec2(worldPos.x + YZone2 * 2, worldPos.z + YZone2 * 2) * 0.1) * 20 + valueNoise(vec2(worldPos.x + YZone2 * 2, worldPos.z + YZone2 * 2) * 0.1) * 10+ valueNoise(vec2(worldPos.x + YZone2 * 2, worldPos.z + YZone2 * 2)) * 0.5 - 5 + YZone2;
float islandheight2 = 100 + valueNoise(vec2(-worldPos.z, -worldPos.x) * 0.005) * 100 + valueNoise(vec2(-worldPos.x, -worldPos.z) * 0.1) * 20 + valueNoise(vec2(worldPos.x, worldPos.z) * 0.1) * 5+ valueNoise(vec2(worldPos.x, worldPos.z)) * 0.5 - 5; float height2 = valueNoise(vec2(worldPos.x + YZone2 * 2, worldPos.z + YZone2 * 2) * 0.005) * 50 + valueNoise(vec2(worldPos.x + YZone2 * 2, worldPos.z + YZone2 * 2) * 0.01) * 10 + valueNoise(vec2(worldPos.x + YZone2 * 2, worldPos.z + YZone2 * 2) * 0.1) * 5+ valueNoise(vec2(worldPos.x + YZone2 * 2, worldPos.z + YZone2 * 2)) * 0.5 + YZone2;
//float height2 = valueNoise(vec2(-worldPos.x, -worldPos.z) * 0.005) * 100 + valueNoise(vec2(-worldPos.x, -worldPos.z) * 0.01) * 10 + valueNoise(vec2(-worldPos.x, -worldPos.z) * 0.1) * 5+ valueNoise(vec2(-worldPos.x, -worldPos.z)) * 0.5 + 100;
//float islandheight2 = 100 + valueNoise(vec2(-worldPos.z, -worldPos.x) * 0.005) * 100 + valueNoise(vec2(-worldPos.x, -worldPos.z) * 0.1) * 20 + valueNoise(vec2(worldPos.x, worldPos.z) * 0.1) * 5+ valueNoise(vec2(worldPos.x, worldPos.z)) * 0.5 - 5;
//height = clamp(height, 4.0, 28.0); //height = clamp(height, 4.0, 28.0);
uint voxelType = 0u; uint voxelType = 0u;
@ -114,14 +119,14 @@ void main() {
float depthBelowSurface = height - float(worldPos.y); float depthBelowSurface = height - float(worldPos.y);
if (depthBelowSurface < 1.5) { if (depthBelowSurface < 1.5) {
voxelType = 1u; // Grass/topsoil voxelType = 1u; // Grass
} else if (depthBelowSurface < 5.0) { } else if (depthBelowSurface < 5.0) {
voxelType = 2u; // Dirt voxelType = 2u; // Dirt(also stone rn)
} else { } else {
voxelType = 3u; // Stone voxelType = 3u; // Stone
} }
} }
if(float(worldPos.y) <= height2 && float(worldPos.y) >= islandheight2){ else if (float(worldPos.y) <= height2 && float(worldPos.y) >= islandheight2) {
float depthBelowSurface = height2 - float(worldPos.y); float depthBelowSurface = height2 - float(worldPos.y);
if (depthBelowSurface < 1.5) { if (depthBelowSurface < 1.5) {

View file

@ -51,78 +51,32 @@ const vec3 BITANGENTS[6] = vec3[6](
); );
const vec2 CORNER_UVS[16] = vec2[16]( const vec2 CORNER_UVS[16] = vec2[16](
vec2(0.5, 0.0), vec2(0.5, 0.0), vec2(0.5, 0.5), vec2(1.0, 0.5), vec2(1.0, 0.0),
vec2(0.5, 0.5), vec2(0.0, 0.5), vec2(0.0, 1.0), vec2(0.5, 1.0), vec2(0.5, 0.5),
vec2(1.0, 0.5), vec2(0.5, 0.0), vec2(0.5, 0.5), vec2(1.0, 0.5), vec2(1.0, 0.0),
vec2(1.0, 0.0), vec2(0.5, 0.0), vec2(0.5, 0.5), vec2(1.0, 0.5), vec2(1.0, 0.0)
vec2(0.0, 0.5),
vec2(0.0, 1.0),
vec2(0.5, 1.0),
vec2(0.5, 0.5),
vec2(0.5, 0.0),
vec2(0.5, 0.5),
vec2(1.0, 0.5),
vec2(1.0, 0.0),
vec2(0.5, 0.0),
vec2(0.5, 0.5),
vec2(1.0, 0.5),
vec2(1.0, 0.0)
); );
vec3 buildFaceCornerPosition(uvec3 voxelPos, uint faceId, uint cornerIndex) { const vec3 FACE_CORNERS[6][4] = vec3[6][4](
vec3 p = vec3(voxelPos); 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)
if (faceId == 0u) { 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)
if (cornerIndex == 0u) return p + vec3(0.0, 1.0, 0.0); 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)
if (cornerIndex == 1u) return p + vec3(0.0, 1.0, 1.0); 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)
if (cornerIndex == 2u) return p + vec3(1.0, 1.0, 1.0); 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)
return p + vec3(1.0, 1.0, 0.0); );
}
if (faceId == 1u) {
if (cornerIndex == 0u) return p + vec3(0.0, 0.0, 0.0);
if (cornerIndex == 1u) return p + vec3(1.0, 0.0, 0.0);
if (cornerIndex == 2u) return p + vec3(1.0, 0.0, 1.0);
return p + vec3(0.0, 0.0, 1.0);
}
if (faceId == 2u) {
if (cornerIndex == 0u) return p + vec3(1.0, 0.0, 0.0);
if (cornerIndex == 1u) return p + vec3(1.0, 1.0, 0.0);
if (cornerIndex == 2u) return p + vec3(1.0, 1.0, 1.0);
return p + vec3(1.0, 0.0, 1.0);
}
if (faceId == 3u) {
if (cornerIndex == 0u) return p + vec3(0.0, 0.0, 0.0);
if (cornerIndex == 1u) return p + vec3(0.0, 0.0, 1.0);
if (cornerIndex == 2u) return p + vec3(0.0, 1.0, 1.0);
return p + vec3(0.0, 1.0, 0.0);
}
if (faceId == 4u) {
if (cornerIndex == 0u) return p + vec3(0.0, 0.0, 1.0);
if (cornerIndex == 1u) return p + vec3(1.0, 0.0, 1.0);
if (cornerIndex == 2u) return p + vec3(1.0, 1.0, 1.0);
return p + vec3(0.0, 1.0, 1.0);
}
if (cornerIndex == 0u) return p + vec3(0.0, 0.0, 0.0);
if (cornerIndex == 1u) return p + vec3(0.0, 1.0, 0.0);
if (cornerIndex == 2u) return p + vec3(1.0, 1.0, 0.0);
return p + vec3(1.0, 0.0, 0.0);
}
void main() { void main() {
viewMatrix = viewUniform.matrix; viewMatrix = viewUniform.matrix;
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 & 0x1Fu;
@ -134,7 +88,7 @@ void main() {
faceId = min(faceId, 5u); faceId = min(faceId, 5u);
matId = min(matId, 3u); matId = min(matId, 3u);
vec3 localPos = buildFaceCornerPosition(uvec3(voxelX, voxelY, voxelZ), 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;
vec4 worldPosVec4 = vec4(worldPos, 1.0); vec4 worldPosVec4 = vec4(worldPos, 1.0);
@ -145,5 +99,5 @@ void main() {
outNormal = NORMALS[faceId]; outNormal = NORMALS[faceId];
outTangent = TANGENTS[faceId]; outTangent = TANGENTS[faceId];
outBitangent = BITANGENTS[faceId]; outBitangent = BITANGENTS[faceId];
outTextCoords = CORNER_UVS[cornerIndex + 4u * matId]; outTextCoords = CORNER_UVS[cornerIndex + (matId << 2u)];
} }

View file

@ -29,6 +29,7 @@ import net.halbear.Terrain4J.EngineCore.Main.Util.Maths.Noise2D;
import net.halbear.Terrain4J.EngineCore.Main.Util.Maths.PermutationArray; import net.halbear.Terrain4J.EngineCore.Main.Util.Maths.PermutationArray;
import net.halbear.Terrain4J.EngineCore.Profiling.CPUMonitor; import net.halbear.Terrain4J.EngineCore.Profiling.CPUMonitor;
import net.halbear.Terrain4J.EngineCore.Profiling.GPUProfiler; import net.halbear.Terrain4J.EngineCore.Profiling.GPUProfiler;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Universal.Projection.Project3D;
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.ServerNetworking.ClientSideNetworkUtils; import net.halbear.Terrain4J.EngineCore.ServerNetworking.ClientSideNetworkUtils;
@ -658,14 +659,14 @@ public class GameCore implements GameLogic {
@Override @Override
public void Update(EngineInstance engineInstance, long FrameDiffNanoSeconds) { public void Update(EngineInstance engineInstance, long FrameDiffNanoSeconds) {
if(!PrimaryRuntime.IsServer && !RenderThread.Headless) { if(!PrimaryRuntime.IsServer && !RenderThread.Headless) {
CamPos.set(engineInstance.scene().GetCamera().GetPosition()); Camera cam = engineInstance.scene().GetCamera();
Project3D projection = engineInstance.scene().GetProjection();
CamPos.set(cam.GetPosition());
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) { // if(ChunkPos.x != VoxelWorldManager.LastPosition.x || ChunkPos.y != VoxelWorldManager.LastPosition.y || ChunkPos.z != VoxelWorldManager.LastPosition.z) {
// VoxelWorldManager.GenerateChunks(ChunkPos, new Vector3i(5, 5, 5)); // VoxelWorldManager.GenerateChunks(ChunkPos, new Vector3i(5, 5, 5));
// VoxelWorldManager.UnloadFarChunks(ChunkPos, 10); // VoxelWorldManager.UnloadFarChunks(ChunkPos, 10);
//} else { //} else {
VoxelWorldManager.GenerateChunks(ChunkPos, new Vector3i(24,5,24));
VoxelWorldManager.UnloadFarChunks(ChunkPos, 24);
//} //}
for (int i = 0; i < VisualisedCollisionActor3D.CollisionVisuals.size(); i++) { for (int i = 0; i < VisualisedCollisionActor3D.CollisionVisuals.size(); i++) {
@ -685,6 +686,11 @@ public class GameCore implements GameLogic {
float PhysicsFramerate = 24f; float PhysicsFramerate = 24f;
float PhysicsFrameTime = 1000f/PhysicsFramerate; float PhysicsFrameTime = 1000f/PhysicsFramerate;
float DeltaTime = (float)FrameDiffNanoSeconds/(PhysicsFrameTime*1000000f); float DeltaTime = (float)FrameDiffNanoSeconds/(PhysicsFrameTime*1000000f);
Camera cam = engineInstance.scene().GetCamera();
Project3D projection = engineInstance.scene().GetProjection();
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));
VoxelWorldManager.UnloadFarChunks(ChunkPos, 12,cam.GetViewMatrix(),projection.GetProjectionMatrix());
VoxelWorldManager.GenerateChunks(ChunkPos, new Vector3i(12,6,12),cam.GetViewMatrix(),projection.GetProjectionMatrix());
if(PrimaryRuntime.IsServer){ if(PrimaryRuntime.IsServer){
/* if(UseLegacyNetworking) Server.LegacyCollectIncomingPackets(); /* if(UseLegacyNetworking) Server.LegacyCollectIncomingPackets();
else*/ //Server.CollectIncomingPackets(); else*/ //Server.CollectIncomingPackets();

View file

@ -42,51 +42,35 @@ public class VoxelChunkGenerator {
pushConstants.putInt(24, indirectCommandIndex); pushConstants.putInt(24, indirectCommandIndex);
pushConstants.putInt(28, 0); pushConstants.putInt(28, 0);
LongBuffer resetDescriptorSet = stack.longs( LongBuffer resetDescriptorSet = stack.longs(allocator.GetDescriptorSet(
allocator.GetDescriptorSet(resources.resetDescriptorId()).GetVkDescriptorSet() resources.resetDescriptorId()).GetVkDescriptorSet());
); LongBuffer voxelDescriptorSet = stack.longs(allocator.GetDescriptorSet(
resources.voxelGenerationDescriptorId()).GetVkDescriptorSet());
LongBuffer voxelDescriptorSet = stack.longs( LongBuffer meshDescriptorSet = stack.longs(allocator.GetDescriptorSet(
allocator.GetDescriptorSet(resources.voxelGenerationDescriptorId()).GetVkDescriptorSet() resources.meshDescriptorId()).GetVkDescriptorSet());
);
LongBuffer meshDescriptorSet = stack.longs(
allocator.GetDescriptorSet(resources.meshDescriptorId()).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 );
vkCmdPushConstants( cmd, resources.resetPipeline().GetVulkanPipelineLayout(),VK_SHADER_STAGE_COMPUTE_BIT,0, pushConstants ); vkCmdPushConstants( cmd, resources.resetPipeline().GetVulkanPipelineLayout(),VK_SHADER_STAGE_COMPUTE_BIT,0, pushConstants );
vkCmdDispatch(cmd, 1, 1, 1); vkCmdDispatch(cmd, 1, 1, 1);
VulkanUtils.BufferBarriers(stack, cmd, VulkanUtils.BufferBarriers(stack, cmd, new long[]{
new long[]{
resources.meshPool().indirectPoolHandle(), resources.meshPool().indirectPoolHandle(),
resources.counters().GetBuffer() resources.counters().GetBuffer()
}, }, VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
VK_ACCESS_2_SHADER_WRITE_BIT, VK_ACCESS_2_SHADER_WRITE_BIT,
VK_ACCESS_2_SHADER_READ_BIT | VK_ACCESS_2_SHADER_WRITE_BIT VK_ACCESS_2_SHADER_READ_BIT | VK_ACCESS_2_SHADER_WRITE_BIT
); );
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_COMPUTE,resources.voxelGenerationPipeline().GetVulkanPipeline()); vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_COMPUTE,resources.voxelGenerationPipeline().GetVulkanPipeline());
vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_COMPUTE,resources.voxelGenerationPipeline().GetVulkanPipelineLayout(),0, voxelDescriptorSet,null ); vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_COMPUTE,resources.voxelGenerationPipeline().GetVulkanPipelineLayout(),0, voxelDescriptorSet,null );
vkCmdPushConstants( cmd, resources.voxelGenerationPipeline().GetVulkanPipelineLayout(),VK_SHADER_STAGE_COMPUTE_BIT,0, pushConstants ); vkCmdPushConstants( cmd, resources.voxelGenerationPipeline().GetVulkanPipelineLayout(),VK_SHADER_STAGE_COMPUTE_BIT,0, pushConstants );
vkCmdDispatch(cmd, DISPATCH_SIZE, DISPATCH_SIZE, DISPATCH_SIZE); vkCmdDispatch(cmd, DISPATCH_SIZE, DISPATCH_SIZE, DISPATCH_SIZE);
VulkanUtils.BufferBarrier(stack, cmd,resources.voxelData().GetBuffer(), VulkanUtils.BufferBarrier(stack, cmd,resources.voxelData().GetBuffer(),
VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT, VK_ACCESS_2_SHADER_WRITE_BIT, VK_ACCESS_2_SHADER_READ_BIT);
VK_ACCESS_2_SHADER_WRITE_BIT,
VK_ACCESS_2_SHADER_READ_BIT
);
vkCmdBindPipeline(cmd,VK_PIPELINE_BIND_POINT_COMPUTE,resources.meshGenerationPipeline().GetVulkanPipeline() ); vkCmdBindPipeline(cmd,VK_PIPELINE_BIND_POINT_COMPUTE,resources.meshGenerationPipeline().GetVulkanPipeline() );
@ -96,22 +80,13 @@ public class VoxelChunkGenerator {
vkCmdDispatch(cmd, DISPATCH_SIZE, DISPATCH_SIZE, DISPATCH_SIZE); vkCmdDispatch(cmd, DISPATCH_SIZE, DISPATCH_SIZE, DISPATCH_SIZE);
VulkanUtils.BufferBarriers(stack, cmd, VulkanUtils.BufferBarriers(stack, cmd, new long[]{
new long[]{ resources.voxelData().GetBuffer(), resources.counters().GetBuffer(),
resources.voxelData().GetBuffer(), resources.meshPool().facePoolHandle(), resources.meshPool().indirectPoolHandle()
resources.counters().GetBuffer(), }, VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT |
resources.meshPool().facePoolHandle(), VK_PIPELINE_STAGE_2_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_2_DRAW_INDIRECT_BIT,
resources.meshPool().indirectPoolHandle() VK_ACCESS_2_SHADER_WRITE_BIT, VK_ACCESS_2_SHADER_STORAGE_READ_BIT |
}, VK_ACCESS_2_SHADER_READ_BIT | VK_ACCESS_2_INDIRECT_COMMAND_READ_BIT);
VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT |
VK_PIPELINE_STAGE_2_VERTEX_SHADER_BIT |
VK_PIPELINE_STAGE_2_DRAW_INDIRECT_BIT,
VK_ACCESS_2_SHADER_WRITE_BIT,
VK_ACCESS_2_SHADER_STORAGE_READ_BIT |
VK_ACCESS_2_SHADER_READ_BIT |
VK_ACCESS_2_INDIRECT_COMMAND_READ_BIT
);
} }
} }
} }

View file

@ -5,8 +5,7 @@ import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.P
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.VkModel.MaterialsCache; import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.VkModel.MaterialsCache;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DeviceLayers.CommandBuffer; import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DeviceLayers.CommandBuffer;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Util.VulkanUtils; import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Util.VulkanUtils;
import org.joml.Vector3i; import org.joml.*;
import org.joml.Vector4f;
import org.lwjgl.vulkan.VkCommandBuffer; import org.lwjgl.vulkan.VkCommandBuffer;
import org.tinylog.Logger; import org.tinylog.Logger;
@ -17,8 +16,9 @@ import java.util.concurrent.ConcurrentLinkedQueue;
import static org.lwjgl.vulkan.VK13.*; import static org.lwjgl.vulkan.VK13.*;
public class VoxelWorldManager { public class VoxelWorldManager {
public static final int CHUNK_SIZE = 16;
private static final int MAX_RESIDENT_CHUNKS = 8192 * 2; private static final int MAX_RESIDENT_CHUNKS = 8192 * 2;
private static final int MAX_CHUNK_GENERATIONS_PER_FRAME = 256; 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<>();
private static final ConcurrentHashMap<Vector3i, RenderChunk> RenderChunks = new ConcurrentHashMap<>(); private static final ConcurrentHashMap<Vector3i, RenderChunk> RenderChunks = new ConcurrentHashMap<>();
@ -63,7 +63,18 @@ public class VoxelWorldManager {
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);
public static void GenerateChunks(Vector3i Position, Vector3i Radius) { private static final FrustumIntersection frustumIntersection = new FrustumIntersection();
private static final Matrix4f viewProjectionMatrix = new Matrix4f();
private static Vector3f max = new Vector3f();
private static Vector3f max2 = new Vector3f();
private static Vector3f min = new Vector3f();
private static Vector3f min2 = new Vector3f();
public static void GenerateChunks(Vector3i Position, Vector3i Radius, Matrix4f cameraView,Matrix4f projectionMatrix) {
projectionMatrix.mul(cameraView, viewProjectionMatrix);
frustumIntersection.set(viewProjectionMatrix);
int ChunkX = Position.x; int ChunkX = Position.x;
int ChunkY = Position.y; int ChunkY = Position.y;
int ChunkY2 = Position.y; int ChunkY2 = Position.y;
@ -78,10 +89,18 @@ public class VoxelWorldManager {
ChunkY = Position.y + Ry; ChunkY = Position.y + Ry;
ChunkY2 = Position.y - Ry; ChunkY2 = Position.y - Ry;
ChunkZ = Position.z + Rz; ChunkZ = Position.z + Rz;
min.set(ChunkX * CHUNK_SIZE, ChunkY * CHUNK_SIZE, ChunkZ * CHUNK_SIZE);
min2.set(ChunkX * CHUNK_SIZE, ChunkY2 * CHUNK_SIZE, ChunkZ * CHUNK_SIZE);
max.set(min.x + CHUNK_SIZE, min.y + CHUNK_SIZE, min.z + CHUNK_SIZE);
max2.set(min2.x + CHUNK_SIZE, min2.y + CHUNK_SIZE, min2.z + CHUNK_SIZE);
if (Rx == -IterationX || Rz == -IterationX || Rx == IterationX || Rz == IterationX) if (Rx == -IterationX || Rz == -IterationX || Rx == IterationX || Rz == IterationX)
{ {
GenerateChunk(ChunkPos.set(ChunkX, ChunkY, ChunkZ)); if(frustumIntersection.testAab(min.x, min.y, min.z, max.x, max.y, max.z)) {
GenerateChunk(ChunkPos2.set(ChunkX, ChunkY2, ChunkZ)); GenerateChunk(ChunkPos.set(ChunkX, ChunkY, ChunkZ));
}
if(frustumIntersection.testAab(min2.x, min2.y, min2.z, max2.x, max2.y, max2.z)) {
GenerateChunk(ChunkPos2.set(ChunkX, ChunkY2, ChunkZ));
}
} }
} }
} }
@ -171,19 +190,25 @@ public class VoxelWorldManager {
} }
public static void UnloadFarChunks(Vector3i centerChunk, int unloadRadius) { public static void UnloadFarChunks(Vector3i centerChunk, int unloadRadius,Matrix4f cameraView,Matrix4f projectionMatrix) {
int maxDistSq = unloadRadius * unloadRadius; int maxDistSq = unloadRadius * unloadRadius;
RenderChunks.entrySet().removeIf(entry -> { RenderChunks.entrySet().removeIf(entry -> {
Vector3i pos = entry.getKey(); Vector3i pos = entry.getKey();
projectionMatrix.mul(cameraView, viewProjectionMatrix);
frustumIntersection.set(viewProjectionMatrix);
min.set(pos.x * CHUNK_SIZE, pos.y * CHUNK_SIZE, pos.z * CHUNK_SIZE);
max.set(min.x + CHUNK_SIZE, min.y + CHUNK_SIZE, min.z + CHUNK_SIZE);
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;
boolean InView = frustumIntersection.testAab(min.x, min.y, min.z, max.x, max.y, max.z);
if (distSq > maxDistSq) { if (distSq > maxDistSq || !InView) {
RenderChunk chunk = entry.getValue(); RenderChunk chunk = entry.getValue();
Resources.meshPool().free(chunk); Resources.meshPool().free(chunk);