SSAO, performance sucks and it flickers so tweaking is needed, also more material support
This commit is contained in:
parent
5b231d6920
commit
577836a03f
39 changed files with 889 additions and 74 deletions
|
|
@ -12,6 +12,7 @@ import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.DeferredRe
|
|||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.Images.Attachment;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.Images.TextureCache;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.PostProcessing.PostProcess;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.ScreenSpace.AmbientOcclusionRenderer;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Shadows.ShadowRenderer;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.VkModel.*;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.SpriteRendering.SpriteRenderer;
|
||||
|
|
@ -51,6 +52,7 @@ public class VulkanRenderer implements Renderer {
|
|||
private final Queue.PresentQueue PresentQueue;
|
||||
private final Semaphore[] RenderCompleteSemaphores;
|
||||
private final SceneRenderer sceneRender;
|
||||
private final AmbientOcclusionRenderer ssaoRenderer;
|
||||
private final SpriteRenderer spriteRenderer;
|
||||
private final LightRenderer lightRenderer;
|
||||
private final PostProcess PostProcessor;
|
||||
|
|
@ -110,13 +112,16 @@ public class VulkanRenderer implements Renderer {
|
|||
if(Deferred) {
|
||||
sceneRender = new DeferredSceneRender(RendererContext, engineInstance);
|
||||
shadowRender = new ShadowRenderer(RendererContext);
|
||||
ssaoRenderer = new AmbientOcclusionRenderer(RendererContext,sceneRender.GetMRTAttachments().GetColourAttachments(), GraphicsQueue);
|
||||
List<Attachment> attachments = new ArrayList<>(sceneRender.GetMRTAttachments().GetColourAttachments());
|
||||
attachments.add(ssaoRenderer.getSSAOBlurAttachment());
|
||||
attachments.add(shadowRender.getShadowAttachment());
|
||||
lightRenderer = new LightRenderer(RendererContext, attachments);
|
||||
PostProcessor = new PostProcess(RendererContext, lightRenderer.getAttachment());
|
||||
|
||||
} else{
|
||||
sceneRender = new ForwardSceneRender(RendererContext);
|
||||
ssaoRenderer = null;
|
||||
PostProcessor = new PostProcess(RendererContext, sceneRender.GetAttachmentColour());
|
||||
lightRenderer = null;
|
||||
shadowRender = null;
|
||||
|
|
@ -189,6 +194,7 @@ public class VulkanRenderer implements Renderer {
|
|||
RendererContext.GetDevice().waitIdle();
|
||||
Logger.debug("Waiting Vulkan Context");
|
||||
sceneRender.cleanup(RendererContext);
|
||||
if(ssaoRenderer != null)ssaoRenderer.cleanup(RendererContext);
|
||||
if(shadowRender != null)shadowRender.cleanup(RendererContext);
|
||||
if(lightRenderer != null)lightRenderer.cleanup(RendererContext);
|
||||
PostProcessor.CleanUp(RendererContext);
|
||||
|
|
@ -231,16 +237,15 @@ public class VulkanRenderer implements Renderer {
|
|||
|
||||
sceneRender.Render(engineInstance,RendererContext,CommandBuffer, modelsCache,materialsCache,CurrentFrame);
|
||||
boolean RenderShadows = ShadowRenderer.AllowShadowRendering() && EngineConfig.getInstance().RenderShadows();
|
||||
//lightRenderer.render(engineInstance, RendererContext, CommandBuffer, sceneRender.GetMRTAttachments(), shadowRender.getShadowAttachment(), CurrentFrame, shadowRender.getCascadeShadows(CurrentFrame));
|
||||
if(RenderShadows) {shadowRender.render(engineInstance, RendererContext, CommandBuffer, modelsCache, materialsCache, CurrentFrame); }
|
||||
ssaoRenderer.Render(RendererContext,engineInstance, CommandBuffer, sceneRender.GetMRTAttachments(), CurrentFrame);
|
||||
if(RenderShadows) {
|
||||
shadowRender.render(engineInstance, RendererContext, CommandBuffer, modelsCache, materialsCache, CurrentFrame);
|
||||
lightRenderer.render(engineInstance, RendererContext, CommandBuffer, sceneRender.GetMRTAttachments(), shadowRender.getShadowAttachment(), CurrentFrame, shadowRender.getCascadeShadows(CurrentFrame));
|
||||
} else lightRenderer.render(engineInstance, RendererContext, CommandBuffer, sceneRender.GetMRTAttachments(),CurrentFrame);
|
||||
lightRenderer.render(engineInstance, RendererContext, CommandBuffer, sceneRender.GetMRTAttachments(),
|
||||
shadowRender.getShadowAttachment(), ssaoRenderer.getSSAOBlurAttachment(), CurrentFrame, shadowRender.getCascadeShadows(CurrentFrame));
|
||||
} else lightRenderer.render(engineInstance, RendererContext, CommandBuffer, sceneRender.GetMRTAttachments(),ssaoRenderer.getSSAOBlurAttachment(),CurrentFrame);
|
||||
PostProcessor.Render(RendererContext,CommandBuffer,lightRenderer.getAttachment());
|
||||
spriteRenderer.Render(engineInstance,RendererContext,CommandBuffer,PostProcessor.GetAttachment(),modelsCache,CurrentFrame);
|
||||
GuiRender.Render(RendererContext,CommandBuffer,CurrentFrame,PostProcessor.GetAttachment());
|
||||
|
||||
|
||||
swapChainRender.Render(RendererContext,CommandBuffer,PostProcessor.GetAttachment(),ImageIndex);
|
||||
|
||||
RecordingStop(CommandBuffer);
|
||||
|
|
@ -302,6 +307,7 @@ public class VulkanRenderer implements Renderer {
|
|||
shadowRender.RebuildPipelineAndRenderingAttachments(RendererContext);
|
||||
|
||||
List<Attachment> attachments = new ArrayList<>(sceneRender.GetMRTAttachments().GetColourAttachments());
|
||||
attachments.add(ssaoRenderer.getSSAOBlurAttachment());
|
||||
attachments.add(shadowRender.getShadowAttachment());
|
||||
lightRenderer.updateAttachmentDescriptors(RendererContext, attachments);
|
||||
|
||||
|
|
@ -332,6 +338,11 @@ public class VulkanRenderer implements Renderer {
|
|||
sceneRender.Resize(engineInstance,RendererContext);
|
||||
if(Deferred) {
|
||||
List<Attachment> attachments = new ArrayList<>(sceneRender.GetMRTAttachments().GetColourAttachments());
|
||||
List<Attachment> ssaoAttachments = new ArrayList<>();
|
||||
ssaoAttachments.add(attachments.get(0));
|
||||
ssaoAttachments.add(attachments.get(2));
|
||||
ssaoRenderer.resize(RendererContext, ssaoAttachments);
|
||||
attachments.add(ssaoRenderer.getSSAOBlurAttachment());
|
||||
attachments.add(shadowRender.getShadowAttachment());
|
||||
lightRenderer.resize(RendererContext, attachments);
|
||||
PostProcessor.Resize(RendererContext, lightRenderer.getAttachment());
|
||||
|
|
|
|||
|
|
@ -122,6 +122,7 @@ public class ModelCompiler {
|
|||
String NormalTexture = ProcessTexture(aiScene,aiMaterial,BaseDirectory,aiTextureType_NORMALS);
|
||||
String EmissiveTexture = ProcessTexture(aiScene,aiMaterial,BaseDirectory,aiTextureType_EMISSIVE);
|
||||
String TranslucencyTexture = ProcessTexture(aiScene,aiMaterial,BaseDirectory,aiTextureType_TRANSMISSION);
|
||||
String SpecularTexture = ProcessTexture(aiScene,aiMaterial,BaseDirectory,aiTextureType_SPECULAR);
|
||||
String MetallicRoughTexture = ProcessTexture(aiScene, aiMaterial, BaseDirectory, AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLICROUGHNESS_TEXTURE);
|
||||
String OpacityTexture = ProcessTexture(aiScene,aiMaterial,BaseDirectory,aiTextureType_OPACITY);
|
||||
|
||||
|
|
@ -132,6 +133,18 @@ public class ModelCompiler {
|
|||
MetallicArray = new float[]{0.0f};
|
||||
}
|
||||
|
||||
float[] SpecularArray = new float[]{0.0f};
|
||||
Result = aiGetMaterialFloatArray(aiMaterial,AI_MATKEY_SPECULAR_FACTOR,aiTextureType_NONE,0,SpecularArray,MaxPointer);
|
||||
if(Result != aiReturn_SUCCESS){
|
||||
SpecularArray = new float[]{0.0f};
|
||||
}
|
||||
|
||||
if(MetallicArray[0] == 0.0f && SpecularArray[0] != 0.0f)
|
||||
MetallicArray[0] = SpecularArray[0];
|
||||
if(MetallicRoughTexture.isEmpty()){
|
||||
MetallicRoughTexture = SpecularTexture;
|
||||
}
|
||||
|
||||
float[] RoughnessArray = new float[]{0.0f};
|
||||
Result = aiGetMaterialFloatArray(aiMaterial,AI_MATKEY_ROUGHNESS_FACTOR,aiTextureType_NONE,0,RoughnessArray,MaxPointer);
|
||||
if(Result != aiReturn_SUCCESS){
|
||||
|
|
@ -151,13 +164,32 @@ public class ModelCompiler {
|
|||
}
|
||||
|
||||
float[] OpacityArray = new float[]{0.0f};
|
||||
|
||||
Result = aiGetMaterialFloatArray(aiMaterial,AI_MATKEY_OPACITY,aiTextureType_NONE,0,OpacityArray,MaxPointer);
|
||||
if(Result != aiReturn_SUCCESS){
|
||||
OpacityArray = new float[]{0.0f};
|
||||
}
|
||||
|
||||
return new MaterialData(ModelName + "-mat-" + Position,DiffuseTexture,NormalTexture, MetallicRoughTexture,diffuse,RoughnessArray[0],MetallicArray[0], EmissiveTexture,emissiveColour, TranslucencyTexture, TranslucencyArray[0], OpacityTexture, OpacityArray[0]);
|
||||
float[] RefractionArray = new float[]{0.0f};
|
||||
Result = aiGetMaterialFloatArray(aiMaterial,AI_MATKEY_REFRACTI,aiTextureType_NONE,0,RefractionArray,MaxPointer);
|
||||
if(Result != aiReturn_SUCCESS){
|
||||
RefractionArray = new float[]{0.0f};
|
||||
}
|
||||
|
||||
float[] ReflectionArray = new float[]{0.0f};
|
||||
Result = aiGetMaterialFloatArray(aiMaterial,AI_MATKEY_REFLECTIVITY,aiTextureType_NONE,0,ReflectionArray,MaxPointer);
|
||||
if(Result != aiReturn_SUCCESS){
|
||||
ReflectionArray = new float[]{0.0f};
|
||||
}
|
||||
|
||||
AIColor4D colour_transparency = AIColor4D.create();
|
||||
Vector4f ColorTransparency = new Vector4f();
|
||||
|
||||
Result = aiGetMaterialColor(aiMaterial,AI_MATKEY_COLOR_TRANSPARENT,aiTextureType_NONE,0,colour_transparency);
|
||||
if(Result != aiReturn_SUCCESS){
|
||||
ColorTransparency.set(colour_transparency.r(),colour_transparency.g(),colour_transparency.b(),colour_transparency.a());
|
||||
}
|
||||
|
||||
return new MaterialData(ModelName + "-mat-" + Position,DiffuseTexture,NormalTexture, MetallicRoughTexture,diffuse,RoughnessArray[0],MetallicArray[0], EmissiveTexture,emissiveColour, TranslucencyTexture, TranslucencyArray[0], OpacityTexture, OpacityArray[0],ColorTransparency,RefractionArray[0], ReflectionArray[0]);
|
||||
}
|
||||
|
||||
public static MeshData ProcessMesh(AIMesh aiMesh, List<MaterialData> MaterialList, int MeshPosition, ModelBinaryData BinaryData) throws IOException {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,52 @@
|
|||
package net.halbear.Terrain4J.EngineCore.RenderingAPI.Universal.SSAO;
|
||||
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Util.VulkanUtils;
|
||||
import org.joml.Vector4f;
|
||||
import org.lwjgl.BufferUtils;
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.util.Random;
|
||||
|
||||
public class SSAO_Utils {
|
||||
|
||||
public static FloatBuffer GenerateSampleKernel(int size, long MappedMemory) {
|
||||
FloatBuffer kernel = MemoryUtil.memFloatBuffer(MappedMemory,size * 4); // vec4 alignment
|
||||
Random rnd = new Random();
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
|
||||
Vector4f sample = new Vector4f(rnd.nextFloat() * 2.0f - 1.0f,rnd.nextFloat() * 2.0f - 1.0f,rnd.nextFloat(),0);
|
||||
sample = sample.normalize();
|
||||
|
||||
float scale = (float) i / (float) size;
|
||||
scale = Lerp(0.1f, 1.0f, scale * scale);
|
||||
sample.mul(scale);
|
||||
kernel.put(sample.x);
|
||||
kernel.put(sample.y);
|
||||
kernel.put(sample.z);
|
||||
kernel.put(0.0f);
|
||||
}
|
||||
return kernel;
|
||||
}
|
||||
|
||||
public static ByteBuffer GenerateNoiseTexture() {
|
||||
ByteBuffer buffer = BufferUtils.createByteBuffer(16 * 4 * Float.BYTES);
|
||||
Random rnd = new Random();
|
||||
for (int i = 0; i < 16; i++) {
|
||||
float x = rnd.nextFloat() * 2.0f - 1.0f;
|
||||
float y = rnd.nextFloat() * 2.0f - 1.0f;
|
||||
buffer.putFloat(x);
|
||||
buffer.putFloat(y);
|
||||
buffer.putFloat(0.0f);
|
||||
buffer.putFloat(0.0f);
|
||||
}
|
||||
buffer.flip();
|
||||
return buffer;
|
||||
}
|
||||
|
||||
private static float Lerp(float a, float b, float f) {
|
||||
return a + f * (b - a);
|
||||
}
|
||||
}
|
||||
|
|
@ -50,7 +50,7 @@ public class LightRenderer {
|
|||
private static final String FRAGMENT_SHADER_FILE_SPV = FRAGMENT_SHADER_FILE_GLSL + ".spv";
|
||||
private static final String NO_SHADOWS_FRAGMENT_SHADER_FILE_GLSL = "resources/EngineResources/shaders/lighting_frag.glsl";
|
||||
private static final String NO_SHADOWS_FRAGMENT_SHADER_FILE_SPV = NO_SHADOWS_FRAGMENT_SHADER_FILE_GLSL + ".spv";
|
||||
private static final String VERTEX_SHADER_FILE_GLSL = "resources/EngineResources/shaders/lighting_vertex.glsl";
|
||||
private static final String VERTEX_SHADER_FILE_GLSL = "resources/EngineResources/shaders/basic_screen_vertex.glsl";
|
||||
private static final String VERTEX_SHADER_FILE_SPV = VERTEX_SHADER_FILE_GLSL + ".spv";
|
||||
|
||||
private final DescriptorSetLayout AttachmentDescriptorSetLayout;
|
||||
|
|
@ -69,6 +69,8 @@ public class LightRenderer {
|
|||
private final DescriptorSetLayout StorageDescriptorSetLayout;
|
||||
private final VulkanBuffer[] shadowMatrices;
|
||||
|
||||
private int MinimumAttachments = 9; // shadow + ssaoBlur
|
||||
|
||||
public LightRenderer(VulkanContext VkCtx, List<Attachment> attachments){
|
||||
ClearValueColour = VkClearValue.calloc().color(
|
||||
c -> c.float32(0, 0.0f).float32(1, 0.0f).float32(2, 0.0f).float32(3, 0.0f));
|
||||
|
|
@ -84,8 +86,9 @@ public class LightRenderer {
|
|||
VK_BORDER_COLOR_INT_OPAQUE_BLACK, 1, true);
|
||||
textureSampler = new TextureSampler(VkCtx, textureSamplerInfo);
|
||||
int numAttachments = attachments.size();
|
||||
DescriptorSetLayout.LayoutInformation[] descSetLayouts = new DescriptorSetLayout.LayoutInformation[numAttachments + 1];
|
||||
for (int i = 0; i < numAttachments + 1; i++) {
|
||||
if(numAttachments < MinimumAttachments) numAttachments = MinimumAttachments;
|
||||
DescriptorSetLayout.LayoutInformation[] descSetLayouts = new DescriptorSetLayout.LayoutInformation[numAttachments];
|
||||
for (int i = 0; i < numAttachments; i++) {
|
||||
descSetLayouts[i] = new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, i, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
}
|
||||
AttachmentDescriptorSetLayout = new DescriptorSetLayout(VkCtx, descSetLayouts);
|
||||
|
|
@ -209,7 +212,7 @@ public class LightRenderer {
|
|||
}
|
||||
|
||||
|
||||
public void render(EngineInstance engineInstance, VulkanContext VkCtx, CommandBuffer cmdBuffer, MultiRenderTargetAttachments mrtAttachments,Attachment shadowAttachment, int CurrentFrame, CascadeShadows cascadeShadows) {
|
||||
public void render(EngineInstance engineInstance, VulkanContext VkCtx, CommandBuffer cmdBuffer, MultiRenderTargetAttachments mrtAttachments,Attachment shadowAttachment, Attachment ssaoBlurAttachment, int CurrentFrame, CascadeShadows cascadeShadows) {
|
||||
try (var stack = MemoryStack.stackPush()) {
|
||||
VkCommandBuffer cmdHandle = cmdBuffer.GetVulkanCommandBuffer();
|
||||
|
||||
|
|
@ -219,16 +222,6 @@ public class LightRenderer {
|
|||
VK_ACCESS_2_NONE, VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
|
||||
List<Attachment> attachments = mrtAttachments.GetColourAttachments();
|
||||
int numAttachments = attachments.size();
|
||||
for (int i = 0; i < numAttachments; i++) {
|
||||
Attachment attachment = attachments.get(i);
|
||||
VulkanUtils.ImageBarrier(stack, cmdHandle, attachment.GetVkImage().getVulkanImage(),
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||
VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT,
|
||||
VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_2_SHADER_READ_BIT,
|
||||
VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
}
|
||||
VulkanUtils.ImageBarrier(stack, cmdHandle, mrtAttachments.GetDepthAttachment().GetVkImage().getVulkanImage(),
|
||||
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||
VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT,
|
||||
|
|
@ -285,7 +278,7 @@ public class LightRenderer {
|
|||
}
|
||||
}
|
||||
|
||||
public void render(EngineInstance engineInstance, VulkanContext VkCtx, CommandBuffer cmdBuffer, MultiRenderTargetAttachments mrtAttachments, int CurrentFrame) {
|
||||
public void render(EngineInstance engineInstance, VulkanContext VkCtx, CommandBuffer cmdBuffer, MultiRenderTargetAttachments mrtAttachments, Attachment SSAOattachment, int CurrentFrame) {
|
||||
try (var stack = MemoryStack.stackPush()) {
|
||||
VkCommandBuffer cmdHandle = cmdBuffer.GetVulkanCommandBuffer();
|
||||
|
||||
|
|
@ -295,16 +288,6 @@ public class LightRenderer {
|
|||
VK_ACCESS_2_NONE, VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
|
||||
List<Attachment> attachments = mrtAttachments.GetColourAttachments();
|
||||
int numAttachments = attachments.size();
|
||||
for (int i = 0; i < numAttachments; i++) {
|
||||
Attachment attachment = attachments.get(i);
|
||||
VulkanUtils.ImageBarrier(stack, cmdHandle, attachment.GetVkImage().getVulkanImage(),
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||
VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT,
|
||||
VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_2_SHADER_READ_BIT,
|
||||
VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
}
|
||||
VulkanUtils.ImageBarrier(stack, cmdHandle, mrtAttachments.GetDepthAttachment().GetVkImage().getVulkanImage(),
|
||||
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||
VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT,
|
||||
|
|
@ -422,7 +405,7 @@ public class LightRenderer {
|
|||
|
||||
DescriptorSet noShadowDescSet = VkCtx.GetDescriptorAllocator().GetDescriptorSet(DESC_ID_NOSHADOW_ATT);
|
||||
var noShadowImageViews = new ArrayList<ImageView>();
|
||||
for (int i = 0; i < attachments.size() - 1; i++) {
|
||||
for (int i = 0; i < attachments.size(); i++) {
|
||||
noShadowImageViews.add(attachments.get(i).GetVkImageView());
|
||||
}
|
||||
noShadowDescSet.SetImages(VkCtx.GetDevice(), noShadowImageViews, textureSampler, 0);
|
||||
|
|
@ -444,7 +427,7 @@ public class LightRenderer {
|
|||
|
||||
DescriptorSet noShadowDescSet = VkCtx.GetDescriptorAllocator().GetDescriptorSet(DESC_ID_NOSHADOW_ATT);
|
||||
var noShadowImageViews = new ArrayList<ImageView>();
|
||||
for (int i = 0; i < attachments.size() - 1; i++) {
|
||||
for (int i = 0; i < attachments.size(); i++) {
|
||||
noShadowImageViews.add(attachments.get(i).GetVkImageView());
|
||||
}
|
||||
noShadowDescSet.SetImages(VkCtx.GetDevice(), noShadowImageViews, textureSampler, 0);
|
||||
|
|
|
|||
|
|
@ -18,7 +18,9 @@ public class MultiRenderTargetAttachments {
|
|||
public static final int EMISSIVE_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT;
|
||||
public static final int TRANSLUCECNY_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT;
|
||||
public static final int OPACITY_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT;
|
||||
public static final int POSITION_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT;
|
||||
public static final int POSITION_FORMAT = VK_FORMAT_R32G32B32A32_SFLOAT;
|
||||
public static final int SSAO_RAW_ATTACHMENT = VK_FORMAT_R8_UNORM;
|
||||
public static final int SSAO_BLUR_ATTACHMENT = VK_FORMAT_R8_UNORM;
|
||||
private final List<Attachment> ColourAttachments;
|
||||
private final Attachment DepthAttachment;
|
||||
private final int Height;
|
||||
|
|
|
|||
|
|
@ -3,12 +3,20 @@ package net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.
|
|||
import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig;
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.Rendering.VulkanContext;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DisplayToScreen.ImageView;
|
||||
import org.w3c.dom.Text;
|
||||
|
||||
import static org.lwjgl.vulkan.VK13.*;
|
||||
public class Attachment {
|
||||
private final Image VkImage;
|
||||
private final ImageView VkImageView;
|
||||
private boolean DepthAttachment;
|
||||
|
||||
public Attachment(VulkanContext VkCtx, Texture ExistingImage){
|
||||
VkImageView = ExistingImage.GetImageView();
|
||||
VkImage = ExistingImage.GetImage();
|
||||
DepthAttachment = VkImageView.IsDepthImage();
|
||||
}
|
||||
|
||||
public Attachment(VulkanContext VkCtx, int Width, int Height, int Format, int Usage, boolean MultiSamples){
|
||||
var ImageData = new Image.ImageData().Width(Width).Height(Height).Format(Format).SampleCount(EngineConfig.getInstance().GetRenderSampleCount());
|
||||
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ public class Texture implements ITexture {
|
|||
.AspectMask(VK_IMAGE_ASPECT_COLOR_BIT).MipLevels(MipMapLevels);
|
||||
imageView = new ImageView(VkCtx.GetDevice(), image.getVulkanImage(), ImageViewData, false);
|
||||
}
|
||||
public Image GetImage(){return image;}
|
||||
public boolean HasTransparency(){return Transparent;}
|
||||
public void SetTransparency(ByteBuffer data){
|
||||
int PixelCount = data.capacity()/4;
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ import java.util.UUID;
|
|||
import static org.lwjgl.vulkan.VK10.VK_FORMAT_R8G8B8A8_SRGB;
|
||||
|
||||
public class TextureCache implements ITextureCache {
|
||||
public static final int MAX_TEXTURES = 256;
|
||||
public static final int MAX_TEXTURES = 512;
|
||||
private final IndexedLinkedHashMap<String, ITexture> TextureMap;
|
||||
private final IndexedLinkedHashMap<String, ITexture> CubemapTextures;
|
||||
private final List<String> ActualTextures;
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ public class PostProcess {
|
|||
private static final String MULTI_PASS_FRAGMENT_SHADER_FILE_SPV = MULTI_PASS_FRAGMENT_SHADER_FILE_GLSL + ".spv";
|
||||
private static final String SINGLE_PASS_FRAGMENT_SHADER_FILE_GLSL = "resources/EngineResources/shaders/post_process_frag.glsl";
|
||||
private static final String SINGLE_PASS_FRAGMENT_SHADER_FILE_SPV = SINGLE_PASS_FRAGMENT_SHADER_FILE_GLSL + ".spv";
|
||||
private static final String VERTEX_SHADER_FILE_GLSL = "resources/EngineResources/shaders/post_process_vtx.glsl";
|
||||
private static final String VERTEX_SHADER_FILE_GLSL = "resources/EngineResources/shaders/basic_screen_vertex.glsl";
|
||||
private static final String VERTEX_SHADER_FILE_SPV = VERTEX_SHADER_FILE_GLSL + ".spv";
|
||||
|
||||
private final DescriptorSetLayout AttachmentDescriptorSetLayout;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,442 @@
|
|||
package net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.ScreenSpace;
|
||||
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig;
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance;
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.Rendering.VulkanContext;
|
||||
import net.halbear.Terrain4J.EngineCore.Main.Scene.IScene;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Universal.SSAO.SSAO_Utils;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.DeferredRendering.MultiRenderTargetAttachments;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.EmptyVertexBufferStruct;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.DefaultPipeline;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.Images.Attachment;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.Images.Image;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.Images.ImageSrc;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.Images.Texture;
|
||||
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.Shader.*;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DeviceLayers.CommandBuffer;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DeviceLayers.CommandPool;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DeviceLayers.Queues.Queue;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DisplayToScreen.ImageView;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.SwapChain.SwapChain;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Util.VulkanBuffer;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Util.VulkanUtils;
|
||||
import org.lwjgl.system.MemoryStack;
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
import org.lwjgl.util.shaderc.Shaderc;
|
||||
import org.lwjgl.vulkan.*;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.nio.LongBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.DeferredRendering.MultiRenderTargetAttachments.SSAO_BLUR_ATTACHMENT;
|
||||
import static net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.DeferredRendering.MultiRenderTargetAttachments.SSAO_RAW_ATTACHMENT;
|
||||
import static org.lwjgl.vulkan.VK10.*;
|
||||
import static org.lwjgl.vulkan.VK10.VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||
import static org.lwjgl.vulkan.VK13.*;
|
||||
|
||||
public class AmbientOcclusionRenderer {
|
||||
|
||||
private static final long SSAO_INFO_BUFFER_SIZE =
|
||||
VulkanUtils.MATRIX4X4_SIZE + // projection
|
||||
VulkanUtils.MATRIX4X4_SIZE + // view
|
||||
VulkanUtils.VEC4_SIZE + // screenSize.xy, radius, bias
|
||||
VulkanUtils.VEC4_SIZE; // kernelSize + padding
|
||||
private static final int SSAO_KERNEL_SIZE = 32;
|
||||
private static final float SSAO_RADIUS = 5.0f;
|
||||
private static final float SSAO_BIAS = 0.15f;
|
||||
private static final long SSAO_KERNEL_BUFFER_SIZE = SSAO_KERNEL_SIZE * 4L * VulkanUtils.FLOAT_SIZE;
|
||||
|
||||
private static final String DESC_ID_SSAO_ATTACHMENTS = "SSAO_DESC_ID_ATTACHMENTS";
|
||||
private static final String DESC_ID_SSAO_KERNEL = "SSAO_DESC_ID_KERNEL";
|
||||
private static final String DESC_ID_SSAO_INFO = "SSAO_DESC_ID_INFO";
|
||||
private static final String DESC_ID_SSAO_BLUR_INPUT = "SSAO_DESC_ID_BLUR_INPUT";
|
||||
|
||||
private static final String BLUR_FRAGMENT_SHADER_FILE_GLSL = "resources/EngineResources/shaders/ssao_blur_frag.glsl";
|
||||
private static final String BLUR_FRAGMENT_SHADER_FILE_SPV = BLUR_FRAGMENT_SHADER_FILE_GLSL + ".spv";
|
||||
private static final String FRAGMENT_SHADER_FILE_GLSL = "resources/EngineResources/shaders/ssao_frag.glsl";
|
||||
private static final String FRAGMENT_SHADER_FILE_SPV = FRAGMENT_SHADER_FILE_GLSL + ".spv";
|
||||
private static final String VERTEX_SHADER_FILE_GLSL = "resources/EngineResources/shaders/basic_screen_vertex.glsl";
|
||||
private static final String VERTEX_SHADER_FILE_SPV = VERTEX_SHADER_FILE_GLSL + ".spv";
|
||||
private Attachment ssaoAttachment;
|
||||
private VkRenderingAttachmentInfo.Buffer ssaoAttachmentInfo;
|
||||
private Attachment ssaoBlurAttachment;
|
||||
private VkRenderingAttachmentInfo.Buffer ssaoBlurAttachmentInfo;
|
||||
private final Attachment[] SSAO_ATTACHMENTS = new Attachment[2];
|
||||
|
||||
private final Pipeline ssaoPipeline;
|
||||
private final Pipeline blurPipeline;
|
||||
private final TextureSampler textureSampler;
|
||||
|
||||
private DescriptorSetLayout ssaoAttachmentDescriptorLayout;
|
||||
private DescriptorSetLayout ssaoKernelDescriptorLayout;
|
||||
private DescriptorSetLayout ssaoInfoDescriptorLayout;
|
||||
private DescriptorSetLayout blurDescriptorLayout;
|
||||
|
||||
private final VkClearValue clearColour;
|
||||
private VulkanBuffer sampleKernelBuffer;
|
||||
private VkRenderingInfo ssaoRenderInfo;
|
||||
private VkRenderingInfo ssaoBlurRenderInfo;
|
||||
|
||||
private VulkanBuffer[] ssaoInfoBuffers;
|
||||
|
||||
private Texture NoiseTexture;
|
||||
private Attachment NoiseImageAttachment;
|
||||
|
||||
public AmbientOcclusionRenderer(VulkanContext VkCtx, List<Attachment> MRTAttachments, Queue queue) {
|
||||
List<Attachment> attachments = new ArrayList<>();
|
||||
attachments.add(MRTAttachments.get(0)); // position
|
||||
attachments.add(MRTAttachments.get(2)); // normal
|
||||
CreateAttachments(VkCtx);
|
||||
clearColour = VkClearValue.calloc().color(
|
||||
c -> c.float32(0, 0.0f).float32(1, 0.0f).float32(2, 0.0f).float32(3, 0.0f));
|
||||
ssaoAttachmentInfo = CreateColourAttachmentInfo(ssaoAttachment, clearColour);
|
||||
ssaoBlurAttachmentInfo = CreateColourAttachmentInfo(ssaoBlurAttachment, clearColour);
|
||||
var textureSamplerInfo = new TextureSamplerInfo(VK_SAMPLER_ADDRESS_MODE_REPEAT,
|
||||
VK_BORDER_COLOR_INT_OPAQUE_BLACK, 1, true);
|
||||
textureSampler = new TextureSampler(VkCtx, textureSamplerInfo);
|
||||
|
||||
ByteBuffer NoiseTexturedata = SSAO_Utils.GenerateNoiseTexture();
|
||||
ImageSrc imageSrc = new ImageSrc(NoiseTexturedata, 4, 4,4);
|
||||
NoiseTexture = new Texture(VkCtx,"SSAO_NOISE_SAMPLE", imageSrc,VK_FORMAT_R32G32B32A32_SFLOAT);
|
||||
|
||||
var commandPool = new CommandPool(VkCtx, queue.GetQueueFamilyIndex(), false);
|
||||
var commandBuffer = new CommandBuffer(VkCtx, commandPool, true, true);
|
||||
commandBuffer.BeginRecording();
|
||||
NoiseTexture.RecordTextureTransition(commandBuffer);
|
||||
commandBuffer.EndRecording();
|
||||
commandBuffer.SubmitAndWait(VkCtx, queue);
|
||||
commandBuffer.cleanup(VkCtx,commandPool);
|
||||
commandPool.cleanup(VkCtx);
|
||||
|
||||
NoiseImageAttachment = new Attachment(VkCtx, NoiseTexture);
|
||||
|
||||
attachments.add(NoiseImageAttachment);
|
||||
|
||||
ssaoKernelDescriptorLayout = new DescriptorSetLayout(VkCtx, new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
0, 1, VK_SHADER_STAGE_FRAGMENT_BIT));
|
||||
sampleKernelBuffer = VulkanUtils.CreateHostVisibleBuffer(VkCtx, SSAO_KERNEL_BUFFER_SIZE, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
|
||||
DESC_ID_SSAO_KERNEL, ssaoKernelDescriptorLayout);
|
||||
long MappedMemory = sampleKernelBuffer.MapMemory(VkCtx);
|
||||
FloatBuffer KernelBuffer = SSAO_Utils.GenerateSampleKernel(SSAO_KERNEL_SIZE, MappedMemory);
|
||||
sampleKernelBuffer.UnMapMemory(VkCtx);
|
||||
|
||||
int numAttachments = attachments.size();
|
||||
DescriptorSetLayout.LayoutInformation[] descSetLayouts = new DescriptorSetLayout.LayoutInformation[numAttachments];
|
||||
for (int i = 0; i < numAttachments; i++) {
|
||||
descSetLayouts[i] = new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, i, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
}
|
||||
ssaoAttachmentDescriptorLayout = new DescriptorSetLayout(VkCtx, descSetLayouts);
|
||||
CreateSSAOAttachmentDescriptorSet(VkCtx, attachments);
|
||||
|
||||
ssaoInfoDescriptorLayout = new DescriptorSetLayout(VkCtx,new DescriptorSetLayout.LayoutInformation( VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
||||
0,1,VK_SHADER_STAGE_FRAGMENT_BIT ));
|
||||
|
||||
blurDescriptorLayout = new DescriptorSetLayout(VkCtx,new DescriptorSetLayout.LayoutInformation( VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
||||
0,1,VK_SHADER_STAGE_FRAGMENT_BIT ));
|
||||
|
||||
CreateBlurDescriptorSet(VkCtx);
|
||||
|
||||
ssaoInfoBuffers = VulkanUtils.CreateHostVisibleBuffers(VkCtx,SSAO_INFO_BUFFER_SIZE, VulkanUtils.MAX_IN_FLIGHT,
|
||||
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, DESC_ID_SSAO_INFO,ssaoInfoDescriptorLayout);
|
||||
|
||||
ssaoRenderInfo = CreateRenderInfo(ssaoAttachment, ssaoAttachmentInfo);
|
||||
ssaoBlurRenderInfo = CreateRenderInfo(ssaoBlurAttachment, ssaoBlurAttachmentInfo);
|
||||
|
||||
ShaderModule[] shaderModules = CreateRawShaderModules(VkCtx);
|
||||
ssaoPipeline = CreatePipeline(VkCtx, shaderModules,
|
||||
new DescriptorSetLayout[]{
|
||||
ssaoAttachmentDescriptorLayout,
|
||||
ssaoKernelDescriptorLayout,
|
||||
ssaoInfoDescriptorLayout
|
||||
},false);
|
||||
Arrays.stream(shaderModules).toList().forEach(shaderModule -> shaderModule.CleanUp(VkCtx));
|
||||
|
||||
shaderModules = CreateBlurShaderModules(VkCtx);
|
||||
blurPipeline = CreatePipeline( VkCtx, shaderModules,
|
||||
new DescriptorSetLayout[]{ blurDescriptorLayout },
|
||||
true );
|
||||
Arrays.stream(shaderModules).toList().forEach(shaderModule -> shaderModule.CleanUp(VkCtx));
|
||||
}
|
||||
|
||||
|
||||
private static Pipeline CreatePipeline(VulkanContext VkCtx, ShaderModule[] shaderModules, DescriptorSetLayout[] descSetLayouts, boolean blur) {
|
||||
var vtxBuffStruct = new EmptyVertexBufferStruct();
|
||||
var buildInfo = new PipelineBuildInfo(shaderModules, vtxBuffStruct.GetVertexInput(),new int[]{blur ? SSAO_BLUR_ATTACHMENT : SSAO_RAW_ATTACHMENT})
|
||||
.SetDescriptorSetLayouts(descSetLayouts)
|
||||
.BlendingIsUsed(false)
|
||||
.SetDepthWrite(false)
|
||||
.SetDepthTest(false);
|
||||
var pipeline = new DefaultPipeline(VkCtx, buildInfo);
|
||||
vtxBuffStruct.CleanUp();
|
||||
return pipeline;
|
||||
}
|
||||
|
||||
private static ShaderModule[] CreateRawShaderModules(VulkanContext VkCtx) {
|
||||
if (EngineConfig.getInstance().RecompileShaders()) {
|
||||
ShaderCompiler.CompileGLSLShaderOnChange(VERTEX_SHADER_FILE_GLSL, Shaderc.shaderc_glsl_vertex_shader);
|
||||
ShaderCompiler.CompileGLSLShaderOnChange( 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_FRAGMENT_BIT, FRAGMENT_SHADER_FILE_SPV, null),
|
||||
};
|
||||
}
|
||||
|
||||
private static ShaderModule[] CreateBlurShaderModules(VulkanContext VkCtx) {
|
||||
if (EngineConfig.getInstance().RecompileShaders()) {
|
||||
ShaderCompiler.CompileGLSLShaderOnChange(VERTEX_SHADER_FILE_GLSL, Shaderc.shaderc_glsl_vertex_shader);
|
||||
ShaderCompiler.CompileGLSLShaderOnChange( BLUR_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_FRAGMENT_BIT, BLUR_FRAGMENT_SHADER_FILE_SPV, null),
|
||||
};
|
||||
}
|
||||
|
||||
private static VkRenderingAttachmentInfo.Buffer CreateColourAttachmentInfo(Attachment attachment, VkClearValue clearValue) {
|
||||
return VkRenderingAttachmentInfo.calloc(1)
|
||||
.sType$Default()
|
||||
.imageView(attachment.GetVkImageView().GetVulkanImageView())
|
||||
.imageLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)
|
||||
.loadOp(VK_ATTACHMENT_LOAD_OP_CLEAR)
|
||||
.storeOp(VK_ATTACHMENT_STORE_OP_STORE)
|
||||
.clearValue(clearValue);
|
||||
}
|
||||
|
||||
private static VkRenderingInfo CreateRenderInfo(Attachment attachment, VkRenderingAttachmentInfo.Buffer attachmentInfo) {
|
||||
return VkRenderingInfo.calloc()
|
||||
.sType$Default()
|
||||
.renderArea(area -> area
|
||||
.offset(offset -> offset.x(0).y(0))
|
||||
.extent(extent -> extent
|
||||
.width(attachment.GetVkImage().GetWidth())
|
||||
.height(attachment.GetVkImage().GetHeight())))
|
||||
.layerCount(1)
|
||||
.pColorAttachments(attachmentInfo);
|
||||
}
|
||||
|
||||
private void CreateSSAOAttachmentDescriptorSet(VulkanContext vkCtx, List<Attachment> Attachments ) {
|
||||
DescriptorSet descSet = vkCtx.GetDescriptorAllocator().AddDescriptorSet(
|
||||
vkCtx.GetDevice(), DESC_ID_SSAO_ATTACHMENTS,ssaoAttachmentDescriptorLayout );
|
||||
|
||||
List<ImageView> imageViews = new ArrayList<>();
|
||||
Attachments.forEach(a -> imageViews.add(a.GetVkImageView()));
|
||||
|
||||
descSet.SetImages(vkCtx.GetDevice(), imageViews, textureSampler, 0);
|
||||
}
|
||||
|
||||
|
||||
private void CreateBlurDescriptorSet(VulkanContext vkCtx) {
|
||||
DescriptorSet descSet = vkCtx.GetDescriptorAllocator().AddDescriptorSet(
|
||||
vkCtx.GetDevice(),DESC_ID_SSAO_BLUR_INPUT, blurDescriptorLayout);
|
||||
|
||||
descSet.SetImage(vkCtx.GetDevice(), ssaoAttachment.GetVkImageView(),
|
||||
textureSampler,0);
|
||||
}
|
||||
|
||||
private void CreateAttachments(VulkanContext VkCtx){
|
||||
SwapChain swapChain = VkCtx.GetSwapChain();
|
||||
VkExtent2D swapChainExtent = swapChain.GetSwapChainExtent();
|
||||
//SSAO Raw
|
||||
ssaoAttachment = new Attachment(VkCtx, swapChainExtent.width(), swapChainExtent.height(), SSAO_RAW_ATTACHMENT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, 1);
|
||||
SSAO_ATTACHMENTS[0] = ssaoAttachment;
|
||||
//SSAO Blur
|
||||
ssaoBlurAttachment = new Attachment(VkCtx, swapChainExtent.width(), swapChainExtent.height(), SSAO_BLUR_ATTACHMENT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, 1);
|
||||
SSAO_ATTACHMENTS[1] = ssaoBlurAttachment;
|
||||
}
|
||||
|
||||
public void Render(VulkanContext VkCtx,EngineInstance engineInstance, CommandBuffer cmdBuffer, MultiRenderTargetAttachments MRT,int CurrentFrame) {
|
||||
try (var stack = MemoryStack.stackPush()) {
|
||||
|
||||
|
||||
VkCommandBuffer cmdHandle = cmdBuffer.GetVulkanCommandBuffer();
|
||||
|
||||
UpdateSSAOInfo(VkCtx, engineInstance, CurrentFrame);
|
||||
|
||||
VulkanUtils.ImageBarrier(stack, cmdHandle, ssaoAttachment.GetVkImage().getVulkanImage(),
|
||||
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT,
|
||||
VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||
VK_ACCESS_2_SHADER_READ_BIT,
|
||||
VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
|
||||
TransitionMRTtoReadOnly(stack, cmdHandle, MRT);
|
||||
|
||||
|
||||
vkCmdBeginRendering(cmdHandle, ssaoRenderInfo);
|
||||
|
||||
vkCmdBindPipeline(cmdHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, ssaoPipeline.GetVulkanPipeline());
|
||||
|
||||
SetViewportAndScissor(stack, cmdHandle, ssaoAttachment);
|
||||
|
||||
DescriptorAllocator descAllocator = VkCtx.GetDescriptorAllocator();
|
||||
LongBuffer descriptorSets = stack.mallocLong(3)
|
||||
.put(0, descAllocator.GetDescriptorSet(DESC_ID_SSAO_ATTACHMENTS).GetVkDescriptorSet())
|
||||
.put(1, descAllocator.GetDescriptorSet(DESC_ID_SSAO_KERNEL).GetVkDescriptorSet())
|
||||
.put(2, descAllocator.GetDescriptorSet(DESC_ID_SSAO_INFO, CurrentFrame).GetVkDescriptorSet());
|
||||
|
||||
vkCmdBindDescriptorSets(cmdHandle, VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
ssaoPipeline.GetVulkanPipelineLayout(), 0, descriptorSets, null);
|
||||
|
||||
vkCmdDraw(cmdHandle, 3, 1, 0, 0);
|
||||
|
||||
vkCmdEndRendering(cmdHandle);
|
||||
|
||||
//blur pass
|
||||
VulkanUtils.ImageBarrier(stack, cmdHandle, ssaoAttachment.GetVkImage().getVulkanImage(),
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||
VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||
VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT,
|
||||
VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
VK_ACCESS_2_SHADER_READ_BIT,
|
||||
VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
|
||||
VulkanUtils.ImageBarrier(stack, cmdHandle, ssaoBlurAttachment.GetVkImage().getVulkanImage(),
|
||||
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT,
|
||||
VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||
VK_ACCESS_2_SHADER_READ_BIT,
|
||||
VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
|
||||
vkCmdBeginRendering(cmdHandle, ssaoBlurRenderInfo);
|
||||
|
||||
vkCmdBindPipeline(cmdHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, blurPipeline.GetVulkanPipeline());
|
||||
|
||||
SetViewportAndScissor(stack, cmdHandle, ssaoBlurAttachment);
|
||||
|
||||
LongBuffer blurDescriptorSets = stack.mallocLong(1)
|
||||
.put(0, descAllocator.GetDescriptorSet(DESC_ID_SSAO_BLUR_INPUT).GetVkDescriptorSet());
|
||||
|
||||
vkCmdBindDescriptorSets(cmdHandle,VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
blurPipeline.GetVulkanPipelineLayout(),0, blurDescriptorSets,null );
|
||||
|
||||
vkCmdDraw(cmdHandle, 3, 1, 0, 0);
|
||||
|
||||
vkCmdEndRendering(cmdHandle);
|
||||
|
||||
VulkanUtils.ImageBarrier( stack, cmdHandle, ssaoBlurAttachment.GetVkImage().getVulkanImage(),
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||
VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||
VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT,
|
||||
VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
VK_ACCESS_2_SHADER_READ_BIT,
|
||||
VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
}
|
||||
}
|
||||
|
||||
private static void TransitionMRTtoReadOnly(MemoryStack stack,VkCommandBuffer cmdHandle, MultiRenderTargetAttachments MRT) {
|
||||
List<Attachment> attachments = MRT.GetColourAttachments();
|
||||
|
||||
for (Attachment attachment : attachments) {
|
||||
VulkanUtils.ImageBarrier( stack,cmdHandle, attachment.GetVkImage().getVulkanImage(),
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||
VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||
VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT,
|
||||
VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
VK_ACCESS_2_SHADER_READ_BIT,
|
||||
VK_IMAGE_ASPECT_COLOR_BIT
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private void SetViewportAndScissor(MemoryStack stack, VkCommandBuffer cmdHandle, Attachment attachment){
|
||||
Image ColourImage = attachment.GetVkImage();
|
||||
int width = ColourImage.GetWidth();
|
||||
int height = ColourImage.GetHeight();
|
||||
var viewport = VkViewport.calloc(1, stack)
|
||||
.x(0)
|
||||
.y(height)
|
||||
.height(-height)
|
||||
.width(width)
|
||||
.minDepth(0.0f)
|
||||
.maxDepth(1.0f);
|
||||
vkCmdSetViewport(cmdHandle, 0, viewport);
|
||||
|
||||
var scissor = VkRect2D.calloc(1, stack)
|
||||
.extent(it -> it.width(width).height(height))
|
||||
.offset(it -> it.x(0).y(0));
|
||||
vkCmdSetScissor(cmdHandle, 0, scissor);
|
||||
}
|
||||
|
||||
private void UpdateSSAOInfo(VulkanContext vkCtx, EngineInstance engineInstance, int currentFrame) {
|
||||
VulkanBuffer buffer = ssaoInfoBuffers[currentFrame];
|
||||
long mappedMemory = buffer.MapMemory(vkCtx);
|
||||
ByteBuffer data = MemoryUtil.memByteBuffer(mappedMemory, (int) buffer.GetRequestedSize());
|
||||
|
||||
int offset = 0;
|
||||
|
||||
engineInstance.scene().GetProjection().GetProjectionMatrix().get(offset, data);
|
||||
offset += VulkanUtils.MATRIX4X4_SIZE;
|
||||
|
||||
engineInstance.scene().GetCamera().GetViewMatrix().get(offset, data);
|
||||
offset += VulkanUtils.MATRIX4X4_SIZE;
|
||||
|
||||
data.putFloat(offset, ssaoAttachment.GetVkImage().GetWidth());
|
||||
data.putFloat(offset + VulkanUtils.FLOAT_SIZE, ssaoAttachment.GetVkImage().GetHeight());
|
||||
data.putFloat(offset + VulkanUtils.FLOAT_SIZE * 2, SSAO_RADIUS);
|
||||
data.putFloat(offset + VulkanUtils.FLOAT_SIZE * 3, SSAO_BIAS);
|
||||
offset += VulkanUtils.VEC4_SIZE;
|
||||
|
||||
data.putInt(offset, SSAO_KERNEL_SIZE);
|
||||
|
||||
buffer.UnMapMemory(vkCtx);
|
||||
}
|
||||
|
||||
public Attachment getSSAOBlurAttachment() {
|
||||
return ssaoBlurAttachment;
|
||||
}
|
||||
|
||||
public void resize(VulkanContext VkCtx, List<Attachment> attachments) {
|
||||
ssaoRenderInfo.free();
|
||||
ssaoBlurRenderInfo.free();
|
||||
ssaoAttachmentInfo.free();
|
||||
ssaoAttachment.CleanUp(VkCtx);
|
||||
ssaoBlurAttachmentInfo.free();
|
||||
ssaoBlurAttachment.CleanUp(VkCtx);
|
||||
|
||||
CreateAttachments(VkCtx);
|
||||
|
||||
ssaoAttachmentInfo = CreateColourAttachmentInfo(ssaoAttachment, clearColour);
|
||||
ssaoBlurAttachmentInfo = CreateColourAttachmentInfo(ssaoBlurAttachment, clearColour);
|
||||
ssaoRenderInfo = CreateRenderInfo(ssaoAttachment, ssaoAttachmentInfo);
|
||||
ssaoBlurRenderInfo = CreateRenderInfo(ssaoBlurAttachment, ssaoBlurAttachmentInfo);
|
||||
|
||||
attachments.add(NoiseImageAttachment);
|
||||
|
||||
CreateSSAOAttachmentDescriptorSet(VkCtx,attachments);
|
||||
CreateBlurDescriptorSet(VkCtx);
|
||||
}
|
||||
|
||||
public void cleanup(VulkanContext VkCtx) {
|
||||
ssaoRenderInfo.free();
|
||||
ssaoBlurRenderInfo.free();
|
||||
ssaoAttachmentInfo.free();
|
||||
ssaoAttachment.CleanUp(VkCtx);
|
||||
ssaoBlurAttachmentInfo.free();
|
||||
ssaoBlurAttachment.CleanUp(VkCtx);
|
||||
ssaoPipeline.CleanUp(VkCtx);
|
||||
blurPipeline.CleanUp(VkCtx);
|
||||
clearColour.free();
|
||||
Arrays.stream(ssaoInfoBuffers).toList().forEach(b -> b.cleanup(VkCtx));
|
||||
sampleKernelBuffer.cleanup(VkCtx);
|
||||
ssaoAttachmentDescriptorLayout.CleanUp(VkCtx);
|
||||
blurDescriptorLayout.CleanUp(VkCtx);
|
||||
ssaoInfoDescriptorLayout.CleanUp(VkCtx);
|
||||
ssaoKernelDescriptorLayout.CleanUp(VkCtx);
|
||||
NoiseTexture.CleanUp(VkCtx);
|
||||
textureSampler.CleanUp(VkCtx);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
package net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Shader;
|
||||
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.Images.TextureCache;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DeviceLayers.Device;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DisplayToScreen.ImageView;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Util.VulkanBuffer;
|
||||
|
|
@ -100,9 +101,19 @@ public class DescriptorSet {
|
|||
public void SetImageArray(Device device, List<ImageView> imageViews, TextureSampler textureSampler, int BaseBinding){
|
||||
try(var MemStack = MemoryStack.stackPush()){
|
||||
int ImageCount = imageViews.size();
|
||||
if (textureSampler == null || textureSampler.GetVkSampler() == 0) {
|
||||
throw new NullPointerException("The provided TextureSampler is uninitialized or null!");
|
||||
}
|
||||
VkDescriptorImageInfo.Buffer imageInfos = VkDescriptorImageInfo.calloc(ImageCount,MemStack);
|
||||
for(int i = 0; i < ImageCount; i++){
|
||||
|
||||
ImageView imageView = imageViews.get(i);
|
||||
if (imageView == null || imageView.GetVulkanImageView() == 0) {
|
||||
Logger.error("Texture or ImageView at index " + i + " is NULL! Check your material cache loading.");
|
||||
imageView = imageViews.getFirst();
|
||||
if(imageView == null || imageView.GetVulkanImageView() == 0) throw new NullPointerException("The provided TextureSampler is uninitialized or null!");
|
||||
}
|
||||
|
||||
VkDescriptorImageInfo imageInfo = imageInfos.get(i);
|
||||
imageInfo.imageView(imageView.GetVulkanImageView()).sampler(textureSampler.GetVkSampler());
|
||||
|
||||
|
|
|
|||
|
|
@ -2,5 +2,5 @@ package net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.VkModel;
|
|||
|
||||
import org.joml.Vector4f;
|
||||
|
||||
public record MaterialData(String ID, String TexturePath,String NormalTexturePath,String MetalRoughnessMap, Vector4f DiffuseColour,float Roughness, float Metallic, String EmissiveTexture,Vector4f EmissiveColour, String TranslucencyTexture, float Translucency, String OpacityTexture, float Opacity) {
|
||||
public record MaterialData(String ID, String TexturePath,String NormalTexturePath,String MetalRoughnessMap, Vector4f DiffuseColour,float Roughness, float Metallic, String EmissiveTexture,Vector4f EmissiveColour, String TranslucencyTexture, float Translucency, String OpacityTexture, float Opacity, Vector4f ColorTransparency, float Refractiveness, float Reflectiveness) {
|
||||
}
|
||||
|
|
|
|||
|
|
@ -205,9 +205,11 @@ public class SpriteRenderer {
|
|||
public void LoadMaterials(VulkanContext VkCtx, MaterialsCache materialsCache, TextureCache textureCache){
|
||||
DescriptorAllocator descriptorAllocator = VkCtx.GetDescriptorAllocator();
|
||||
Device device = VkCtx.GetDevice();
|
||||
List<ImageView> imageViews = new ArrayList<>(textureCache.GetAll2DTextures().stream().map(ITexture::GetImageView).toList());
|
||||
|
||||
ImageView fallback = textureCache.GetTexture("resources/EngineResources/Texture/NoTexture.png").GetImageView();
|
||||
List<ImageView> imageViews = new ArrayList<>();
|
||||
imageViews.add(fallback);
|
||||
imageViews.addAll(textureCache.GetAll2DTextures().stream().map(ITexture::GetImageView).toList());
|
||||
while (imageViews.size() < TextureCache.MAX_TEXTURES) {
|
||||
imageViews.add(fallback);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ public class SwapChainRender {
|
|||
private static final String DESCRIPTOR_ID_ATTACHMENT = "FWD_DESC_ID_ATT";
|
||||
private static final String FRAGMENT_SHADER_FILE_GLSL = "resources/EngineResources/shaders/swap_frag.glsl";
|
||||
private static final String FRAGMENT_SHADER_FILE_SPV = FRAGMENT_SHADER_FILE_GLSL + ".spv";
|
||||
private static final String VERTEX_SHADER_FILE_GLSL = "resources/EngineResources/shaders/swap_vtx.glsl";
|
||||
private static final String VERTEX_SHADER_FILE_GLSL = "resources/EngineResources/shaders/basic_screen_vertex.glsl";
|
||||
private static final String VERTEX_SHADER_FILE_SPV = VERTEX_SHADER_FILE_GLSL + ".spv";
|
||||
private final DescriptorSetLayout AttachmentDescriptorSetLayout;
|
||||
private final VkClearValue ClearValueColour;
|
||||
|
|
|
|||
|
|
@ -160,7 +160,7 @@ public class VulkanUtils {
|
|||
descriptorAllocator.AddDescriptorSets(device, ID, BufferCount, layout);
|
||||
DescriptorSetLayout.LayoutInformation LayoutInfo = layout.GetLayoutInfo();
|
||||
for(int i = 0; i < BufferCount; i++){
|
||||
Result[i] = new VulkanBuffer(VkCtx, BufferSize, Usage,VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE,VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
|
||||
Result[i] = new VulkanBuffer(VkCtx, BufferSize, Usage,VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE,VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
|
||||
DescriptorSet descriptorSet = descriptorAllocator.GetDescriptorSet(ID, i);
|
||||
descriptorSet.SetBuffer(device, Result[i], Result[i].GetRequestedSize(), layout.GetLayoutInfo().Binding(),layout.GetLayoutInfo().DescriptorType());
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue