diff --git a/resources/EngineResources/SkyBoxTextures/SkyTop.png b/resources/EngineResources/SkyBoxTextures/SkyTop.png new file mode 100644 index 0000000..ec7edc4 Binary files /dev/null and b/resources/EngineResources/SkyBoxTextures/SkyTop.png differ diff --git a/resources/EngineResources/SkyBoxTextures/skySide.png b/resources/EngineResources/SkyBoxTextures/skySide.png new file mode 100644 index 0000000..93970fa Binary files /dev/null and b/resources/EngineResources/SkyBoxTextures/skySide.png differ diff --git a/resources/EngineResources/SkyBoxTextures/textureCredit.txt b/resources/EngineResources/SkyBoxTextures/textureCredit.txt new file mode 100644 index 0000000..4092bea --- /dev/null +++ b/resources/EngineResources/SkyBoxTextures/textureCredit.txt @@ -0,0 +1,2 @@ +Sky texture: +kaori669 on deviant art \ No newline at end of file diff --git a/resources/EngineResources/Texture/NoTexture.png b/resources/EngineResources/Texture/NoTexture.png new file mode 100644 index 0000000..1086a19 Binary files /dev/null and b/resources/EngineResources/Texture/NoTexture.png differ diff --git a/resources/EngineResources/shaders/lighting_frag.glsl b/resources/EngineResources/shaders/lighting_frag.glsl index 5cefbad..158a06b 100644 --- a/resources/EngineResources/shaders/lighting_frag.glsl +++ b/resources/EngineResources/shaders/lighting_frag.glsl @@ -149,4 +149,9 @@ void main() { vec3 color = ambient + Lo; outFragColor = vec4(color, 1.0f); + if (length(normal) < 0.001) { + outFragColor = vec4(albedo,1.0f); + return; + } + } diff --git a/resources/EngineResources/shaders/lighting_frag.glsl.spv b/resources/EngineResources/shaders/lighting_frag.glsl.spv index 075c77b..8cd6ee9 100644 Binary files a/resources/EngineResources/shaders/lighting_frag.glsl.spv and b/resources/EngineResources/shaders/lighting_frag.glsl.spv differ diff --git a/resources/EngineResources/shaders/multi-sampled_post_process_frag.glsl b/resources/EngineResources/shaders/multi-sampled_post_process_frag.glsl index e05f91c..dfabc91 100644 --- a/resources/EngineResources/shaders/multi-sampled_post_process_frag.glsl +++ b/resources/EngineResources/shaders/multi-sampled_post_process_frag.glsl @@ -2,7 +2,7 @@ layout(constant_id = 0) const int USE_AA = 0; -const float GAMMA_CONST = 0.8545; +const float GAMMA_CONST = 0.6545; const float SPAN_MAX = 8.0; const float REDUCE_MIN = 1.0/128.0; const float REDUCE_MUL = 1.0/32.0; diff --git a/resources/EngineResources/shaders/multi-sampled_post_process_frag.glsl.spv b/resources/EngineResources/shaders/multi-sampled_post_process_frag.glsl.spv index 1cce2dd..2b3bfbe 100644 Binary files a/resources/EngineResources/shaders/multi-sampled_post_process_frag.glsl.spv and b/resources/EngineResources/shaders/multi-sampled_post_process_frag.glsl.spv differ diff --git a/resources/EngineResources/shaders/post_process_frag.glsl b/resources/EngineResources/shaders/post_process_frag.glsl index b15b7d0..e4c4353 100644 --- a/resources/EngineResources/shaders/post_process_frag.glsl +++ b/resources/EngineResources/shaders/post_process_frag.glsl @@ -2,7 +2,7 @@ layout(constant_id = 0) const int USE_AA = 0; -const float GAMMA_CONST = 0.8545; +const float GAMMA_CONST = 0.4545; const float SPAN_MAX = 8.0; const float REDUCE_MIN = 1.0/128.0; const float REDUCE_MUL = 1.0/32.0; diff --git a/resources/EngineResources/shaders/post_process_frag.glsl.spv b/resources/EngineResources/shaders/post_process_frag.glsl.spv index 055aba0..a4a924f 100644 Binary files a/resources/EngineResources/shaders/post_process_frag.glsl.spv and b/resources/EngineResources/shaders/post_process_frag.glsl.spv differ diff --git a/resources/EngineResources/shaders/scene_fragment.glsl b/resources/EngineResources/shaders/scene_fragment.glsl index 415477f..3832979 100644 --- a/resources/EngineResources/shaders/scene_fragment.glsl +++ b/resources/EngineResources/shaders/scene_fragment.glsl @@ -1,6 +1,6 @@ #version 450 -const int MAX_TEXTURES = 512; +const int MAX_TEXTURES = 128; layout(location = 0) in vec4 inPos; layout(location = 1) in vec3 inNormal; diff --git a/resources/EngineResources/shaders/scene_fragment.glsl.spv b/resources/EngineResources/shaders/scene_fragment.glsl.spv index bf95492..0cf93b5 100644 Binary files a/resources/EngineResources/shaders/scene_fragment.glsl.spv and b/resources/EngineResources/shaders/scene_fragment.glsl.spv differ diff --git a/resources/EngineResources/shaders/scene_fragment_deferred.glsl b/resources/EngineResources/shaders/scene_fragment_deferred.glsl index ad591aa..e7a2cc6 100644 --- a/resources/EngineResources/shaders/scene_fragment_deferred.glsl +++ b/resources/EngineResources/shaders/scene_fragment_deferred.glsl @@ -1,6 +1,6 @@ #version 450 -const int MAX_TEXTURES = 512; +const int MAX_TEXTURES = 128; layout(location = 0) in vec4 inPos; layout(location = 1) in vec3 inNormal; diff --git a/resources/EngineResources/shaders/scene_fragment_deferred.glsl.spv b/resources/EngineResources/shaders/scene_fragment_deferred.glsl.spv index 6d2d089..36a0e20 100644 Binary files a/resources/EngineResources/shaders/scene_fragment_deferred.glsl.spv and b/resources/EngineResources/shaders/scene_fragment_deferred.glsl.spv differ diff --git a/resources/EngineResources/shaders/scene_opaque_fragment.glsl b/resources/EngineResources/shaders/scene_opaque_fragment.glsl index e378777..24eb61d 100644 --- a/resources/EngineResources/shaders/scene_opaque_fragment.glsl +++ b/resources/EngineResources/shaders/scene_opaque_fragment.glsl @@ -1,6 +1,6 @@ #version 450 -const int MAX_TEXTURES = 512; +const int MAX_TEXTURES = 128; layout(location = 0) in vec4 inPos; layout(location = 1) in vec3 inNormal; diff --git a/resources/EngineResources/shaders/scene_opaque_fragment.glsl.spv b/resources/EngineResources/shaders/scene_opaque_fragment.glsl.spv index 4027a18..5a5dfb1 100644 Binary files a/resources/EngineResources/shaders/scene_opaque_fragment.glsl.spv and b/resources/EngineResources/shaders/scene_opaque_fragment.glsl.spv differ diff --git a/resources/EngineResources/shaders/scene_opaque_fragment_deferred.glsl b/resources/EngineResources/shaders/scene_opaque_fragment_deferred.glsl index 752ec04..e0550f0 100644 --- a/resources/EngineResources/shaders/scene_opaque_fragment_deferred.glsl +++ b/resources/EngineResources/shaders/scene_opaque_fragment_deferred.glsl @@ -1,6 +1,6 @@ #version 450 -const int MAX_TEXTURES = 512; +const int MAX_TEXTURES = 128; layout(location = 0) in vec4 inPos; layout(location = 1) in vec3 inNormal; @@ -13,6 +13,13 @@ layout(location = 0) out vec4 outPos; layout(location = 2) out vec4 outNormal; layout(location = 3) out vec4 outPBR; +const float bayerMatrix[16] = float[]( + 0.0 / 16.0, 8.0 / 16.0, 2.0 / 16.0, 10.0 / 16.0, + 12.0 / 16.0, 4.0 / 16.0, 14.0 / 16.0, 6.0 / 16.0, + 3.0 / 16.0, 11.0 / 16.0, 1.0 / 16.0, 9.0 / 16.0, + 15.0 / 16.0, 7.0 / 16.0, 13.0 / 16.0, 5.0 / 16.0 +); + struct Material { vec4 diffuseColor; uint hasTexture; @@ -55,13 +62,17 @@ void main() } else { outAlbedo = material.diffuseColor; } - - + /*int Intensity = 4; + int x = int(gl_FragCoord.x) % Intensity; + int y = int(gl_FragCoord.y) % Intensity; + float threshold = bayerMatrix[y * Intensity + x]; + if(outAlbedo.a < threshold || outAlbedo.a < 0.05f) discard;*/ if(outAlbedo.a < 0.75) discard; + mat3 TBN = mat3(inTangent, inBitangent, inNormal); vec3 newNormal = calcNormal(material, inNormal, inTextCoords, TBN); - outNormal = vec4(newNormal, 1.0f); + outNormal = vec4(newNormal, outAlbedo.a); float ao = 0.5f; float roughnessFactor = 0.0f; @@ -75,6 +86,6 @@ void main() metallicFactor = material.metallicFactor; } - outPBR = vec4(ao, roughnessFactor, metallicFactor, 1.0f); + outPBR = vec4(ao, roughnessFactor, metallicFactor, outAlbedo.a); } \ No newline at end of file diff --git a/resources/EngineResources/shaders/scene_opaque_fragment_deferred.glsl.spv b/resources/EngineResources/shaders/scene_opaque_fragment_deferred.glsl.spv index a44dc8d..54f86b3 100644 Binary files a/resources/EngineResources/shaders/scene_opaque_fragment_deferred.glsl.spv and b/resources/EngineResources/shaders/scene_opaque_fragment_deferred.glsl.spv differ diff --git a/resources/EngineResources/shaders/scene_translucent_fragment.glsl b/resources/EngineResources/shaders/scene_translucent_fragment.glsl index c1a9920..d4f061b 100644 --- a/resources/EngineResources/shaders/scene_translucent_fragment.glsl +++ b/resources/EngineResources/shaders/scene_translucent_fragment.glsl @@ -1,6 +1,6 @@ #version 450 -const int MAX_TEXTURES = 512; +const int MAX_TEXTURES = 128; layout(location = 0) in vec4 inPos; layout(location = 1) in vec3 inNormal; @@ -37,7 +37,7 @@ void main() Material material = matUniform.materials[push_constants.materialIdx]; if(material.hasTexture == 1){ vec4 texColor = texture(textSampler[material.textureIdx],inTextCoords); - if(texColor.a < 0.05 || texColor.a >= 0.9){discard;} + if(texColor.a >= 0.9){discard;} outAlbedo = texColor; } else{ outAlbedo = material.diffuseColor; diff --git a/resources/EngineResources/shaders/scene_translucent_fragment.glsl.spv b/resources/EngineResources/shaders/scene_translucent_fragment.glsl.spv index 6b59bc8..382a9ad 100644 Binary files a/resources/EngineResources/shaders/scene_translucent_fragment.glsl.spv and b/resources/EngineResources/shaders/scene_translucent_fragment.glsl.spv differ diff --git a/resources/EngineResources/shaders/scene_translucent_fragment_deferred.glsl b/resources/EngineResources/shaders/scene_translucent_fragment_deferred.glsl index a330f17..f11c471 100644 --- a/resources/EngineResources/shaders/scene_translucent_fragment_deferred.glsl +++ b/resources/EngineResources/shaders/scene_translucent_fragment_deferred.glsl @@ -1,6 +1,6 @@ #version 450 -const int MAX_TEXTURES = 512; +const int MAX_TEXTURES = 128; layout(location = 0) in vec4 inPos; layout(location = 1) in vec3 inNormal; @@ -13,6 +13,14 @@ layout(location = 0) out vec4 outPos; layout(location = 2) out vec4 outNormal; layout(location = 3) out vec4 outPBR; +const float bayerMatrix[16] = float[]( + 0.0 / 16.0, 8.0 / 16.0, 2.0 / 16.0, 10.0 / 16.0, + 12.0 / 16.0, 4.0 / 16.0, 14.0 / 16.0, 6.0 / 16.0, + 3.0 / 16.0, 11.0 / 16.0, 1.0 / 16.0, 9.0 / 16.0, + 15.0 / 16.0, 7.0 / 16.0, 13.0 / 16.0, 5.0 / 16.0 +); + + struct Material { vec4 diffuseColor; uint hasTexture; @@ -57,7 +65,7 @@ void main() } - if(outAlbedo.a < 0.05 || outAlbedo.a >= 0.75) discard; + if(outAlbedo.a >= 0.75 || outAlbedo.a < 0.05f) discard; mat3 TBN = mat3(inTangent, inBitangent, inNormal); vec3 newNormal = calcNormal(material, inNormal, inTextCoords, TBN); diff --git a/resources/EngineResources/shaders/scene_translucent_fragment_deferred.glsl.spv b/resources/EngineResources/shaders/scene_translucent_fragment_deferred.glsl.spv index 3a9a55b..6544db2 100644 Binary files a/resources/EngineResources/shaders/scene_translucent_fragment_deferred.glsl.spv and b/resources/EngineResources/shaders/scene_translucent_fragment_deferred.glsl.spv differ diff --git a/resources/EngineResources/shaders/shadow_frag.glsl b/resources/EngineResources/shaders/shadow_frag.glsl new file mode 100644 index 0000000..0afc2bd --- /dev/null +++ b/resources/EngineResources/shaders/shadow_frag.glsl @@ -0,0 +1,5 @@ +#version 450 + +void main() { + +} diff --git a/resources/EngineResources/shaders/shadow_geometry.glsl b/resources/EngineResources/shaders/shadow_geometry.glsl new file mode 100644 index 0000000..0afc2bd --- /dev/null +++ b/resources/EngineResources/shaders/shadow_geometry.glsl @@ -0,0 +1,5 @@ +#version 450 + +void main() { + +} diff --git a/resources/EngineResources/shaders/shadow_vertex.glsl b/resources/EngineResources/shaders/shadow_vertex.glsl new file mode 100644 index 0000000..0afc2bd --- /dev/null +++ b/resources/EngineResources/shaders/shadow_vertex.glsl @@ -0,0 +1,5 @@ +#version 450 + +void main() { + +} diff --git a/resources/EngineResources/shaders/skybox_fragment.glsl b/resources/EngineResources/shaders/skybox_fragment.glsl new file mode 100644 index 0000000..e504856 --- /dev/null +++ b/resources/EngineResources/shaders/skybox_fragment.glsl @@ -0,0 +1,11 @@ +#version 450 + +layout(location = 0) in vec3 outTexCoords; + +layout(location = 1) out vec4 outColor; + +layout(set = 2, binding = 0) uniform samplerCube skyboxSampler; + +void main() { + outColor = vec4(texture(skyboxSampler, outTexCoords).rgb, 1.0); +} \ No newline at end of file diff --git a/resources/EngineResources/shaders/skybox_vertex.glsl b/resources/EngineResources/shaders/skybox_vertex.glsl new file mode 100644 index 0000000..e5f4f14 --- /dev/null +++ b/resources/EngineResources/shaders/skybox_vertex.glsl @@ -0,0 +1,18 @@ +#version 450 +layout(location = 0) in vec3 inPosition; +layout(location = 0) out vec3 outTexCoords; + +layout(set = 0, binding = 0) uniform ProjectionBuffer { + mat4 proj; +} uboProj; + +layout(set = 1, binding = 0) uniform ViewBuffer { + mat4 view; +} uboView; + +void main() { + outTexCoords = inPosition; + mat4 skyView = mat4(mat3(uboView.view)); + vec4 pos = uboProj.proj * skyView * vec4(inPosition, 1.0); + gl_Position = vec4(pos.xy, 0.0, pos.w); +} diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Display/Render.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Display/Render.java index 6340117..2886b5b 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Display/Render.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Display/Render.java @@ -3,7 +3,9 @@ package net.halbear.Terrain4J.EngineCore.Display; import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig; import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance; import net.halbear.Terrain4J.EngineCore.Logic.InitData; +import net.halbear.Terrain4J.EngineCore.Logic.Rendering.SkyBox; import net.halbear.Terrain4J.EngineCore.Logic.Rendering.VulkanContext; +import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime; import net.halbear.Terrain4J.EngineCore.Vulkan.GUI.GuiRenderer; import net.halbear.Terrain4J.EngineCore.Vulkan.GUI.GuiTexture; import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.DeferredRendering.LightRenderer; @@ -58,6 +60,8 @@ public class Render { private TextureCache textureCache; private EngineConfig.AntiAliasType CurrentAAMode; private final boolean Deferred; + private float LastGamma = 0.8545f; + public TextureCache GetTextureCache(){return textureCache;} public MaterialsCache GetMaterialsCache(){return materialsCache;} @@ -105,6 +109,7 @@ public class Render { modelsCache = new ModelsCache(); Resize = false; CurrentAAMode = EngineConfig.getInstance().RenderAAType(); + LastGamma = EngineConfig.getInstance().GetGamma(); } public void Initialise(InitData initData){ @@ -115,6 +120,15 @@ public class Render { Logger.debug("Loaded {} Materials", Materials.size()); List guiTextures = initData.GuiTextures(); + String[] SkyBoxTextures = new String[]{ + "resources/EngineResources/SkyBoxTextures/skySide.png", + "resources/EngineResources/SkyBoxTextures/skySide.png", + "resources/EngineResources/SkyBoxTextures/SkyTop.png", + "resources/EngineResources/SkyBoxTextures/SkyTop.png", + "resources/EngineResources/SkyBoxTextures/skySide.png", + "resources/EngineResources/SkyBoxTextures/skySide.png" + }; + textureCache.AddCubeMapTexture(RendererContext, DeferredSceneRender.SkyBoxID,SkyBoxTextures,VK_FORMAT_R8G8B8A8_SRGB); if(guiTextures != null){ initData.GuiTextures().forEach(texture -> textureCache.AddTexture(RendererContext, texture.TexturePath(), texture.TexturePath(), VK_FORMAT_R8G8B8A8_SRGB)); } @@ -127,6 +141,7 @@ public class Render { Models.addAll(initData.Models()); Logger.debug("Loading {} models", Models.size()); //modelsCache.CleanUp(RendererContext); + modelsCache.CreateSkybox(RendererContext, SkyBox.SkyBoxMesh.VERTICES,DeferredSceneRender.SkyBoxID); modelsCache.loadModels(RendererContext, Models, CommandPools[0], GraphicsQueue); Logger.debug("Loaded {} models", Models.size()); @@ -227,6 +242,10 @@ public class Render { public void render(EngineInstance engineInstance){ if(Deferred) DeferredRender(engineInstance); else ForwardRender(engineInstance); + // if(LastGamma != EngineConfig.getInstance().GetGamma()){ + // vkDeviceWaitIdle(RendererContext.GetDevice().FetchVulkanDevice()); + // PrimaryRuntime.GetRenderThread().RefreshRenderer(); + // } } private void resize(EngineInstance engineInstance){ diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Display/Window.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Display/Window.java index bce92c1..4779f0c 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Display/Window.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Display/Window.java @@ -41,7 +41,8 @@ public class Window { glfwDefaultWindowHints(); glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); glfwWindowHint(GLFW_MAXIMIZED, GLFW_FALSE); - + glfwWindowHint(GLFW_ALPHA_BITS, 0); + glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER, GLFW_FALSE); handle = glfwCreateWindow(width, height, title, MemoryUtil.NULL, MemoryUtil.NULL); if (handle == MemoryUtil.NULL) { //throw new RuntimeException("Failed to create the GLFW window"); @@ -72,6 +73,7 @@ public class Window { IconBuffer.free(); //free the buffer once icon is set so when the program closes there isn't memory still floating around Logger.debug("Freeing icon Buffer"); + glfwSetWindowFocusCallback(handle, new GLFWWindowFocusCallback() { @Override public void invoke(long window, boolean focused) { diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Logic/EngineConfig.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Logic/EngineConfig.java index 67ee74c..5265028 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Logic/EngineConfig.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Logic/EngineConfig.java @@ -55,7 +55,7 @@ public class EngineConfig { private String PhysicalDeviceName; private int RequestedImages; private String IconPath = "/WindowResources/Icon/"; - private String DefaultTexturePath = "resources/EngineResources/Texture/DefaultTexture.png"; + private String DefaultTexturePath = "resources/EngineResources/Texture/NoTexture.png"; private String IconName = "ProgramIcon.png"; private float FOV = 60f; private float zFarPlane; @@ -73,7 +73,13 @@ public class EngineConfig { public boolean AlphaToCoverage = false; public boolean CompatibilityMode = false; public Renderer renderer = Renderer.Forward; + public int ShadowMapSize = 16; + public float Gamma = 0.8545f; + public int MaxVulkanCrashesAllowed = 10; + public int GetMaxVulkanCrashes(){return MaxVulkanCrashesAllowed;} + public void SetShadowMapSize(int ShadowSize){this.ShadowMapSize = ShadowSize;} + public int GetShadowMapSize(){return ShadowMapSize;} public void SetRenderer(Renderer renderer){this.renderer = renderer;} public boolean DeferredRendering(){return renderer == Renderer.Deferred;} public boolean AlphaToCoverage(){return AlphaToCoverage;} @@ -85,6 +91,7 @@ public class EngineConfig { CPU_CORE_COUNT = CoreCount; CPU_DETAILS = CPU_NAME + " with " + CPU_CORE_COUNT + " Threads"; } + public float GetGamma(){return Gamma;} public boolean CompatibilityMode(){return CompatibilityMode;} public void SetCompatibilitMode(boolean compatibilityMode){this.CompatibilityMode = compatibilityMode;} public int GetCoreCount(){return CPU_CORE_COUNT;} @@ -217,6 +224,8 @@ public class EngineConfig { zFarPlane = (Float.parseFloat(EngineConfigVar.getOrDefault("z_far_plane", 100.0f).toString())); AAValue = (Integer.parseInt(EngineConfigVar.getOrDefault("anti_alias_mode", 1).toString())); renderer = Integer.parseInt(EngineConfigVar.getOrDefault("Renderer", 1).toString()) == 0 ? Renderer.Forward: Renderer.Deferred; + ShadowMapSize = Integer.parseInt(EngineConfigVar.getOrDefault("ShadowMapSize", 16).toString()); + MaxVulkanCrashesAllowed = Integer.parseInt(EngineConfigVar.getOrDefault("MaxAllowedVulkanCrashes", 10).toString()); CompatibilityMode = Boolean.parseBoolean(EngineConfigVar.getOrDefault("compatibility_mode", false).toString()); AlphaToCoverage = Boolean.parseBoolean(EngineConfigVar.getOrDefault("AlphaToCoverage", false).toString()); ForwardSceneRender.SetDualPassRendering(Boolean.parseBoolean(EngineConfigVar.getOrDefault("DualPassRendering", true).toString())); diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Logic/Rendering/SkyBox.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Logic/Rendering/SkyBox.java new file mode 100644 index 0000000..431ff95 --- /dev/null +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Logic/Rendering/SkyBox.java @@ -0,0 +1,32 @@ +package net.halbear.Terrain4J.EngineCore.Logic.Rendering; + +import net.halbear.Terrain4J.EngineCore.Main.Scene.Camera; +import org.joml.Matrix4f; +import org.joml.Vector3f; + +import java.nio.ByteBuffer; + +public class SkyBox { + + public static class SkyBoxMesh{ + public static final float[] VERTICES = { + -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, + 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, + + -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, + -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, + + 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, + + -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, + + -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, + + -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, + 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f + }; + } +} diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Main/GameCore.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Main/GameCore.java index 469881d..405f4d1 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Main/GameCore.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Main/GameCore.java @@ -38,7 +38,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.525f; + private static final float MOVEMENT_SPEED = 0.025f; private static final String SOUND_BUFFER_MUSIC = "music-sound-buffer"; private static final String SOUND_BUFFER_PLAYER = "player-sound-buffer"; @@ -80,25 +80,25 @@ public class GameCore implements GameLogic { List models = new ArrayList<>(); MusicParticle = ModelLoader.LoadModel("resources/models/MusicParticle/MusicParticle.json"); List MusicParticleMat = ModelLoader.LoadMaterials("resources/models/MusicParticle/MusicParticle_mat.json"); - // ModelData SponzaData = ModelLoader.LoadModel("resources/models/room/living_room.json"); - // List SponzaMaterial = ModelLoader.LoadMaterials("resources/models/room/living_room_mat.json"); + ModelData SponzaData = ModelLoader.LoadModel("resources/models/Forest/forest.json"); + List SponzaMaterial = ModelLoader.LoadMaterials("resources/models/Forest/forest_mat.json"); radio = ModelLoader.LoadModel("resources/models/radio/radio.json"); List SponzaMaterial2 = ModelLoader.LoadMaterials("resources/models/radio/radio_mat.json"); - ModelData SponzaData = ModelLoader.LoadModel("resources/models/Cafe/exterior.json"); - List SponzaMaterial = ModelLoader.LoadMaterials("resources/models/Cafe/exterior_mat.json"); - ModelData SponzaData1 = ModelLoader.LoadModel("resources/models/Cafe/interior.json"); - List SponzaMaterial1= ModelLoader.LoadMaterials("resources/models/Cafe/interior_mat.json"); + // ModelData SponzaData = ModelLoader.LoadModel("resources/models/Cafe/exterior.json"); + // List SponzaMaterial = ModelLoader.LoadMaterials("resources/models/Cafe/exterior_mat.json"); + // ModelData SponzaData1 = ModelLoader.LoadModel("resources/models/Cafe/interior.json"); + // List SponzaMaterial1= ModelLoader.LoadMaterials("resources/models/Cafe/interior_mat.json"); scene.AddActor(new Actor("Sponza1", SponzaData.ID(), new Vector3f(0,0f,-5f))); - scene.AddActor(new Actor("Sponza2", SponzaData1.ID(), new Vector3f(0,0f,-5f))); + // scene.AddActor(new Actor("Sponza2", SponzaData1.ID(), new Vector3f(0,0f,-5f))); CubeActors.forEach(scene::AddActor); List materials = new ArrayList<>(); materials.addAll(SponzaMaterial); materials.addAll(MusicParticleMat); - materials.addAll(SponzaMaterial1); + // materials.addAll(SponzaMaterial1); materials.addAll(SponzaMaterial2); - models.add(SponzaData1); + // models.add(SponzaData1); models.add(SponzaData); models.add(MusicParticle); models.add(radio); @@ -110,26 +110,26 @@ public class GameCore implements GameLogic { scene.AddCameraFrame("Fifth", new CameraFrame(new Vector3f(64.92f,158.06f,-35.25f),new Vector3f(-11.20f,156.5f,0.0f),scene.GetCamera().GetFOV(),"Sixth")); scene.AddCameraFrame("Sixth", new CameraFrame(new Vector3f(94.52f,172.54f,47.57f),new Vector3f(4.3f,329.27f,0.0f),scene.GetCamera().GetFOV(),"NO_FRAME")); camera.SetPosition(40.0f, 155.0f, -42.0f); - camera.SetPosition(0,0,0); + //camera.SetPosition(0,0,0); camera.SetRotation((float) Math.toRadians(10.0f), (float) Math.toRadians(-90.0f),0); - camera.SetRotation(0,0,0); + //camera.SetRotation(0,0,0); - guiTexture = new GuiTexture("resources/EngineResources/Texture/DefaultTexture.png"); + guiTexture = new GuiTexture("resources/EngineResources/Texture/Billy.png"); Logger.debug("GUI TEXTURE CREATED, ID->[{}], PATH->[{}]",guiTexture.ID(),guiTexture.TexturePath()); List guiTextures = new ArrayList<>(); guiTextures.add(guiTexture); - scene.GetLightingManager().GetAmbientLightColour().set(0.5f, 0.5f, 0.5f); - scene.GetLightingManager().SetAmbientLightIntensity(0.01f); + scene.GetLightingManager().GetAmbientLightColour().set(1.0f, 0.9f, 0.75f); + scene.GetLightingManager().SetAmbientLightIntensity(1.5f); - SkyLight = new Light(new Vector3f(0.25f, 1.0f, 1.5f),new Vector3f(0.0f, -1.0f, 0.0f), true, 0.70f); + SkyLight = new Light(new Vector3f(1.5f, 1.20f, 1.0f),new Vector3f(0.0f, -1.0f, 0.0f), true, 10.00f); List lights = new ArrayList<>(); //lights.add(new Light(new Vector3f(2.9f,2.75f,1.5f),new Vector3f(0.35f,2.69f,-2.11f),false,3.0f)); //lights.add(new Light(new Vector3f(3.0f,2.5f,0.75f),new Vector3f(2.65f,1.57f,-3.31f),false,0.5f)); - lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-433, 445f, -424f),false,300000.0f+ (float)(Math.random() * 10000.0))); + /*lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-433, 445f, -424f),false,300000.0f+ (float)(Math.random() * 10000.0))); lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-210, 445f, 460f),false,70000.0f + (float)(Math.random() * 15000.0f))); lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-966, 445f, 204f),false,70000.0f + (float)(Math.random() * 15000.0f))); lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-176, 445f, 1000f),false,70000.0f + (float)(Math.random() * 15000.0f))); @@ -160,9 +160,10 @@ public class GameCore implements GameLogic { lights.add(new Light(new Vector3f(0.75f,2.0f,0.75f),new Vector3f(1086, 425, -3375),false,50000.0f)); + */ - //lights.add(new Light(new Vector3f(3.0f,2.75f,0.0f),new Vector3f(35.0f, 150.0f, -42.0f),false,100.0f)); - //lights.add(new Light(new Vector3f(0.0f,3.0f,0.0f),new Vector3f(40.0f, 155.0f, -35.0f),false,20.0f)); + lights.add(new Light(new Vector3f(3.0f,2.75f,0.0f),new Vector3f(35.0f, 150.0f, -42.0f),false,100.0f)); + lights.add(new Light(new Vector3f(0.0f,3.0f,0.0f),new Vector3f(40.0f, 155.0f, -35.0f),false,20.0f)); lights.add(SkyLight); ILight[] lightArr = new ILight[lights.size()]; diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Main/Scene/GUIs/PerformanceOverlay.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Main/Scene/GUIs/PerformanceOverlay.java index 8cf4f02..93dc58c 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Main/Scene/GUIs/PerformanceOverlay.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Main/Scene/GUIs/PerformanceOverlay.java @@ -2,7 +2,9 @@ package net.halbear.Terrain4J.EngineCore.Main.Scene.GUIs; import imgui.ImGui; import imgui.flag.ImGuiCond; +import imgui.flag.ImGuiInputTextFlags; import imgui.flag.ImGuiWindowFlags; +import imgui.type.ImFloat; import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig; import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance; import net.halbear.Terrain4J.EngineCore.Main.GameCore; @@ -15,6 +17,7 @@ import org.joml.Vector3f; import org.tinylog.Logger; public class PerformanceOverlay implements GUIOverlay { + private final ImFloat GammaValue = new ImFloat(0.8545f); @Override public void RenderGUI(EngineInstance engineInstance, long frameTimeNS, GameCore parent) { int windowFlags = ImGuiWindowFlags.NoDecoration @@ -139,6 +142,10 @@ public class PerformanceOverlay implements GUIOverlay { EngineConfig.getInstance().SetAlphaToCoverage(true); 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 Radio")){ diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Main/Scene/IScene.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Main/Scene/IScene.java index 8b4ca3d..455e8c0 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Main/Scene/IScene.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Main/Scene/IScene.java @@ -1,6 +1,7 @@ package net.halbear.Terrain4J.EngineCore.Main.Scene; import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance; +import net.halbear.Terrain4J.EngineCore.Logic.Rendering.SkyBox; import net.halbear.Terrain4J.EngineCore.Main.GameCore; import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Projection.Project3D; @@ -31,4 +32,6 @@ public interface IScene { public String GetActiveCameraFrame(); public void SetUpAudio(EngineInstance engineInstance); public ISceneLightingManager GetLightingManager(); + public SkyBox GetSkyBox(); + public void SetSkyBox(SkyBox skyBox); } diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Main/Scene/Scene.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Main/Scene/Scene.java index 6dea581..aff0653 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Main/Scene/Scene.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Main/Scene/Scene.java @@ -5,6 +5,7 @@ import net.halbear.Terrain4J.EngineCore.Input.KeyboardInput; import net.halbear.Terrain4J.EngineCore.Input.MouseListener; import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig; import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance; +import net.halbear.Terrain4J.EngineCore.Logic.Rendering.SkyBox; import net.halbear.Terrain4J.EngineCore.Main.GameCore; import net.halbear.Terrain4J.EngineCore.Main.Scene.GUIs.PerformanceOverlay; import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Projection.Project3D; @@ -38,10 +39,17 @@ public class Scene implements IScene { public float CurrentTransitionTick = 0; private Vector2f LastMousePos = new Vector2f(0,0); private final ISceneLightingManager lightingManager; + private SkyBox skyBox; public List ActiveGUIs = new ArrayList<>(); public Map GUIReg = new HashMap<>(); + public void SetSkyBox(SkyBox skyBox){ + this.skyBox = skyBox; + } + + public SkyBox GetSkyBox(){return skyBox;} + public Scene(Window window) { lightingManager = new SceneLightingManager(1000,new Vector3f(1f,1f,1f), 0.5f); Actors = new ArrayList<>(); diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Main/Scene/SceneLightingManager.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Main/Scene/SceneLightingManager.java index d9e9484..2df3d3f 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Main/Scene/SceneLightingManager.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Main/Scene/SceneLightingManager.java @@ -7,6 +7,7 @@ import java.util.Arrays; import java.util.List; public class SceneLightingManager implements ISceneLightingManager { + public static int SHADOW_MAP_CASCADE_COUNT = 10; public static int MaxLights; private Vector3f AmbientLightingColour; private float AmbientLightIntensity; diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Threads/RenderThread.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Threads/RenderThread.java index b97df17..96b7827 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Threads/RenderThread.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Threads/RenderThread.java @@ -15,6 +15,7 @@ public class RenderThread extends EngineThread { private Render render; private Window window; private final InitData initData; + public static int VulkanCrashCount = 0; public RenderThread(Window window, EngineInstance engineInstance, InitData initData, GameLogic appLogic) { //this.window = window; @@ -24,6 +25,17 @@ public class RenderThread extends EngineThread { render.Initialise(initData); } + public void RestartCrashedRenderer(){ + if(VulkanCrashCount < EngineConfig.getInstance().GetMaxVulkanCrashes()){ + RefreshRenderer(); + VulkanCrashCount++; + }else{ + Logger.error("MAX VULKAN CRASHES REACHED, CLOSING SOFTWARE"); + PrimaryRuntime.GetEngineInstance().window().setShouldClose(); + PrimaryRuntime.CloseRuntime(); + } + } + public Render GetRenderer(){return render;} @Override @@ -40,6 +52,7 @@ public class RenderThread extends EngineThread { } public void RefreshRenderer(){ + Logger.debug("REFRESHING RENDERER"); render.cleanup(); render = new Render(PrimaryRuntime.GetEngineInstance()); render.Initialise(initData); diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/GUI/GuiRenderer.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/GUI/GuiRenderer.java index c334187..7172ff1 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/GUI/GuiRenderer.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/GUI/GuiRenderer.java @@ -145,7 +145,7 @@ public class GuiRenderer { var guiTexture = GuiTextures.get(i); String descriptorID = guiTexture.TexturePath(); DescriptorSet descriptorSet = descriptorAllocator.AddDescriptorSets(device, descriptorID, 1, TextDescriptorSetLayout)[0]; - Texture texture = textureCache.GetTexture(guiTexture.TexturePath()); + ITexture texture = textureCache.GetTexture(guiTexture.TexturePath()); descriptorSet.SetImage(device,texture.GetImageView(),FontsTextureSampler,TextDescriptorSetLayout.GetLayoutInfo().Binding()); //Logger.debug("TEXTURE ID -> [{}] DESCRIPTOR SET -> [{}] TEXTURE -> [{}] IMAGE PATH -> [{}] TEXTURE SAMPLER ->[{}]",guiTexture.ID(),descriptorSet.GetVkDescriptorSet(),texture,guiTexture.TexturePath(),FontsTextureSampler); GuiTexturesMap.put(guiTexture.ID(),descriptorSet.GetVkDescriptorSet()); diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/DeferredRendering/MultiRenderTargetAttachments.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/DeferredRendering/MultiRenderTargetAttachments.java index f3a01d2..dd1629a 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/DeferredRendering/MultiRenderTargetAttachments.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/DeferredRendering/MultiRenderTargetAttachments.java @@ -12,7 +12,7 @@ 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 DEPTH_FORMAT = VK_FORMAT_D32_SFLOAT_S8_UINT; + public static final int DEPTH_FORMAT = VK_FORMAT_D32_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 POSITION_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT; diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Pipeline/DefaultPipeline.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Pipeline/DefaultPipeline.java index ae6a82d..cf29e2c 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Pipeline/DefaultPipeline.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Pipeline/DefaultPipeline.java @@ -124,6 +124,7 @@ public class DefaultPipeline implements Pipeline { ppLayout.put(i, descriptorSetLayouts[i].GetVkDescriptorLayout()); } + Logger.debug("registered Descriptor sets"); int[] ColourFormats = BuildInfo.GetColourFormat(); int ColourFormatCount = ColourFormats.length; @@ -135,6 +136,8 @@ public class DefaultPipeline implements Pipeline { .colorAttachmentCount(ColourFormatCount) .pColorAttachmentFormats(ColourFormatsBuffer); + Logger.debug("created render info"); + if(DepthStencil != null){RendererCreateInfo.depthAttachmentFormat(BuildInfo.GetDepthFormat());} VkPipelineColorBlendAttachmentState.Buffer BlendAttributeState = VkPipelineColorBlendAttachmentState.calloc(ColourFormatCount,MemStack); @@ -146,10 +149,11 @@ public class DefaultPipeline implements Pipeline { .alphaBlendOp(VK_BLEND_OP_ADD) .srcColorBlendFactor(VK_BLEND_FACTOR_SRC_ALPHA) .dstColorBlendFactor(VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA) - .srcAlphaBlendFactor(BuildInfo.GetBlendingMethod() == 0 ? VK_BLEND_FACTOR_ONE : VK_BLEND_FACTOR_SRC_ALPHA) + .srcAlphaBlendFactor(BuildInfo.GetBlendingMethod() == 0 || BuildInfo.GetBlendingMethod() == 2 ? VK_BLEND_FACTOR_ONE : VK_BLEND_FACTOR_SRC_ALPHA) .dstAlphaBlendFactor(BuildInfo.GetBlendingMethod() == 0 ? VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA : VK_BLEND_FACTOR_ZERO); } } + Logger.debug("created BlendAttributeStates"); var ColourBlendState = VkPipelineColorBlendStateCreateInfo.calloc(MemStack) .sType$Default() @@ -157,17 +161,44 @@ public class DefaultPipeline implements Pipeline { var PipelineLayoutCreateInfoPtr = VkPipelineLayoutCreateInfo.calloc(MemStack) .sType$Default() - .pSetLayouts(ppLayout) - .pPushConstantRanges(VkPushConstRangeBuffer); + .pSetLayouts(ppLayout); + //.pPushConstantRanges(VkPushConstRangeBuffer); + + if (PushConstCount > 0 && VkPushConstRangeBuffer != null) { + PipelineLayoutCreateInfoPtr.pPushConstantRanges(VkPushConstRangeBuffer); + } else { + PipelineLayoutCreateInfoPtr.pPushConstantRanges(null); + } + + VulkanUtils.vkCheck(vkCreatePipelineLayout(device.FetchVulkanDevice(), PipelineLayoutCreateInfoPtr,null,longPtr) ,"Unable to create new pipeline layout"); VulkanPipelineLayout = longPtr.get(0); + Logger.debug("created PipelineLayout"); + + VkPipelineVertexInputStateCreateInfo vertexInputState; + var originalInputState = BuildInfo.GetVertexInputStateCreateInfo(); + + if (originalInputState != null) { + vertexInputState = VkPipelineVertexInputStateCreateInfo.calloc(MemStack) + .sType(VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO) + .pVertexBindingDescriptions(originalInputState.pVertexBindingDescriptions()) + .pVertexAttributeDescriptions(originalInputState.pVertexAttributeDescriptions()); + } else { + // Fix for your cut-off block: Instantiate an explicit, empty state configuration structure + vertexInputState = VkPipelineVertexInputStateCreateInfo.calloc(MemStack) + .sType(VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO) + .pVertexBindingDescriptions(null) + .pVertexAttributeDescriptions(null); + } + + Logger.debug("created vertexInputState"); var PipelineCreateInfo = VkGraphicsPipelineCreateInfo.calloc(1,MemStack) .sType$Default() .pStages(ShaderStages) - .pVertexInputState(BuildInfo.GetVertexInputStateCreateInfo()) + .pVertexInputState(vertexInputState) .pInputAssemblyState(AssemblyStateCreateInfo) .pViewportState(ViewportCreateStateInfo) .pRasterizationState(RasterizationStateCreateInfo) @@ -177,12 +208,14 @@ public class DefaultPipeline implements Pipeline { .layout(VulkanPipelineLayout) .pNext(RendererCreateInfo); + Logger.debug("created PipelineCreateInfo"); if(DepthStencil != null){PipelineCreateInfo.pDepthStencilState(DepthStencil);} VulkanUtils.vkCheck(vkCreateGraphicsPipelines(device.FetchVulkanDevice(), VkCtx.GetVkPipelineCache().GetVkPipelineCache(), PipelineCreateInfo, null, longPtr),"Could not create new pipeline"); + Logger.debug("created GraphicsPipeline"); VulkanPipeline = longPtr.get(0); } } diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Pipeline/Images/Attachment.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Pipeline/Images/Attachment.java index 35d2bc3..e73ce9a 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Pipeline/Images/Attachment.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Pipeline/Images/Attachment.java @@ -22,7 +22,7 @@ public class Attachment { } if((Usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) > 0){ ImageData.Usage(Usage | VK_IMAGE_USAGE_SAMPLED_BIT); - AspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; + AspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; DepthAttachment = true; } VkImage = new Image(VkCtx, ImageData); diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Pipeline/Images/CubeMapTexture.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Pipeline/Images/CubeMapTexture.java new file mode 100644 index 0000000..5fed400 --- /dev/null +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Pipeline/Images/CubeMapTexture.java @@ -0,0 +1,169 @@ +package net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Images; + +import net.halbear.Terrain4J.EngineCore.Logic.Rendering.VulkanContext; +import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.GraphUtils; +import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.CommandBuffer; +import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DisplayToScreen.ImageView; +import net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanBuffer; +import org.lwjgl.system.MemoryStack; +import org.lwjgl.system.MemoryUtil; +import org.lwjgl.vulkan.*; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.LongBuffer; + +import static org.lwjgl.system.MemoryUtil.memByteBuffer; +import static org.lwjgl.util.vma.Vma.VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT; +import static org.lwjgl.util.vma.Vma.VMA_MEMORY_USAGE_AUTO; +import static org.lwjgl.vulkan.VK10.*; +import static org.lwjgl.vulkan.VK13.vkCmdPipelineBarrier2; + +public class CubeMapTexture implements ITexture{ + private final String id; + private final int Height; + private final int Width; + private final Image image; + private final ImageView imageView; + private boolean RecordedTransition; + private VulkanBuffer stgBuffer; + private final long layerSize; + + public CubeMapTexture(VulkanContext vkCtx, String id, String[] facePaths, int format) throws IOException { + this.id = id; + + ImageSrc firstFace = GraphUtils.LoadImage(facePaths[0]); + Width = firstFace.Width(); + Height = firstFace.Height(); + this.layerSize = (long) Width * Height * 4; + long totalBufferSize = layerSize * 6; + GraphUtils.CleanImageData(firstFace); + + this.stgBuffer = new VulkanBuffer(vkCtx, totalBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, + 0, 0, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); + + long mappedAddress = stgBuffer.MapMemory(vkCtx); + ByteBuffer byteBuffer = memByteBuffer(mappedAddress, (int) totalBufferSize); + + for (int i = 0; i < 6; i++) { + ImageSrc currentFace = GraphUtils.LoadImage(facePaths[i]); + ByteBuffer pixelData = currentFace.data(); + + ByteBuffer targetSlice = byteBuffer.duplicate(); + targetSlice.position((int) (i * layerSize)); + targetSlice.limit((int) ((i + 1) * layerSize)); + + targetSlice.put(pixelData); + + GraphUtils.CleanImageData(currentFace); + + } + + CreateStgBuffer(vkCtx, byteBuffer); + stgBuffer.UnMapMemory(vkCtx); + var ImageData = new Image.ImageData().Width(Width).Height(Height) + .Usage(VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT) + .Format(format).MipMapLevels(1).ArrayLayers(6).Flags(VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT); + image = new Image(vkCtx, ImageData); + var ImageViewData = new ImageView.ImageViewData().Format(image.GetFormat()) + .AspectMask(VK_IMAGE_ASPECT_COLOR_BIT).MipLevels(1).LayerCount(6).ViewType(VK_IMAGE_VIEW_TYPE_CUBE); + imageView = new ImageView(vkCtx.GetDevice(), image.getVulkanImage(), ImageViewData, false); + } + + @Override + public boolean HasTransparency() { + return false; + } + + @Override + public void SetTransparency(ByteBuffer data) { + + } + + public void CreateStgBuffer(VulkanContext VkCtx, ByteBuffer data){ + int Size = data.remaining(); + stgBuffer = new VulkanBuffer(VkCtx, Size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VMA_MEMORY_USAGE_AUTO, + VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); + long MappedMemory = stgBuffer.MapMemory(VkCtx); + ByteBuffer buffer = memByteBuffer(MappedMemory, (int) stgBuffer.GetRequestedSize()); + buffer.put(data); + data.flip(); + stgBuffer.UnMapMemory(VkCtx); + } + private void RecordImageTransition(MemoryStack stack, CommandBuffer cmd) { + var imageBarrier = VkImageMemoryBarrier2.calloc(1, stack) + .sType$Default() + .oldLayout(VK_IMAGE_LAYOUT_UNDEFINED) + .newLayout(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) + .srcStageMask(VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT) + .dstStageMask(VK_PIPELINE_STAGE_TRANSFER_BIT) + .srcAccessMask(0) + .dstAccessMask(VK_ACCESS_TRANSFER_WRITE_BIT) + .subresourceRange(it -> it + .aspectMask(VK_IMAGE_ASPECT_COLOR_BIT) + .baseMipLevel(0) + .levelCount(image.GetMipLevels()) + .baseArrayLayer(0) + .layerCount(1)) + .image(image.getVulkanImage()); + + VkDependencyInfo depInfo = VkDependencyInfo.calloc(stack) + .sType$Default() + .pImageMemoryBarriers(imageBarrier); + + vkCmdPipelineBarrier2(cmd.GetVulkanCommandBuffer(), depInfo); + } + + public void RecordTextureTransition(CommandBuffer commandBuffer){ + if(stgBuffer != null && !RecordedTransition){ + RecordedTransition = true; + try(var MemStack = MemoryStack.stackPush()){ + RecordImageTransition(MemStack, commandBuffer); + RecordCopyBuffer(MemStack, commandBuffer, stgBuffer); + } + } + } + + private void RecordCopyBuffer(MemoryStack MemStack, CommandBuffer commandBuffer, VulkanBuffer bufferData){ + VkBufferImageCopy.Buffer copyRegions = VkBufferImageCopy.calloc(6, MemStack); + for(int i = 0; i < 6; i++) { + int BaseLayer = i; + copyRegions.get(i).bufferOffset(i * layerSize) + .bufferRowLength(0) + .bufferImageHeight(0) + .imageSubresource(it -> + it.aspectMask(VK_IMAGE_ASPECT_COLOR_BIT) + .mipLevel(0) + .baseArrayLayer(BaseLayer) + .layerCount(1) + ).imageOffset(it -> it.x(0).y(0).z(0)) + .imageExtent().set(Width, Height, 1); + } + vkCmdCopyBufferToImage(commandBuffer.GetVulkanCommandBuffer(), bufferData.GetBuffer(), image.getVulkanImage(), + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, copyRegions); + } + + public void CleanUp(VulkanContext VkCtx){ + CleanUpStgBuffer(VkCtx); + imageView.cleanup(VkCtx.GetDevice()); + image.CleanUp(VkCtx); + } + + public void CleanUpStgBuffer(VulkanContext VkCtx){ + if(stgBuffer != null){ + stgBuffer.cleanup(VkCtx); + stgBuffer = null; + } + } + + public int GetHeight(){return Height;} + public int GetWidth(){return Width;} + public String GetID(){return id;} + public ImageView GetImageView(){return imageView;} + + @Override + public TextureType getType() { + return TextureType.CubeMap; + } + +} diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Pipeline/Images/ITexture.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Pipeline/Images/ITexture.java new file mode 100644 index 0000000..4d791de --- /dev/null +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Pipeline/Images/ITexture.java @@ -0,0 +1,25 @@ +package net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Images; + +import net.halbear.Terrain4J.EngineCore.Logic.Rendering.VulkanContext; +import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.CommandBuffer; +import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DisplayToScreen.ImageView; + +import java.nio.ByteBuffer; + +public interface ITexture { + public enum TextureType{ + FlatImage, + CubeMap + } + public boolean HasTransparency(); + public void SetTransparency(ByteBuffer data); + public void CreateStgBuffer(VulkanContext VkCtx, ByteBuffer data); + public void RecordTextureTransition(CommandBuffer commandBuffer); + public void CleanUp(VulkanContext VkCtx); + public void CleanUpStgBuffer(VulkanContext VkCtx); + public int GetHeight(); + public int GetWidth(); + public String GetID(); + public ImageView GetImageView(); + public TextureType getType(); +} diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Pipeline/Images/Image.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Pipeline/Images/Image.java index 2aa45d3..f11e1db 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Pipeline/Images/Image.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Pipeline/Images/Image.java @@ -46,6 +46,7 @@ public class Image { .height(imageData.Height) .depth(1)) .mipLevels(MipLevels) + .flags(imageData.Flag) .arrayLayers(imageData.ArrayLayers) .samples(imageData.SampleCount) .initialLayout(VK_IMAGE_LAYOUT_UNDEFINED) @@ -83,18 +84,24 @@ public class Image { private int MipMapLevels; private int SampleCount; private int Usage; + private int Flag; public ImageData(){ Format = VK_FORMAT_R8G8B8A8_SRGB; MipMapLevels = 1; SampleCount = 1; ArrayLayers = 1; + Flag = 0; MemoryUsage = VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT; } public ImageData MemoryUsage(int memoryUsage){ this.MemoryUsage = memoryUsage; return this; } + public ImageData Flags(int flag){ + this.Flag = flag; + return this; + } public ImageData ArrayLayers(int ArrayLayers){ this.ArrayLayers = ArrayLayers; return this; diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Pipeline/Images/Texture.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Pipeline/Images/Texture.java index e8e38a8..8114992 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Pipeline/Images/Texture.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Pipeline/Images/Texture.java @@ -19,7 +19,7 @@ import static org.lwjgl.vulkan.VK10.*; import static org.lwjgl.vulkan.VK13.VK_ACCESS_2_NONE; import static org.lwjgl.vulkan.VK13.vkCmdPipelineBarrier2; -public class Texture { +public class Texture implements ITexture { private final String ID; private final int Height; @@ -212,4 +212,8 @@ public class Texture { public int GetWidth(){return Width;} public String GetID(){return ID;} public ImageView GetImageView(){return imageView;} + @Override + public TextureType getType() { + return TextureType.FlatImage; + } } diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Pipeline/Images/TextureCache.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Pipeline/Images/TextureCache.java index 6e8baac..0233c3f 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Pipeline/Images/TextureCache.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Pipeline/Images/TextureCache.java @@ -18,8 +18,8 @@ import java.util.UUID; import static org.lwjgl.vulkan.VK10.VK_FORMAT_R8G8B8A8_SRGB; public class TextureCache { - public static final int MAX_TEXTURES = 512; - private final IndexedLinkedHashMap TextureMap; + public static final int MAX_TEXTURES = 128; + private final IndexedLinkedHashMap TextureMap; private final List ActualTextures; public TextureCache(){ @@ -27,14 +27,28 @@ public class TextureCache { ActualTextures = new ArrayList<>(); } - public Texture AddTexture(VulkanContext VkCtx, String ID, ImageSrc imageSrc, int Format) { + public ITexture AddCubeMapTexture(VulkanContext VkCtx, String ID, String[] FacePaths, int Format) { + ITexture cubemap = TextureMap.get(ID); + if (cubemap == null) { + try { + cubemap = new CubeMapTexture(VkCtx, ID, FacePaths, Format); + TextureMap.put(ID, cubemap); + ActualTextures.add(ID); + } catch (IOException exception) { + Logger.error("Could not load cubemap texture faces, exception: {}", exception.getMessage()); + } + } + return cubemap; + } + + public ITexture AddTexture(VulkanContext VkCtx, String ID, ImageSrc imageSrc, int Format) { return AddTexture(VkCtx,ID,imageSrc,Format,false); } - public Texture AddTexture(VulkanContext VkCtx, String ID, ImageSrc imageSrc, int Format, boolean PaddingTexture){ + public ITexture AddTexture(VulkanContext VkCtx, String ID, ImageSrc imageSrc, int Format, boolean PaddingTexture){ if(TextureMap.size() > MAX_TEXTURES){ throw new IllegalArgumentException("Texture Cache Is Full"); } - Texture newTexture = TextureMap.get(ID); + ITexture newTexture = TextureMap.get(ID); if(newTexture == null){ newTexture = new Texture(VkCtx, ID, imageSrc, Format); if(!PaddingTexture)ActualTextures.add(ID); @@ -42,12 +56,12 @@ public class TextureCache { } return newTexture; } - public Texture AddTexture(VulkanContext VkCtx, String ID, String TexturePath, int Format) { + public ITexture AddTexture(VulkanContext VkCtx, String ID, String TexturePath, int Format) { return AddTexture(VkCtx,ID,TexturePath,Format,false); } - public Texture AddTexture(VulkanContext VkCtx, String ID, String TexturePath, int Format, boolean PaddingTexture) { + public ITexture AddTexture(VulkanContext VkCtx, String ID, String TexturePath, int Format, boolean PaddingTexture) { ImageSrc imageSrc = null; - Texture result = null; + ITexture result = null; try{ imageSrc = GraphUtils.LoadImage(TexturePath); result = AddTexture(VkCtx, ID, imageSrc, Format,PaddingTexture); @@ -63,7 +77,7 @@ public class TextureCache { public void TransitionTexts(VulkanContext VkCtx, CommandPool CmdPool, Queue queue){ Logger.debug("Recording Texture Transition"); - IndexedLinkedHashMap NewTextureMap = new IndexedLinkedHashMap<>(); + IndexedLinkedHashMap NewTextureMap = new IndexedLinkedHashMap<>(); TextureMap.forEach((name,texture)->{ if(ActualTextures.contains(name)){ NewTextureMap.put(name,texture); @@ -89,12 +103,12 @@ public class TextureCache { TextureMap.forEach((key,value)->value.CleanUpStgBuffer(VkCtx)); Logger.debug("Recorded Texture Transition"); } - public Texture GetTexture(String TexturePath){ + public ITexture GetTexture(String TexturePath){ Logger.debug("Fetching Texture -> [{}]",TexturePath.trim()); return TextureMap.get(TexturePath.trim()); } - public IndexedLinkedHashMap GetTextureCache(){return TextureMap;} - public List GetTextureList(){return new ArrayList<>(TextureMap.values());} + public IndexedLinkedHashMap GetTextureCache(){return TextureMap;} + public List GetTextureList(){return new ArrayList<>(TextureMap.values());} public int GetPosition(String ID){ int result = -1; if(ID != null){ diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/PostProcessing/PostProcess.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/PostProcessing/PostProcess.java index 61b63c4..a4ca4c8 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/PostProcessing/PostProcess.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/PostProcessing/PostProcess.java @@ -71,7 +71,6 @@ public class PostProcess { specConstants = new SpecializationConstants(); ShaderModule[] shaderModules = CreateShaderModules(VkCtx, specConstants); - pipeline = CreatePipeline(VkCtx, shaderModules, new DescriptorSetLayout[]{AttachmentDescriptorSetLayout, FragmentUniformDescriptorSetLayout}); Arrays.asList(shaderModules).forEach(shader->shader.CleanUp(VkCtx)); Logger.debug("Post Process Renderer Pipeline -> [{}]",pipeline.GetVulkanPipeline()); @@ -137,6 +136,7 @@ public class PostProcess { new ShaderModule(VkCtx,VK_SHADER_STAGE_VERTEX_BIT,VERTEX_SHADER_FILE_SPV,null), new ShaderModule(VkCtx,VK_SHADER_STAGE_FRAGMENT_BIT,ShaderPath,specConstants.GetSpecializationInfo()) }; + } public void Render(VulkanContext VkCtx, CommandBuffer commandBuffer, Attachment SrcAttachment){ diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Shader/DescriptorSet.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Shader/DescriptorSet.java index d192133..57863c0 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Shader/DescriptorSet.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Shader/DescriptorSet.java @@ -8,6 +8,7 @@ import org.lwjgl.vulkan.VkDescriptorBufferInfo; import org.lwjgl.vulkan.VkDescriptorImageInfo; import org.lwjgl.vulkan.VkDescriptorSetAllocateInfo; import org.lwjgl.vulkan.VkWriteDescriptorSet; +import org.tinylog.Logger; import java.nio.LongBuffer; import java.util.ArrayList; @@ -58,11 +59,24 @@ public class DescriptorSet { SetImages(device, imageViews, textureSampler, BaseBinding); } public void SetImages(Device device, List imageViews, TextureSampler textureSampler, int BaseBinding){ + if(textureSampler == null || textureSampler.GetVkSampler() == VK_NULL_HANDLE){ + Logger.error("Null texture sampler during Set Images function"); + throw new RuntimeException("yo this texture sampler ain't present"); + } + try(var MemStack = MemoryStack.stackPush()){ int ImageCount = imageViews.size(); var DescriptorBuffer = VkWriteDescriptorSet.calloc(ImageCount,MemStack); for(int i = 0; i < ImageCount; i++){ ImageView imageView = imageViews.get(i); + if(imageView == null || imageView.GetVulkanImageView() == VK_NULL_HANDLE){ + Logger.error("Null Image View or Image View Handle during Set Images function"); + throw new RuntimeException("yo this ImageView ain't present"); + } + if(imageView.GetVulkanImage() == VK_NULL_HANDLE){ + Logger.error("Null Image Handle during Set Images function"); + throw new RuntimeException("yo this Image ain't present"); + } var ImageInfo = VkDescriptorImageInfo.calloc(1,MemStack) .imageView(imageView.GetVulkanImageView()) .sampler(textureSampler.GetVkSampler()); diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Shadows/CascadeData.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Shadows/CascadeData.java new file mode 100644 index 0000000..f672008 --- /dev/null +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Shadows/CascadeData.java @@ -0,0 +1,21 @@ +package net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Shadows; + +import org.joml.Matrix4f; + +public class CascadeData { + private final Matrix4f ProjectionViewMatrix; + private float SplitDistance; + + public CascadeData(){ + ProjectionViewMatrix = new Matrix4f(); + } + + public Matrix4f GetProjectionViewMatrix(){return ProjectionViewMatrix;} + public float GetSplitDistance(){return SplitDistance;} + public void SetProjectionViewMatrix(Matrix4f ProjViewMat){ + this.ProjectionViewMatrix.set(ProjViewMat); + } + public void SetSplitDistance(float splitDistance){ + this.SplitDistance = splitDistance; + } +} diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Shadows/CascadeShadows.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Shadows/CascadeShadows.java new file mode 100644 index 0000000..dd087b1 --- /dev/null +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Shadows/CascadeShadows.java @@ -0,0 +1,19 @@ +package net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Shadows; + +import net.halbear.Terrain4J.EngineCore.Main.Scene.SceneLightingManager; + +import java.util.ArrayList; +import java.util.List; + +public class CascadeShadows { + private final List cascadeDataList; + + public CascadeShadows(){ + this.cascadeDataList = new ArrayList<>(); + for(int i = 0; i < SceneLightingManager.SHADOW_MAP_CASCADE_COUNT; i++){ + cascadeDataList.add(new CascadeData()); + } + } + + public List GetCascadeData(){return cascadeDataList;} +} diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Shadows/ShadowRenderer.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Shadows/ShadowRenderer.java new file mode 100644 index 0000000..6f058d7 --- /dev/null +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Shadows/ShadowRenderer.java @@ -0,0 +1,22 @@ +package net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Shadows; + +import net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanUtils; + +import static org.lwjgl.vulkan.VK10.VK_FORMAT_D32_SFLOAT; +import static org.lwjgl.vulkan.VK10.VK_FORMAT_R32G32_SFLOAT; + +public class ShadowRenderer { + public static final int DEPTH_FORMAT = VK_FORMAT_D32_SFLOAT; + private static final int ATTACHMENT_FORMATT = VK_FORMAT_R32G32_SFLOAT; + private static final String DESCRIPTOR_ID_MAT = "SHADOW_DESC_ID_MAT"; + private static final String DESCRIPTOR_ID_PRJ = "SHADOW_DESC_ID_PRJ"; + private static final String DESCRIPTOR_ID_TEXT = "SHADOW_SCN_DESC_ID_TEXT"; + private static final String FRAGMENT_SHADER_FILE_GLSL = "resources/EngineResources/shaders/shadow_frag.glsl"; + private static final String FRAGMENT_SHADER_FILE_SPV = FRAGMENT_SHADER_FILE_GLSL + ".spv"; + private static final int PUSH_CONSTANTS_SIZE = VulkanUtils.MATRIX4X4_SIZE + VulkanUtils.INT_SIZE; + private static final String SHADOW_GEOMETRY_SHADER_FILE_GLSL = "resources/EngineResources/shaders/shadow_geometry.glsl"; + private static final String SHADOW_GEOMETRY_SHADER_FILE_SPV = SHADOW_GEOMETRY_SHADER_FILE_GLSL + ".spv"; + private static final String VERTEX_SHADER_FILE_GLSL = "resources/EngineResources/shaders/shadow_vertex.glsl"; + private static final String VERTEX_SHADER_FILE_SPV = VERTEX_SHADER_FILE_GLSL + ".spv"; + +} diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Shadows/ShadowUtils.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Shadows/ShadowUtils.java new file mode 100644 index 0000000..0322f21 --- /dev/null +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/Shadows/ShadowUtils.java @@ -0,0 +1,144 @@ +package net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Shadows; + +import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig; +import net.halbear.Terrain4J.EngineCore.Main.Scene.Camera; +import net.halbear.Terrain4J.EngineCore.Main.Scene.ILight; +import net.halbear.Terrain4J.EngineCore.Main.Scene.IScene; +import net.halbear.Terrain4J.EngineCore.Main.Scene.SceneLightingManager; +import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Projection.Project3D; +import org.joml.Matrix4f; +import org.joml.Vector3f; +import org.joml.Vector4f; + +import javax.swing.text.View; +import java.util.List; + +public class ShadowUtils { + + private static final float LAMBDA = 0.95f; + private static final Vector3f Up = new Vector3f(0.0f,1.0f,0.0f); + private static final Vector3f UpAlt = new Vector3f(0.0f,0.0f,1.0f); + + private ShadowUtils(){ + + } + + public static void UpdateCascadeShadows(CascadeShadows shadows, IScene scene){ + Camera camera = scene.GetCamera(); + Matrix4f ViewMatrix = camera.GetViewMatrix(); + Project3D projection = scene.GetProjection(); + Matrix4f ProjectionMatrix = projection.GetProjectionMatrix(); + ILight[] lights = scene.GetLightingManager().GetLights(); + int LightCount = lights.length; + ILight SkyLight = null; + for(int i = 0; i < LightCount; i++){ + if(lights[i].IsDirectional()){ + SkyLight = lights[i]; + break; + } + } + if(SkyLight == null){ + throw new RuntimeException("No SkyLight on scene"); + } + Vector4f LightPosition = new Vector4f(SkyLight.GetPosition(),0.0f); + float[] CascadeSplits = new float[SceneLightingManager.SHADOW_MAP_CASCADE_COUNT]; + float NearClip = Math.min(projection.GetNearZ(), projection.GetFarZ()); + float FarClip = Math.max(projection.GetNearZ(), projection.GetFarZ()); + float ClipRange = FarClip - NearClip; + + float MinZ = NearClip; + float MaxZ = NearClip + ClipRange; + + float Range = MaxZ - MinZ; + float Ratio = MaxZ/MinZ; + + List cascadeDataList = shadows.GetCascadeData(); + int CascadeCount = cascadeDataList.size(); + + for(int i = 0; i < CascadeCount; i++){ + float p = (i + 1) / (float) (SceneLightingManager.SHADOW_MAP_CASCADE_COUNT); + float Log = (float) (MinZ * Math.pow(Ratio, p)); + float Uniform = MinZ + Range * p; + float d = LAMBDA * (Log - Uniform) + Uniform; + CascadeSplits[i] = (d - NearClip) / ClipRange; + } + + float LastSplitDist = 0.0f; + for(int i = 0; i < CascadeCount; i++){ + float SplitDist = CascadeSplits[i]; + + Vector3f[] FustrumCorners = new Vector3f[]{ + new Vector3f(-1.0f, 1.0f, 0.0f), + new Vector3f(1.0f, 1.0f, 0.0f), + new Vector3f(1.0f, -1.0f, 0.0f), + new Vector3f(-1.0f, -1.0f, 0.0f), + new Vector3f(-1.0f, 1.0f, 1.0f), + new Vector3f(1.0f, 1.0f, 1.0f), + new Vector3f(1.0f, -1.0f, 1.0f), + new Vector3f(-1.0f, -1.0f, 1.0f) + }; + + var InvertedCam = (new Matrix4f(ProjectionMatrix).mul(ViewMatrix)).invert(); + for(int j = 0; j < 8; j++){ + Vector4f InvertedCorner = new Vector4f(FustrumCorners[j],1.0f).mul(InvertedCam); + FustrumCorners[j] = new Vector3f(InvertedCorner.x,InvertedCorner.y,InvertedCorner.z).div(InvertedCorner.w); + } + + for(int j = 0; j < 4; j++){ + var Distance = new Vector3f(FustrumCorners[j + 4]).sub(FustrumCorners[j]); + FustrumCorners[j + 4] = new Vector3f(FustrumCorners[j]).add(new Vector3f(Distance).mul(SplitDist)); + FustrumCorners[j] = new Vector3f(FustrumCorners[j]).add(new Vector3f(Distance).mul(LastSplitDist)); + } + + var FustrumCenter = new Vector3f(0.0f); + for(int j = 0; j < 8; j++){ + FustrumCenter.add(FustrumCorners[j]); + } + FustrumCenter.div(8); + + var up = Up; + float SphereRadius = 0.0f; + for(int j = 0; j < 8; j++){ + float Distance = new Vector3f(FustrumCorners[j]).sub(FustrumCenter).length(); + SphereRadius = Math.max(SphereRadius,Distance); + } + SphereRadius = (float)Math.ceil(SphereRadius * 16.0f) / 16.0f; + + var MaxExtents = new Vector3f(SphereRadius); + var MinExtents = new Vector3f(-SphereRadius); + + var LightDirection = new Vector3f(LightPosition.x, LightPosition.y, LightPosition.z); + var ShadowCamPosition = new Vector3f(FustrumCenter).add(LightDirection.mul(MinExtents.z)); + + float Dot = Math.abs(new Vector3f(LightPosition.x, LightPosition.y, LightPosition.z).dot(up)); + if(Dot == 1.0f){ + up = UpAlt; + } + + var LightViewMatrix = new Matrix4f().lookAt(ShadowCamPosition,FustrumCenter,up); + var LightOrthoMatrix = new Matrix4f().ortho(MinExtents.x,MaxExtents.x,MinExtents.y,MaxExtents.y,0.0f,MaxExtents.z - MinExtents.z,true); + + int ShadowMapSize = EngineConfig.getInstance().GetShadowMapSize(); + Vector4f ShadowOrigin = new Vector4f(0f,0f,0f,1f); + LightViewMatrix.transform(ShadowOrigin); + ShadowOrigin.mul(ShadowMapSize/2.0f); + + Vector4f RoundedOrigin = new Vector4f(ShadowOrigin).round(); + Vector4f RoundOffset = RoundedOrigin.sub(ShadowOrigin); + RoundOffset.mul(2.0f/ShadowMapSize); + RoundOffset.z = 0.0f; + RoundOffset.w = 0.0f; + + LightOrthoMatrix.m30(LightOrthoMatrix.m30() + RoundOffset.x); + LightOrthoMatrix.m31(LightOrthoMatrix.m31() + RoundOffset.y); + LightOrthoMatrix.m32(LightOrthoMatrix.m32() + RoundOffset.z); + LightOrthoMatrix.m33(LightOrthoMatrix.m33() + RoundOffset.w); + + CascadeData cascadeData = cascadeDataList.get(i); + cascadeData.SetSplitDistance((NearClip + SplitDist * ClipRange) * -1.0f); + cascadeData.SetProjectionViewMatrix(LightOrthoMatrix.mul(LightViewMatrix)); + + LastSplitDist = CascadeSplits[i]; + } + } +} diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/VkModel/MaterialsCache.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/VkModel/MaterialsCache.java index 3e8bd4b..5868b77 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/VkModel/MaterialsCache.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/VkModel/MaterialsCache.java @@ -1,6 +1,7 @@ package net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel; import net.halbear.Terrain4J.EngineCore.Logic.Rendering.VulkanContext; +import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Images.ITexture; import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Images.Texture; import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Images.TextureCache; import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.IndexedLinkedHashMap; @@ -56,14 +57,14 @@ public class MaterialsCache { boolean TransparentTexture; Logger.debug("Material Texture Path -> [{}]",Material.TexturePath()); if(ValidTexture){ - Texture newTexture = textureCache.AddTexture(VkCtx, TexturePath, TexturePath, VK_FORMAT_R8G8B8A8_SRGB); + ITexture newTexture = textureCache.AddTexture(VkCtx, TexturePath, TexturePath, VK_FORMAT_R8G8B8A8_SRGB); if(newTexture == null) { TransparentTexture = false; - TexturePath = "resources/EngineResources/Texture/DefaultTexture.png"; + TexturePath = "resources/EngineResources/Texture/NoTexture.png"; } else TransparentTexture = newTexture.HasTransparency(); } else{ - TexturePath = "resources/EngineResources/Texture/DefaultTexture.png"; + TexturePath = "resources/EngineResources/Texture/NoTexture.png"; TransparentTexture = Material.DiffuseColour().w < 1.0f; } VulkanMaterial newMaterial = new VulkanMaterial(Material.ID(),TransparentTexture); diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/VkModel/ModelsCache.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/VkModel/ModelsCache.java index 76b4dc6..68a2c97 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/VkModel/ModelsCache.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Rendering/VkModel/ModelsCache.java @@ -1,18 +1,26 @@ package net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel; import net.halbear.Terrain4J.EngineCore.Logic.Rendering.VulkanContext; +import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime; +import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Shader.DescriptorAllocator; +import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Shader.DescriptorSet; import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.CommandBuffer; import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.CommandPool; import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.GPUSynchronisation.TransferBuffer; import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.Queues.Queue; +import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DisplayToScreen.DeferredSceneRender; import net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanBuffer; import net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanUtils; +import org.lwjgl.PointerBuffer; +import org.lwjgl.system.MemoryStack; import org.lwjgl.system.MemoryUtil; +import org.lwjgl.vulkan.VkCommandBuffer; import org.tinylog.Logger; import java.io.*; import java.nio.FloatBuffer; import java.nio.IntBuffer; +import java.nio.LongBuffer; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -28,6 +36,51 @@ public class ModelsCache { ModelsMap = new HashMap<>(); } + private final java.util.Map SkyboxBuffers = new java.util.HashMap<>(); + + public String CreateSkybox(VulkanContext vulkanContext, float[] vertices, String SkyBoxID) { + long bufferSize = (long) vertices.length * Float.BYTES; // 36 * 4 bytes = 144 bytes + + VulkanBuffer meshBuffer = VulkanUtils.CreateRawVertexAttrBuffer(vulkanContext, bufferSize); + + long meshBuffPtr = meshBuffer.MapMemory(vulkanContext); + + if (meshBuffPtr == 0 || meshBuffPtr == -1) { + throw new RuntimeException("CRITICAL ERROR: meshBuffer.MapMemory() returned an invalid native address pointer: " + meshBuffPtr + + ". Check your underlying vkMapMemory/vmaMapMemory configurations."); + } + + try { + java.nio.FloatBuffer floatBuffer = org.lwjgl.system.MemoryUtil.memFloatBuffer(meshBuffPtr, vertices.length); + floatBuffer.put(vertices); + floatBuffer.flip(); + } catch (Exception e) { + throw new RuntimeException("Failed during FloatBuffer array memory payload copy wrapper pass", e); + } finally { + meshBuffer.UnMapMemory(vulkanContext); + } + + this.SkyboxBuffers.put(SkyBoxID, meshBuffer.GetBuffer()); + + return SkyBoxID; + } + + public void bindAndDrawCubeMesh(VkCommandBuffer commandHandle, String skyboxMeshBufferId) { + Long vkBufferHandle = SkyboxBuffers.get(skyboxMeshBufferId); + if (vkBufferHandle == null) { + throw new RuntimeException("Skybox mesh buffer ID [" + skyboxMeshBufferId + "] not loaded in ModelsCache!"); + } + + try (MemoryStack MemStack = MemoryStack.stackPush()) { + LongBuffer pBuffers = MemStack.longs(vkBufferHandle); + LongBuffer pOffsets = MemStack.longs(0); + + vkCmdBindVertexBuffers(commandHandle, 0, pBuffers, pOffsets); + + vkCmdDraw(commandHandle, 36, 1, 0, 0); + } + } + public void loadModels(VulkanContext VkCtx, List Models, CommandPool commandPool, Queue queue){ try { List StagingBufferList = new ArrayList<>(); diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Structure/DisplayToScreen/DeferredSceneRender.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Structure/DisplayToScreen/DeferredSceneRender.java index 1564288..8486ebb 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Structure/DisplayToScreen/DeferredSceneRender.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Structure/DisplayToScreen/DeferredSceneRender.java @@ -3,15 +3,11 @@ package net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DisplayToScreen; 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.PrimaryRuntime; import net.halbear.Terrain4J.EngineCore.Main.Scene.Actor; import net.halbear.Terrain4J.EngineCore.Main.Scene.IScene; -import net.halbear.Terrain4J.EngineCore.Main.Scene.Scene; import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.DeferredRendering.MultiRenderTargetAttachments; import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.DefaultPipeline; -import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Images.Attachment; -import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Images.Texture; -import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Images.TextureCache; +import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Images.*; import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Pipeline; import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.PipelineBuildInfo; import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.PushConstantsRange; @@ -42,12 +38,16 @@ public class DeferredSceneRender implements SceneRenderer {//dynamic rendering private static final String DESCRIPTOR_ID_PRJ = "SCN_DESC_ID_PRJ"; private static final String DESCRIPTOR_ID_TEXT = "SCN_DESC_ID_TEXT"; private static final String DESCRIPTOR_ID_VIEW = "SCN_DESC_ID_VIEW"; + private static final String DESCRIPTOR_ID_SKYBOX_VIEW = "SCN_DESC_ID_SKYBOX_VIEW"; + public static final String DESCRIPTOR_ID_SKYBOX_CUBEMAP = "SCN_DESC_ID_SKYBOX_CUBEMAP"; private static final int PUSH_CONSTANTS_SIZE = VulkanUtils.MATRIX4X4_SIZE + VulkanUtils.INT_SIZE; private final VulkanBuffer BufferProjectionMatrix; private final DescriptorSetLayout descriptorLayoutFragStorage; private final DescriptorSetLayout descriptorLayoutTexture; private final DescriptorSetLayout descriptorLayoutVertexUniform; + private DescriptorSet SkyboxDescriptorSet; private final TextureSampler textureSampler; + public static String SkyBoxID = "SKYBOX_TEXTURE"; public static final int COLOUR_FORMAT = VK_FORMAT_R32G32B32A32_SFLOAT; public static final int DEPTH_FORMAT = VK_FORMAT_D32_SFLOAT; @@ -63,6 +63,11 @@ public class DeferredSceneRender implements SceneRenderer {//dynamic rendering public static long CYCLES = 0; private static boolean DualPassRendering = false; + private static final String SKYBOX_FRAGMENT_SHADER_FILE_GLSL = "resources/EngineResources/shaders/skybox_fragment.glsl"; + private static final String SKYBOX_FRAGMENT_SHADER_FILE_SPV = SKYBOX_FRAGMENT_SHADER_FILE_GLSL + ".spv"; + private static final String SKYBOX_VERTEX_SHADER_FILE_GLSL = "resources/EngineResources/shaders/skybox_vertex.glsl"; + private static final String SKYBOX_VERTEX_SHADER_FILE_SPV = SKYBOX_VERTEX_SHADER_FILE_GLSL + ".spv"; + private static final String FRAGMENT_SHADER_FILE_GLSL = "resources/EngineResources/shaders/scene_fragment_deferred.glsl"; private static final String FRAGMENT_TRANSLUCENT_SHADER_FILE_GLSL = "resources/EngineResources/shaders/scene_translucent_fragment_deferred.glsl"; private static final String FRAGMENT_OPAQUE_SHADER_FILE_GLSL = "resources/EngineResources/shaders/scene_opaque_fragment_deferred.glsl"; @@ -75,12 +80,17 @@ public class DeferredSceneRender implements SceneRenderer {//dynamic rendering private Pipeline VkPipeline; private Pipeline VkPipelineOpaque; private Pipeline VkPipelineTranslucent; - private float R = 0.00f; - private float G = 0.05f; - private float B = 0.15f; + private float R = 0.4f; + private float G = 0.75f; + private float B = 1.0f; private Matrix4f ProjectionMatrix; private MultiRenderTargetAttachments MRTAttachments; + private DescriptorSetLayout descriptorLayoutSkyboxTexture; + private VulkanBuffer[] BufferSkyboxViewMatrices; + private Pipeline VkSkyboxPipeline; + private long skyboxMeshBufferId; + public static long GetGPUTimeNS(){ long time = 0; if(CYCLES > 0){ @@ -93,7 +103,7 @@ public class DeferredSceneRender implements SceneRenderer {//dynamic rendering public DeferredSceneRender(VulkanContext vulkanContext, EngineInstance engineInstance){ ClearValueColour = VkClearValue.calloc().color( - c -> c.float32(0, R).float32(1, G).float32(2, B).float32(3, 0.5f)); + c -> c.float32(0, 0.0f).float32(1, 0.0f).float32(2, 0.0f).float32(3, 0.0f)); ClearValueDepth = VkClearValue.calloc().color(c -> c.float32(0, 0.0f)); MRTAttachments = new MultiRenderTargetAttachments(vulkanContext); AttachmentInfoColour = CreateColourAttachmentInfo(MRTAttachments, ClearValueColour); @@ -120,6 +130,14 @@ public class DeferredSceneRender implements SceneRenderer {//dynamic rendering descriptorLayoutTexture = new DescriptorSetLayout(vulkanContext, new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 0, TextureCache.MAX_TEXTURES, VK_SHADER_STAGE_FRAGMENT_BIT)); + descriptorLayoutSkyboxTexture = new DescriptorSetLayout(vulkanContext, + new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + 0, 1, VK_SHADER_STAGE_FRAGMENT_BIT)); + + BufferSkyboxViewMatrices = VulkanUtils.CreateHostVisibleBuffers(vulkanContext, VulkanUtils.MATRIX4X4_SIZE, VulkanUtils.MAX_IN_FLIGHT, + VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, DESCRIPTOR_ID_SKYBOX_VIEW, descriptorLayoutVertexUniform); + + CreatePipelines(vulkanContext); Logger.debug("Deferred Renderer Pipeline -> [{}]",VkPipeline.GetVulkanPipeline()); @@ -134,13 +152,24 @@ public class DeferredSceneRender implements SceneRenderer {//dynamic rendering }; ShaderModule[] shaderModules = DeferredSceneRender.CreateShaderModules(vulkanContext,0); - VkPipeline = CreatePipeline(vulkanContext, shaderModules, layouts, true, false,EngineConfig.getInstance().AlphaToCoverage()); + VkPipeline = CreatePipeline(vulkanContext, shaderModules, layouts, true,true, false,EngineConfig.getInstance().AlphaToCoverage(),0); Arrays.asList(shaderModules).forEach(shaderModule -> shaderModule.CleanUp(vulkanContext)); shaderModules = DeferredSceneRender.CreateShaderModules(vulkanContext,1); - VkPipelineOpaque = CreatePipeline(vulkanContext, shaderModules, layouts, true, true,EngineConfig.getInstance().AlphaToCoverage()); + VkPipelineOpaque = CreatePipeline(vulkanContext, shaderModules, layouts, true,false, true,EngineConfig.getInstance().AlphaToCoverage(),0); Arrays.asList(shaderModules).forEach(shaderModule -> shaderModule.CleanUp(vulkanContext)); shaderModules = DeferredSceneRender.CreateShaderModules(vulkanContext,2); - VkPipelineTranslucent = CreatePipeline(vulkanContext, shaderModules, layouts, false, true,EngineConfig.getInstance().AlphaToCoverage()); + VkPipelineTranslucent = CreatePipeline(vulkanContext, shaderModules, layouts, false, true,true,EngineConfig.getInstance().AlphaToCoverage(),2); + Arrays.asList(shaderModules).forEach(shaderModule -> shaderModule.CleanUp(vulkanContext)); + + DescriptorSetLayout[] skyboxLayouts = new DescriptorSetLayout[]{ + descriptorLayoutVertexUniform, + descriptorLayoutVertexUniform, + descriptorLayoutSkyboxTexture + }; + + shaderModules = DeferredSceneRender.CreateSkyboxShaderModules(vulkanContext); + + VkSkyboxPipeline = CreateSkyboxPipeline(vulkanContext, shaderModules, skyboxLayouts, false, false, false,false); Arrays.asList(shaderModules).forEach(shaderModule -> shaderModule.CleanUp(vulkanContext)); } @@ -181,6 +210,17 @@ public class DeferredSceneRender implements SceneRenderer {//dynamic rendering .clearValue(clearValue); } + private static ShaderModule[] CreateSkyboxShaderModules(VulkanContext VkCtx){ + if(EngineConfig.getInstance().RecompileShaders()){ + ShaderCompiler.CompileGLSLShaderOnChange(SKYBOX_VERTEX_SHADER_FILE_GLSL, Shaderc.shaderc_glsl_vertex_shader); + ShaderCompiler.CompileGLSLShaderOnChange( SKYBOX_FRAGMENT_SHADER_FILE_GLSL, Shaderc.shaderc_glsl_fragment_shader); + } + return new ShaderModule[]{ + new ShaderModule(VkCtx, VK_SHADER_STAGE_VERTEX_BIT, SKYBOX_VERTEX_SHADER_FILE_SPV,null), + new ShaderModule(VkCtx, VK_SHADER_STAGE_FRAGMENT_BIT, SKYBOX_FRAGMENT_SHADER_FILE_SPV,null) + }; + } + private static ShaderModule[] CreateShaderModules(VulkanContext VkCtx, int Translucent){ if(EngineConfig.getInstance().RecompileShaders()){ ShaderCompiler.CompileGLSLShaderOnChange(VERTEX_SHADER_FILE_GLSL, Shaderc.shaderc_glsl_vertex_shader); @@ -192,7 +232,47 @@ public class DeferredSceneRender implements SceneRenderer {//dynamic rendering }; } - private static Pipeline CreatePipeline(VulkanContext VkCtx, ShaderModule[] ShaderModules, DescriptorSetLayout[] DescriptorSetLayouts, boolean DepthWrite, boolean DualRender, boolean AlphaToCoverage){ + private static Pipeline CreateSkyboxPipeline(VulkanContext VkCtx, ShaderModule[] ShaderModules, DescriptorSetLayout[] DescriptorSetLayouts, boolean DepthWrite, boolean DualRender, boolean Blending, boolean AlphaToCoverage){ + int[] skyboxFormats = new int[] { + MultiRenderTargetAttachments.POSITION_FORMAT, + MultiRenderTargetAttachments.ALBEDO_FORMAT, + MultiRenderTargetAttachments.NORMAL_FORMAT, + MultiRenderTargetAttachments.PBR_FORMAT + }; + + try (MemoryStack MemStack = MemoryStack.stackPush()) { + VkVertexInputBindingDescription.Buffer bindingDescription = VkVertexInputBindingDescription.calloc(1, MemStack) + .binding(0) + .stride(3 * Float.BYTES) + .inputRate(VK_VERTEX_INPUT_RATE_VERTEX); + + VkVertexInputAttributeDescription.Buffer attributeDescription = VkVertexInputAttributeDescription.calloc(1, MemStack) + .binding(0) + .location(0) + .format(VK_FORMAT_R32G32B32_SFLOAT) + .offset(0); + + VkPipelineVertexInputStateCreateInfo skyboxVertexInputState = VkPipelineVertexInputStateCreateInfo.calloc(MemStack) + .sType(VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO) + .pVertexBindingDescriptions(bindingDescription) + .pVertexAttributeDescriptions(attributeDescription); + + var BuildInfo = new PipelineBuildInfo(ShaderModules, skyboxVertexInputState, skyboxFormats) + .SetDepthFormat(MultiRenderTargetAttachments.DEPTH_FORMAT) + .SetDepthWrite(false) + .SetDepthTest(true) + .SetPushConstantRanges(new PushConstantsRange[0]) + .SetDescriptorSetLayouts(DescriptorSetLayouts) + .BlendingIsUsed(true) + .SetDualPass(false) + .SetAlphaToCoverage(false); + var pipeline = new DefaultPipeline(VkCtx, BuildInfo); + Logger.debug("Skybox Pipeline Created Successfully"); + return pipeline; + } + } + + private static Pipeline CreatePipeline(VulkanContext VkCtx, ShaderModule[] ShaderModules, DescriptorSetLayout[] DescriptorSetLayouts, boolean DepthWrite, boolean DualRender, boolean Blending, boolean AlphaToCoverage, int BlendingMethod){ var vertexBufferStructure = new VertexBufferStructure(); var BuildInfo = new PipelineBuildInfo(ShaderModules,vertexBufferStructure.getVertexInput(),new int[]{ MultiRenderTargetAttachments.POSITION_FORMAT, MultiRenderTargetAttachments.ALBEDO_FORMAT, MultiRenderTargetAttachments.NORMAL_FORMAT, MultiRenderTargetAttachments.PBR_FORMAT}) @@ -204,10 +284,12 @@ public class DeferredSceneRender implements SceneRenderer {//dynamic rendering new PushConstantsRange(VK_SHADER_STAGE_FRAGMENT_BIT,VulkanUtils.MATRIX4X4_SIZE,VulkanUtils.INT_SIZE) }) .SetDescriptorSetLayouts(DescriptorSetLayouts) - .BlendingIsUsed(DualRender ? !DepthWrite : true) + .SetBlendingMethod(BlendingMethod) + .BlendingIsUsed(Blending) .SetDualPass(DualRender) .SetAlphaToCoverage(AlphaToCoverage); var pipeline = new DefaultPipeline(VkCtx, BuildInfo); + Logger.debug("Pipeline Created"); vertexBufferStructure.cleanup(); return pipeline; } @@ -255,6 +337,7 @@ public class DeferredSceneRender implements SceneRenderer {//dynamic rendering vkCmdSetScissor(CommandHandle, 0, Scissor); VulkanUtils.CopyMatrixToBuffer(vulkanContext, BufferViewMatrices[CurrentFrame],engineInstance.scene().GetCamera().GetViewMatrix(), 0); // here + DescriptorAllocator descriptorAllocator = vulkanContext.GetDescriptorAllocator(); LongBuffer DescriptorSets = MemStack.mallocLong(4) .put(0,descriptorAllocator.GetDescriptorSet(DESCRIPTOR_ID_PRJ).GetVkDescriptorSet()) @@ -264,14 +347,38 @@ public class DeferredSceneRender implements SceneRenderer {//dynamic rendering vkCmdBindDescriptorSets(CommandHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, DualPassRendering ? VkPipelineOpaque.GetVulkanPipelineLayout() : VkPipeline.GetVulkanPipelineLayout(),0,DescriptorSets,null); RenderActors(engineInstance, CommandHandle, modelsCache, materialsCache, false); + + Matrix4f skyboxViewMatrix = new Matrix4f().identity(); + skyboxViewMatrix.set(engineInstance.scene().GetCamera().GetViewMatrix()); + skyboxViewMatrix.m30(0.0f); + skyboxViewMatrix.m31(0.0f); + skyboxViewMatrix.m32(0.0f); + + VulkanUtils.CopyMatrixToBuffer(vulkanContext, BufferSkyboxViewMatrices[CurrentFrame], skyboxViewMatrix, 0); + + vkCmdBindPipeline(CommandHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, VkSkyboxPipeline.GetVulkanPipeline()); + + LongBuffer skyboxDescriptorSets = MemStack.mallocLong(3) + .put(0, descriptorAllocator.GetDescriptorSet(DESCRIPTOR_ID_PRJ).GetVkDescriptorSet()) + .put(1, descriptorAllocator.GetDescriptorSet(DESCRIPTOR_ID_SKYBOX_VIEW, CurrentFrame).GetVkDescriptorSet()) + .put(2, descriptorAllocator.GetDescriptorSet(DESCRIPTOR_ID_SKYBOX_CUBEMAP).GetVkDescriptorSet()); + + vkCmdBindDescriptorSets(CommandHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, VkSkyboxPipeline.GetVulkanPipelineLayout(), 0, skyboxDescriptorSets, null); + + modelsCache.bindAndDrawCubeMesh(CommandHandle, SkyBoxID); + VulkanUtils.CopyMatrixToBuffer(vulkanContext, BufferViewMatrices[CurrentFrame],engineInstance.scene().GetCamera().GetViewMatrix(), 0); // here if(DualPassRendering) { vkCmdBindPipeline(CommandHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, VkPipelineTranslucent.GetVulkanPipeline()); - vkCmdSetViewport(CommandHandle, 0, Viewport); - vkCmdSetScissor(CommandHandle, 0, Scissor); vkCmdBindDescriptorSets(CommandHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, VkPipelineTranslucent.GetVulkanPipelineLayout(), 0, DescriptorSets, null); + //vkCmdBindPipeline(CommandHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, VkPipelineOpaque.GetVulkanPipeline()); + //vkCmdBindDescriptorSets(CommandHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, VkPipelineOpaque.GetVulkanPipelineLayout(), 0, DescriptorSets, null); + } else{ + vkCmdBindPipeline(CommandHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, VkPipeline.GetVulkanPipeline()); + vkCmdBindDescriptorSets(CommandHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, VkPipeline.GetVulkanPipelineLayout(),0,DescriptorSets,null); } RenderActors(engineInstance, CommandHandle, modelsCache, materialsCache, true); + vkCmdEndRendering(CommandHandle); GPUTIME += System.nanoTime() - InitialTime; @@ -346,9 +453,21 @@ public class DeferredSceneRender implements SceneRenderer {//dynamic rendering var buffer = materialsCache.GetMaterialsBuffer(); descSet.SetBuffer(device, buffer, buffer.GetRequestedSize(), layoutInfo.Binding(), layoutInfo.DescriptorType()); - List imageViews = textureCache.GetTextureList().stream().map(Texture::GetImageView).toList(); + List imageViews = textureCache.GetTextureList().stream().map(ITexture::GetImageView).toList(); descSet = VkCtx.GetDescriptorAllocator().AddDescriptorSet(device, DESCRIPTOR_ID_TEXT, descriptorLayoutTexture); descSet.SetImageArray(device, imageViews, textureSampler, 0); + + DescriptorSet descSetSkyBox = descAllocator.AddDescriptorSet(device, DESCRIPTOR_ID_SKYBOX_CUBEMAP, descriptorLayoutSkyboxTexture); + ITexture SkyBoxTexture = textureCache.GetTexture(SkyBoxID); + if (SkyBoxTexture == null) { + throw new RuntimeException("Skybox texture map was not properly cached before descriptor binding phase!"); + } + descSetSkyBox.SetImage( + device, + SkyBoxTexture.GetImageView(), + textureSampler, + descriptorLayoutSkyboxTexture.GetLayoutInfo().Binding() + ); } private static VkRenderingInfo CreateRenderInfo(VulkanContext VkCtx, VkRenderingAttachmentInfo.Buffer ColourAttachmentInfo, VkRenderingAttachmentInfo DepthAttachmentInfo){ @@ -368,6 +487,7 @@ public class DeferredSceneRender implements SceneRenderer {//dynamic rendering public void cleanup(VulkanContext VkCtx){ VkPipeline.CleanUp(VkCtx); + // VkSkyboxPipeline.CleanUp(VkCtx); VkPipelineOpaque.CleanUp(VkCtx); VkPipelineTranslucent.CleanUp(VkCtx); Arrays.asList(BufferViewMatrices).forEach(b -> b.cleanup(VkCtx)); diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Structure/DisplayToScreen/ForwardSceneRender.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Structure/DisplayToScreen/ForwardSceneRender.java index 06f364b..76cafe9 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Structure/DisplayToScreen/ForwardSceneRender.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Structure/DisplayToScreen/ForwardSceneRender.java @@ -9,10 +9,7 @@ import net.halbear.Terrain4J.EngineCore.Main.Scene.IScene; import net.halbear.Terrain4J.EngineCore.Main.Scene.Scene; import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.DeferredRendering.MultiRenderTargetAttachments; import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.DefaultPipeline; -import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Images.Attachment; -import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Images.Image; -import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Images.Texture; -import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Images.TextureCache; +import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Images.*; import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Pipeline; import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.PipelineBuildInfo; import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.PushConstantsRange; @@ -60,7 +57,7 @@ public class ForwardSceneRender implements SceneRenderer {//dynamic rendering private final DescriptorSetLayout descriptorLayoutVertexUniform; private final TextureSampler textureSampler; private static final int COLOUR_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT; - private static final int DEPTH_FORMAT = VK_FORMAT_D32_SFLOAT_S8_UINT; + private static final int DEPTH_FORMAT = VK_FORMAT_D32_SFLOAT; private final VkClearValue ClearValueDepth; private final ByteBuffer PushConstBuffer; private Attachment AttachmentDepth; @@ -356,7 +353,7 @@ public class ForwardSceneRender implements SceneRenderer {//dynamic rendering DescriptorSetLayout.LayoutInformation LayoutInfo = descriptorLayoutFragStorage.GetLayoutInfo(); var Buffer = materialsCache.GetMaterialsBuffer(); descriptorSet.SetBuffer(device,Buffer,Buffer.GetRequestedSize(),LayoutInfo.Binding(),LayoutInfo.DescriptorType()); - List imageViews = textureCache.GetTextureList().stream().map(Texture::GetImageView).toList(); + List imageViews = textureCache.GetTextureList().stream().map(ITexture::GetImageView).toList(); descriptorSet = VkCtx.GetDescriptorAllocator().AddDescriptorSet(device,DESCRIPTOR_ID_TEXT,descriptorLayoutTexture); descriptorSet.SetImageArray(device,imageViews,textureSampler,0); } diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Structure/SwapChain/SwapChain.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Structure/SwapChain/SwapChain.java index 5c46f38..10b5f03 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Structure/SwapChain/SwapChain.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Structure/SwapChain/SwapChain.java @@ -17,6 +17,7 @@ import java.nio.LongBuffer; import java.util.Arrays; import static net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanUtils.vkCheck; +import static org.lwjgl.vulkan.KHRSurface.VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; import static org.lwjgl.vulkan.VK13.*; public class SwapChain { @@ -43,7 +44,7 @@ public class SwapChain { .imageArrayLayers(1) .imageUsage(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) .preTransform(SurfaceCapabilities.currentTransform()) - .compositeAlpha(KHRSurface.VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR) + .compositeAlpha(VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR) .clipped(true); if (VSYNC){ VulkanSwapChainCreateInfo.presentMode(KHRSurface.VK_PRESENT_MODE_FIFO_KHR); diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Structure/SwapChain/SwapChainRender.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Structure/SwapChain/SwapChainRender.java index 2520a4a..3db2ed4 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Structure/SwapChain/SwapChainRender.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Structure/SwapChain/SwapChainRender.java @@ -87,7 +87,7 @@ public class SwapChainRender { } private static Pipeline CreatePipeline(VulkanContext VkCtx, ShaderModule[] shaderModules, DescriptorSetLayout[] descriptorSetLayouts){ var VertexBufferStruct = new EmptyVertexBufferStruct(); - var BuildInfo = new PipelineBuildInfo(shaderModules, VertexBufferStruct.GetVertexInput(),new int[]{VkCtx.GetSurface().GetSurfaceFormat().ImageFormat()}).SetDescriptorSetLayouts(descriptorSetLayouts).BlendingIsUsed(true); + var BuildInfo = new PipelineBuildInfo(shaderModules, VertexBufferStruct.GetVertexInput(),new int[]{VkCtx.GetSurface().GetSurfaceFormat().ImageFormat()}).SetDescriptorSetLayouts(descriptorSetLayouts).BlendingIsUsed(false); var pipeline = new DefaultPipeline(VkCtx,BuildInfo); VertexBufferStruct.CleanUp(); return pipeline; @@ -167,9 +167,16 @@ public class SwapChainRender { vkCmdEndRendering(CommandHandle); - VulkanUtils.ImageBarrier(MemStack,CommandHandle,SwapChainImage,VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, - VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT, VK_ACCESS_2_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT, - VK_PIPELINE_STAGE_2_NONE, VK_IMAGE_ASPECT_COLOR_BIT); + VulkanUtils.ImageBarrier(MemStack, + CommandHandle, + SwapChainImage, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, + VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, // Source Stage + VK_PIPELINE_STAGE_2_NONE, // Destination Stage (Replacing BOTTOM_OF_PIPE) + VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT, // Source Access Mask + VK_ACCESS_2_NONE, // Destination Access Mask (Replacing Stage_2_None) + VK_IMAGE_ASPECT_COLOR_BIT); } } diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Util/VulkanUtils.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Util/VulkanUtils.java index 9914200..c6ab8a1 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Util/VulkanUtils.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Vulkan/Util/VulkanUtils.java @@ -1,6 +1,7 @@ package net.halbear.Terrain4J.EngineCore.Vulkan.Util; import net.halbear.Terrain4J.EngineCore.Logic.Rendering.VulkanContext; +import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime; import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Shader.DescriptorAllocator; import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Shader.DescriptorSet; import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Shader.DescriptorSetLayout; @@ -9,6 +10,7 @@ import org.joml.Matrix4f; import org.lwjgl.system.MemoryStack; import org.lwjgl.system.MemoryUtil; import org.lwjgl.vulkan.*; +import org.tinylog.Logger; import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; @@ -41,7 +43,16 @@ public class VulkanUtils { matrix.get(Offset, matrixBuffer); VkBuffer.UnMapMemory(VkCtx); } - + public static VulkanBuffer CreateRawVertexAttrBuffer(VulkanContext VkCtx, long BufferSize) { + return new VulkanBuffer( + VkCtx, + BufferSize, + VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, + VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE, + VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT, + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT + ); + } public static VulkanBuffer[] CreateHostVisibleBuffers(VulkanContext VkCtx, long BufferSize, int BufferCount, int Usage, String ID, DescriptorSetLayout layout){ DescriptorAllocator descriptorAllocator = VkCtx.GetDescriptorAllocator(); Device device = VkCtx.GetDevice(); @@ -142,7 +153,12 @@ public class VulkanUtils { case VK_ERROR_UNKNOWN -> "VK_ERROR_UNKNOWN"; default -> "Not mapped"; }; - throw new RuntimeException(ErrorMessage + ": " + ErrorCode + " [" + Error + "]"); + Logger.error("FATAL VULKAN ERROR -> " + ErrorMessage + ": " + ErrorCode + " [" + Error + "]\nAttempting To Restart Vulkan..."); + if(PrimaryRuntime.GetRenderThread() != null)PrimaryRuntime.GetRenderThread().RestartCrashedRenderer(); + else{ + PrimaryRuntime.GetEngineInstance().window().setShouldClose(); + PrimaryRuntime.CloseRuntime(); + } } } diff --git a/terrain4j.properties b/terrain4j.properties index 79db29c..6fb61f8 100644 --- a/terrain4j.properties +++ b/terrain4j.properties @@ -27,6 +27,8 @@ compatibility_mode=false #0 = Forward rendering #1 = Deferred rendering Renderer=1 +ShadowMapSize=16 +MaxAllowedVulkanCrashes=10 AlphaToCoverage=false DualPassRendering=false #AA settings @@ -43,7 +45,7 @@ vkValidated=true vsync=false #Swap Chain Images RequestedImages=3 -DefaultTexturePath=resources/EngineResources/Texture/DefaultTexture.png +DefaultTexturePath=resources/EngineResources/Texture/NoTexture.png #This is the name of the GPU you want the engine to use PhysicalDeviceName=