diff --git a/resources/EngineResources/VoxelComputeShaders/voxelGenerationShared.glsl b/resources/EngineResources/VoxelComputeShaders/voxelGenerationShared.glsl index dfce9e2..493f74c 100644 --- a/resources/EngineResources/VoxelComputeShaders/voxelGenerationShared.glsl +++ b/resources/EngineResources/VoxelComputeShaders/voxelGenerationShared.glsl @@ -102,11 +102,16 @@ void main() { ivec3 localPos = ivec3(gl_GlobalInvocationID.xyz); 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 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; + float YZone2 = floor(worldPos.y/75.0)*75.0; + 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 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); uint voxelType = 0u; @@ -114,14 +119,14 @@ void main() { float depthBelowSurface = height - float(worldPos.y); if (depthBelowSurface < 1.5) { - voxelType = 1u; // Grass/topsoil + voxelType = 1u; // Grass } else if (depthBelowSurface < 5.0) { - voxelType = 2u; // Dirt + voxelType = 2u; // Dirt(also stone rn) } else { 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); if (depthBelowSurface < 1.5) { diff --git a/resources/EngineResources/shaders/packed_scene_vertex.glsl b/resources/EngineResources/shaders/packed_scene_vertex.glsl index 0726e3d..61b5eda 100644 --- a/resources/EngineResources/shaders/packed_scene_vertex.glsl +++ b/resources/EngineResources/shaders/packed_scene_vertex.glsl @@ -51,78 +51,32 @@ const vec3 BITANGENTS[6] = vec3[6]( ); const vec2 CORNER_UVS[16] = vec2[16]( - 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) + 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) { - vec3 p = vec3(voxelPos); - - if (faceId == 0u) { - if (cornerIndex == 0u) return p + vec3(0.0, 1.0, 0.0); - if (cornerIndex == 1u) return p + vec3(0.0, 1.0, 1.0); - if (cornerIndex == 2u) return p + vec3(1.0, 1.0, 1.0); - 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); -} +const vec3 FACE_CORNERS[6][4] = vec3[6][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) +); void main() { viewMatrix = viewUniform.matrix; 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 faceRecordIndex = uint(gl_VertexIndex) / 6u; + //uint triangleVertex = uint(gl_VertexIndex) % 6u; + //uint cornerIndex = TRI_TO_CORNER[triangleVertex]; + uint packedFace = faces[faceRecordIndex]; uint voxelX = packedFace & 0x1Fu; @@ -134,7 +88,7 @@ void main() { faceId = min(faceId, 5u); 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; vec4 worldPosVec4 = vec4(worldPos, 1.0); @@ -145,5 +99,5 @@ void main() { outNormal = NORMALS[faceId]; outTangent = TANGENTS[faceId]; outBitangent = BITANGENTS[faceId]; - outTextCoords = CORNER_UVS[cornerIndex + 4u * matId]; + outTextCoords = CORNER_UVS[cornerIndex + (matId << 2u)]; } \ No newline at end of file diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Main/GameCore.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Main/GameCore.java index e8344bc..6f3b29d 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Main/GameCore.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Main/GameCore.java @@ -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.Profiling.CPUMonitor; 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.VoxelWorldManager; import net.halbear.Terrain4J.EngineCore.ServerNetworking.ClientSideNetworkUtils; @@ -658,14 +659,14 @@ public class GameCore implements GameLogic { @Override public void Update(EngineInstance engineInstance, long FrameDiffNanoSeconds) { 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)); // 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.UnloadFarChunks(ChunkPos, 10); //} else { - VoxelWorldManager.GenerateChunks(ChunkPos, new Vector3i(24,5,24)); - VoxelWorldManager.UnloadFarChunks(ChunkPos, 24); //} for (int i = 0; i < VisualisedCollisionActor3D.CollisionVisuals.size(); i++) { @@ -685,6 +686,11 @@ public class GameCore implements GameLogic { float PhysicsFramerate = 24f; float PhysicsFrameTime = 1000f/PhysicsFramerate; 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(UseLegacyNetworking) Server.LegacyCollectIncomingPackets(); else*/ //Server.CollectIncomingPackets(); diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Computing/VoxelTerrainGeneration/VoxelChunkGenerator.java b/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Computing/VoxelTerrainGeneration/VoxelChunkGenerator.java index 2a16932..0430a45 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Computing/VoxelTerrainGeneration/VoxelChunkGenerator.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Computing/VoxelTerrainGeneration/VoxelChunkGenerator.java @@ -42,51 +42,35 @@ public class VoxelChunkGenerator { pushConstants.putInt(24, indirectCommandIndex); pushConstants.putInt(28, 0); - LongBuffer resetDescriptorSet = stack.longs( - allocator.GetDescriptorSet(resources.resetDescriptorId()).GetVkDescriptorSet() - ); - - LongBuffer voxelDescriptorSet = stack.longs( - allocator.GetDescriptorSet(resources.voxelGenerationDescriptorId()).GetVkDescriptorSet() - ); - - LongBuffer meshDescriptorSet = stack.longs( - allocator.GetDescriptorSet(resources.meshDescriptorId()).GetVkDescriptorSet() - ); + LongBuffer resetDescriptorSet = stack.longs(allocator.GetDescriptorSet( + resources.resetDescriptorId()).GetVkDescriptorSet()); + LongBuffer voxelDescriptorSet = stack.longs(allocator.GetDescriptorSet( + resources.voxelGenerationDescriptorId()).GetVkDescriptorSet()); + LongBuffer meshDescriptorSet = stack.longs(allocator.GetDescriptorSet( + resources.meshDescriptorId()).GetVkDescriptorSet()); vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_COMPUTE,resources.resetPipeline().GetVulkanPipeline()); - 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 ); - vkCmdDispatch(cmd, 1, 1, 1); - VulkanUtils.BufferBarriers(stack, cmd, - new long[]{ + VulkanUtils.BufferBarriers(stack, cmd, new long[]{ resources.meshPool().indirectPoolHandle(), 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_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()); - 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 ); - vkCmdDispatch(cmd, DISPATCH_SIZE, DISPATCH_SIZE, DISPATCH_SIZE); VulkanUtils.BufferBarrier(stack, cmd,resources.voxelData().GetBuffer(), - 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_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); 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); - VulkanUtils.BufferBarriers(stack, cmd, - new long[]{ - resources.voxelData().GetBuffer(), - resources.counters().GetBuffer(), - resources.meshPool().facePoolHandle(), - resources.meshPool().indirectPoolHandle() - }, - 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 - ); + VulkanUtils.BufferBarriers(stack, cmd, new long[]{ + resources.voxelData().GetBuffer(), resources.counters().GetBuffer(), + resources.meshPool().facePoolHandle(), resources.meshPool().indirectPoolHandle() + }, 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); } } } \ No newline at end of file diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Computing/VoxelTerrainGeneration/VoxelWorldManager.java b/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Computing/VoxelTerrainGeneration/VoxelWorldManager.java index 2cc5a55..a7d0562 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Computing/VoxelTerrainGeneration/VoxelWorldManager.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Computing/VoxelTerrainGeneration/VoxelWorldManager.java @@ -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.Structure.DeviceLayers.CommandBuffer; import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Util.VulkanUtils; -import org.joml.Vector3i; -import org.joml.Vector4f; +import org.joml.*; import org.lwjgl.vulkan.VkCommandBuffer; import org.tinylog.Logger; @@ -17,8 +16,9 @@ import java.util.concurrent.ConcurrentLinkedQueue; import static org.lwjgl.vulkan.VK13.*; public class VoxelWorldManager { + public static final int CHUNK_SIZE = 16; 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 RequestedChunks = new ConcurrentLinkedQueue<>(); private static final ConcurrentHashMap RenderChunks = new ConcurrentHashMap<>(); @@ -63,7 +63,18 @@ public class VoxelWorldManager { static Vector3i ChunkPos = 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 ChunkY = Position.y; int ChunkY2 = Position.y; @@ -78,10 +89,18 @@ public class VoxelWorldManager { ChunkY = Position.y + Ry; ChunkY2 = Position.y - Ry; 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) { - GenerateChunk(ChunkPos.set(ChunkX, ChunkY, ChunkZ)); - GenerateChunk(ChunkPos2.set(ChunkX, ChunkY2, ChunkZ)); + if(frustumIntersection.testAab(min.x, min.y, min.z, max.x, max.y, max.z)) { + 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; RenderChunks.entrySet().removeIf(entry -> { + 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 dy = pos.y - centerChunk.y; int dz = pos.z - centerChunk.z; int distSq = dx * dx + dy * dy + dz * dz; - - if (distSq > maxDistSq) { + boolean InView = frustumIntersection.testAab(min.x, min.y, min.z, max.x, max.y, max.z); + if (distSq > maxDistSq || !InView) { RenderChunk chunk = entry.getValue(); Resources.meshPool().free(chunk);