diff --git a/resources/EngineResources/shaders/forward_skybox_fragment.glsl b/resources/EngineResources/shaders/forward_skybox_fragment.glsl new file mode 100644 index 0000000..00cc1b1 --- /dev/null +++ b/resources/EngineResources/shaders/forward_skybox_fragment.glsl @@ -0,0 +1,11 @@ +#version 450 + +layout(location = 0) in vec3 outTexCoords; + +layout(location = 0) 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/forward_skybox_fragment.glsl.spv b/resources/EngineResources/shaders/forward_skybox_fragment.glsl.spv new file mode 100644 index 0000000..c62d0b9 Binary files /dev/null and b/resources/EngineResources/shaders/forward_skybox_fragment.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 dfabc91..0dd511b 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.6545; +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/src/main/java/net/halbear/Terrain4J/EngineCore/Logic/Physics/RigidBody/RigidBody.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Logic/Physics/RigidBody/RigidBody.java index e106738..ad04333 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Logic/Physics/RigidBody/RigidBody.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Logic/Physics/RigidBody/RigidBody.java @@ -4,6 +4,7 @@ import net.halbear.Terrain4J.EngineCore.Logic.Physics.IPhysicsController; import org.joml.Matrix3f; import org.joml.Quaternionf; import org.joml.Vector3f; +import org.joml.primitives.AABBf; import java.util.ArrayList; import java.util.HashMap; @@ -18,6 +19,8 @@ public class RigidBody { public final ConvexMesh shape; + public AABBf BoundingBox; + public final Vector3f Position; public final Quaternionf Rotation; public Vector3f WeightBalance = new Vector3f(0,0,0); @@ -37,7 +40,7 @@ public class RigidBody { public final Matrix3f InverseInertiaLocal = new Matrix3f(); public final Matrix3f InverseInertiaWorld = new Matrix3f(); - public float Restitution = 0.0f; // 0 = fully inelastic, 1 = perfectly elastic + public float Restitution = 0.0f; // 0 = not bouncy, 1 = bouncy public float Friction = 0.5f; public boolean IsStatic = false; diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Logic/Physics/RigidBody/RigidCollision.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Logic/Physics/RigidBody/RigidCollision.java index f6ce725..795bb6b 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Logic/Physics/RigidBody/RigidCollision.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Logic/Physics/RigidBody/RigidCollision.java @@ -5,8 +5,8 @@ import org.joml.Vector3f; //Resolves the Separating Axis Theorem Test into reaction forces in impulses and position correction public class RigidCollision { - private static final float CORRECTION_THRESHOLD = 1.0f; //how much it gets corrected positionally per physics step - private static final float SLOP = 0.000f; // amount of overlap can happen before collision gets corrected + private static final float CORRECTION_THRESHOLD = 0.9f; //how much it gets corrected positionally per physics step + private static final float SLOP = 0.001f; // amount of overlap can happen before collision gets corrected public synchronized static void ResolveCollision(RigidBody body1, RigidBody body2, SeparatingAxisTheoremTester.CollisionResult collisionResult){ Vector3f Normal = collisionResult.Normal; @@ -44,7 +44,7 @@ public class RigidCollision { Impulse.set(normal).mul(j); body1.LinearVelocity.mul(-1,body1.LinearVelocity.y < 0 ? 1 : -1,-1).mul(body1.Bounciness,body1.LinearVelocity.y < 0 ? 1 : body1.Bounciness,body1.Bounciness); - body2.LinearVelocity.mul(-1,body1.LinearVelocity.y < 0 ? 1 : -1,-1).mul(body1.Bounciness,body1.LinearVelocity.y < 0 ? 1 : body1.Bounciness,body1.Bounciness); + body2.LinearVelocity.mul(-1,body2.LinearVelocity.y < 0 ? 1 : -1,-1).mul(body2.Bounciness,body2.LinearVelocity.y < 0 ? 1 : body2.Bounciness,body2.Bounciness); body1.ApplyImpulse(NegatedImpulse.set(Impulse).negate(), Point); diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Logic/Physics/RigidBody/RigidPhysicsController.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Logic/Physics/RigidBody/RigidPhysicsController.java index 6c92326..1776eb0 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Logic/Physics/RigidBody/RigidPhysicsController.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Logic/Physics/RigidBody/RigidPhysicsController.java @@ -97,6 +97,16 @@ public class RigidPhysicsController implements IPhysicsController { public void PhysicsTick(float DeltaTime, float TargetFrameRate) { DeltaTime/=10f; // if(DeltaTime >0.1f) DeltaTime = 0.1f; + + if(RigidBodyID != null && RigidBodyRegister.get(RigidBodyID) != null && ActorID != "NULL") { + RigidBody rigidBody = RigidBodyRegister.get(RigidBodyID); + rigidBody.Integrate(DeltaTime, new Vector3f(0,-1.8f,0)); + if(Actor.Actors.get(ActorID) != null) { + Actor.Actors.get(ActorID).SetPosition(new Vector3f(rigidBody.Position)); + Actor.Actors.get(ActorID).SetRotation(rigidBody.Rotation); + } + } + /* if(RigidBodyID != null && RigidBodyRegister.get(RigidBodyID) != null && ActorID != "NULL") { RigidBody rigidBody = RigidBodyRegister.get(RigidBodyID); rigidBody.Integrate(DeltaTime, new Vector3f(0,-1.8f,0)); @@ -113,7 +123,7 @@ public class RigidPhysicsController implements IPhysicsController { Actor.Actors.get(ActorID).SetPosition(new Vector3f(rigidBody.Position)); Actor.Actors.get(ActorID).SetRotation(rigidBody.Rotation); } - } + }*/ } @Override diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Logic/Physics/WorldPhysicsManager.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Logic/Physics/WorldPhysicsManager.java index 80a69d7..1d1ecbd 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Logic/Physics/WorldPhysicsManager.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Logic/Physics/WorldPhysicsManager.java @@ -1,6 +1,9 @@ package net.halbear.Terrain4J.EngineCore.Logic.Physics; import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig; +import net.halbear.Terrain4J.EngineCore.Logic.Physics.RigidBody.RigidBody; +import net.halbear.Terrain4J.EngineCore.Logic.Physics.RigidBody.RigidCollision; +import net.halbear.Terrain4J.EngineCore.Logic.Physics.RigidBody.SeparatingAxisTheoremTester; import net.halbear.Terrain4J.EngineCore.Threads.PhysicsThread; import java.util.ArrayList; @@ -19,7 +22,7 @@ public class WorldPhysicsManager { public static final Map PhysicsObjects = new HashMap<>(); public static List ActiveControllers = new ArrayList<>(); - public static float FixedTimeStep = 1f / 60f; + public static float FixedTimeStep = 1f / 24f; public static int MaxSubStepsPerFrame = 8; private static float Accumulator = 0f; private static boolean SingleThread = false; @@ -58,6 +61,60 @@ public class WorldPhysicsManager { // } } + public static void SteppedPhysicsTick2(float DeltaTime, float TargetFrameTime){ + DeltaTime *= EngineConfig.getInstance().PhysicsSpeed(); + if(EngineConfig.getInstance().IsEngineThrottled()) return; + + Accumulator += DeltaTime; + float maxAccumulated = FixedTimeStep * MaxSubStepsPerFrame; + if (Accumulator > maxAccumulated) Accumulator = maxAccumulated; + + int stepsRun = 0; + while (Accumulator >= FixedTimeStep && stepsRun < MaxSubStepsPerFrame) { + PhysicsTick++; + for (int i = 0; i < ActiveControllers.size(); i++) { + PhysicsObjects.get(ActiveControllers.get(i)).PhysicsTick(FixedTimeStep, TargetFrameTime); + } + ResolveAllCollisions(); + Accumulator -= FixedTimeStep; + stepsRun++; + } + + for (int i = 0; i < ActiveControllers.size(); i++) { + PhysicsObjects.get(ActiveControllers.get(i)).Collisions().clear(); + } + } + private static void ResolveAllCollisions() { + List ids = RigidBody.RigidBodies; + for (int i = 0; i < ids.size(); i++) { + RigidBody a = RigidBody.RigidBodyRegister.get(ids.get(i)); + if (a == null) continue; + for (int j = i + 1; j < ids.size(); j++) { + RigidBody b = RigidBody.RigidBodyRegister.get(ids.get(j)); + if (b == null) continue; + if (a.IsStatic && b.IsStatic) continue; + + SeparatingAxisTheoremTester.CollisionResult result = SeparatingAxisTheoremTester.TestCollision(a.shape, b.shape); + if (result != null) { + RigidCollision.ResolveCollision(a, b, result); + } + } + } + } + + public static void PhysicsTick2(float DeltaTime, float TargetFrameTime){ + DeltaTime *= EngineConfig.getInstance().PhysicsSpeed(); + if(EngineConfig.getInstance().IsEngineThrottled()) return; + PhysicsTick++; + for (int i = 0; i < ActiveControllers.size(); i++) { + PhysicsObjects.get(ActiveControllers.get(i)).PhysicsTick(DeltaTime, TargetFrameTime); + } + ResolveAllCollisions(); + for (int i = 0; i < ActiveControllers.size(); i++) { + PhysicsObjects.get(ActiveControllers.get(i)).Collisions().clear(); + } + } + public static void PhysicsTick(float DeltaTime, float TargetFrameTime){ DeltaTime *= EngineConfig.getInstance().PhysicsSpeed(); if(!EngineConfig.getInstance().IsEngineThrottled()) { 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 0583abd..8b28a97 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Main/GameCore.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Main/GameCore.java @@ -340,7 +340,7 @@ public class GameCore implements GameLogic { if(PrimaryRuntime.GetFastThread().Ticks(20)==0){ //CollisionManager.UpdateCollisionChunks(); } - WorldPhysicsManager.PhysicsTick(DeltaTime, PhysicsFramerate); + WorldPhysicsManager.SteppedPhysicsTick2(DeltaTime, PhysicsFramerate); } @Override 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 76cafe9..12f8971 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 @@ -38,6 +38,10 @@ import static org.lwjgl.vulkan.VK13.*; public class ForwardSceneRender implements SceneRenderer {//dynamic rendering + private static final String SKYBOX_FRAGMENT_SHADER_FILE_GLSL = "resources/EngineResources/shaders/forward_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.glsl"; private static final String FRAGMENT_TRANSLUCENT_SHADER_FILE_GLSL = "resources/EngineResources/shaders/scene_translucent_fragment.glsl"; private static final String FRAGMENT_OPAQUE_SHADER_FILE_GLSL = "resources/EngineResources/shaders/scene_opaque_fragment.glsl"; @@ -50,6 +54,9 @@ public class ForwardSceneRender 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"; + public static String SkyBoxID = "SKYBOX_TEXTURE"; private static final int PUSH_CONSTANTS_SIZE = VulkanUtils.MATRIX4X4_SIZE + VulkanUtils.INT_SIZE; private final VulkanBuffer BufferProjectionMatrix; private final DescriptorSetLayout descriptorLayoutFragStorage; @@ -82,6 +89,10 @@ public class ForwardSceneRender implements SceneRenderer {//dynamic rendering private Pipeline VkPipelineOpaque; private Pipeline VkPipelineTranslucent; private Matrix4f ProjectionMatrix; + private DescriptorSetLayout descriptorLayoutSkyboxTexture; + private VulkanBuffer[] BufferSkyboxViewMatrices; + private Pipeline VkSkyboxPipeline; + private long skyboxMeshBufferId; private boolean Deferred = false; public static long GetGPUTimeNS(){ @@ -125,12 +136,17 @@ public class ForwardSceneRender implements SceneRenderer {//dynamic rendering VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 0, TextureCache.MAX_TEXTURES, VK_SHADER_STAGE_FRAGMENT_BIT )); BufferViewMatrices = VulkanUtils.CreateHostVisibleBuffers(vulkanContext, VulkanUtils.MATRIX4X4_SIZE, VulkanUtils.MAX_IN_FLIGHT, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, DESCRIPTOR_ID_VIEW, descriptorLayoutVertexUniform); + 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("Forward Renderer Pipelines:\nSingle Pass -> [{}]\nOpaque Dual Pass -> [{}]\nTranslucent Dual Pass -> [{}]",VkPipeline.GetVulkanPipeline(),VkPipelineOpaque.GetVulkanPipeline(), VkPipelineTranslucent.GetVulkanPipeline()); } public void CreatePipelines(VulkanContext vulkanContext){ - DescriptorSetLayout[] layouts = new DescriptorSetLayout[]{ descriptorLayoutVertexUniform, descriptorLayoutVertexUniform, @@ -139,11 +155,24 @@ public class ForwardSceneRender implements SceneRenderer {//dynamic rendering }; ShaderModule[] shaderModules = 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 = 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 = 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 = CreateSkyboxShaderModules(vulkanContext); + + VkSkyboxPipeline = CreateSkyboxPipeline(vulkanContext, shaderModules, skyboxLayouts, false, false, false,false); Arrays.asList(shaderModules).forEach(shaderModule -> shaderModule.CleanUp(vulkanContext)); } @@ -192,6 +221,17 @@ public class ForwardSceneRender 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()){ @@ -202,25 +242,70 @@ public class ForwardSceneRender implements SceneRenderer {//dynamic rendering new ShaderModule(VkCtx, VK_SHADER_STAGE_VERTEX_BIT, VERTEX_SHADER_FILE_SPV,null), new ShaderModule(VkCtx, VK_SHADER_STAGE_FRAGMENT_BIT, Translucent == 2 ? FRAGMENT_TRANSLUCENT_SHADER_FILE_SPV : Translucent == 1 ? FRAGMENT_OPAQUE_SHADER_FILE_SPV : FRAGMENT_SHADER_FILE_SPV,null) }; + + } - 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}) - .SetDepthFormat(DEPTH_FORMAT) + .SetDepthFormat(MultiRenderTargetAttachments.DEPTH_FORMAT) .SetDepthWrite(DepthWrite) .SetPushConstantRanges( - new PushConstantsRange[]{ + new PushConstantsRange[]{ new PushConstantsRange(VK_SHADER_STAGE_VERTEX_BIT,0,VulkanUtils.MATRIX4X4_SIZE), new PushConstantsRange(VK_SHADER_STAGE_FRAGMENT_BIT,VulkanUtils.MATRIX4X4_SIZE,VulkanUtils.INT_SIZE) }) .SetDescriptorSetLayouts(DescriptorSetLayouts) - .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; } @@ -270,11 +355,32 @@ public class ForwardSceneRender implements SceneRenderer {//dynamic rendering .put(3,descriptorAllocator.GetDescriptorSet(DESCRIPTOR_ID_TEXT).GetVkDescriptorSet()); vkCmdBindDescriptorSets(CommandHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, DualPassRendering ? VkPipelineOpaque.GetVulkanPipelineLayout() : VkPipeline.GetVulkanPipelineLayout(),0,DescriptorSets,null); RenderActors(engineInstance, CommandHandle, modelsCache, materialsCache, false); + + 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, DeferredSceneRender.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); + } 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); @@ -356,6 +462,17 @@ public class ForwardSceneRender implements SceneRenderer {//dynamic rendering List imageViews = textureCache.GetTextureList().stream().map(ITexture::GetImageView).toList(); descriptorSet = VkCtx.GetDescriptorAllocator().AddDescriptorSet(device,DESCRIPTOR_ID_TEXT,descriptorLayoutTexture); descriptorSet.SetImageArray(device,imageViews,textureSampler,0); + DescriptorSet descSetSkyBox = descriptorAllocator.AddDescriptorSet(device, DESCRIPTOR_ID_SKYBOX_CUBEMAP, descriptorLayoutSkyboxTexture); + ITexture SkyBoxTexture = textureCache.GetTexture(DeferredSceneRender.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 CreateDeferredRenderInfo(VulkanContext VkCtx, VkRenderingAttachmentInfo.Buffer ColourAttachmentInfo, VkRenderingAttachmentInfo DepthAttachmentInfo){