i did a little memory optimisation (19GB of VRAM -> 2.6GB of VRAM), lost some FPS in vertex rendering as a result but i'll figure it out
This commit is contained in:
parent
bf9af81f38
commit
ce7051d8ca
21 changed files with 766 additions and 592 deletions
|
|
@ -183,7 +183,7 @@ public class VulkanRenderer implements Renderer {
|
|||
spriteRenderer.CompileSprites(RendererContext,modelsCache, textureCache);
|
||||
spriteRenderer.LoadMaterials(RendererContext,materialsCache,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));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -660,13 +660,13 @@ public class GameCore implements GameLogic {
|
|||
if(!PrimaryRuntime.IsServer && !RenderThread.Headless) {
|
||||
CamPos.set(engineInstance.scene().GetCamera().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, 3, 5));
|
||||
VoxelWorldManager.UnloadFarChunks(ChunkPos, 10);
|
||||
} else {
|
||||
VoxelWorldManager.GenerateChunks(ChunkPos, new Vector3i(24,10,24));
|
||||
VoxelWorldManager.UnloadFarChunks(ChunkPos, 48);
|
||||
}
|
||||
// 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++) {
|
||||
VisualisedCollisionActor3D.CollisionVisuals.get(i).Update();
|
||||
|
|
|
|||
|
|
@ -93,10 +93,10 @@ public class CPUMonitor {
|
|||
break;
|
||||
}
|
||||
}
|
||||
return output.toString().isEmpty() ? "Unknown CPU" : output.toString();
|
||||
return output.toString().isEmpty() || output.toString().contains("cannot") ? "Unknown CPU" : output.toString();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return "Error reading CPU name: " + e.getMessage();
|
||||
return "Couldn't read CPU name";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ public class ComputeVoxelTerrain {
|
|||
|
||||
private static final int FLOATS_PER_VERTEX = 14;
|
||||
private static final int VERTEX_SIZE_BYTES = FLOATS_PER_VERTEX * Float.BYTES;
|
||||
private static final int DRAW_INDEXED_INDIRECT_COMMAND_SIZE = 5 * Integer.BYTES;
|
||||
private static final int DRAW_INDEXED_INDIRECT_COMMAND_SIZE = 4 * Integer.BYTES;
|
||||
private static final int COUNTER_BUFFER_SIZE = 2 * Integer.BYTES;
|
||||
|
||||
private final String DESCRIPTOR_ID_MESH;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Computing.VoxelTerrainGeneration;
|
||||
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Vector3i;
|
||||
|
||||
public record RenderChunk(Vector3i position, int slot,long vertexOffsetBytes, long indexOffsetBytes,int maxIndexCount,long indirectCommandOffsetBytes) {
|
||||
public record RenderChunk(Vector3i position, int slot, long faceOffsetBytes,int maxFaceCount,long indirectCommandOffsetBytes, Matrix4f ModelMatrix) {
|
||||
}
|
||||
|
|
@ -17,31 +17,15 @@ public class SharedVoxelTerrainResources {
|
|||
public static final int CHUNK_SIZE = 16;
|
||||
public static final int VOXEL_COUNT = CHUNK_SIZE * CHUNK_SIZE * CHUNK_SIZE;
|
||||
|
||||
public static final int DRAW_INDEXED_INDIRECT_COMMAND_SIZE = 5 * Integer.BYTES;
|
||||
public static final int COUNTER_BUFFER_SIZE = 2 * Integer.BYTES;
|
||||
|
||||
public static final int DRAW_INDIRECT_COMMAND_SIZE = 4 * Integer.BYTES;
|
||||
public static final int COUNTER_BUFFER_SIZE = Integer.BYTES;
|
||||
|
||||
public static final int TERRAIN_GENERATION_PUSH_CONSTANT_SIZE = Integer.BYTES * 8;
|
||||
/*Push constants:
|
||||
int chunkX
|
||||
int chunkY
|
||||
int chunkZ
|
||||
int slot
|
||||
uint vertexFloatOffset
|
||||
uint indexOffset
|
||||
uint indirectCommandOffset
|
||||
uint padding */
|
||||
|
||||
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_MESH = "VOXEL_SHARED_DESC_MESH";
|
||||
|
||||
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_RESET_GLSL = "resources/EngineResources/VoxelComputeShaders/resetVoxelDrawShared.glsl";
|
||||
|
||||
private static final String MESH_GENERATION_SPV = MESH_GENERATION_GLSL + ".spv";
|
||||
private static final String VOXEL_GENERATION_SPV = VOXEL_GENERATION_GLSL + ".spv";
|
||||
private static final String VOXEL_RESET_SPV = VOXEL_RESET_GLSL + ".spv";
|
||||
private static final String DESC_ID_FACE_GRAPHICS = "VOXEL_SHARED_DESC_FACE_GRAPHICS";
|
||||
|
||||
private final VoxelMeshPool meshPool;
|
||||
|
||||
|
|
@ -51,6 +35,15 @@ public class SharedVoxelTerrainResources {
|
|||
private final DescriptorSetLayout voxelGenerationLayout;
|
||||
private final DescriptorSetLayout resetLayout;
|
||||
private final DescriptorSetLayout meshGenerationLayout;
|
||||
private final DescriptorSetLayout faceGraphicsLayout;
|
||||
|
||||
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_RESET_GLSL = "resources/EngineResources/VoxelComputeShaders/resetVoxelDrawShared.glsl";
|
||||
|
||||
private static final String MESH_GENERATION_SPV = MESH_GENERATION_GLSL + ".spv";
|
||||
private static final String VOXEL_GENERATION_SPV = VOXEL_GENERATION_GLSL + ".spv";
|
||||
private static final String VOXEL_RESET_SPV = VOXEL_RESET_GLSL + ".spv";
|
||||
|
||||
private final Pipeline voxelGenerationPipeline;
|
||||
private final Pipeline resetPipeline;
|
||||
|
|
@ -60,26 +53,29 @@ public class SharedVoxelTerrainResources {
|
|||
meshPool = new VoxelMeshPool(VkCtx, maxResidentChunks);
|
||||
|
||||
voxelData = new VulkanBuffer(VkCtx, (long) VOXEL_COUNT * Integer.BYTES,
|
||||
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE,0,0 );
|
||||
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE, 0, 0);
|
||||
|
||||
counters = new VulkanBuffer( VkCtx,COUNTER_BUFFER_SIZE,VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
|
||||
VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE,0,0 );
|
||||
counters = new VulkanBuffer(VkCtx, COUNTER_BUFFER_SIZE, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
|
||||
VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE, 0, 0);
|
||||
|
||||
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)
|
||||
});
|
||||
|
||||
resetLayout = 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,1,1,VK_SHADER_STAGE_COMPUTE_BIT)
|
||||
new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 0, 1, VK_SHADER_STAGE_COMPUTE_BIT),
|
||||
new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, 1, VK_SHADER_STAGE_COMPUTE_BIT)
|
||||
});
|
||||
|
||||
meshGenerationLayout = 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,1,1,VK_SHADER_STAGE_COMPUTE_BIT),
|
||||
new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,2,1,VK_SHADER_STAGE_COMPUTE_BIT),
|
||||
new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,3,1,VK_SHADER_STAGE_COMPUTE_BIT),
|
||||
new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,4,1,VK_SHADER_STAGE_COMPUTE_BIT)
|
||||
new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 0, 1, VK_SHADER_STAGE_COMPUTE_BIT),
|
||||
new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, 1, VK_SHADER_STAGE_COMPUTE_BIT),
|
||||
new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 2, 1, VK_SHADER_STAGE_COMPUTE_BIT),
|
||||
new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 3, 1, VK_SHADER_STAGE_COMPUTE_BIT)
|
||||
});
|
||||
|
||||
faceGraphicsLayout = new DescriptorSetLayout(VkCtx, new DescriptorSetLayout.LayoutInformation[]{
|
||||
new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,0,1,VK_SHADER_STAGE_VERTEX_BIT )
|
||||
});
|
||||
|
||||
createDescriptorSets(VkCtx);
|
||||
|
|
@ -124,10 +120,20 @@ public class SharedVoxelTerrainResources {
|
|||
|
||||
DescriptorSet meshSet = allocator.AddDescriptorSet(device, DESC_ID_MESH, meshGenerationLayout);
|
||||
meshSet.SetBuffer(device, voxelData, voxelData.GetRequestedSize(), 0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
|
||||
meshSet.SetBuffer(device, meshPool.vertexPool(), meshPool.vertexPool().GetRequestedSize(), 1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
|
||||
meshSet.SetBuffer(device, meshPool.indexPool(), meshPool.indexPool().GetRequestedSize(), 2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
|
||||
meshSet.SetBuffer(device, meshPool.indirectPool(), meshPool.indirectPool().GetRequestedSize(), 3, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
|
||||
meshSet.SetBuffer(device, counters, counters.GetRequestedSize(), 4, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
|
||||
meshSet.SetBuffer(device, meshPool.facePool(), meshPool.facePool().GetRequestedSize(), 1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
|
||||
meshSet.SetBuffer(device, meshPool.indirectPool(), meshPool.indirectPool().GetRequestedSize(), 2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
|
||||
meshSet.SetBuffer(device, counters, counters.GetRequestedSize(), 3, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
|
||||
|
||||
DescriptorSet faceGraphicsSet = allocator.AddDescriptorSet(device, DESC_ID_FACE_GRAPHICS, faceGraphicsLayout);
|
||||
faceGraphicsSet.SetBuffer(device, meshPool.facePool(), meshPool.facePool().GetRequestedSize(), 0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
|
||||
}
|
||||
|
||||
public DescriptorSetLayout faceGraphicsLayout() {
|
||||
return faceGraphicsLayout;
|
||||
}
|
||||
|
||||
public String faceGraphicsDescriptorId() {
|
||||
return DESC_ID_FACE_GRAPHICS;
|
||||
}
|
||||
|
||||
public VoxelMeshPool meshPool() {
|
||||
|
|
@ -174,6 +180,7 @@ public class SharedVoxelTerrainResources {
|
|||
resetLayout.CleanUp(VkCtx);
|
||||
voxelGenerationLayout.CleanUp(VkCtx);
|
||||
meshGenerationLayout.CleanUp(VkCtx);
|
||||
faceGraphicsLayout.CleanUp(VkCtx);
|
||||
|
||||
voxelData.cleanup(VkCtx);
|
||||
counters.cleanup(VkCtx);
|
||||
|
|
|
|||
|
|
@ -30,16 +30,15 @@ public class VoxelChunkGenerator {
|
|||
|
||||
ByteBuffer pushConstants = stack.malloc(SharedVoxelTerrainResources.TERRAIN_GENERATION_PUSH_CONSTANT_SIZE);
|
||||
|
||||
int vertexFloatOffset = (int) (chunk.vertexOffsetBytes() / Float.BYTES);
|
||||
int indexOffset = (int) (chunk.indexOffsetBytes() / Integer.BYTES);
|
||||
int indirectCommandIndex = (int) (chunk.indirectCommandOffsetBytes() / VoxelMeshPool.DRAW_INDEXED_INDIRECT_COMMAND_SIZE);
|
||||
int indirectCommandIndex = (int) (chunk.indirectCommandOffsetBytes() / VoxelMeshPool.DRAW_INDIRECT_COMMAND_SIZE);
|
||||
int faceOffset = (int) (chunk.faceOffsetBytes() / VoxelMeshPool.FACE_RECORD_SIZE_BYTES);
|
||||
|
||||
pushConstants.putInt(0, chunk.position().x);
|
||||
pushConstants.putInt(4, chunk.position().y);
|
||||
pushConstants.putInt(8, chunk.position().z);
|
||||
pushConstants.putInt(12, chunk.slot());
|
||||
pushConstants.putInt(16, vertexFloatOffset);
|
||||
pushConstants.putInt(20, indexOffset);
|
||||
pushConstants.putInt(16, faceOffset);
|
||||
pushConstants.putInt(20, 0);
|
||||
pushConstants.putInt(24, indirectCommandIndex);
|
||||
pushConstants.putInt(28, 0);
|
||||
|
||||
|
|
@ -101,19 +100,16 @@ public class VoxelChunkGenerator {
|
|||
new long[]{
|
||||
resources.voxelData().GetBuffer(),
|
||||
resources.counters().GetBuffer(),
|
||||
resources.meshPool().vertexPoolHandle(),
|
||||
resources.meshPool().indexPoolHandle(),
|
||||
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_INPUT_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_READ_BIT |
|
||||
VK_ACCESS_2_SHADER_WRITE_BIT |
|
||||
VK_ACCESS_2_VERTEX_ATTRIBUTE_READ_BIT |
|
||||
VK_ACCESS_2_INDEX_READ_BIT |
|
||||
VK_ACCESS_2_SHADER_STORAGE_READ_BIT |
|
||||
VK_ACCESS_2_SHADER_READ_BIT |
|
||||
VK_ACCESS_2_INDIRECT_COMMAND_READ_BIT
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@ package net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Computing.VoxelTerr
|
|||
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.Rendering.VulkanContext;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Util.VulkanBuffer;
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Vector3f;
|
||||
import org.joml.Vector3i;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
|
|
@ -13,24 +15,16 @@ import static org.lwjgl.vulkan.VK13.*;
|
|||
public class VoxelMeshPool{
|
||||
public static final int CHUNK_SIZE = 16;
|
||||
|
||||
public static final int FLOATS_PER_VERTEX = 14;
|
||||
public static final int VERTEX_SIZE_BYTES = FLOATS_PER_VERTEX * Float.BYTES;
|
||||
|
||||
public static final int MAX_VISIBLE_FACES_PER_CHUNK = CHUNK_SIZE * CHUNK_SIZE * 12;
|
||||
public static final int MAX_VERTICES_PER_CHUNK = MAX_VISIBLE_FACES_PER_CHUNK * 4;
|
||||
public static final int MAX_INDICES_PER_CHUNK = MAX_VISIBLE_FACES_PER_CHUNK * 6;
|
||||
|
||||
public static final int INDEX_SIZE_BYTES = Integer.BYTES;
|
||||
public static final int DRAW_INDEXED_INDIRECT_COMMAND_SIZE = 5 * Integer.BYTES;
|
||||
public static final int MAX_VISIBLE_FACES_PER_CHUNK = CHUNK_SIZE * CHUNK_SIZE * CHUNK_SIZE * 6;
|
||||
public static final int FACE_RECORD_SIZE_BYTES = Integer.BYTES;
|
||||
public static final int DRAW_INDIRECT_COMMAND_SIZE = 4 * Integer.BYTES;
|
||||
|
||||
private final int maxChunks;
|
||||
|
||||
private final long vertexSlotSizeBytes;
|
||||
private final long indexSlotSizeBytes;
|
||||
private final long faceSlotSizeBytes;
|
||||
private final long indirectSlotSizeBytes;
|
||||
|
||||
private final VulkanBuffer vertexPool;
|
||||
private final VulkanBuffer indexPool;
|
||||
private final VulkanBuffer facePool;
|
||||
private final VulkanBuffer indirectPool;
|
||||
|
||||
private final Queue<Integer> freeSlots = new ArrayDeque<>();
|
||||
|
|
@ -38,19 +32,14 @@ public class VoxelMeshPool{
|
|||
public VoxelMeshPool(VulkanContext VkCtx, int maxChunks) {
|
||||
this.maxChunks = maxChunks;
|
||||
|
||||
this.vertexSlotSizeBytes = (long) MAX_VERTICES_PER_CHUNK * VERTEX_SIZE_BYTES;
|
||||
this.indexSlotSizeBytes = (long) MAX_INDICES_PER_CHUNK * INDEX_SIZE_BYTES;
|
||||
this.indirectSlotSizeBytes = DRAW_INDEXED_INDIRECT_COMMAND_SIZE;
|
||||
this.faceSlotSizeBytes = (long) MAX_VISIBLE_FACES_PER_CHUNK * FACE_RECORD_SIZE_BYTES;
|
||||
this.indirectSlotSizeBytes = DRAW_INDIRECT_COMMAND_SIZE;
|
||||
|
||||
long vertexPoolSize = vertexSlotSizeBytes * maxChunks;
|
||||
long indexPoolSize = indexSlotSizeBytes * maxChunks;
|
||||
long facePoolSize = faceSlotSizeBytes * maxChunks;
|
||||
long indirectPoolSize = indirectSlotSizeBytes * maxChunks;
|
||||
|
||||
vertexPool = new VulkanBuffer(VkCtx,vertexPoolSize,VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
|
||||
facePool = new VulkanBuffer(VkCtx,facePoolSize,VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
|
||||
VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE,0,0);
|
||||
|
||||
indexPool = new VulkanBuffer(VkCtx,indexPoolSize,VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
|
||||
VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE,0,0);
|
||||
|
||||
indirectPool = new VulkanBuffer(VkCtx,indirectPoolSize,VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
|
||||
VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE,0,0);
|
||||
|
|
@ -66,44 +55,44 @@ public class VoxelMeshPool{
|
|||
if (slot == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new RenderChunk(new Vector3i(position),slot, vertexOffsetBytes(slot),indexOffsetBytes(slot),MAX_INDICES_PER_CHUNK,indirectCommandOffsetBytes(slot));
|
||||
return new RenderChunk(
|
||||
new Vector3i(position),
|
||||
slot,
|
||||
faceOffsetBytes(slot),
|
||||
MAX_VISIBLE_FACES_PER_CHUNK,
|
||||
indirectCommandOffsetBytes(slot),
|
||||
new Matrix4f().identity().translate(
|
||||
new Vector3f(
|
||||
position.x * CHUNK_SIZE,
|
||||
position.y * CHUNK_SIZE,
|
||||
position.z * CHUNK_SIZE
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public void free(RenderChunk chunk) {
|
||||
freeSlots.add(chunk.slot());
|
||||
}
|
||||
|
||||
public long vertexOffsetBytes(int slot) {
|
||||
return vertexSlotSizeBytes * slot;
|
||||
}
|
||||
|
||||
public long indexOffsetBytes(int slot) {
|
||||
return indexSlotSizeBytes * slot;
|
||||
public long faceOffsetBytes(int slot) {
|
||||
return faceSlotSizeBytes * slot;
|
||||
}
|
||||
|
||||
public long indirectCommandOffsetBytes(int slot) {
|
||||
return indirectSlotSizeBytes * slot;
|
||||
}
|
||||
|
||||
public VulkanBuffer vertexPool() {
|
||||
return vertexPool;
|
||||
}
|
||||
|
||||
public VulkanBuffer indexPool() {
|
||||
return indexPool;
|
||||
public VulkanBuffer facePool() {
|
||||
return facePool;
|
||||
}
|
||||
|
||||
public VulkanBuffer indirectPool() {
|
||||
return indirectPool;
|
||||
}
|
||||
|
||||
public long vertexPoolHandle() {
|
||||
return vertexPool.GetBuffer();
|
||||
}
|
||||
|
||||
public long indexPoolHandle() {
|
||||
return indexPool.GetBuffer();
|
||||
public long facePoolHandle() {
|
||||
return facePool.GetBuffer();
|
||||
}
|
||||
|
||||
public long indirectPoolHandle() {
|
||||
|
|
@ -119,8 +108,7 @@ public class VoxelMeshPool{
|
|||
}
|
||||
|
||||
public void cleanup(VulkanContext VkCtx) {
|
||||
vertexPool.cleanup(VkCtx);
|
||||
indexPool.cleanup(VkCtx);
|
||||
facePool.cleanup(VkCtx);
|
||||
indirectPool.cleanup(VkCtx);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ public final class VoxelTerrainHeightSampler {
|
|||
double minHeight = minHeightForChunkXZ(chunkX, chunkZ, chunkSize);
|
||||
double maxHeight = maxHeightForChunkXZ(chunkX, chunkZ, chunkSize);
|
||||
|
||||
double safetyPadding = 32.0;
|
||||
double safetyPadding = 16.0;
|
||||
|
||||
if (chunkMinY > maxHeight + safetyPadding) {
|
||||
return VoxelChunkVisibility.EMPTY_AIR;
|
||||
|
|
|
|||
|
|
@ -4,22 +4,21 @@ import net.halbear.Terrain4J.EngineCore.Logic.Rendering.VulkanContext;
|
|||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.Pipeline;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.VkModel.MaterialsCache;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DeviceLayers.CommandBuffer;
|
||||
import org.joml.Matrix4f;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Util.VulkanUtils;
|
||||
import org.joml.Vector3i;
|
||||
import org.lwjgl.system.MemoryStack;
|
||||
import org.joml.Vector4f;
|
||||
import org.lwjgl.vulkan.VkCommandBuffer;
|
||||
import org.tinylog.Logger;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.LongBuffer;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
|
||||
import static org.lwjgl.vulkan.VK13.*;
|
||||
|
||||
public class VoxelWorldManager {
|
||||
private static final int MAX_RESIDENT_CHUNKS = 512 * 24;
|
||||
private static final int MAX_CHUNK_GENERATIONS_PER_FRAME = 32;
|
||||
private static final int MAX_RESIDENT_CHUNKS = 8192 * 2;
|
||||
private static final int MAX_CHUNK_GENERATIONS_PER_FRAME = 256;
|
||||
|
||||
private static final ConcurrentLinkedQueue<Vector3i> RequestedChunks = new ConcurrentLinkedQueue<>();
|
||||
private static final ConcurrentHashMap<Vector3i, RenderChunk> RenderChunks = new ConcurrentHashMap<>();
|
||||
|
|
@ -41,8 +40,8 @@ public class VoxelWorldManager {
|
|||
Generator = new VoxelChunkGenerator(Resources);
|
||||
|
||||
GraphicsPushConstants = org.lwjgl.system.MemoryUtil.memAlloc(
|
||||
net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Util.VulkanUtils.MATRIX4X4_SIZE +
|
||||
net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Util.VulkanUtils.INT_SIZE
|
||||
VulkanUtils.MATRIX4X4_SIZE +
|
||||
VulkanUtils.INT_SIZE
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -116,7 +115,7 @@ public class VoxelWorldManager {
|
|||
// VoxelChunkGenerator.CHUNK_SIZE
|
||||
// );
|
||||
//
|
||||
// if (visibility != VoxelChunkVisibility.SURFACE) {
|
||||
// if (visibility == VoxelChunkVisibility.EMPTY_AIR) {
|
||||
// CulledChunks.put(new Vector3i(position), visibility);
|
||||
// continue;
|
||||
// }
|
||||
|
|
@ -136,48 +135,42 @@ public class VoxelWorldManager {
|
|||
}
|
||||
}
|
||||
|
||||
public static void RecordRender(VkCommandBuffer CommandBuffer,Pipeline graphicsPipeline, MaterialsCache materialsCache) {
|
||||
public static SharedVoxelTerrainResources Resources() {
|
||||
return Resources;
|
||||
}
|
||||
|
||||
public static void RecordRender(VkCommandBuffer CommandBuffer, Pipeline graphicsPipeline, MaterialsCache materialsCache, boolean shadowPass) {
|
||||
if (Resources == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
int terrainMaterialIndex = materialsCache.GetPosition("VoxelTerrain");
|
||||
int terrainMaterialIndex;
|
||||
|
||||
if (terrainMaterialIndex < 0) {
|
||||
if (materialsCache.GetPosition("VoxelTerrain") < 0) {
|
||||
terrainMaterialIndex = 0;
|
||||
} else {
|
||||
terrainMaterialIndex = materialsCache.GetPosition("VoxelTerrain");
|
||||
}
|
||||
|
||||
try (MemoryStack stack = MemoryStack.stackPush()) {
|
||||
Matrix4f identity = new Matrix4f().identity();
|
||||
RenderChunks.forEach((position, chunk) -> {
|
||||
SetPushConstants(CommandBuffer, new Vector4f(position, 0), graphicsPipeline, terrainMaterialIndex, shadowPass);
|
||||
vkCmdDrawIndirect(CommandBuffer, Resources.meshPool().indirectPoolHandle(), chunk.indirectCommandOffsetBytes(),
|
||||
1, VoxelMeshPool.DRAW_INDIRECT_COMMAND_SIZE);
|
||||
});
|
||||
}
|
||||
|
||||
identity.get(0, GraphicsPushConstants);
|
||||
GraphicsPushConstants.putInt(
|
||||
net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Util.VulkanUtils.MATRIX4X4_SIZE,
|
||||
terrainMaterialIndex
|
||||
);
|
||||
|
||||
vkCmdPushConstants(CommandBuffer, graphicsPipeline.GetVulkanPipelineLayout(),VK_SHADER_STAGE_VERTEX_BIT,
|
||||
0,GraphicsPushConstants.slice(
|
||||
0,
|
||||
net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Util.VulkanUtils.MATRIX4X4_SIZE));
|
||||
|
||||
vkCmdPushConstants(CommandBuffer,graphicsPipeline.GetVulkanPipelineLayout(), VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Util.VulkanUtils.MATRIX4X4_SIZE,
|
||||
GraphicsPushConstants.slice(
|
||||
net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Util.VulkanUtils.MATRIX4X4_SIZE,
|
||||
net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Util.VulkanUtils.INT_SIZE ) );
|
||||
|
||||
LongBuffer vertexBuffers = stack.longs(Resources.meshPool().vertexPoolHandle());
|
||||
LongBuffer offsets = stack.longs(0L);
|
||||
|
||||
vkCmdBindVertexBuffers(CommandBuffer, 0, vertexBuffers, offsets);
|
||||
vkCmdBindIndexBuffer(CommandBuffer, Resources.meshPool().indexPoolHandle(), 0, VK_INDEX_TYPE_UINT32);
|
||||
|
||||
RenderChunks.forEach((position, chunk) -> vkCmdDrawIndexedIndirect(CommandBuffer,Resources.meshPool().indirectPoolHandle(),
|
||||
chunk.indirectCommandOffsetBytes(), 1,VoxelMeshPool.DRAW_INDEXED_INDIRECT_COMMAND_SIZE));
|
||||
private static void SetPushConstants(VkCommandBuffer CmdHandle, Vector4f ModelMatrix, Pipeline VkPipeline, int MaterialIndex, boolean shadowPass){
|
||||
ModelMatrix.get(0,GraphicsPushConstants);
|
||||
GraphicsPushConstants.putInt(VulkanUtils.MATRIX4X4_SIZE, MaterialIndex);
|
||||
vkCmdPushConstants(CmdHandle, VkPipeline.GetVulkanPipelineLayout(), VK_SHADER_STAGE_VERTEX_BIT, 0,
|
||||
GraphicsPushConstants.slice(0,VulkanUtils.MATRIX4X4_SIZE));
|
||||
if(!shadowPass){
|
||||
vkCmdPushConstants(CmdHandle, VkPipeline.GetVulkanPipelineLayout(), VK_SHADER_STAGE_FRAGMENT_BIT, VulkanUtils.MATRIX4X4_SIZE,
|
||||
GraphicsPushConstants.slice(VulkanUtils.MATRIX4X4_SIZE, VulkanUtils.INT_SIZE));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void UnloadFarChunks(Vector3i centerChunk, int unloadRadius) {
|
||||
int maxDistSq = unloadRadius * unloadRadius;
|
||||
|
||||
|
|
|
|||
|
|
@ -82,6 +82,9 @@ 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 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 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 Pipeline VkVoxelPipeline;
|
||||
private final VulkanBuffer[] BufferViewMatrices;
|
||||
private Pipeline VkPipeline;
|
||||
private Pipeline VkPipelineOpaque;
|
||||
|
|
@ -166,6 +169,19 @@ public class DeferredSceneRender implements SceneRenderer {//dynamic rendering
|
|||
shaderModules = DeferredSceneRender.CreateShaderModules(vulkanContext,2);
|
||||
VkPipelineTranslucent = CreatePipeline(vulkanContext, shaderModules, layouts, false, true,true,EngineConfig.getInstance().AlphaToCoverage(),2);
|
||||
Arrays.asList(shaderModules).forEach(shaderModule -> shaderModule.CleanUp(vulkanContext));
|
||||
VoxelWorldManager.Init(vulkanContext);
|
||||
|
||||
DescriptorSetLayout[] voxelLayouts = new DescriptorSetLayout[]{
|
||||
descriptorLayoutVertexUniform,
|
||||
descriptorLayoutVertexUniform,
|
||||
descriptorLayoutFragStorage,
|
||||
descriptorLayoutTexture,
|
||||
VoxelWorldManager.Resources().faceGraphicsLayout()
|
||||
};
|
||||
|
||||
shaderModules = DeferredSceneRender.CreateShaderModules(vulkanContext, 3);
|
||||
VkVoxelPipeline = CreateVoxelPipeline(vulkanContext, shaderModules, voxelLayouts);
|
||||
Arrays.asList(shaderModules).forEach(shaderModule -> shaderModule.CleanUp(vulkanContext));
|
||||
|
||||
DescriptorSetLayout[] skyboxLayouts = new DescriptorSetLayout[]{
|
||||
descriptorLayoutVertexUniform,
|
||||
|
|
@ -229,11 +245,11 @@ public class DeferredSceneRender implements SceneRenderer {//dynamic rendering
|
|||
|
||||
private static ShaderModule[] CreateShaderModules(VulkanContext VkCtx, int Translucent){
|
||||
if(EngineConfig.getInstance().RecompileShaders()){
|
||||
ShaderCompiler.CompileGLSLShaderOnChange(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);
|
||||
}
|
||||
return new ShaderModule[]{
|
||||
new ShaderModule(VkCtx, VK_SHADER_STAGE_VERTEX_BIT, 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)
|
||||
};
|
||||
}
|
||||
|
|
@ -282,6 +298,41 @@ public class DeferredSceneRender implements SceneRenderer {//dynamic rendering
|
|||
}
|
||||
}
|
||||
|
||||
private static Pipeline CreateVoxelPipeline(VulkanContext VkCtx, ShaderModule[] ShaderModules, DescriptorSetLayout[] DescriptorSetLayouts) {
|
||||
int[] colorFormats = new int[]{
|
||||
MultiRenderTargetAttachments.POSITION_FORMAT,
|
||||
MultiRenderTargetAttachments.ALBEDO_FORMAT,
|
||||
MultiRenderTargetAttachments.NORMAL_FORMAT,
|
||||
MultiRenderTargetAttachments.PBR_FORMAT,
|
||||
MultiRenderTargetAttachments.EMISSIVE_FORMAT,
|
||||
MultiRenderTargetAttachments.TRANSLUCECNY_FORMAT,
|
||||
MultiRenderTargetAttachments.OPACITY_FORMAT,
|
||||
MultiRenderTargetAttachments.VIEW_POS_FORMAT
|
||||
};
|
||||
|
||||
try (MemoryStack stack = MemoryStack.stackPush()) {
|
||||
VkPipelineVertexInputStateCreateInfo vertexInputState = VkPipelineVertexInputStateCreateInfo.calloc(stack)
|
||||
.sType(VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO)
|
||||
.pVertexBindingDescriptions(null)
|
||||
.pVertexAttributeDescriptions(null);
|
||||
|
||||
var BuildInfo = new PipelineBuildInfo(ShaderModules, vertexInputState, colorFormats)
|
||||
.SetDepthFormat(MultiRenderTargetAttachments.DEPTH_FORMAT)
|
||||
.SetDepthWrite(true)
|
||||
.SetPushConstantRanges(new PushConstantsRange[]{
|
||||
new PushConstantsRange(VK_SHADER_STAGE_VERTEX_BIT, 0, VulkanUtils.MATRIX4X4_SIZE),
|
||||
new PushConstantsRange(VK_SHADER_STAGE_FRAGMENT_BIT, VulkanUtils.MATRIX4X4_SIZE, VulkanUtils.INT_SIZE)
|
||||
})
|
||||
.SetDescriptorSetLayouts(DescriptorSetLayouts)
|
||||
.SetBlendingMethod(0)
|
||||
.BlendingIsUsed(false)
|
||||
.SetDualPass(false)
|
||||
.SetAlphaToCoverage(true);
|
||||
|
||||
return new DefaultPipeline(VkCtx, BuildInfo);
|
||||
}
|
||||
}
|
||||
|
||||
private static Pipeline CreatePipeline(VulkanContext VkCtx, ShaderModule[] ShaderModules, DescriptorSetLayout[] DescriptorSetLayouts, boolean DepthWrite, boolean DualRender, boolean Blending, boolean AlphaToCoverage, int BlendingMethod){
|
||||
var vertexBufferStructure = new VertexBufferStructure();
|
||||
var BuildInfo = new PipelineBuildInfo(ShaderModules,vertexBufferStructure.getVertexInput(),new int[]{
|
||||
|
|
@ -356,18 +407,6 @@ public class DeferredSceneRender implements SceneRenderer {//dynamic rendering
|
|||
|
||||
VulkanUtils.CopyMatrixToBuffer(vulkanContext, BufferViewMatrices[CurrentFrame],engineInstance.scene().GetCamera().GetViewMatrix(), 0); // here
|
||||
|
||||
/* LongBuffer vBuffers = memAllocLong(1).put(0, terrainMesh.GetVertexBuffer());
|
||||
LongBuffer offsets = memAllocLong(1).put(0, 0L);
|
||||
|
||||
vkCmdBindVertexBuffers(commandBuffer.GetVulkanCommandBuffer(), 0, vBuffers, offsets);
|
||||
vkCmdBindIndexBuffer(commandBuffer.GetVulkanCommandBuffer(), terrainMesh.GetIndexBuffer(), 0, VK_INDEX_TYPE_UINT32);
|
||||
|
||||
// Draw the procedural geometry primitives
|
||||
vkCmdDrawIndexed(commandBuffer.GetVulkanCommandBuffer(), terrainMesh.GetIndexCount(), 1, 0, 0, 0);
|
||||
|
||||
memFree(vBuffers);
|
||||
memFree(offsets);
|
||||
*/
|
||||
vkCmdBindPipeline(CommandHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, DualPassRendering ? VkPipelineOpaque.GetVulkanPipeline() : VkPipeline.GetVulkanPipeline());
|
||||
|
||||
DescriptorAllocator descriptorAllocator = vulkanContext.GetDescriptorAllocator();
|
||||
|
|
@ -377,10 +416,20 @@ public class DeferredSceneRender implements SceneRenderer {//dynamic rendering
|
|||
.put(2,descriptorAllocator.GetDescriptorSet(DESCRIPTOR_ID_MAT).GetVkDescriptorSet())
|
||||
.put(3,descriptorAllocator.GetDescriptorSet(DESCRIPTOR_ID_TEXT).GetVkDescriptorSet());
|
||||
vkCmdBindDescriptorSets(CommandHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, DualPassRendering ? VkPipelineOpaque.GetVulkanPipelineLayout() : VkPipeline.GetVulkanPipelineLayout(),0,DescriptorSets,null);
|
||||
|
||||
RenderActors(engineInstance, CommandHandle, modelsCache, materialsCache, false);
|
||||
|
||||
VoxelWorldManager.RecordRender(CommandHandle, DualPassRendering ? VkPipelineOpaque : VkPipeline,materialsCache);
|
||||
vkCmdBindPipeline(CommandHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, VkVoxelPipeline.GetVulkanPipeline());
|
||||
|
||||
LongBuffer voxelDescriptorSets = MemStack.mallocLong(5)
|
||||
.put(0, descriptorAllocator.GetDescriptorSet(DESCRIPTOR_ID_PRJ).GetVkDescriptorSet())
|
||||
.put(1, descriptorAllocator.GetDescriptorSet(DESCRIPTOR_ID_VIEW, CurrentFrame).GetVkDescriptorSet())
|
||||
.put(2, descriptorAllocator.GetDescriptorSet(DESCRIPTOR_ID_MAT).GetVkDescriptorSet())
|
||||
.put(3, descriptorAllocator.GetDescriptorSet(DESCRIPTOR_ID_TEXT).GetVkDescriptorSet())
|
||||
.put(4, descriptorAllocator.GetDescriptorSet(VoxelWorldManager.Resources().faceGraphicsDescriptorId()).GetVkDescriptorSet());
|
||||
|
||||
vkCmdBindDescriptorSets(CommandHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, VkVoxelPipeline.GetVulkanPipelineLayout(), 0, voxelDescriptorSets, null);
|
||||
|
||||
VoxelWorldManager.RecordRender(CommandHandle, VkVoxelPipeline, materialsCache, false);
|
||||
|
||||
Matrix4f skyboxViewMatrix = new Matrix4f().identity();
|
||||
skyboxViewMatrix.set(engineInstance.scene().GetCamera().GetViewMatrix());
|
||||
|
|
@ -542,6 +591,7 @@ public class DeferredSceneRender implements SceneRenderer {//dynamic rendering
|
|||
public void cleanup(VulkanContext VkCtx){
|
||||
VkPipeline.CleanUp(VkCtx);
|
||||
// VkSkyboxPipeline.CleanUp(VkCtx);
|
||||
VkVoxelPipeline.CleanUp(VkCtx);
|
||||
VkPipelineOpaque.CleanUp(VkCtx);
|
||||
VkPipelineTranslucent.CleanUp(VkCtx);
|
||||
Arrays.asList(BufferViewMatrices).forEach(b -> b.cleanup(VkCtx));
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime;
|
|||
import net.halbear.Terrain4J.EngineCore.Main.Scene.Actor.Actor3D;
|
||||
import net.halbear.Terrain4J.EngineCore.Main.Scene.Actor.Actor3DElement;
|
||||
import net.halbear.Terrain4J.EngineCore.Main.Scene.IScene;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Computing.VoxelTerrainGeneration.SharedVoxelTerrainResources;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Computing.VoxelTerrainGeneration.VoxelWorldManager;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.RenderPasses.DeferredRendering.DeferredSceneRender;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DisplayToScreen.ImageView;
|
||||
|
|
@ -65,6 +66,9 @@ public class ForwardSceneRender implements SceneRenderer {//dynamic rendering
|
|||
public static String SkyBoxID = "SKYBOX_TEXTURE";
|
||||
private static final int PUSH_CONSTANTS_SIZE = VulkanUtils.MATRIX4X4_SIZE + VulkanUtils.INT_SIZE;
|
||||
private final VulkanBuffer BufferProjectionMatrix;
|
||||
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 Pipeline VkVoxelPipeline;
|
||||
private final DescriptorSetLayout descriptorLayoutFragStorage;
|
||||
private final DescriptorSetLayout descriptorLayoutTexture;
|
||||
private final DescriptorSetLayout descriptorLayoutVertexUniform;
|
||||
|
|
@ -169,6 +173,19 @@ public class ForwardSceneRender implements SceneRenderer {//dynamic rendering
|
|||
shaderModules = CreateShaderModules(vulkanContext,2);
|
||||
VkPipelineTranslucent = CreatePipeline(vulkanContext, shaderModules, layouts, false, true,true,EngineConfig.getInstance().AlphaToCoverage(),2);
|
||||
Arrays.asList(shaderModules).forEach(shaderModule -> shaderModule.CleanUp(vulkanContext));
|
||||
VoxelWorldManager.Init(vulkanContext);
|
||||
|
||||
DescriptorSetLayout[] voxelLayouts = new DescriptorSetLayout[]{
|
||||
descriptorLayoutVertexUniform,
|
||||
descriptorLayoutVertexUniform,
|
||||
descriptorLayoutFragStorage,
|
||||
descriptorLayoutTexture,
|
||||
VoxelWorldManager.Resources().faceGraphicsLayout()
|
||||
};
|
||||
|
||||
shaderModules = CreateShaderModules(vulkanContext, 3);
|
||||
VkVoxelPipeline = CreateVoxelPipeline(vulkanContext, shaderModules, voxelLayouts);
|
||||
Arrays.asList(shaderModules).forEach(shaderModule -> shaderModule.CleanUp(vulkanContext));
|
||||
|
||||
DescriptorSetLayout[] skyboxLayouts = new DescriptorSetLayout[]{
|
||||
descriptorLayoutVertexUniform,
|
||||
|
|
@ -198,6 +215,40 @@ public class ForwardSceneRender implements SceneRenderer {//dynamic rendering
|
|||
return new Attachment(VkCtx, SwapChainExtent.width(), SwapChainExtent.height(), COLOUR_FORMAT,VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
|
||||
}
|
||||
|
||||
private static Pipeline CreateVoxelPipeline(VulkanContext VkCtx, ShaderModule[] ShaderModules, DescriptorSetLayout[] DescriptorSetLayouts) {
|
||||
int[] colorFormats = new int[]{
|
||||
MultiRenderTargetAttachments.POSITION_FORMAT,
|
||||
MultiRenderTargetAttachments.ALBEDO_FORMAT,
|
||||
MultiRenderTargetAttachments.NORMAL_FORMAT,
|
||||
MultiRenderTargetAttachments.PBR_FORMAT,
|
||||
MultiRenderTargetAttachments.EMISSIVE_FORMAT,
|
||||
MultiRenderTargetAttachments.TRANSLUCECNY_FORMAT,
|
||||
MultiRenderTargetAttachments.OPACITY_FORMAT,
|
||||
MultiRenderTargetAttachments.VIEW_POS_FORMAT
|
||||
};
|
||||
|
||||
try (MemoryStack stack = MemoryStack.stackPush()) {
|
||||
VkPipelineVertexInputStateCreateInfo vertexInputState = VkPipelineVertexInputStateCreateInfo.calloc(stack)
|
||||
.sType(VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO)
|
||||
.pVertexBindingDescriptions(null)
|
||||
.pVertexAttributeDescriptions(null);
|
||||
|
||||
var BuildInfo = new PipelineBuildInfo(ShaderModules, vertexInputState, colorFormats)
|
||||
.SetDepthFormat(MultiRenderTargetAttachments.DEPTH_FORMAT)
|
||||
.SetDepthWrite(true)
|
||||
.SetPushConstantRanges(new PushConstantsRange[]{
|
||||
new PushConstantsRange(VK_SHADER_STAGE_VERTEX_BIT, 0, VulkanUtils.MATRIX4X4_SIZE),
|
||||
new PushConstantsRange(VK_SHADER_STAGE_FRAGMENT_BIT, VulkanUtils.MATRIX4X4_SIZE, VulkanUtils.INT_SIZE)
|
||||
})
|
||||
.SetDescriptorSetLayouts(DescriptorSetLayouts)
|
||||
.SetBlendingMethod(0)
|
||||
.BlendingIsUsed(false)
|
||||
.SetDualPass(false)
|
||||
.SetAlphaToCoverage(true);
|
||||
|
||||
return new DefaultPipeline(VkCtx, BuildInfo);
|
||||
}
|
||||
}
|
||||
|
||||
private static VkRenderingAttachmentInfo.Buffer CreateColourAttachmentInfo(Attachment attachment, VkClearValue ClearValue){
|
||||
return VkRenderingAttachmentInfo.calloc(1)
|
||||
|
|
@ -241,11 +292,11 @@ public class ForwardSceneRender implements SceneRenderer {//dynamic rendering
|
|||
|
||||
private static ShaderModule[] CreateShaderModules(VulkanContext VkCtx, int Translucent){
|
||||
if(EngineConfig.getInstance().RecompileShaders()){
|
||||
ShaderCompiler.CompileGLSLShaderOnChange(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);
|
||||
}
|
||||
return new ShaderModule[]{
|
||||
new ShaderModule(VkCtx, VK_SHADER_STAGE_VERTEX_BIT, 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)
|
||||
};
|
||||
|
||||
|
|
@ -364,7 +415,19 @@ public class ForwardSceneRender implements SceneRenderer {//dynamic rendering
|
|||
.put(3,descriptorAllocator.GetDescriptorSet(DESCRIPTOR_ID_TEXT).GetVkDescriptorSet());
|
||||
vkCmdBindDescriptorSets(CommandHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, DualPassRendering ? VkPipelineOpaque.GetVulkanPipelineLayout() : VkPipeline.GetVulkanPipelineLayout(),0,DescriptorSets,null);
|
||||
RenderActors(engineInstance, CommandHandle, modelsCache, materialsCache, false);
|
||||
VoxelWorldManager.RecordRender(CommandHandle, DualPassRendering ? VkPipelineOpaque : VkPipeline,materialsCache);
|
||||
vkCmdBindPipeline(CommandHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, VkVoxelPipeline.GetVulkanPipeline());
|
||||
|
||||
LongBuffer voxelDescriptorSets = MemStack.mallocLong(5)
|
||||
.put(0, descriptorAllocator.GetDescriptorSet(DESCRIPTOR_ID_PRJ).GetVkDescriptorSet())
|
||||
.put(1, descriptorAllocator.GetDescriptorSet(DESCRIPTOR_ID_VIEW, CurrentFrame).GetVkDescriptorSet())
|
||||
.put(2, descriptorAllocator.GetDescriptorSet(DESCRIPTOR_ID_MAT).GetVkDescriptorSet())
|
||||
.put(3, descriptorAllocator.GetDescriptorSet(DESCRIPTOR_ID_TEXT).GetVkDescriptorSet())
|
||||
.put(4, descriptorAllocator.GetDescriptorSet(VoxelWorldManager.Resources().faceGraphicsDescriptorId()).GetVkDescriptorSet());
|
||||
|
||||
vkCmdBindDescriptorSets(CommandHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, VkVoxelPipeline.GetVulkanPipelineLayout(), 0, voxelDescriptorSets, null);
|
||||
|
||||
VoxelWorldManager.RecordRender(CommandHandle, VkVoxelPipeline, materialsCache, false);
|
||||
|
||||
|
||||
Matrix4f skyboxViewMatrix = new Matrix4f().identity();
|
||||
skyboxViewMatrix.set(engineInstance.scene().GetCamera().GetViewMatrix());
|
||||
|
|
@ -530,6 +593,7 @@ public class ForwardSceneRender implements SceneRenderer {//dynamic rendering
|
|||
VkPipeline.CleanUp(VkCtx);
|
||||
VkPipelineTranslucent.CleanUp(VkCtx);
|
||||
VkPipelineOpaque.CleanUp(VkCtx);
|
||||
VkVoxelPipeline.CleanUp(VkCtx);
|
||||
Arrays.asList(BufferViewMatrices).forEach(buffer -> buffer.cleanup(VkCtx));
|
||||
RenderInfo.free();
|
||||
AttachmentInfoColour.free();
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ public class AmbientOcclusionRenderer {
|
|||
VulkanUtils.VEC4_SIZE + // screenSize.xy, radius, bias
|
||||
VulkanUtils.VEC4_SIZE; // kernelSize + padding
|
||||
private static final int SSAO_KERNEL_SIZE = 64;
|
||||
private static final float SSAO_RADIUS = 0.75f;
|
||||
private static final float SSAO_RADIUS = 0.35f;
|
||||
private static final float SSAO_BIAS = 0.025f;
|
||||
private static final long SSAO_KERNEL_BUFFER_SIZE = SSAO_KERNEL_SIZE * 4L * VulkanUtils.FLOAT_SIZE;
|
||||
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.I
|
|||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.Pipeline;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.PipelineBuildInfo;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.PushConstantsRange;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.RenderPasses.DeferredRendering.MultiRenderTargetAttachments;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Shader.*;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.VertexBufferStructure;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.VkModel.*;
|
||||
|
|
@ -80,7 +81,8 @@ public class ShadowRenderer {
|
|||
private static final String SHADOW_GEOMETRY_SHADER_FILE_SPV = SHADOW_GEOMETRY_SHADER_FILE_GLSL + ".spv";
|
||||
private static final String VERTEX_SHADER_FILE_GLSL = "resources/EngineResources/shaders/shadow_vertex.glsl";
|
||||
private static final String VERTEX_SHADER_FILE_SPV = VERTEX_SHADER_FILE_GLSL + ".spv";
|
||||
|
||||
private static final String PACKED_VERTEX_SHADER_FILE_GLSL = "resources/EngineResources/shaders/shadow_vertex_packed.glsl";
|
||||
private static final String PACKED_VERTEX_SHADER_FILE_SPV = PACKED_VERTEX_SHADER_FILE_GLSL + ".spv";
|
||||
private final CascadeShadows[] cascadeShadows;
|
||||
private final VkClearValue ClearValueColour;
|
||||
private final VkClearValue ClearValueDepth;
|
||||
|
|
@ -90,6 +92,7 @@ public class ShadowRenderer {
|
|||
private VkRenderingAttachmentInfo depthAttachmentInfo;
|
||||
private final DescriptorSetLayout descLayoutFrgStorage;
|
||||
private Pipeline pipeline;
|
||||
private Pipeline pipelinePacked;
|
||||
private final VulkanBuffer[] prjBuffers;
|
||||
private final ByteBuffer pushConstBuff;
|
||||
private VkRenderingInfo renderingInfo;
|
||||
|
|
@ -180,6 +183,14 @@ public class ShadowRenderer {
|
|||
pipeline = createPipeline(VulkanContext, shaderModules, new DescriptorSetLayout[]{uniformGeomDescriptorSetLayout, textDescriptorSetLayout,
|
||||
descLayoutFrgStorage});
|
||||
Arrays.asList(shaderModules).forEach(s -> s.CleanUp(VulkanContext));
|
||||
shaderModules = createPackedVertexShaderModules(VulkanContext);
|
||||
pipelinePacked = CreateVoxelPipeline(VulkanContext, shaderModules, new DescriptorSetLayout[]{
|
||||
uniformGeomDescriptorSetLayout,
|
||||
textDescriptorSetLayout,
|
||||
descLayoutFrgStorage,
|
||||
VoxelWorldManager.Resources().faceGraphicsLayout()
|
||||
});
|
||||
Arrays.asList(shaderModules).forEach(s -> s.CleanUp(VulkanContext));
|
||||
|
||||
cascadeShadows = new CascadeShadows[VulkanUtils.MAX_IN_FLIGHT];
|
||||
for (int i = 0; i < VulkanUtils.MAX_IN_FLIGHT; i++) {
|
||||
|
|
@ -238,6 +249,32 @@ public class ShadowRenderer {
|
|||
return pipeline;
|
||||
}
|
||||
|
||||
private static Pipeline CreateVoxelPipeline(VulkanContext VkCtx, ShaderModule[] ShaderModules, DescriptorSetLayout[] DescriptorSetLayouts) {
|
||||
int[] colorFormats = new int[]{
|
||||
ATTACHMENT_FORMATT
|
||||
};
|
||||
|
||||
try (MemoryStack stack = MemoryStack.stackPush()) {
|
||||
VkPipelineVertexInputStateCreateInfo vertexInputState = VkPipelineVertexInputStateCreateInfo.calloc(stack)
|
||||
.sType(VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO)
|
||||
.pVertexBindingDescriptions(null)
|
||||
.pVertexAttributeDescriptions(null);
|
||||
|
||||
var BuildInfo = new PipelineBuildInfo(ShaderModules, vertexInputState, colorFormats)
|
||||
.SetDepthFormat(DEPTH_FORMAT)
|
||||
.SetPushConstantRanges(
|
||||
new PushConstantsRange[]{
|
||||
new PushConstantsRange(VK_SHADER_STAGE_VERTEX_BIT, 0, PUSH_CONSTANTS_SIZE)
|
||||
})
|
||||
.SetDescriptorSetLayouts(DescriptorSetLayouts)
|
||||
.SetDepthClamp(VkCtx.GetDevice().getDepthClamp())
|
||||
.CullMode(VK_CULL_MODE_FRONT_BIT)
|
||||
.DepthBuffer(VK_COMPARE_OP_LESS_OR_EQUAL);
|
||||
|
||||
return new DefaultPipeline(VkCtx, BuildInfo);
|
||||
}
|
||||
}
|
||||
|
||||
private static VkRenderingInfo createRenderInfo(VkRenderingAttachmentInfo.Buffer colorAttachmentInfo,
|
||||
VkRenderingAttachmentInfo depthAttachments) {
|
||||
var result = VkRenderingInfo.calloc().sType$Default();
|
||||
|
|
@ -254,7 +291,18 @@ public class ShadowRenderer {
|
|||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static ShaderModule[] createPackedVertexShaderModules(VulkanContext VulkanContext) {
|
||||
if (EngineConfig.getInstance().RecompileShaders()) {
|
||||
ShaderCompiler.CompileGLSLShaderOnChange(PACKED_VERTEX_SHADER_FILE_GLSL, Shaderc.shaderc_glsl_vertex_shader);
|
||||
ShaderCompiler.CompileGLSLShaderOnChange(SHADOW_GEOMETRY_SHADER_FILE_GLSL, Shaderc.shaderc_glsl_geometry_shader);
|
||||
ShaderCompiler.CompileGLSLShaderOnChange(FRAGMENT_SHADER_FILE_GLSL, Shaderc.shaderc_glsl_fragment_shader);
|
||||
}
|
||||
return new ShaderModule[]{
|
||||
new ShaderModule(VulkanContext, VK_SHADER_STAGE_VERTEX_BIT, PACKED_VERTEX_SHADER_FILE_SPV, null),
|
||||
new ShaderModule(VulkanContext, VK_SHADER_STAGE_GEOMETRY_BIT, SHADOW_GEOMETRY_SHADER_FILE_SPV, null),
|
||||
new ShaderModule(VulkanContext, VK_SHADER_STAGE_FRAGMENT_BIT, FRAGMENT_SHADER_FILE_SPV, null),
|
||||
};
|
||||
}
|
||||
private static ShaderModule[] createShaderModules(VulkanContext VulkanContext) {
|
||||
if (EngineConfig.getInstance().RecompileShaders()) {
|
||||
ShaderCompiler.CompileGLSLShaderOnChange(VERTEX_SHADER_FILE_GLSL, Shaderc.shaderc_glsl_vertex_shader);
|
||||
|
|
@ -271,6 +319,7 @@ public class ShadowRenderer {
|
|||
public void cleanup(VulkanContext VulkanContext) {
|
||||
AllowShadowRendering(false);
|
||||
pipeline.CleanUp(VulkanContext);
|
||||
pipelinePacked.CleanUp(VulkanContext);
|
||||
uniformGeomDescriptorSetLayout.CleanUp(VulkanContext);
|
||||
descLayoutFrgStorage.CleanUp(VulkanContext);
|
||||
textDescriptorSetLayout.CleanUp(VulkanContext);
|
||||
|
|
@ -394,7 +443,15 @@ public class ShadowRenderer {
|
|||
vkCmdDrawIndexed(cmdHandle, vulkanMesh.IndicesCount(), 1, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
VoxelWorldManager.RecordRender(cmdHandle,pipeline,materialsCache);
|
||||
|
||||
descriptorSets = stack.mallocLong(4)
|
||||
.put(0, descAllocator.GetDescriptorSet(DESCRIPTOR_ID_PRJ, currentFrame).GetVkDescriptorSet())
|
||||
.put(1, descAllocator.GetDescriptorSet(DESCRIPTOR_ID_TEXT).GetVkDescriptorSet())
|
||||
.put(2, descAllocator.GetDescriptorSet(DESCRIPTOR_ID_MAT).GetVkDescriptorSet())
|
||||
.put(3, descAllocator.GetDescriptorSet(VoxelWorldManager.Resources().faceGraphicsDescriptorId()).GetVkDescriptorSet());
|
||||
vkCmdBindPipeline(cmdHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelinePacked.GetVulkanPipeline());
|
||||
vkCmdBindDescriptorSets(cmdHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelinePacked.GetVulkanPipelineLayout(),0,descriptorSets,null);
|
||||
VoxelWorldManager.RecordRender(cmdHandle,pipelinePacked,materialsCache,true);
|
||||
vkCmdEndRendering(cmdHandle);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue