HDR, Bloom and SSR

This commit is contained in:
Halbear 2026-09-04 00:23:48 +01:00
parent 577836a03f
commit 04befce27d
44 changed files with 1377 additions and 269 deletions

View file

@ -13,6 +13,7 @@ import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.I
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.ScreenSpace.ReflectionsRenderer;
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;
@ -53,6 +54,7 @@ public class VulkanRenderer implements Renderer {
private final Semaphore[] RenderCompleteSemaphores;
private final SceneRenderer sceneRender;
private final AmbientOcclusionRenderer ssaoRenderer;
private final ReflectionsRenderer ssrRender;
private final SpriteRenderer spriteRenderer;
private final LightRenderer lightRenderer;
private final PostProcess PostProcessor;
@ -117,7 +119,8 @@ public class VulkanRenderer implements Renderer {
attachments.add(ssaoRenderer.getSSAOBlurAttachment());
attachments.add(shadowRender.getShadowAttachment());
lightRenderer = new LightRenderer(RendererContext, attachments);
PostProcessor = new PostProcess(RendererContext, lightRenderer.getAttachment());
ssrRender = new ReflectionsRenderer(RendererContext, sceneRender.GetMRTAttachments().GetColourAttachments(), lightRenderer.getAttachment());
PostProcessor = new PostProcess(RendererContext, ssrRender.GetSSRAttachment());
} else{
sceneRender = new ForwardSceneRender(RendererContext);
@ -125,6 +128,7 @@ public class VulkanRenderer implements Renderer {
PostProcessor = new PostProcess(RendererContext, sceneRender.GetAttachmentColour());
lightRenderer = null;
shadowRender = null;
ssrRender = null;
}
spriteRenderer= new SpriteRenderer(engineInstance, RendererContext, PostProcessor.GetAttachment());
GuiRender = new GuiRenderer(engineInstance, RendererContext, GraphicsQueue, PostProcessor.GetAttachment());
@ -195,6 +199,7 @@ public class VulkanRenderer implements Renderer {
Logger.debug("Waiting Vulkan Context");
sceneRender.cleanup(RendererContext);
if(ssaoRenderer != null)ssaoRenderer.cleanup(RendererContext);
if(ssrRender != null)ssrRender.cleanup(RendererContext);
if(shadowRender != null)shadowRender.cleanup(RendererContext);
if(lightRenderer != null)lightRenderer.cleanup(RendererContext);
PostProcessor.CleanUp(RendererContext);
@ -219,6 +224,23 @@ public class VulkanRenderer implements Renderer {
VulkanUtils.CleanUpRemaining(RendererContext.GetDevice());
RendererContext.cleanup();
}
public enum DebugRenderMode{
Albedo,
Normals,
Pos,
SSAO,
Depth,
NoPosProcess,
Emissive,
Translucency,
Opacity,
PBR
}
public static volatile boolean Debug = false;
public static volatile DebugRenderMode debugMode = DebugRenderMode.Albedo;
public void DeferredRender(EngineInstance engineInstance){
SwapChain swapChain = RendererContext.GetSwapChain();
WaitForFence(CurrentFrame);
@ -227,12 +249,6 @@ public class VulkanRenderer implements Renderer {
var CommandPool = CommandPools[CurrentFrame];
var CommandBuffer = CommandBuffers[CurrentFrame];
int ImageIndex;
if (Resize || (ImageIndex = swapChain.FetchNextImage(RendererContext.GetDevice(), PresentCompleteSemaphores[imageAcquisitionIndex])) < 0){
resize(engineInstance);
return;
}
RecordingStart(CommandPool, CommandBuffer);
sceneRender.Render(engineInstance,RendererContext,CommandBuffer, modelsCache,materialsCache,CurrentFrame);
@ -243,9 +259,17 @@ public class VulkanRenderer implements Renderer {
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());
ssrRender.Render( RendererContext, engineInstance, CommandBuffer, CurrentFrame);
PostProcessor.Render(RendererContext,CommandBuffer,ssrRender.GetSSRAttachment());
spriteRenderer.Render(engineInstance,RendererContext,CommandBuffer,PostProcessor.GetAttachment(),modelsCache,CurrentFrame);
GuiRender.Render(RendererContext,CommandBuffer,CurrentFrame,PostProcessor.GetAttachment());
int ImageIndex;
if (Resize || (ImageIndex = swapChain.FetchNextImage(RendererContext.GetDevice(), PresentCompleteSemaphores[imageAcquisitionIndex])) < 0){
resize(engineInstance);
return;
}
swapChainRender.Render(RendererContext,CommandBuffer,PostProcessor.GetAttachment(),ImageIndex);
RecordingStop(CommandBuffer);
@ -290,8 +314,8 @@ public class VulkanRenderer implements Renderer {
RebuildShadowsRequested = false;
RebuildShadows();
}
if(Deferred) DeferredRender(engineInstance);
if (Deferred) DeferredRender(engineInstance);
// else if(Deferred)DebugDeferredRender(engineInstance, debugMode);
else ForwardRender(engineInstance);
}
@ -338,14 +362,21 @@ 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());
List<Attachment> ssaoAttachments = new ArrayList<>();
ssaoAttachments.add(attachments.get(7));
ssaoAttachments.add(attachments.get(2));
ssaoRenderer.resize(RendererContext, ssaoAttachments);
ssaoAttachments.clear();
ssaoAttachments.add(lightRenderer.getAttachment());
ssaoAttachments.add(attachments.get(0));
ssaoAttachments.add(attachments.get(2));
ssaoAttachments.add(attachments.get(3));
ssrRender.resize(RendererContext, ssaoAttachments);
PostProcessor.Resize(RendererContext, ssrRender.GetSSRAttachment());
} else{
PostProcessor.Resize(RendererContext, sceneRender.GetAttachmentColour());
}

View file

@ -139,12 +139,20 @@ public class ModelCompiler {
SpecularArray = new float[]{0.0f};
}
float[] GlossinessArray = new float[]{0.0f};
Result = aiGetMaterialFloatArray(aiMaterial,AI_MATKEY_GLOSSINESS_FACTOR,aiTextureType_NONE,0,GlossinessArray,MaxPointer);
if(Result != aiReturn_SUCCESS){
GlossinessArray = new float[]{0.0f};
}
if(SpecularArray[0] == 0.0f && GlossinessArray[0] != 0.0f)
SpecularArray[0] = GlossinessArray[0];
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){
@ -169,6 +177,13 @@ public class ModelCompiler {
OpacityArray = 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());
}
float[] RefractionArray = new float[]{0.0f};
Result = aiGetMaterialFloatArray(aiMaterial,AI_MATKEY_REFRACTI,aiTextureType_NONE,0,RefractionArray,MaxPointer);
if(Result != aiReturn_SUCCESS){
@ -181,14 +196,6 @@ public class ModelCompiler {
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]);
}

View file

@ -52,7 +52,7 @@ import static org.lwjgl.glfw.GLFW.*;
public class GameCore implements GameLogic {
private static final float MOUSE_SENSITIVITY = 0.1f;
private static final float MOVEMENT_SPEED = 0.1f;
private static final float MOVEMENT_SPEED = 0.01f;
public static boolean LoadingLevel = false;
private Vector2f LastMousePos = new Vector2f(0,0);
@ -100,11 +100,15 @@ public class GameCore implements GameLogic {
List<ModelData> models = new ArrayList<>();
List<MaterialData> materials = new ArrayList<>();
ModelData SponzaData = ModelLoader.LoadModel("resources/models/Cafe/exterior.json");
models.add(SponzaData);
List<MaterialData> SponzaMaterial = ModelLoader.LoadMaterials("resources/models/Cafe/exterior_mat.json");
materials.addAll(SponzaMaterial);
ModelData SponzaData1 = ModelLoader.LoadModel("resources/models/Cafe/interior.json");
models.add(SponzaData1);
List<MaterialData> SponzaMaterial1= ModelLoader.LoadMaterials("resources/models/Cafe/interior_mat.json");
scene.AddActor(new Actor3D("Sponza1", SponzaData.ID(), new Vector3f(0,0f,-5f)).SetScale(0.1f));
scene.AddActor(new Actor3D("Sponza2", SponzaData1.ID(), new Vector3f(0,0f,-5f)).SetScale(0.1f));
materials.addAll(SponzaMaterial1);
scene.AddActor(new Actor3D("Sponza1", SponzaData.ID(), new Vector3f(0,0f,-5f)).SetScale(0.05f));
scene.AddActor(new Actor3D("Sponza2", SponzaData1.ID(), new Vector3f(0,0f,-5f)).SetScale(0.05f));
// ModelData treeModel = ModelLoader.LoadModel("resources/models/tree/tree.json");
// models.add(treeModel);
// Actor3D treeEntity = new Actor3D("treeEntity", treeModel.ID(), new Vector3f(0.0f, 0.0f, 0.0f));
@ -113,8 +117,8 @@ public class GameCore implements GameLogic {
// materials.addAll(ModelLoader.LoadMaterials("resources/models/tree/tree_mat.json"));
// ModelData treeModel = ModelLoader.LoadModel("resources/models/Forest/forest.json");
// models.add(treeModel);
// Actor3D treeEntity = new Actor3D("treeEntity", treeModel.ID(), new Vector3f(0.0f, -100.0f, 0.0f));
// treeEntity.SetScale(10f);
// Actor3D treeEntity = new Actor3D("treeEntity", treeModel.ID(), new Vector3f(0.0f, 00.0f, 0.0f));
// treeEntity.SetScale(0.1f);
// scene.AddActor(treeEntity);
// materials.addAll(ModelLoader.LoadMaterials("resources/models/Forest/forest_mat.json"));
MelonaData = ModelLoader.LoadModel("resources/models/cube/Cube.json");
@ -158,10 +162,6 @@ public class GameCore implements GameLogic {
}
boolean createOfflinePlayer = !PrimaryRuntime.IsServer && !ClientSideNetworkUtils.Connected;
materials.addAll(SponzaMaterial);
materials.addAll(SponzaMaterial1);
models.add(SponzaData);
models.add(SponzaData1);
materials.addAll(MelonaMat);
materials.addAll(CollisionVisualisationMat);
materials.addAll(MelonaMaterial);
@ -191,90 +191,105 @@ public class GameCore implements GameLogic {
}
scene.GetLightingManager().GetAmbientLightColour().set(1.0f, 0.9f, 0.75f);
scene.GetLightingManager().SetAmbientLightIntensity(0.15f);
scene.GetLightingManager().GetAmbientLightColour().set(0.3f, 0.35f, 0.5f);
scene.GetLightingManager().SetAmbientLightIntensity(0.05f);
SkyLight = new Light(new Vector3f(1.5f, 1.20f, 1.0f),new Vector3f(0.0f, -1.0f, 0.3f), true, 4.00f);
SkyLight = new Light(new Vector3f(0.25f, 0.75f, 1.3f),new Vector3f(0.0f, -1.0f, 0.0f), true, 4.0f);
SkyLight.SetType(Light.LightType.Directional);
scene.GetLightingManager().SetAmbientLightIntensity(0.1f);
// scene.GetLightingManager().GetAmbientLightColour().set(0.6f, 0.5f, 0.4f);
// scene.GetLightingManager().SetAmbientLightIntensity(0.1f);
List<ILight> lights = new ArrayList<>();
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-433, 445f, -424f).div(10.0f),false,3000.0f+ (float)(Math.random() * 100.0)));
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-210, 445f, 460f).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-966, 445f, 204f).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-176, 445f, 1000f).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(777, 445f, 858).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(376, 445f, -2136).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,2.0f),new Vector3f(2163, 445f, 1880).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(3334, 445f, 2405).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(3509, 445f, 1825).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(3877, 445f, 3378).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(4925, 445f, 3430).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-2083, 445f, -1826).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(2076, 410, 1272).div(10.0f),false,100.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(2446, 465, 2303).div(10.0f),false,100.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-842, 410, -1141).div(10.0f),false,100.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-207, 410, -1830).div(10.0f),false,100.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(899, 460, -2015).div(10.0f),false,100.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(1775, 460, -3448).div(10.0f),false,100.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(1800, 460, -4154).div(10.0f),false,1000.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-1727, 410, -387).div(10.0f),false,100.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-1198, 410, -964).div(10.0f),false,100.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-1778, 410, -1502).div(10.0f),false,100.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-2692, 333, -2109).div(10.0f),false,100.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-2849, 333, -1724).div(10.0f),false,100.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-2019, 410, -729).div(10.0f),false,100.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-1727, 410, -389).div(10.0f),false,100.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-1337, 410, 122).div(10.0f),false,100.0f));
SkyLight = new Light(new Vector3f(1.5f, 1.20f, 1.0f),new Vector3f(0.0f, -1.0f, 0.3f), true, 4.00f);
// SkyLight = new Light(new Vector3f(2.75f, 1.75f, 0.3f),new Vector3f(0.0f, -1.0f, 0.0f), true, 6.0f);
//SkyLight = new Light(new Vector3f(1.5f, 1.20f, 1.0f),new Vector3f(0.0f, -1.0f, 0.3f), true, 5.00f);
SkyLight.SetType(Light.LightType.Directional);
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(615.8f, 305.5f, -904.1f).div(10.0f),false,200.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(425.4f, 305.5f, -541.0f).div(10.0f),false,200.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(501.4f, 305.5f, -102.7f).div(10.0f),false,200.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(803.0f, 305.5f, 50.2f).div(10.0f),false,200.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(720.4f, 261.6f, -329.2f).div(10.0f),false,75.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(879.4f,261.6f,-246.3f).div(10.0f),false,75.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(1037.7f,261.6f,-155.0f).div(10.0f),false,75.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(663.4f,261.6f,-468.9f).div(10.0f),false,75.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(772.3f,243.7f,-513.7f).div(10.0f),false,50.0f));
lights.add(new Light(new Vector3f(1.2f + (float)Math.random(),1.1f,1.0f),new Vector3f(193.1f,260.7f,-859.3f).div(10.0f),false,50.0f));
lights.add(new Light(new Vector3f(1.2f + (float)Math.random(),1.1f,1.0f),new Vector3f(51.0f,260.7f,-603.0f).div(10.0f),false,50.0f));
lights.add(new Light(new Vector3f(1.2f + (float)Math.random(),1.1f,1.0f),new Vector3f(-95.0f,260.7f,-334.2f).div(10.0f),false,50.0f));
lights.add(new Light(new Vector3f(1.2f + (float)Math.random(),1.1f,1.0f),new Vector3f(41.5f,260.7f,5.7f).div(10.0f),false,50.0f));
lights.add(new Light(new Vector3f(1.2f + (float)Math.random(),1.1f,1.0f),new Vector3f(335.8f,260.7f,144.6f).div(10.0f),false,50.0f));
lights.add(new Light(new Vector3f(1.2f + (float)Math.random(),1.1f,1.0f),new Vector3f(616.9f,260.7f,255.4f).div(10.0f),false,50.0f));
lights.add(new Light(new Vector3f(0.75f,2.0f,0.75f),new Vector3f(1086, 425, -3375).div(10.0f),false,500.0f));
// lights.add(new Light(new Vector3f(3.0f,2.25f,0.0f),new Vector3f(350.0f, 1500.0f, -420.0f),false,10000.0f));
// lights.add(new Light(new Vector3f(3.0f,2.25f,0.0f),new Vector3f(400.0f, 1550.0f, -350.0f),false,10000.0f));
lights.add(SkyLight);
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-433, 445f, -424f).div(20.0f),false,3000.0f/10.0f+ (float)(Math.random() * 100.0/10.0f)));
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-210, 445f, 460f).div(20.0f),false,700.0f/10.0f + (float)(Math.random() * 150.0f/10.0f)));
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-966, 445f, 204f).div(20.0f),false,700.0f/10.0f + (float)(Math.random() * 150.0f/10.0f)));
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-176, 445f, 1000f).div(20.0f),false,700.0f/10.0f + (float)(Math.random() * 150.0f/10.0f)));
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(777, 445f, 858).div(20.0f),false,700.0f/10.0f + (float)(Math.random() * 150.0f/10.0f)));
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(376, 445f, -2136).div(20.0f),false,700.0f/10.0f + (float)(Math.random() * 150.0f/10.0f)));
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,2.0f),new Vector3f(2163, 445f, 1880).div(20.0f),false,700.0f/10.0f + (float)(Math.random() * 150.0f/10.0f)));
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(3334, 445f, 2405).div(20.0f),false,700.0f/10.0f + (float)(Math.random() * 150.0f/10.0f)));
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(3509, 445f, 1825).div(20.0f),false,700.0f/10.0f + (float)(Math.random() * 150.0f/10.0f)));
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(3877, 445f, 3378).div(20.0f),false,700.0f/10.0f + (float)(Math.random() * 150.0f/10.0f)));
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(4925, 445f, 3430).div(20.0f),false,700.0f/10.0f + (float)(Math.random() * 150.0f/10.0f)));
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-2083, 445f, -1826).div(20.0f),false,700.0f/10.0f + (float)(Math.random() * 150.0f/10.0f)));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(2076, 410, 1272).div(20.0f),false,100.0f/10.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(2446, 465, 2303).div(20.0f),false,100.0f/10.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-842, 410, -1141).div(20.0f),false,100.0f/10.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-207, 410, -1830).div(20.0f),false,100.0f/10.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(899, 460, -2015).div(20.0f),false,100.0f/10.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(1775, 460, -3448).div(20.0f),false,100.0f/10.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(1800, 460, -4154).div(20.0f),false,1000.0f/10.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-1727, 410, -387).div(20.0f),false,100.0f/10.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-1198, 410, -964).div(20.0f),false,100.0f/10.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-1778, 410, -1502).div(20.0f),false,100.0f/10.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-2692, 333, -2109).div(20.0f),false,100.0f/10.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-2849, 333, -1724).div(20.0f),false,100.0f/10.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-2019, 410, -729).div(20.0f),false,100.0f/10.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-1727, 410, -389).div(20.0f),false,100.0f/10.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-1337, 410, 122).div(20.0f),false,100.0f/10.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(615.8f, 305.5f, -904.1f).div(20.0f),false,200.0f/10.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(425.4f, 305.5f, -541.0f).div(20.0f),false,200.0f/10.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(501.4f, 305.5f, -102.7f).div(20.0f),false,200.0f/10.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(803.0f, 305.5f, 50.2f).div(20.0f),false,200.0f/10.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(720.4f, 261.6f, -329.2f).div(20.0f),false,75.0f/10.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(879.4f,261.6f,-246.3f).div(20.0f),false,75.0f/10.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(1037.7f,261.6f,-155.0f).div(20.0f),false,75.0f/10.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(663.4f,261.6f,-468.9f).div(20.0f),false,75.0f/10.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(772.3f,243.7f,-513.7f).div(20.0f),false,50.0f/10.0f));
lights.add(new Light(new Vector3f(1.2f + (float)Math.random(),1.1f,1.0f),new Vector3f(193.1f,260.7f,-859.3f).div(20.0f),false,50.0f/10.0f));
lights.add(new Light(new Vector3f(1.2f + (float)Math.random(),1.1f,1.0f),new Vector3f(51.0f,260.7f,-603.0f).div(20.0f),false,50.0f/10.0f));
lights.add(new Light(new Vector3f(1.2f + (float)Math.random(),1.1f,1.0f),new Vector3f(-95.0f,260.7f,-334.2f).div(20.0f),false,50.0f/10.0f));
lights.add(new Light(new Vector3f(1.2f + (float)Math.random(),1.1f,1.0f),new Vector3f(41.5f,260.7f,5.7f).div(20.0f),false,50.0f/10.0f));
lights.add(new Light(new Vector3f(1.2f + (float)Math.random(),1.1f,1.0f),new Vector3f(335.8f,260.7f,144.6f).div(20.0f),false,50.0f/10.0f));
lights.add(new Light(new Vector3f(1.2f + (float)Math.random(),1.1f,1.0f),new Vector3f(616.9f,260.7f,255.4f).div(20.0f),false,50.0f/10.0f));
lights.add(new Light(new Vector3f(0.75f,2.0f,0.75f),new Vector3f(1086, 425, -3375).div(20.0f),false,500.0f));
lights.add(new Light(new Vector3f(3.0f,2.25f,0.0f),new Vector3f(350.0f, 1500.0f, -420.0f),false,10000.0f));
lights.add(new Light(new Vector3f(3.0f,2.25f,0.0f),new Vector3f(400.0f, 1550.0f, -350.0f),false,10000.0f));
ILight[] lightArr = new ILight[lights.size()];
lightArr = lights.toArray(lightArr);
scene.GetLightingManager().AddLights(lightArr);
Vector3f Position = new Vector3f(-40, 5, 10);
SpawnPosition.set(Position);
rotationMatrix.set(new Matrix4f().rotateX((float)Math.random()).rotateY((float)Math.random()).rotateZ((float)Math.random()));
SpawnDirection.set(new Vector3f((float)Math.random()));
rotationMatrix.positiveZ(SpawnDirection).negate().mul(5);
SpawnPosition.add(SpawnDirection);
var Cube = new Actor3D("MelonaSpawned" + scene.GetActors().size(), CubeModelID, new Vector3f(SpawnPosition));
Cube.SetScale(5f);
ConvexMesh mesh = ConvexMesh.Box(0.5f,0.5f,0.5f);
Cube.CreatePhysicsController(mesh ,0);
Cube.SetPositionOffset(new Vector3f(0,0,0));
Cube.SetServerSynced(false);
scene.AddActor(Cube);
InitiateAudio(engineInstance);
for(int i = 0; i < ActorEditorComponents.size(); i++){
ActorEditorComponents.get(i).UpdateAll();
}
//if(PrimaryRuntime.IsServer) {
permutation.GeneratePermutationArray(5783904701859L);
// for(int x = -1; x < 2; x++){
// for(int y = -1; y < 2; y++){
// GenerateChunk(new Vector3i(x, 0, y), 16);
//
// }
// permutation.GeneratePermutationArray(5783904701859L);
// for(int x = -1; x < 2; x++){
// for(int y = -1; y < 2; y++){
// GenerateChunk(new Vector3i(x, 0, y), 16);
// }
// for(int i = 0; i < 20; i++){
// SpawnNewActor(engineInstance, new Vector3f(-5 + (float)Math.random() * 10,10 + (float)Math.random() * 10, -5 + (float)Math.random() * 10), new Vector3f(0, 0, 0), new Vector3f(1, 1, 1));
// }
//}
// }
// for(int i = 0; i < 20; i++){
// SpawnNewActor(engineInstance, new Vector3f(-5 + (float)Math.random() * 10,10 + (float)Math.random() * 10, -5 + (float)Math.random() * 10), new Vector3f(0, 0, 0), new Vector3f(1, 1, 1));
// }
Settings.textBuffer.set(ClientSideNetworkUtils.ServerIP);
Settings.UsernameBuffer.set("Player");
return new InitData(models,materials,guiTextures);
@ -348,7 +363,7 @@ public class GameCore implements GameLogic {
RigidPhysicsController physicsController = (RigidPhysicsController) Melona.GetPhysicsController();
//RigidBody.RigidBodyRegister.get(physicsController.RigidBodyID).LinearVelocity.set(0,0,-20f -(40f * (float)Math.random()));
scene.AddActor(Melona);
//scene.AddActor(Melona);
}
public void SetPlayerActorID(String id) {
this.PlayerActorID = id;

View file

@ -4,20 +4,28 @@ import imgui.ImGui;
import imgui.flag.ImGuiCond;
import imgui.flag.ImGuiWindowFlags;
import imgui.type.ImFloat;
import net.halbear.Terrain4J.EngineCore.Display.VulkanRenderer;
import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig;
import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance;
import net.halbear.Terrain4J.EngineCore.Main.AudioInstance;
import net.halbear.Terrain4J.EngineCore.Main.GameCore;
import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime;
import net.halbear.Terrain4J.EngineCore.Main.Scene.GUIOverlay;
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.Structure.DisplayToScreen.DeferredSceneRender;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DisplayToScreen.ForwardSceneRender;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Util.VulkanBuffer;
import org.tinylog.Logger;
public class PerformanceOverlay implements GUIOverlay {
private final ImFloat GammaValue = new ImFloat(0.8545f);
public int[] ShadowSize = new int[]{4096};
public int[] ShadowDistance = new int[]{1000};
public float[] Gamma = new float[]{1.75f};
public float[] Exposure = new float[]{2.5f};
public float[] BlurRadius = new float[]{2.5f};
public float[] SSAOscale = new float[]{1.0f};
public PerformanceOverlay(){
ShadowSize[0] = EngineConfig.getInstance().GetShadowMapSize();
@ -46,6 +54,64 @@ public class PerformanceOverlay implements GUIOverlay {
ImGui.separator();
ImGui.text("GRAPHICS SETTINGS:");
ImGui.text(" ");
// ImGui.text("Debug Options");
// ImGui.text(" ");
// if(ImGui.button("Debug On")){
// Logger.debug("Debug On");
// VulkanRenderer.Debug = true;
// }
// ImGui.sameLine();
// if(ImGui.button("Debug Off")){
// Logger.debug("Debug Off");
// VulkanRenderer.Debug = false;
// }
// if(ImGui.button("Albedo")){
// Logger.debug("Albedo");
// VulkanRenderer.debugMode = VulkanRenderer.DebugRenderMode.Albedo;
// }
// ImGui.sameLine();
// if(ImGui.button("Normals")){
// Logger.debug("Normals");
// VulkanRenderer.debugMode = VulkanRenderer.DebugRenderMode.Normals;
// }
// ImGui.sameLine();
// if(ImGui.button("PBR")){
// Logger.debug("PBR");
// VulkanRenderer.debugMode = VulkanRenderer.DebugRenderMode.PBR;
// }
// ImGui.sameLine();
// if(ImGui.button("SSAO")){
// Logger.debug("SSAO");
// VulkanRenderer.debugMode = VulkanRenderer.DebugRenderMode.SSAO;
// }
// if(ImGui.button("Position")){
// Logger.debug("Position");
// VulkanRenderer.debugMode = VulkanRenderer.DebugRenderMode.Pos;
// }
// ImGui.sameLine();
// if(ImGui.button("Emissive")){
// Logger.debug("Emissive");
// VulkanRenderer.debugMode = VulkanRenderer.DebugRenderMode.Emissive;
// }
// ImGui.sameLine();
// if(ImGui.button("Opacity")){
// Logger.debug("Opacity");
// VulkanRenderer.debugMode = VulkanRenderer.DebugRenderMode.Opacity;
// }
// ImGui.sameLine();
// if(ImGui.button("Translucency")){
// Logger.debug("Translucency");
// VulkanRenderer.debugMode = VulkanRenderer.DebugRenderMode.Translucency;
// }
// if(ImGui.button("No PostFX")){
// Logger.debug("No PostFX");
// VulkanRenderer.debugMode = VulkanRenderer.DebugRenderMode.NoPosProcess;
// }
// ImGui.sameLine();
// if(ImGui.button("Depth")){
// Logger.debug("Depth");
// VulkanRenderer.debugMode = VulkanRenderer.DebugRenderMode.Depth;
// }
ImGui.text("Rendering API:");
if(ImGui.button("Vulkan")){
Logger.debug("Switch to Vulkan");
@ -162,6 +228,18 @@ public class PerformanceOverlay implements GUIOverlay {
parent.CoolDown = 2000;
EngineConfig.getInstance().MaxShadowDistance(ShadowDistance[0]);
}
if (ImGui.sliderFloat("Gamma", Gamma, 0,10f)) {
PostProcess.GAMMA = Gamma[0];
}
if (ImGui.sliderFloat("Exposure", Exposure, 0,10f)) {
PostProcess.EXPOSURE = Exposure[0];
}
if (ImGui.sliderFloat("Bloom Radius", BlurRadius, 0,10f)) {
PostProcess.BLOOM_RADIUS = BlurRadius[0];
}
if (ImGui.sliderFloat("SSAO Resolution", SSAOscale, 0,2f)) {
AmbientOcclusionRenderer.SSAO_RESOLUTION_SCALE = SSAOscale[0];
}
ImGui.text(" ");
ImGui.text("anti aliasing:");
if(ImGui.button("No AA")){
@ -234,10 +312,6 @@ public class PerformanceOverlay implements GUIOverlay {
EngineConfig.getInstance().SetAlphaToCoverage(true);
if(engineInstance.window().GetLinkedApi() == EngineConfig.RenderAPI.Vulkan) PrimaryRuntime.GetRenderThread().GetRenderer().GetSceneRender().RebuildPipelines(PrimaryRuntime.GetRenderThread().GetRenderer().GetVulkanContext());
}
ImGui.inputFloat("Gamma", GammaValue, 0.0025f, 0.22725f, "%.4f");
if (ImGui.isItemDeactivatedAfterEdit()) {
// EngineConfig.getInstance().Gamma = GammaValue.get();
}
ImGui.separator();
ImGui.text("Level Tools:");
if(ImGui.button("Spawn Melona")){

View file

@ -32,9 +32,9 @@ public class SSAO_Utils {
}
public static ByteBuffer GenerateNoiseTexture() {
ByteBuffer buffer = BufferUtils.createByteBuffer(16 * 4 * Float.BYTES);
ByteBuffer buffer = BufferUtils.createByteBuffer(4 * 4 * 4 * Float.BYTES);
Random rnd = new Random();
for (int i = 0; i < 16; i++) {
for (int i = 0; i < 4 * 4; i++) {
float x = rnd.nextFloat() * 2.0f - 1.0f;
float y = rnd.nextFloat() * 2.0f - 1.0f;
buffer.putFloat(x);

View file

@ -82,7 +82,7 @@ public class LightRenderer {
lightSpecConsts = new LightSpecConsts();
ShaderModule[] shaderModules = CreateShaderModules(VkCtx, lightSpecConsts,true);
var textureSamplerInfo = new TextureSamplerInfo(VK_SAMPLER_ADDRESS_MODE_REPEAT,
var textureSamplerInfo = new TextureSamplerInfo(VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
VK_BORDER_COLOR_INT_OPAQUE_BLACK, 1, true);
textureSampler = new TextureSampler(VkCtx, textureSamplerInfo);
int numAttachments = attachments.size();
@ -155,7 +155,7 @@ public class LightRenderer {
SwapChain swapChain = VkCtx.GetSwapChain();
VkExtent2D swapChainExtent = swapChain.GetSwapChainExtent();
return new Attachment(VkCtx, swapChainExtent.width(), swapChainExtent.height(),
COLOUR_FORMAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,1);
COLOUR_FORMAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,1);
}
private static VkRenderingAttachmentInfo.Buffer CreateColourAttachmentInfo(Attachment attachment, VkClearValue clearValue) {

View file

@ -12,13 +12,16 @@ import static org.lwjgl.vulkan.VK10.VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
public class MultiRenderTargetAttachments {
public static final int ALBEDO_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT;
public static final int SSR_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT;
public static final int DEPTH_FORMAT = VK_FORMAT_D32_SFLOAT;
public static final int REFLECT_REFRACT = VK_FORMAT_R16G16_SFLOAT;
public static final int NORMAL_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT;
public static final int PBR_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT;
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_R32G32B32A32_SFLOAT;
public static final int VIEW_POS_FORMAT = VK_FORMAT_R16G16B16A16_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;
@ -53,6 +56,10 @@ public class MultiRenderTargetAttachments {
//Opacity
Attachment = new Attachment(VkCtx, Width, Height, OPACITY_FORMAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 1);
ColourAttachments.add(Attachment);
//ViewPos
Attachment = new Attachment(VkCtx, Width, Height, VIEW_POS_FORMAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 1);
ColourAttachments.add(Attachment);
DepthAttachment = new Attachment(VkCtx, Width, Height, DEPTH_FORMAT, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, 1);
}

View file

@ -11,6 +11,7 @@ import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.P
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Shader.*;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DeviceLayers.CommandBuffer;
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.Structure.SwapChain.SwapChain;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Util.VulkanBuffer;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Util.VulkanUtils;
@ -20,9 +21,12 @@ import org.lwjgl.util.shaderc.Shaderc;
import org.lwjgl.vulkan.*;
import org.tinylog.Logger;
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 org.lwjgl.vulkan.VK10.*;
import static org.lwjgl.vulkan.VK13.*;
@ -30,56 +34,124 @@ import static org.lwjgl.vulkan.VK13.*;
public class PostProcess {
public static final int COLOUR_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT;
private static final String DESCRIPTOR_ID_ATTACHMENT = "POST_DESC_ID_ATT";
private static final String DESCRIPTOR_ID_BLOOM_PROPERTIES_HORIZONTAL = "POST_DESC_ID_BLOOM_PROPERTIES_HORIZONTAL";
private static final String DESCRIPTOR_ID_BLOOM_PROPERTIES_VERTICAL = "POST_DESC_ID_BLOOM_PROPERTIES_VERTICAL";
private static final String DESCRIPTOR_ID_BLOOM_PROPERTIES_FINAL = "POST_DESC_ID_BLOOM_PROPERTIES_FINAL";
private static final String DESCRIPTOR_ID_BLOOM_ATTACHMENT = "POST_DESC_ID_BLOOM_ATT";
private static final String DESCRIPTOR_ID_BLOOM_PONG_ATTACHMENT = "POST_DESC_ID_BLOOM_PONG_ATT";
private static final String DESCRIPTOR_ID_BLOOM_IMAGE_ATTACHMENT = "POST_DESC_ID_BLOOM_IMAGE_ATT";
private static final String DESCRIPTOR_ID_SCREEN_SIZE = "POST_DESC_ID_SCREEN_SIZE";
private static final String MULTI_PASS_FRAGMENT_SHADER_FILE_GLSL = "resources/EngineResources/shaders/multi-sampled_post_process_frag.glsl";
private static final String MULTI_PASS_FRAGMENT_SHADER_FILE_SPV = MULTI_PASS_FRAGMENT_SHADER_FILE_GLSL + ".spv";
private static final String BLOOM_FRAGMENT_SHADER_FILE_GLSL = "resources/EngineResources/shaders/bloom_pass_frag.glsl";
private static final String BLOOM_FRAGMENT_SHADER_FILE_SPV = BLOOM_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/basic_screen_vertex.glsl";
private static final String VERTEX_SHADER_FILE_SPV = VERTEX_SHADER_FILE_GLSL + ".spv";
private final DescriptorSetLayout AttachmentDescriptorSetLayout;
private final DescriptorSetLayout[] MultiAttachmentDescriptorSetLayout = new DescriptorSetLayout[2];
private final VkClearValue ClearValueColour;
private final DescriptorSetLayout FragmentUniformDescriptorSetLayout;
private final Pipeline pipeline;
private final Pipeline bloomPipeline;
private final VulkanBuffer ScreenSizeBuffer;
private final VulkanBuffer BloomPropertiesHorizontalBuffer;
private final VulkanBuffer BloomPropertiesVerticalBuffer;
private final VulkanBuffer BloomPropertiesFinalBuffer;
private final SpecializationConstants specConstants;
private final TextureSampler textureSampler;
private Attachment ColourAttachment;
private VkRenderingAttachmentInfo.Buffer ColourAttachmentInfo;
private VkRenderingAttachmentInfo.Buffer FinalOutputInfo;
private Attachment BloomPingAttachment;
private Attachment BloomPongAttachment;
private Attachment FinalAttachment;
private VkRenderingAttachmentInfo.Buffer BloomPingAttachmentInfo;
private VkRenderingAttachmentInfo.Buffer BloomPongAttachmentInfo;
private VkRenderingInfo RenderingInfo;
private VkRenderingInfo SingleRenderingInfo;
private VkRenderingInfo BloomPingRenderingInfo;
private VkRenderingInfo BloomPongRenderingInfo;
public PostProcess(VulkanContext VkCtx, Attachment SrcAttachment){
ClearValueColour = VkClearValue.calloc();
ClearValueColour.color(c->c.float32(0,0.0f).float32(1,0.0f).float32(2,0.0f).float32(3,0.0f));
ColourAttachment = CreateColourAttachment(VkCtx);
ColourAttachmentInfo = CreateColourAttachmentInfo(ColourAttachment,ClearValueColour);
RenderingInfo = CreateRenderInfo(ColourAttachment,ColourAttachmentInfo);
BloomPingAttachment = CreateColourAttachment(VkCtx);
BloomPongAttachment = CreateColourAttachment(VkCtx);
FinalAttachment = CreateColourAttachment(VkCtx);
var TextureSamplerInfo = new TextureSamplerInfo(VK_SAMPLER_ADDRESS_MODE_REPEAT,VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK,1,true);
textureSampler = new TextureSampler(VkCtx, TextureSamplerInfo);
List<Attachment> attachments = new ArrayList<>();
attachments.add(ColourAttachment);
attachments.add(BloomPingAttachment);
ColourAttachmentInfo = CreateColourAttachmentInfos(attachments,ClearValueColour);
BloomPingAttachmentInfo = CreateColourAttachmentInfo(BloomPingAttachment,ClearValueColour);
BloomPongAttachmentInfo = CreateColourAttachmentInfo(BloomPongAttachment,ClearValueColour);
FinalOutputInfo = CreateColourAttachmentInfo(FinalAttachment,ClearValueColour);
RenderingInfo = CreateRenderInfo(ColourAttachment,ColourAttachmentInfo);
BloomPingRenderingInfo = CreateRenderInfo(BloomPingAttachment, BloomPingAttachmentInfo);
BloomPongRenderingInfo = CreateRenderInfo(BloomPongAttachment, BloomPongAttachmentInfo);
SingleRenderingInfo = CreateRenderInfo(FinalAttachment,FinalOutputInfo);
var textureSamplerInfo = new TextureSamplerInfo(VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
VK_BORDER_COLOR_INT_OPAQUE_BLACK, 1, true);
textureSampler = new TextureSampler(VkCtx, textureSamplerInfo);
DescriptorSetLayout.LayoutInformation[] descSetLayouts = new DescriptorSetLayout.LayoutInformation[2];
for (int i = 0; i < 2; i++) {
descSetLayouts[i] = new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, i, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
}
var LayoutInfo = new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,0,1,VK_SHADER_STAGE_FRAGMENT_BIT);
AttachmentDescriptorSetLayout = new DescriptorSetLayout(VkCtx, LayoutInfo);
CreateAttachmentDescriptorSet(VkCtx, AttachmentDescriptorSetLayout, SrcAttachment,textureSampler);
MultiAttachmentDescriptorSetLayout[0] = new DescriptorSetLayout(VkCtx, descSetLayouts);
CreateAttachmentDescriptorSet(VkCtx, AttachmentDescriptorSetLayout, SrcAttachment,textureSampler, DESCRIPTOR_ID_ATTACHMENT);
CreateAttachmentDescriptorSets(VkCtx, MultiAttachmentDescriptorSetLayout[0], new Attachment[]{BloomPingAttachment, BloomPingAttachment},textureSampler, DESCRIPTOR_ID_BLOOM_ATTACHMENT);
CreateAttachmentDescriptorSets(VkCtx, MultiAttachmentDescriptorSetLayout[0], new Attachment[]{BloomPongAttachment, BloomPongAttachment},textureSampler, DESCRIPTOR_ID_BLOOM_PONG_ATTACHMENT);
CreateAttachmentDescriptorSets(VkCtx, MultiAttachmentDescriptorSetLayout[0], new Attachment[]{ColourAttachment, BloomPingAttachment},textureSampler, DESCRIPTOR_ID_BLOOM_IMAGE_ATTACHMENT);
LayoutInfo = new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0,1,VK_SHADER_STAGE_FRAGMENT_BIT);
FragmentUniformDescriptorSetLayout = new DescriptorSetLayout(VkCtx, LayoutInfo);
ScreenSizeBuffer = VulkanUtils.CreateHostVisibleBuffer(VkCtx, VulkanUtils.VEC2_SIZE, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,DESCRIPTOR_ID_SCREEN_SIZE,FragmentUniformDescriptorSetLayout);
BloomPropertiesHorizontalBuffer = VulkanUtils.CreateHostVisibleBuffer(VkCtx, VulkanUtils.BOOLEAN_SIZE * 2 + VulkanUtils.FLOAT_SIZE * 2+ VulkanUtils.VEC4_SIZE, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,DESCRIPTOR_ID_BLOOM_PROPERTIES_HORIZONTAL,FragmentUniformDescriptorSetLayout);
BloomPropertiesVerticalBuffer = VulkanUtils.CreateHostVisibleBuffer(VkCtx, VulkanUtils.BOOLEAN_SIZE * 2 + VulkanUtils.FLOAT_SIZE * 2 + VulkanUtils.VEC4_SIZE, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,DESCRIPTOR_ID_BLOOM_PROPERTIES_VERTICAL,FragmentUniformDescriptorSetLayout);
BloomPropertiesFinalBuffer = VulkanUtils.CreateHostVisibleBuffer(VkCtx, VulkanUtils.BOOLEAN_SIZE * 2 + VulkanUtils.FLOAT_SIZE * 2+ VulkanUtils.VEC4_SIZE, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,DESCRIPTOR_ID_BLOOM_PROPERTIES_FINAL,FragmentUniformDescriptorSetLayout);
SetScreenSizeBuffer(VkCtx);
SetBloomPropertiesBuffer(VkCtx, BloomPropertiesHorizontalBuffer, true, false);
SetBloomPropertiesBuffer(VkCtx, BloomPropertiesVerticalBuffer, false, false);
SetBloomPropertiesBuffer(VkCtx, BloomPropertiesFinalBuffer, false, true);
specConstants = new SpecializationConstants();
ShaderModule[] shaderModules = CreateShaderModules(VkCtx, specConstants);
pipeline = CreatePipeline(VkCtx, shaderModules, new DescriptorSetLayout[]{AttachmentDescriptorSetLayout, FragmentUniformDescriptorSetLayout});
Arrays.asList(shaderModules).forEach(shader->shader.CleanUp(VkCtx));
shaderModules = CreateBloomShaderModules(VkCtx, specConstants);
bloomPipeline = CreateSingleOutputPipeline(VkCtx, shaderModules, new DescriptorSetLayout[]{MultiAttachmentDescriptorSetLayout[0], FragmentUniformDescriptorSetLayout});
Logger.debug("Post Process Renderer Pipeline -> [{}]",pipeline.GetVulkanPipeline());
}
private static VkRenderingAttachmentInfo.Buffer CreateColourAttachmentInfos(List<Attachment> attachments, VkClearValue ClearValue){
int numAttachments = attachments.size();
VkRenderingAttachmentInfo.Buffer result = VkRenderingAttachmentInfo.calloc(numAttachments);
for (int i = 0; i < numAttachments; ++i) {
result.get(i)
.sType$Default()
.imageView(attachments.get(i).GetVkImageView().GetVulkanImageView())
.imageLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)
.loadOp(VK_ATTACHMENT_LOAD_OP_CLEAR)
.storeOp(VK_ATTACHMENT_STORE_OP_STORE)
.clearValue(ClearValue);
}
return result;
}
private static Attachment CreateColourAttachment(VulkanContext VkCtx){
SwapChain swapChain = VkCtx.GetSwapChain();
VkExtent2D SwapChainExtent = swapChain.GetSwapChainExtent();
return new Attachment(VkCtx,SwapChainExtent.width(),SwapChainExtent.height(),COLOUR_FORMAT,VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
return new Attachment(VkCtx,SwapChainExtent.width(),SwapChainExtent.height(),COLOUR_FORMAT,VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
}
private static VkRenderingAttachmentInfo.Buffer CreateColourAttachmentInfo(Attachment SrcAttachment, VkClearValue ClearValue){
@ -94,8 +166,20 @@ public class PostProcess {
private static Pipeline CreatePipeline(VulkanContext VkCtx, ShaderModule[] shaderModules, DescriptorSetLayout[] descriptorSetLayouts){
var VertexBufferStruct = new EmptyVertexBufferStruct();
var BuildInfo = new PipelineBuildInfo(shaderModules,VertexBufferStruct.GetVertexInput(),new int[]{COLOUR_FORMAT}).SetDescriptorSetLayouts(descriptorSetLayouts).BlendingIsUsed(true);
var PipeLine = new DefaultPipeline(VkCtx,BuildInfo);
var BuildInfo = new PipelineBuildInfo(shaderModules, VertexBufferStruct.GetVertexInput(), new int[]{COLOUR_FORMAT, COLOUR_FORMAT})
.SetDescriptorSetLayouts(descriptorSetLayouts)
.BlendingIsUsed(true);
var PipeLine = new DefaultPipeline(VkCtx, BuildInfo);
VertexBufferStruct.CleanUp();
return PipeLine;
}
private static Pipeline CreateSingleOutputPipeline(VulkanContext VkCtx, ShaderModule[] shaderModules, DescriptorSetLayout[] descriptorSetLayouts){
var VertexBufferStruct = new EmptyVertexBufferStruct();
var BuildInfo = new PipelineBuildInfo(shaderModules, VertexBufferStruct.GetVertexInput(), new int[]{COLOUR_FORMAT})
.SetDescriptorSetLayouts(descriptorSetLayouts)
.BlendingIsUsed(true);
var PipeLine = new DefaultPipeline(VkCtx, BuildInfo);
VertexBufferStruct.CleanUp();
return PipeLine;
}
@ -116,13 +200,37 @@ public class PostProcess {
return renderingInfo;
}
private static void CreateAttachmentDescriptorSet(VulkanContext VkCtx, DescriptorSetLayout descriptorSetLayout, Attachment attachment, TextureSampler textureSampler){
private static void CreateAttachmentDescriptorSets(VulkanContext VkCtx, DescriptorSetLayout descriptorSetLayout, Attachment[] attachment, TextureSampler textureSampler, String descriptorID){
DescriptorAllocator descriptorAllocator = VkCtx.GetDescriptorAllocator();
Device device = VkCtx.GetDevice();
DescriptorSet descriptorSet = descriptorAllocator.AddDescriptorSets(device,DESCRIPTOR_ID_ATTACHMENT,1 , descriptorSetLayout)[0];
DescriptorSet descriptorSet = descriptorAllocator.AddDescriptorSets(device,descriptorID,1 , descriptorSetLayout)[0];
List<ImageView> images = new ArrayList<>();
for(int i = 0; i < attachment.length; i++) {
images.add(attachment[i].GetVkImageView());
}
descriptorSet.SetImages(device,images,textureSampler,0);
}
private static void CreateAttachmentDescriptorSet(VulkanContext VkCtx, DescriptorSetLayout descriptorSetLayout, Attachment attachment, TextureSampler textureSampler, String descriptorID){
DescriptorAllocator descriptorAllocator = VkCtx.GetDescriptorAllocator();
Device device = VkCtx.GetDevice();
DescriptorSet descriptorSet = descriptorAllocator.AddDescriptorSets(device,descriptorID,1 , descriptorSetLayout)[0];
descriptorSet.SetImage(device,attachment.GetVkImageView(),textureSampler,0);
}
private static ShaderModule[] CreateBloomShaderModules(VulkanContext VkCtx, SpecializationConstants specConstants){
if(EngineConfig.getInstance().RecompileShaders()){
ShaderCompiler.CompileGLSLShaderOnChange(VERTEX_SHADER_FILE_GLSL, Shaderc.shaderc_glsl_vertex_shader);
ShaderCompiler.CompileGLSLShaderOnChange(BLOOM_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,BLOOM_FRAGMENT_SHADER_FILE_SPV,null)
};
}
private static ShaderModule[] CreateShaderModules(VulkanContext VkCtx, SpecializationConstants specConstants){
String ShaderPath = SINGLE_PASS_FRAGMENT_SHADER_FILE_GLSL;
if(EngineConfig.getInstance().RecompileShaders()){
@ -140,6 +248,9 @@ public class PostProcess {
}
public void Render(VulkanContext VkCtx, CommandBuffer commandBuffer, Attachment SrcAttachment){
SetBloomPropertiesBuffer(VkCtx, BloomPropertiesHorizontalBuffer, true, false);
SetBloomPropertiesBuffer(VkCtx, BloomPropertiesVerticalBuffer, false, false);
SetBloomPropertiesBuffer(VkCtx, BloomPropertiesFinalBuffer, false, true);
try(var MemStack = MemoryStack.stackPush()){
SwapChain swapChain = VkCtx.GetSwapChain();
VkCommandBuffer CommandHandle = commandBuffer.GetVulkanCommandBuffer();
@ -150,6 +261,12 @@ public class PostProcess {
VulkanUtils.ImageBarrier(MemStack,CommandHandle,ColourAttachment.GetVkImage().getVulkanImage(),
VK_IMAGE_LAYOUT_UNDEFINED,VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT,VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT,
VK_ACCESS_2_NONE,VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT,VK_IMAGE_ASPECT_COLOR_BIT);
VulkanUtils.ImageBarrier(MemStack,CommandHandle,BloomPingAttachment.GetVkImage().getVulkanImage(),
VK_IMAGE_LAYOUT_UNDEFINED,VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT,VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT,
VK_ACCESS_2_NONE,VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT,VK_IMAGE_ASPECT_COLOR_BIT);
VulkanUtils.ImageBarrier(MemStack,CommandHandle,BloomPongAttachment.GetVkImage().getVulkanImage(),
VK_IMAGE_LAYOUT_UNDEFINED,VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT,VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT,
VK_ACCESS_2_NONE,VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT,VK_IMAGE_ASPECT_COLOR_BIT);
vkCmdBeginRendering(CommandHandle,RenderingInfo);
vkCmdBindPipeline(CommandHandle,VK_PIPELINE_BIND_POINT_GRAPHICS,pipeline.GetVulkanPipeline());
@ -177,9 +294,82 @@ public class PostProcess {
vkCmdBindDescriptorSets(CommandHandle,VK_PIPELINE_BIND_POINT_GRAPHICS,pipeline.GetVulkanPipelineLayout(),0,DescriptorSets,null);
vkCmdDraw(CommandHandle,3,1,0,0);
vkCmdEndRendering(CommandHandle);
VulkanUtils.ImageBarrier(MemStack,CommandHandle,ColourAttachment.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(MemStack,CommandHandle,BloomPingAttachment.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);
int Passes = 10;
boolean bloomPongHasBeenWritten = false;
for(int i = 0; i < Passes; i++){
boolean writePong = i % 2 == 0;
Attachment srcBloomAttachment = writePong ? BloomPingAttachment : BloomPongAttachment;
Attachment dstBloomAttachment = writePong ? BloomPongAttachment : BloomPingAttachment;
VkRenderingInfo dstRenderingInfo = writePong ? BloomPongRenderingInfo : BloomPingRenderingInfo;
String srcDescriptorId = writePong ? DESCRIPTOR_ID_BLOOM_ATTACHMENT : DESCRIPTOR_ID_BLOOM_PONG_ATTACHMENT;
String bloomPropertiesDescriptorId = writePong ? DESCRIPTOR_ID_BLOOM_PROPERTIES_HORIZONTAL : DESCRIPTOR_ID_BLOOM_PROPERTIES_VERTICAL;
int dstOldLayout = writePong && !bloomPongHasBeenWritten
? VK_IMAGE_LAYOUT_UNDEFINED
: VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
VulkanUtils.ImageBarrier(MemStack,CommandHandle,dstBloomAttachment.GetVkImage().getVulkanImage(),
dstOldLayout,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(CommandHandle,dstRenderingInfo);
vkCmdBindPipeline(CommandHandle,VK_PIPELINE_BIND_POINT_GRAPHICS,bloomPipeline.GetVulkanPipeline());
vkCmdSetViewport(CommandHandle,0,Viewport);
vkCmdSetScissor(CommandHandle,0,Scissor);
LongBuffer BloomDescriptorSets = MemStack.mallocLong(2)
.put(0,descriptorAllocator.GetDescriptorSet(srcDescriptorId).GetVkDescriptorSet())
.put(1,descriptorAllocator.GetDescriptorSet(bloomPropertiesDescriptorId).GetVkDescriptorSet());
vkCmdBindDescriptorSets(CommandHandle,VK_PIPELINE_BIND_POINT_GRAPHICS,bloomPipeline.GetVulkanPipelineLayout(),0,BloomDescriptorSets,null);
vkCmdDraw(CommandHandle,3,1,0,0);
vkCmdEndRendering(CommandHandle);
VulkanUtils.ImageBarrier(MemStack,CommandHandle,dstBloomAttachment.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);
if(writePong){
bloomPongHasBeenWritten = true;
}
}
VulkanUtils.ImageBarrier(MemStack,CommandHandle,FinalAttachment.GetVkImage().getVulkanImage(),
VK_IMAGE_LAYOUT_UNDEFINED,VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT,VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT,
VK_ACCESS_2_NONE,VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT,
VK_IMAGE_ASPECT_COLOR_BIT);
vkCmdBeginRendering(CommandHandle,SingleRenderingInfo);
vkCmdBindPipeline(CommandHandle,VK_PIPELINE_BIND_POINT_GRAPHICS,bloomPipeline.GetVulkanPipeline());
vkCmdSetViewport(CommandHandle,0,Viewport);
vkCmdSetScissor(CommandHandle,0,Scissor);
LongBuffer BloomDescriptorSets = MemStack.mallocLong(2)
.put(0,descriptorAllocator.GetDescriptorSet(DESCRIPTOR_ID_BLOOM_IMAGE_ATTACHMENT).GetVkDescriptorSet())
.put(1,descriptorAllocator.GetDescriptorSet(DESCRIPTOR_ID_BLOOM_PROPERTIES_FINAL).GetVkDescriptorSet());
vkCmdBindDescriptorSets(CommandHandle,VK_PIPELINE_BIND_POINT_GRAPHICS,bloomPipeline.GetVulkanPipelineLayout(),0,BloomDescriptorSets,null);
vkCmdDraw(CommandHandle,3,1,0,0);
vkCmdEndRendering(CommandHandle);
}
}
public void Resize(VulkanContext VkCtx, Attachment SrcAttachment){
RenderingInfo.free();;
ColourAttachment.CleanUp(VkCtx);
@ -188,11 +378,14 @@ public class PostProcess {
ColourAttachmentInfo = CreateColourAttachmentInfo(ColourAttachment,ClearValueColour);
RenderingInfo = CreateRenderInfo(ColourAttachment,ColourAttachmentInfo);
DescriptorAllocator descriptorAllocator = VkCtx.GetDescriptorAllocator();
DescriptorSet descriptorSet = descriptorAllocator.GetDescriptorSet(DESCRIPTOR_ID_ATTACHMENT);
descriptorSet.SetImage(VkCtx.GetDevice(),SrcAttachment.GetVkImageView(),textureSampler,0);
CreateAttachmentDescriptorSet(VkCtx, AttachmentDescriptorSetLayout, SrcAttachment,textureSampler, DESCRIPTOR_ID_ATTACHMENT);
CreateAttachmentDescriptorSets(VkCtx, MultiAttachmentDescriptorSetLayout[0], new Attachment[]{BloomPingAttachment, BloomPingAttachment},textureSampler, DESCRIPTOR_ID_BLOOM_ATTACHMENT);
CreateAttachmentDescriptorSets(VkCtx, MultiAttachmentDescriptorSetLayout[0], new Attachment[]{BloomPongAttachment, BloomPongAttachment},textureSampler, DESCRIPTOR_ID_BLOOM_PONG_ATTACHMENT);
CreateAttachmentDescriptorSets(VkCtx, MultiAttachmentDescriptorSetLayout[0], new Attachment[]{ColourAttachment, BloomPingAttachment},textureSampler, DESCRIPTOR_ID_BLOOM_IMAGE_ATTACHMENT);
SetScreenSizeBuffer(VkCtx);
SetBloomPropertiesBuffer(VkCtx, BloomPropertiesHorizontalBuffer, true, false);
SetBloomPropertiesBuffer(VkCtx, BloomPropertiesVerticalBuffer, false, false);
SetBloomPropertiesBuffer(VkCtx, BloomPropertiesFinalBuffer, false, true);
}
private void SetScreenSizeBuffer(VulkanContext VkCtx){
@ -204,11 +397,35 @@ public class PostProcess {
ScreenSizeBuffer.UnMapMemory(VkCtx);
}
public Attachment GetAttachment(){return ColourAttachment;}
public static float GAMMA = 1.75f;
public static float EXPOSURE = 2.5f;
public static float BLOOM_RADIUS = 2.5f;
private void SetBloomPropertiesBuffer(VulkanContext VkCtx, VulkanBuffer buffer, boolean horizontal, boolean Complete){
long MappedMemory = buffer.MapMemory(VkCtx);
ByteBuffer dataBuffer = MemoryUtil.memByteBuffer(MappedMemory,(int)buffer.GetRequestedSize());
int Offset = 0;
dataBuffer.putInt(Offset,Complete ? 1 : 0);
Offset += VulkanUtils.BOOLEAN_SIZE;
dataBuffer.putInt(Offset,horizontal ? 1 : 0);
Offset += VulkanUtils.BOOLEAN_SIZE;
dataBuffer.putFloat(Offset,GAMMA);
Offset += VulkanUtils.FLOAT_SIZE;
dataBuffer.putFloat(Offset,EXPOSURE);
Offset += VulkanUtils.FLOAT_SIZE;
dataBuffer.putFloat(Offset,BLOOM_RADIUS);
Offset += VulkanUtils.FLOAT_SIZE;
buffer.UnMapMemory(VkCtx);
}
public Attachment GetAttachment(){return FinalAttachment;}
public void CleanUp(VulkanContext VkCtx){
ClearValueColour.free();
ColourAttachment.CleanUp(VkCtx);
BloomPingAttachment.CleanUp(VkCtx);
BloomPongAttachment.CleanUp(VkCtx);
FinalAttachment.CleanUp(VkCtx);
textureSampler.CleanUp(VkCtx);
AttachmentDescriptorSetLayout.CleanUp(VkCtx);
FragmentUniformDescriptorSetLayout.CleanUp(VkCtx);
@ -216,6 +433,9 @@ public class PostProcess {
RenderingInfo.free();
ColourAttachmentInfo.free();
ScreenSizeBuffer.cleanup(VkCtx);
BloomPropertiesHorizontalBuffer.cleanup(VkCtx);
BloomPropertiesVerticalBuffer.cleanup(VkCtx);
BloomPropertiesFinalBuffer.cleanup(VkCtx);
specConstants.CleanUp();
}
}

View file

@ -34,8 +34,7 @@ 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 net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.DeferredRendering.MultiRenderTargetAttachments.*;
import static org.lwjgl.vulkan.VK10.*;
import static org.lwjgl.vulkan.VK10.VK_SHADER_STAGE_FRAGMENT_BIT;
import static org.lwjgl.vulkan.VK13.*;
@ -47,9 +46,9 @@ public class AmbientOcclusionRenderer {
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 int SSAO_KERNEL_SIZE = 64;
private static final float SSAO_RADIUS = 2.75f;
private static final float SSAO_BIAS = 0.25f;
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";
@ -67,7 +66,9 @@ public class AmbientOcclusionRenderer {
private VkRenderingAttachmentInfo.Buffer ssaoAttachmentInfo;
private Attachment ssaoBlurAttachment;
private VkRenderingAttachmentInfo.Buffer ssaoBlurAttachmentInfo;
private final Attachment[] SSAO_ATTACHMENTS = new Attachment[2];
private Attachment ssaoViewPosAttachment;
private VkRenderingAttachmentInfo.Buffer ssaoViewPosAttachmentInfo;
private final Attachment[] SSAO_ATTACHMENTS = new Attachment[3];
private final Pipeline ssaoPipeline;
private final Pipeline blurPipeline;
@ -90,14 +91,15 @@ public class AmbientOcclusionRenderer {
public AmbientOcclusionRenderer(VulkanContext VkCtx, List<Attachment> MRTAttachments, Queue queue) {
List<Attachment> attachments = new ArrayList<>();
attachments.add(MRTAttachments.get(0)); // position
attachments.add(MRTAttachments.get(7)); // 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,
ssaoViewPosAttachmentInfo = CreateColourAttachmentInfo(ssaoViewPosAttachment, clearColour);
var textureSamplerInfo = new TextureSamplerInfo(VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
VK_BORDER_COLOR_INT_OPAQUE_BLACK, 1, true);
textureSampler = new TextureSampler(VkCtx, textureSamplerInfo);
@ -118,9 +120,9 @@ public class AmbientOcclusionRenderer {
attachments.add(NoiseImageAttachment);
ssaoKernelDescriptorLayout = new DescriptorSetLayout(VkCtx, new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
ssaoKernelDescriptorLayout = new DescriptorSetLayout(VkCtx, new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
0, 1, VK_SHADER_STAGE_FRAGMENT_BIT));
sampleKernelBuffer = VulkanUtils.CreateHostVisibleBuffer(VkCtx, SSAO_KERNEL_BUFFER_SIZE, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
sampleKernelBuffer = VulkanUtils.CreateHostVisibleBuffer(VkCtx, SSAO_KERNEL_BUFFER_SIZE, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
DESC_ID_SSAO_KERNEL, ssaoKernelDescriptorLayout);
long MappedMemory = sampleKernelBuffer.MapMemory(VkCtx);
FloatBuffer KernelBuffer = SSAO_Utils.GenerateSampleKernel(SSAO_KERNEL_SIZE, MappedMemory);
@ -137,16 +139,20 @@ public class AmbientOcclusionRenderer {
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 ));
DescriptorSetLayout.LayoutInformation[] descriptorSetLayouts = new DescriptorSetLayout.LayoutInformation[]{
new DescriptorSetLayout.LayoutInformation( VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
0,1,VK_SHADER_STAGE_FRAGMENT_BIT ),
new DescriptorSetLayout.LayoutInformation( VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
1,1,VK_SHADER_STAGE_FRAGMENT_BIT )};
blurDescriptorLayout = new DescriptorSetLayout(VkCtx,descriptorSetLayouts);
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);
ssaoRenderInfo = CreateRenderInfo(ssaoAttachment, ssaoAttachmentInfo,true);
ssaoBlurRenderInfo = CreateRenderInfo(ssaoBlurAttachment, ssaoBlurAttachmentInfo,false);
ShaderModule[] shaderModules = CreateRawShaderModules(VkCtx);
ssaoPipeline = CreatePipeline(VkCtx, shaderModules,
@ -159,15 +165,20 @@ public class AmbientOcclusionRenderer {
shaderModules = CreateBlurShaderModules(VkCtx);
blurPipeline = CreatePipeline( VkCtx, shaderModules,
new DescriptorSetLayout[]{ blurDescriptorLayout },
true );
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})
int[] formats;
if(blur){
formats = new int[]{SSAO_BLUR_ATTACHMENT, VIEW_POS_FORMAT};
} else {
formats = new int[]{SSAO_RAW_ATTACHMENT, VIEW_POS_FORMAT};
}
var buildInfo = new PipelineBuildInfo(shaderModules, vtxBuffStruct.GetVertexInput(),formats)
.SetDescriptorSetLayouts(descSetLayouts)
.BlendingIsUsed(false)
.SetDepthWrite(false)
@ -209,14 +220,17 @@ public class AmbientOcclusionRenderer {
.clearValue(clearValue);
}
private static VkRenderingInfo CreateRenderInfo(Attachment attachment, VkRenderingAttachmentInfo.Buffer attachmentInfo) {
private static VkRenderingInfo CreateRenderInfo(Attachment attachment, VkRenderingAttachmentInfo.Buffer attachmentInfo, boolean Raw) {
int Width = attachment.GetVkImage().GetWidth();
int Height = attachment.GetVkImage().GetHeight();
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())))
.width(Width)
.height(Height)))
.layerCount(1)
.pColorAttachments(attachmentInfo);
}
@ -236,19 +250,31 @@ public class AmbientOcclusionRenderer {
DescriptorSet descSet = vkCtx.GetDescriptorAllocator().AddDescriptorSet(
vkCtx.GetDevice(),DESC_ID_SSAO_BLUR_INPUT, blurDescriptorLayout);
descSet.SetImage(vkCtx.GetDevice(), ssaoAttachment.GetVkImageView(),
textureSampler,0);
List<ImageView> imageViews = new ArrayList<>();
imageViews.add(ssaoAttachment.GetVkImageView());
imageViews.add(ssaoViewPosAttachment.GetVkImageView());
descSet.SetImages(vkCtx.GetDevice(), imageViews,textureSampler,0);
}
private void CreateAttachments(VulkanContext VkCtx){
SwapChain swapChain = VkCtx.GetSwapChain();
VkExtent2D swapChainExtent = swapChain.GetSwapChainExtent();
float AspectRatio = (float)swapChainExtent.width()/(float)swapChainExtent.height();
int Width = swapChainExtent.width();
int Height = swapChainExtent.height();
int RawWidth = (int)(Math.round(Math.min(swapChainExtent.width()/2.0f, 1920 * AspectRatio)));
int RawHeight = (int)(Math.round(Math.min(swapChainExtent.height()/2.0f, 1080)));
//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);
ssaoAttachment = new Attachment(VkCtx, Width, 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);
ssaoBlurAttachment = new Attachment(VkCtx, Width, Height, SSAO_BLUR_ATTACHMENT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, 1);
SSAO_ATTACHMENTS[1] = ssaoBlurAttachment;
ssaoViewPosAttachment = new Attachment(VkCtx, Width, Height, VIEW_POS_FORMAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, 1);
SSAO_ATTACHMENTS[1] = ssaoViewPosAttachment;
}
public void Render(VulkanContext VkCtx,EngineInstance engineInstance, CommandBuffer cmdBuffer, MultiRenderTargetAttachments MRT,int CurrentFrame) {
@ -268,6 +294,15 @@ public class AmbientOcclusionRenderer {
VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT,
VK_IMAGE_ASPECT_COLOR_BIT);
VulkanUtils.ImageBarrier(stack, cmdHandle, ssaoViewPosAttachment.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);
@ -371,6 +406,8 @@ public class AmbientOcclusionRenderer {
vkCmdSetScissor(cmdHandle, 0, scissor);
}
public static float SSAO_RESOLUTION_SCALE = 0.5f;
private void UpdateSSAOInfo(VulkanContext vkCtx, EngineInstance engineInstance, int currentFrame) {
VulkanBuffer buffer = ssaoInfoBuffers[currentFrame];
long mappedMemory = buffer.MapMemory(vkCtx);
@ -383,15 +420,16 @@ public class AmbientOcclusionRenderer {
engineInstance.scene().GetCamera().GetViewMatrix().get(offset, data);
offset += VulkanUtils.MATRIX4X4_SIZE;
//SSAO Raw
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);
offset +=VulkanUtils.INT_SIZE;
data.putFloat(offset, SSAO_RESOLUTION_SCALE);
offset += VulkanUtils.FLOAT_SIZE;
buffer.UnMapMemory(vkCtx);
}
@ -411,8 +449,8 @@ public class AmbientOcclusionRenderer {
ssaoAttachmentInfo = CreateColourAttachmentInfo(ssaoAttachment, clearColour);
ssaoBlurAttachmentInfo = CreateColourAttachmentInfo(ssaoBlurAttachment, clearColour);
ssaoRenderInfo = CreateRenderInfo(ssaoAttachment, ssaoAttachmentInfo);
ssaoBlurRenderInfo = CreateRenderInfo(ssaoBlurAttachment, ssaoBlurAttachmentInfo);
ssaoRenderInfo = CreateRenderInfo(ssaoAttachment, ssaoAttachmentInfo,true);
ssaoBlurRenderInfo = CreateRenderInfo(ssaoBlurAttachment, ssaoBlurAttachmentInfo,false);
attachments.add(NoiseImageAttachment);

View file

@ -0,0 +1,310 @@
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.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.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.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.joml.Matrix4f;
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.LongBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.DeferredRendering.MultiRenderTargetAttachments.*;
import static org.lwjgl.vulkan.VK10.*;
import static org.lwjgl.vulkan.VK13.*;
public class ReflectionsRenderer {
private static final long SSR_INFO_BUFFER_SIZE =
VulkanUtils.MATRIX4X4_SIZE + // projection
VulkanUtils.MATRIX4X4_SIZE + // projection inv
VulkanUtils.MATRIX4X4_SIZE + // view
VulkanUtils.MATRIX4X4_SIZE + // view inv
VulkanUtils.VEC4_SIZE + // steps, distance, max steps
VulkanUtils.VEC4_SIZE; //Camera
public static float STEP_SIZE = 0.25f;
public static float MAX_DIST = 200.0f;
public static int MAX_STEPS = 64;
private static final String DESC_ID_SSR_ATTACHMENTS = "SSR_DESC_ID_ATTACHMENTS";
private static final String DESC_ID_SSR_INFO = "SSR_DESC_ID_INFO";
private static final String FRAGMENT_SHADER_FILE_GLSL = "resources/EngineResources/shaders/screen_space_reflection_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 ssrAttachment;
private Attachment renderedSceneAttachment;
private VkRenderingAttachmentInfo.Buffer ssrAttachmentInfo;
private final Pipeline ssrPipeline;
private final TextureSampler textureSampler;
private DescriptorSetLayout ssrAttachmentDescriptorLayout;
private DescriptorSetLayout ssrInfoDescriptorLayout;
private final VkClearValue clearColour;
private VkRenderingInfo ssrRenderInfo;
private VulkanBuffer[] ssrInfoBuffers;
public ReflectionsRenderer(VulkanContext VkCtx, List<Attachment> MRTAttachments, Attachment Rendered) {
this.renderedSceneAttachment = Rendered;
List<Attachment> attachments = new ArrayList<>();
attachments.add(Rendered);
attachments.add(MRTAttachments.get(0)); // position
attachments.add(MRTAttachments.get(2)); // normal
attachments.add(MRTAttachments.get(3)); // pbr
CreateAttachments(VkCtx);
clearColour = VkClearValue.calloc().color(
c -> c.float32(0, 0.0f).float32(1, 0.0f).float32(2, 0.0f).float32(3, 0.0f));
ssrAttachmentInfo = CreateColourAttachmentInfo(ssrAttachment, clearColour);
var textureSamplerInfo = new TextureSamplerInfo(VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
VK_BORDER_COLOR_INT_OPAQUE_BLACK, 1, true);
textureSampler = new TextureSampler(VkCtx, textureSamplerInfo);
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);
}
ssrAttachmentDescriptorLayout = new DescriptorSetLayout(VkCtx, descSetLayouts);
CreateSSRAttachmentDescriptorSet(VkCtx, attachments);
ssrInfoDescriptorLayout = new DescriptorSetLayout(VkCtx,new DescriptorSetLayout.LayoutInformation( VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
0,1,VK_SHADER_STAGE_FRAGMENT_BIT ));
ssrInfoBuffers = VulkanUtils.CreateHostVisibleBuffers(VkCtx,SSR_INFO_BUFFER_SIZE, VulkanUtils.MAX_IN_FLIGHT,
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, DESC_ID_SSR_INFO,ssrInfoDescriptorLayout);
ssrRenderInfo = CreateRenderInfo(ssrAttachment, ssrAttachmentInfo,true);
ShaderModule[] shaderModules = CreateRawShaderModules(VkCtx);
ssrPipeline = CreatePipeline(VkCtx, shaderModules,
new DescriptorSetLayout[]{
ssrAttachmentDescriptorLayout,
ssrInfoDescriptorLayout
});
Arrays.stream(shaderModules).toList().forEach(shaderModule -> shaderModule.CleanUp(VkCtx));
}
private static Pipeline CreatePipeline(VulkanContext VkCtx, ShaderModule[] shaderModules, DescriptorSetLayout[] descSetLayouts ) {
var vtxBuffStruct = new EmptyVertexBufferStruct();
int[] formats = new int[]{SSR_FORMAT};
var buildInfo = new PipelineBuildInfo(shaderModules, vtxBuffStruct.GetVertexInput(), formats)
.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 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, boolean Raw) {
int Width = attachment.GetVkImage().GetWidth();
int Height = attachment.GetVkImage().GetHeight();
return VkRenderingInfo.calloc()
.sType$Default()
.renderArea(area -> area
.offset(offset -> offset.x(0).y(0))
.extent(extent -> extent
.width(Width)
.height(Height)))
.layerCount(1)
.pColorAttachments(attachmentInfo);
}
private void CreateSSRAttachmentDescriptorSet(VulkanContext vkCtx, List<Attachment> Attachments ) {
DescriptorSet descSet = vkCtx.GetDescriptorAllocator().AddDescriptorSet(
vkCtx.GetDevice(), DESC_ID_SSR_ATTACHMENTS, ssrAttachmentDescriptorLayout);
List<ImageView> imageViews = new ArrayList<>();
Attachments.forEach(a -> imageViews.add(a.GetVkImageView()));
descSet.SetImages(vkCtx.GetDevice(), imageViews, textureSampler, 0);
}
private void CreateAttachments(VulkanContext VkCtx){
SwapChain swapChain = VkCtx.GetSwapChain();
VkExtent2D swapChainExtent = swapChain.GetSwapChainExtent();
float AspectRatio = (float)swapChainExtent.width()/(float)swapChainExtent.height();
int Width = swapChainExtent.width();
int Height = swapChainExtent.height();
int RawWidth = (int)(Math.round(Math.min(swapChainExtent.width()/2.0f, 1920 * AspectRatio)));
int RawHeight = (int)(Math.round(Math.min(swapChainExtent.height()/2.0f, 1080)));
//SSR Raw
ssrAttachment = new Attachment(VkCtx, Width, Height, SSR_FORMAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, 1);
}
public void Render(VulkanContext VkCtx,EngineInstance engineInstance, CommandBuffer cmdBuffer, int CurrentFrame) {
try (var stack = MemoryStack.stackPush()) {
VkCommandBuffer cmdHandle = cmdBuffer.GetVulkanCommandBuffer();
UpdateSSRInfo(VkCtx, engineInstance, CurrentFrame);
VulkanUtils.ImageBarrier(stack, cmdHandle, renderedSceneAttachment.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, ssrAttachment.GetVkImage().getVulkanImage(),
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT,
VK_ACCESS_2_NONE, VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT,
VK_IMAGE_ASPECT_COLOR_BIT);
vkCmdBeginRendering(cmdHandle, ssrRenderInfo);
vkCmdBindPipeline(cmdHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, ssrPipeline.GetVulkanPipeline());
SetViewportAndScissor(stack, cmdHandle, ssrAttachment);
DescriptorAllocator descAllocator = VkCtx.GetDescriptorAllocator();
LongBuffer descriptorSets = stack.mallocLong(2)
.put(0, descAllocator.GetDescriptorSet(DESC_ID_SSR_ATTACHMENTS).GetVkDescriptorSet())
.put(1, descAllocator.GetDescriptorSet(DESC_ID_SSR_INFO, CurrentFrame).GetVkDescriptorSet());
vkCmdBindDescriptorSets(cmdHandle, VK_PIPELINE_BIND_POINT_GRAPHICS,
ssrPipeline.GetVulkanPipelineLayout(), 0, descriptorSets, null);
vkCmdDraw(cmdHandle, 3, 1, 0, 0);
vkCmdEndRendering(cmdHandle);
}
}
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);
}
public Attachment GetSSRAttachment() {
return ssrAttachment;
}
private void UpdateSSRInfo(VulkanContext vkCtx, EngineInstance engineInstance, int currentFrame) {
VulkanBuffer buffer = ssrInfoBuffers[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().GetProjection().GetProjectionMatrix().invert(new Matrix4f()).get(offset, data);
offset += VulkanUtils.MATRIX4X4_SIZE;
engineInstance.scene().GetCamera().GetViewMatrix().get(offset, data);
offset += VulkanUtils.MATRIX4X4_SIZE;
engineInstance.scene().GetCamera().GetViewMatrix().invert(new Matrix4f()).get(offset, data);
offset += VulkanUtils.MATRIX4X4_SIZE;
data.putFloat(offset, STEP_SIZE);
data.putFloat(offset + VulkanUtils.FLOAT_SIZE, MAX_DIST);
data.putInt(offset + VulkanUtils.FLOAT_SIZE * 2, MAX_STEPS);
data.putInt(offset + VulkanUtils.FLOAT_SIZE * 3, 0);
offset += VulkanUtils.VEC4_SIZE;
engineInstance.scene().GetCamera().GetPosition().get(offset, data);
data.putFloat(offset + VulkanUtils.VEC3_SIZE, 1.0f);
offset += VulkanUtils.VEC4_SIZE;
buffer.UnMapMemory(vkCtx);
}
public void resize(VulkanContext VkCtx, List<Attachment> attachments) {
ssrRenderInfo.free();
ssrAttachmentInfo.free();
ssrAttachment.CleanUp(VkCtx);
renderedSceneAttachment = attachments.get(0);
CreateAttachments(VkCtx);
ssrAttachmentInfo = CreateColourAttachmentInfo(ssrAttachment, clearColour);
ssrRenderInfo = CreateRenderInfo(ssrAttachment, ssrAttachmentInfo,true);
CreateSSRAttachmentDescriptorSet(VkCtx, attachments);
}
public void cleanup(VulkanContext VkCtx) {
ssrRenderInfo.free();
ssrAttachmentInfo.free();
ssrAttachment.CleanUp(VkCtx);
ssrPipeline.CleanUp(VkCtx);
clearColour.free();
Arrays.stream(ssrInfoBuffers).toList().forEach(b -> b.cleanup(VkCtx));
ssrAttachmentDescriptorLayout.CleanUp(VkCtx);
ssrInfoDescriptorLayout.CleanUp(VkCtx);
textureSampler.CleanUp(VkCtx);
}
}

View file

@ -22,7 +22,7 @@ import static org.lwjgl.util.vma.Vma.VMA_MEMORY_USAGE_AUTO;
import static org.lwjgl.vulkan.VK10.*;
public class MaterialsCache {
private static final int MATERIAL_RAW_SIZE = VulkanUtils.VEC4_SIZE * 4 + (VulkanUtils.INT_SIZE * 2 + VulkanUtils.FLOAT_SIZE) * 2 + (VulkanUtils.INT_SIZE * 2);
private static final int MATERIAL_RAW_SIZE = VulkanUtils.VEC4_SIZE * 4 + (VulkanUtils.INT_SIZE * 2 + VulkanUtils.FLOAT_SIZE) * 2 + (VulkanUtils.INT_SIZE * 4) + VulkanUtils.FLOAT_SIZE * 2;
private static final int MATERIAL_SIZE = 16 * (int)(Math.ceil(MATERIAL_RAW_SIZE/16.0));
private final IndexedLinkedHashMap<String, VulkanMaterial> MaterialsMap;
private VulkanBuffer MaterialsBuffer;
@ -151,6 +151,12 @@ public class MaterialsCache {
data.putFloat(Offset, Material.Opacity());
Offset += VulkanUtils.FLOAT_SIZE;
data.putFloat(Offset, Material.Reflectiveness());
Offset += VulkanUtils.FLOAT_SIZE;
data.putFloat(Offset, Material.Refractiveness());
Offset += VulkanUtils.FLOAT_SIZE;
Offset = materialBaseOffset + MATERIAL_SIZE;
}
// data.position(0);

View file

@ -244,7 +244,8 @@ public class DeferredSceneRender implements SceneRenderer {//dynamic rendering
MultiRenderTargetAttachments.PBR_FORMAT,
MultiRenderTargetAttachments.EMISSIVE_FORMAT,
MultiRenderTargetAttachments.TRANSLUCECNY_FORMAT,
MultiRenderTargetAttachments.OPACITY_FORMAT
MultiRenderTargetAttachments.OPACITY_FORMAT,
MultiRenderTargetAttachments.VIEW_POS_FORMAT
};
try (MemoryStack MemStack = MemoryStack.stackPush()) {
@ -285,7 +286,7 @@ public class DeferredSceneRender implements SceneRenderer {//dynamic rendering
MultiRenderTargetAttachments.POSITION_FORMAT, MultiRenderTargetAttachments.ALBEDO_FORMAT,
MultiRenderTargetAttachments.NORMAL_FORMAT, MultiRenderTargetAttachments.PBR_FORMAT,
MultiRenderTargetAttachments.EMISSIVE_FORMAT, MultiRenderTargetAttachments.TRANSLUCECNY_FORMAT,
MultiRenderTargetAttachments.OPACITY_FORMAT})
MultiRenderTargetAttachments.OPACITY_FORMAT, MultiRenderTargetAttachments.VIEW_POS_FORMAT})
.SetDepthFormat(MultiRenderTargetAttachments.DEPTH_FORMAT)
.SetDepthWrite(DepthWrite)
.SetPushConstantRanges(

View file

@ -38,6 +38,7 @@ public class VulkanUtils {
public static final int VEC4_SIZE = 4 * FLOAT_SIZE;
public static final int VEC2_SIZE = 2 * FLOAT_SIZE;
public static final int SHORT_LENGTH = 2;
public static final int BOOLEAN_SIZE = 4;
private static final List<DeferredResource> DeletionQueue = new ArrayList<>();