non functional deferred rendering and also camera paths and instanced GUIs

This commit is contained in:
Halbear 2026-06-14 13:39:49 +01:00
parent 4569b471d5
commit 2d37c574d6
25 changed files with 933 additions and 315 deletions

View file

@ -0,0 +1,12 @@
#version 450
layout(location = 0) in vec2 inTextCoord;
layout(location = 0) out vec4 outFragColor;
layout(set = 0, binding = 0) uniform sampler2D albedoSampler;
layout(set = 0, binding = 1) uniform sampler2D depthSampler;
void main() {
outFragColor = vec4(texture(albedoSampler, inTextCoord).rgb, 1.0);
}

View file

@ -0,0 +1,8 @@
#version 450
layout(location = 0) out vec2 outTextCoord;
void main() {
outTextCoord = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2);
gl_Position = vec4(outTextCoord.x * 2.0f - 1.0f, outTextCoord.y * - 2.0f + 1.0f, 0.0f, 1.0f);
}

View file

@ -3,7 +3,7 @@
const int MAX_TEXTURES = 500; const int MAX_TEXTURES = 500;
layout(location = 0) in vec2 inTextCoords; layout(location = 0) in vec2 inTextCoords;
layout(location = 0) out vec4 outFragColor; layout(location = 0) out vec4 outAlbedo;
struct Material{ struct Material{
vec4 diffuseColor; vec4 diffuseColor;
@ -28,8 +28,8 @@ void main()
if(material.hasTexture == 1){ if(material.hasTexture == 1){
vec4 texColor = texture(textSampler[material.textureIdx],inTextCoords); vec4 texColor = texture(textSampler[material.textureIdx],inTextCoords);
if(texColor.a < 0.1){discard;} if(texColor.a < 0.1){discard;}
outFragColor = texColor; outAlbedo = texColor;
} else{ } else{
outFragColor = material.diffuseColor; outAlbedo = material.diffuseColor;
} }
} }

View file

@ -3,7 +3,7 @@
const int MAX_TEXTURES = 500; const int MAX_TEXTURES = 500;
layout(location = 0) in vec2 inTextCoords; layout(location = 0) in vec2 inTextCoords;
layout(location = 0) out vec4 outFragColor; layout(location = 0) out vec4 outAlbedo;
struct Material{ struct Material{
vec4 diffuseColor; vec4 diffuseColor;
@ -28,8 +28,8 @@ void main()
if(material.hasTexture == 1){ if(material.hasTexture == 1){
vec4 texColor = texture(textSampler[material.textureIdx],inTextCoords); vec4 texColor = texture(textSampler[material.textureIdx],inTextCoords);
if(texColor.a < 0.9){discard;} if(texColor.a < 0.9){discard;}
outFragColor = texColor; outAlbedo = texColor;
} else{ } else{
outFragColor = material.diffuseColor; outAlbedo = material.diffuseColor;
} }
} }

View file

@ -3,7 +3,7 @@
const int MAX_TEXTURES = 500; const int MAX_TEXTURES = 500;
layout(location = 0) in vec2 inTextCoords; layout(location = 0) in vec2 inTextCoords;
layout(location = 0) out vec4 outFragColor; layout(location = 0) out vec4 outAlbedo;
struct Material{ struct Material{
vec4 diffuseColor; vec4 diffuseColor;
@ -28,8 +28,8 @@ void main()
if(material.hasTexture == 1){ if(material.hasTexture == 1){
vec4 texColor = texture(textSampler[material.textureIdx],inTextCoords); vec4 texColor = texture(textSampler[material.textureIdx],inTextCoords);
if(texColor.a < 0.05 || texColor.a >= 0.9){discard;} if(texColor.a < 0.05 || texColor.a >= 0.9){discard;}
outFragColor = texColor; outAlbedo = texColor;
} else{ } else{
outFragColor = material.diffuseColor; outAlbedo = material.diffuseColor;
} }
} }

View file

@ -6,6 +6,7 @@ import net.halbear.Terrain4J.EngineCore.Logic.InitData;
import net.halbear.Terrain4J.EngineCore.Logic.Rendering.VulkanContext; import net.halbear.Terrain4J.EngineCore.Logic.Rendering.VulkanContext;
import net.halbear.Terrain4J.EngineCore.Vulkan.GUI.GuiRenderer; import net.halbear.Terrain4J.EngineCore.Vulkan.GUI.GuiRenderer;
import net.halbear.Terrain4J.EngineCore.Vulkan.GUI.GuiTexture; import net.halbear.Terrain4J.EngineCore.Vulkan.GUI.GuiTexture;
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Deferred.LightRenderer;
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Images.TextureCache; import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Images.TextureCache;
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.PostProcessing.PostProcess; import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.PostProcessing.PostProcess;
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel.*; import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel.*;
@ -43,6 +44,7 @@ public class Render {
private final Queue.PresentQueue PresentQueue; private final Queue.PresentQueue PresentQueue;
private final Semaphore[] RenderCompleteSemaphores; private final Semaphore[] RenderCompleteSemaphores;
private final SceneRenderer sceneRender; private final SceneRenderer sceneRender;
private final LightRenderer lightRenderer;
private final PostProcess PostProcessor; private final PostProcess PostProcessor;
private final SwapChainRender swapChainRender; private final SwapChainRender swapChainRender;
private final GuiRenderer GuiRender; private final GuiRenderer GuiRender;
@ -83,7 +85,8 @@ public class Render {
RenderCompleteSemaphores[i] = new Semaphore(RendererContext); RenderCompleteSemaphores[i] = new Semaphore(RendererContext);
} }
sceneRender = new SceneRender(RendererContext); sceneRender = new SceneRender(RendererContext);
PostProcessor = new PostProcess(RendererContext,sceneRender.GetAttachmentColour()); lightRenderer = new LightRenderer(RendererContext, sceneRender.GetMRTAttachments().GetAllAttachments());
PostProcessor = new PostProcess(RendererContext,sceneRender.GetCurrentDeferred() ? lightRenderer.GetColourAttachment() : sceneRender.GetAttachmentColour());
GuiRender = new GuiRenderer(engineInstance, RendererContext, GraphicsQueue, PostProcessor.GetAttachment()); GuiRender = new GuiRenderer(engineInstance, RendererContext, GraphicsQueue, PostProcessor.GetAttachment());
swapChainRender = new SwapChainRender(RendererContext,PostProcessor.GetAttachment()); swapChainRender = new SwapChainRender(RendererContext,PostProcessor.GetAttachment());
textureCache = new TextureCache(); textureCache = new TextureCache();
@ -139,6 +142,7 @@ public class Render {
sceneRender.cleanup(RendererContext); sceneRender.cleanup(RendererContext);
PostProcessor.CleanUp(RendererContext); PostProcessor.CleanUp(RendererContext);
swapChainRender.CleanUp(RendererContext); swapChainRender.CleanUp(RendererContext);
lightRenderer.CleanUp(RendererContext);
GuiRender.CleanUp(RendererContext); GuiRender.CleanUp(RendererContext);
Logger.debug("Dynamic Renderer Cleaned up"); Logger.debug("Dynamic Renderer Cleaned up");
Arrays.asList(RenderCompleteSemaphores).forEach(i->i.cleanup(RendererContext)); Arrays.asList(RenderCompleteSemaphores).forEach(i->i.cleanup(RendererContext));
@ -159,14 +163,7 @@ public class Render {
} }
public void render(EngineInstance engineInstance){ public void render(EngineInstance engineInstance){
SwapChain swapChain = RendererContext.GetSwapChain(); SwapChain swapChain = RendererContext.GetSwapChain();
WaitForFence(CurrentFrame); //problem child found WaitForFence(CurrentFrame);
var CommandPool = CommandPools[CurrentFrame];
var CommandBuffer = CommandBuffers[CurrentFrame];
RecordingStart(CommandPool, CommandBuffer);
sceneRender.Render(engineInstance,RendererContext,CommandBuffer, modelsCache,materialsCache,CurrentFrame);
PostProcessor.Render(RendererContext,CommandBuffer,sceneRender.GetAttachmentColour());
GuiRender.Render(RendererContext,CommandBuffer,CurrentFrame,PostProcessor.GetAttachment());
int ImageIndex; int ImageIndex;
if (Resize || (ImageIndex = swapChain.FetchNextImage(RendererContext.GetDevice(), PresentCompleteSemaphores[CurrentFrame])) < 0){ if (Resize || (ImageIndex = swapChain.FetchNextImage(RendererContext.GetDevice(), PresentCompleteSemaphores[CurrentFrame])) < 0){
@ -174,6 +171,16 @@ public class Render {
return; return;
} }
var CommandPool = CommandPools[CurrentFrame];
var CommandBuffer = CommandBuffers[CurrentFrame];
RecordingStart(CommandPool, CommandBuffer);
sceneRender.Render(engineInstance,RendererContext,CommandBuffer, modelsCache,materialsCache,CurrentFrame);
lightRenderer.Render(RendererContext,CommandBuffer,sceneRender.GetMRTAttachments());
PostProcessor.Render(RendererContext,CommandBuffer,sceneRender.GetCurrentDeferred() ? lightRenderer.GetColourAttachment() : sceneRender.GetAttachmentColour());
GuiRender.Render(RendererContext,CommandBuffer,CurrentFrame,PostProcessor.GetAttachment());
swapChainRender.Render(RendererContext,CommandBuffer,PostProcessor.GetAttachment(),ImageIndex); swapChainRender.Render(RendererContext,CommandBuffer,PostProcessor.GetAttachment(),ImageIndex);
RecordingStop(CommandBuffer); RecordingStop(CommandBuffer);
@ -203,7 +210,8 @@ public class Render {
VkExtent2D extend = RendererContext.GetSwapChain().GetSwapChainExtent(); VkExtent2D extend = RendererContext.GetSwapChain().GetSwapChainExtent();
engineInstance.scene().GetProjection().Resize(extend.width(),extend.height()); engineInstance.scene().GetProjection().Resize(extend.width(),extend.height());
sceneRender.Resize(engineInstance,RendererContext); sceneRender.Resize(engineInstance,RendererContext);
PostProcessor.Resize(RendererContext,sceneRender.GetAttachmentColour()); lightRenderer.Resize(RendererContext,sceneRender.GetMRTAttachments().GetAllAttachments());
PostProcessor.Resize(RendererContext,sceneRender.GetCurrentDeferred() ? lightRenderer.GetColourAttachment() : sceneRender.GetAttachmentColour());
GuiRender.Resize(RendererContext,PostProcessor.GetAttachment()); GuiRender.Resize(RendererContext,PostProcessor.GetAttachment());
swapChainRender.Resize(RendererContext,PostProcessor.GetAttachment()); swapChainRender.Resize(RendererContext,PostProcessor.GetAttachment());
} }

View file

@ -1,6 +1,7 @@
package net.halbear.Terrain4J.EngineCore.Logic; package net.halbear.Terrain4J.EngineCore.Logic;
import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime; import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime;
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DisplayToScreen.SceneRender;
import org.tinylog.Logger; import org.tinylog.Logger;
import java.io.*; import java.io.*;
@ -69,7 +70,11 @@ public class EngineConfig {
public int CPU_CORE_COUNT = 0; public int CPU_CORE_COUNT = 0;
public String CPU_DETAILS = ""; public String CPU_DETAILS = "";
public boolean AlphaToCoverage = false; public boolean AlphaToCoverage = false;
public boolean CompatibilityMode = false;
public Renderer renderer = Renderer.Forward;
public void SetRenderer(Renderer renderer){this.renderer = renderer;}
public boolean DeferredRendering(){return renderer == Renderer.Deferred;}
public boolean AlphaToCoverage(){return AlphaToCoverage;} public boolean AlphaToCoverage(){return AlphaToCoverage;}
public void SetAlphaToCoverage(boolean AlphaToCoverage){this.AlphaToCoverage = AlphaToCoverage;} public void SetAlphaToCoverage(boolean AlphaToCoverage){this.AlphaToCoverage = AlphaToCoverage;}
public String GetGPU(){return GPU_NAME;} public String GetGPU(){return GPU_NAME;}
@ -79,6 +84,8 @@ public class EngineConfig {
CPU_CORE_COUNT = CoreCount; CPU_CORE_COUNT = CoreCount;
CPU_DETAILS = CPU_NAME + " with " + CPU_CORE_COUNT + " Threads"; CPU_DETAILS = CPU_NAME + " with " + CPU_CORE_COUNT + " Threads";
} }
public boolean CompatibilityMode(){return CompatibilityMode;}
public void SetCompatibilitMode(boolean compatibilityMode){this.CompatibilityMode = compatibilityMode;}
public int GetCoreCount(){return CPU_CORE_COUNT;} public int GetCoreCount(){return CPU_CORE_COUNT;}
public String GetCPUName(){return CPU_NAME;} public String GetCPUName(){return CPU_NAME;}
public String GetCPUDetails(){return CPU_DETAILS;} public String GetCPUDetails(){return CPU_DETAILS;}
@ -116,6 +123,11 @@ public class EngineConfig {
} }
} }
public enum Renderer{
Forward,
Deferred
}
public enum AntiAliasType{ public enum AntiAliasType{
NONE, NONE,
FXAA, FXAA,
@ -203,6 +215,10 @@ public class EngineConfig {
zNearPlane = (Float.parseFloat(EngineConfigVar.getOrDefault("z_near_plane", 1.0f).toString())); zNearPlane = (Float.parseFloat(EngineConfigVar.getOrDefault("z_near_plane", 1.0f).toString()));
zFarPlane = (Float.parseFloat(EngineConfigVar.getOrDefault("z_far_plane", 100.0f).toString())); zFarPlane = (Float.parseFloat(EngineConfigVar.getOrDefault("z_far_plane", 100.0f).toString()));
AAValue = (Integer.parseInt(EngineConfigVar.getOrDefault("anti_alias_mode", 1).toString())); AAValue = (Integer.parseInt(EngineConfigVar.getOrDefault("anti_alias_mode", 1).toString()));
renderer = Integer.parseInt(EngineConfigVar.getOrDefault("Renderer", 1).toString()) == 0 ? Renderer.Forward: Renderer.Deferred;
CompatibilityMode = Boolean.parseBoolean(EngineConfigVar.getOrDefault("compatibility_mode", false).toString());
AlphaToCoverage = Boolean.parseBoolean(EngineConfigVar.getOrDefault("AlphaToCoverage", false).toString());
SceneRender.SetDualPassRendering(Boolean.parseBoolean(EngineConfigVar.getOrDefault("DualPassRendering", true).toString()));
switch(AAValue){ switch(AAValue){
case 0: case 0:
AAMode = AntiAliasType.NONE; AAMode = AntiAliasType.NONE;

View file

@ -3,7 +3,6 @@ package net.halbear.Terrain4J.EngineCore.Main;
import imgui.ImGui; import imgui.ImGui;
import imgui.ImGuiIO; import imgui.ImGuiIO;
import imgui.ImGuiViewport; import imgui.ImGuiViewport;
import imgui.ImVec2;
import imgui.flag.ImGuiCond; import imgui.flag.ImGuiCond;
import imgui.flag.ImGuiWindowFlags; import imgui.flag.ImGuiWindowFlags;
import net.halbear.Terrain4J.EngineCore.Audio.AudioManager; import net.halbear.Terrain4J.EngineCore.Audio.AudioManager;
@ -16,6 +15,7 @@ import net.halbear.Terrain4J.EngineCore.Input.MouseListener;
import net.halbear.Terrain4J.EngineCore.Logic.*; import net.halbear.Terrain4J.EngineCore.Logic.*;
import net.halbear.Terrain4J.EngineCore.Logic.Rendering.ModelLoader; import net.halbear.Terrain4J.EngineCore.Logic.Rendering.ModelLoader;
import net.halbear.Terrain4J.EngineCore.Main.Scene.*; import net.halbear.Terrain4J.EngineCore.Main.Scene.*;
import net.halbear.Terrain4J.EngineCore.Main.Scene.GUIs.PerformanceOverlay;
import net.halbear.Terrain4J.EngineCore.Profiling.CPUMonitor; import net.halbear.Terrain4J.EngineCore.Profiling.CPUMonitor;
import net.halbear.Terrain4J.EngineCore.Profiling.GPUProfiler; import net.halbear.Terrain4J.EngineCore.Profiling.GPUProfiler;
import net.halbear.Terrain4J.EngineCore.Vulkan.GUI.GuiTexture; import net.halbear.Terrain4J.EngineCore.Vulkan.GUI.GuiTexture;
@ -25,6 +25,7 @@ import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DisplayToScreen.SceneRe
import org.joml.Vector2f; import org.joml.Vector2f;
import org.joml.Vector3f; import org.joml.Vector3f;
import org.lwjgl.openal.AL11; import org.lwjgl.openal.AL11;
import org.tinylog.Logger;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -48,22 +49,22 @@ public class GameCore implements GameLogic {
private List<Vector3f> rotatingAngles = new ArrayList<>(); private List<Vector3f> rotatingAngles = new ArrayList<>();
private List<Vector3f> Velocities = new ArrayList<>(); private List<Vector3f> Velocities = new ArrayList<>();
private Actor CubeActor; private Actor CubeActor;
private List<Actor> CubeActors = new ArrayList<>(); public List<Actor> CubeActors = new ArrayList<>();
private List<JackOfAllTradesActor> entities = new ArrayList<>(); public List<JackOfAllTradesActor> entities = new ArrayList<>();
private List<ParticleActor> particleActors = new ArrayList<>(); public List<ParticleActor> particleActors = new ArrayList<>();
private Vector2f LastMousePos = new Vector2f(0,0); private Vector2f LastMousePos = new Vector2f(0,0);
private int Ticks = 0; private int Ticks = 0;
private int GUI_MODE = 0; private int GUI_MODE = 0;
private GuiTexture guiTexture; private GuiTexture guiTexture;
private List<String[]> PerformanceMetrics = new ArrayList<>(); public List<String[]> PerformanceMetrics = new ArrayList<>();
private List<String[]> SettingPerformanceMetrics = new ArrayList<>(); public List<String[]> SettingPerformanceMetrics = new ArrayList<>();
private boolean FetchingMetrics = false; public boolean FetchingMetrics = false;
private boolean ChangeGraphicsSettings = false; public boolean ChangeGraphicsSettings = false;
private int NextAAMode = -1; public int NextAAMode = -1;
private long LastFrameTime = 0; public long LastFrameTime = 0;
private long CoolDown = 1000; public long CoolDown = 1000;
private ModelData MusicParticle; public ModelData MusicParticle;
private ModelData radio; public ModelData radio;
@Override @Override
public void cleanup() { public void cleanup() {
@ -115,12 +116,19 @@ public class GameCore implements GameLogic {
models.add(MusicParticle); models.add(MusicParticle);
models.add(radio); models.add(radio);
Camera camera = scene.GetCamera(); Camera camera = scene.GetCamera();
scene.AddCameraFrame("Default", new CameraFrame(new Vector3f(-120.10f,136.83f,-62.63f),new Vector3f(-1.90f,78.09f,0),scene.GetCamera().GetFOV(),"Second"));
scene.AddCameraFrame("Second", new CameraFrame(new Vector3f(-40.26f,141.08f,-72.12f),new Vector3f(-2.40f,143,0.0f),scene.GetCamera().GetFOV(),"Third"));
scene.AddCameraFrame("Third", new CameraFrame(new Vector3f(10.85f,149.56f,-14.10f),new Vector3f(2.5f,36.37f,0.00f),scene.GetCamera().GetFOV(),"Fourth"));
scene.AddCameraFrame("Fourth", new CameraFrame(new Vector3f(40.0f, 155.0f, -42.0f),new Vector3f(10,90,0),scene.GetCamera().GetFOV(),"Fifth"));
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(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((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/DefaultTexture.png");
Logger.debug("GUI TEXTURE CREATED, ID->[{}], PATH->[{}]",guiTexture.ID(),guiTexture.TexturePath());
List<GuiTexture> guiTextures = new ArrayList<>(); List<GuiTexture> guiTextures = new ArrayList<>();
guiTextures.add(guiTexture); guiTextures.add(guiTexture);
@ -154,8 +162,8 @@ public class GameCore implements GameLogic {
public void CameraInput(EngineInstance engineInstance, long FrameDiffNanoSeconds) { public void CameraInput(EngineInstance engineInstance, long FrameDiffNanoSeconds) {
float Multiplier = MOUSE_SENSITIVITY; float Multiplier = MOUSE_SENSITIVITY;
Scene scene = engineInstance.scene(); Scene scene = engineInstance.scene();
Window window = engineInstance.window();
Camera camera = scene.GetCamera(); Camera camera = scene.GetCamera();
Window window = engineInstance.window();
MouseListener MouseInput = window.getMouseInput(); MouseListener MouseInput = window.getMouseInput();
Vector2f CurrentMousePos = window.getMouseInput().getCurrentPos(); Vector2f CurrentMousePos = window.getMouseInput().getCurrentPos();
@ -177,6 +185,7 @@ public class GameCore implements GameLogic {
@Override @Override
public void RenderThreadInput(EngineInstance engineInstance, long FrameDiffNanoSeconds) { public void RenderThreadInput(EngineInstance engineInstance, long FrameDiffNanoSeconds) {
engineInstance.scene().CameraTick(FrameDiffNanoSeconds);
if(ChangeGraphicsSettings){ if(ChangeGraphicsSettings){
if(NextAAMode != -1){ if(NextAAMode != -1){
EngineConfig.getInstance().SetRenderAAType(NextAAMode); EngineConfig.getInstance().SetRenderAAType(NextAAMode);
@ -248,129 +257,15 @@ public class GameCore implements GameLogic {
| ImGuiWindowFlags.NoMove; | ImGuiWindowFlags.NoMove;
ImGui.newFrame(); ImGui.newFrame();
if(GUI_MODE == 0){ if(GUI_MODE == 0){
double FrameTimeMS = (frameTimeNS/1000000.0); PerformanceOverlay overlay = new PerformanceOverlay();
double AverageGPUTimeMS = EngineConfig.LAST_AVERAGE_GPU_TIME/1000000.0; overlay.RenderGUI(engineInstance,frameTimeNS,this);
ImGui.setNextWindowPos(0,0, ImGuiCond.Always);
//ImGui.setNextWindowSize(300,100);
ImGui.begin("FPS overlay",windowFlags);
ImGui.text("PERFORMANCE METRICS:");
ImGui.separator();
ImGui.text(String.format("Vulkan FPS: " + EngineConfig.FrameRate_RENDERTHREAD + "fps | FrameTime: %.2f" + "ms | Avg. GPU Time: %.3f" + "ms | TPS: " + EngineConfig.TPS_RENDERTHREAD,FrameTimeMS,AverageGPUTimeMS));
ImGui.text(String.format("Primary Thread FPS: " + EngineConfig.FrameRate_PRIMARYTHREAD + "fps | GLFW Window FrameRate:" + EngineConfig.FrameRate_WINDOW + "fps | TPS: " + EngineConfig.TPS_PRIMARYTHREAD));
ImGui.text(String.format("Main Thread FPS: " + EngineConfig.FrameRate_MAINENGINETHREAD + "fps | TPS: " + EngineConfig.TPS_MAINENGINETHREAD));
ImGui.text(String.format("Fast Thread FPS: " + EngineConfig.FrameRate_FASTENGINETHREAD + "fps | TPS: " + EngineConfig.TPS_FASTENGINETHREAD));
ImGui.separator();
ImGui.text("GRAPHICS SETTINGS:");
ImGui.text(" ");
ImGui.text("Presets:");
if(ImGui.button("Lowest")){
ChangeGraphicsSettings = true;
CoolDown = 2000;
NextAAMode = (0);
SceneRender.SetDualPassRendering(false);
EngineConfig.getInstance().SetAlphaToCoverage(false);
PrimaryRuntime.GetRenderThread().GetRenderer().GetSceneRender().RebuildPipelines(PrimaryRuntime.GetRenderThread().GetRenderer().GetVulkanContext());
}
ImGui.sameLine();
if(ImGui.button("Medium")){
ChangeGraphicsSettings = true;
CoolDown = 2000;
NextAAMode = (1);
SceneRender.SetDualPassRendering(true);
EngineConfig.getInstance().SetAlphaToCoverage(true);
PrimaryRuntime.GetRenderThread().GetRenderer().GetSceneRender().RebuildPipelines(PrimaryRuntime.GetRenderThread().GetRenderer().GetVulkanContext());
}
ImGui.sameLine();
if(ImGui.button("Highest")){
ChangeGraphicsSettings = true;
CoolDown = 2000;
NextAAMode = (4);
SceneRender.SetDualPassRendering(true);
EngineConfig.getInstance().SetAlphaToCoverage(false);
PrimaryRuntime.GetRenderThread().GetRenderer().GetSceneRender().RebuildPipelines(PrimaryRuntime.GetRenderThread().GetRenderer().GetVulkanContext());
}
ImGui.text(" ");
ImGui.text("anti aliasing:");
if(ImGui.button("No AA")){
ChangeGraphicsSettings = true;
CoolDown = 2000;
NextAAMode = (0);
}
ImGui.sameLine();
if(ImGui.button("FXAA")){
ChangeGraphicsSettings = true;
CoolDown = 2000;
NextAAMode = (1);
}
ImGui.sameLine();
if(ImGui.button("MSAAx2")){
ChangeGraphicsSettings = true;
CoolDown = 2000;
NextAAMode = (2);
}
ImGui.sameLine();
if(ImGui.button("MSAAx4")){
ChangeGraphicsSettings = true;
CoolDown = 2000;
NextAAMode = (3);
}
ImGui.sameLine();
if(ImGui.button("MSAAx8")){
ChangeGraphicsSettings = true;
CoolDown = 2000;
NextAAMode = 4;
}
ImGui.text("pipeline:");
if(ImGui.button("Single Pass")){
ChangeGraphicsSettings = true;
CoolDown = 500;
SceneRender.SetDualPassRendering(false);
}
ImGui.sameLine();
if(ImGui.button("dual Pass")){
ChangeGraphicsSettings = true;
CoolDown = 500;
SceneRender.SetDualPassRendering(true);
}
if(ImGui.button("AlphaToCoverage False")){
ChangeGraphicsSettings = true;
CoolDown = 500;
EngineConfig.getInstance().SetAlphaToCoverage(false);
PrimaryRuntime.GetRenderThread().GetRenderer().GetSceneRender().RebuildPipelines(PrimaryRuntime.GetRenderThread().GetRenderer().GetVulkanContext());
}
ImGui.sameLine();
if(ImGui.button("AlphaToCoverage True")){
ChangeGraphicsSettings = true;
CoolDown = 500;
EngineConfig.getInstance().SetAlphaToCoverage(true);
PrimaryRuntime.GetRenderThread().GetRenderer().GetSceneRender().RebuildPipelines(PrimaryRuntime.GetRenderThread().GetRenderer().GetVulkanContext());
}
ImGui.separator();
ImGui.text("Level Tools:");
if(ImGui.button("Spawn Radio")){
JackOfAllTradesActor newJackentity = new JackOfAllTradesActor("Radio" + entities.size(), radio.ID(), new Vector3f(engineInstance.scene().GetCamera().GetPosition()),MusicParticle).SetAudio(engineInstance, "resources/EngineResources/audio/sounds/youusedtocallmeonyourcellphone.ogg").SetScale(0.01f);
entities.add(newJackentity);
engineInstance.scene().AddActor(newJackentity);
}
if(PerformanceMetrics.size() > 0) {
ImGui.text(" ");
ImGui.separator();
for (int i = 0; i < PerformanceMetrics.size(); i++) {
String[] memoryUsageMetrics = PerformanceMetrics.get(i);
for(int j = 0; j < memoryUsageMetrics.length; j++){
ImGui.text(memoryUsageMetrics[j]);
}
ImGui.separator();
ImGui.text(" ");
}
}
ImGui.end();
} else if (GUI_MODE == 1){ } else if (GUI_MODE == 1){
ImGui.setNextWindowPos(0,0, ImGuiCond.Always); ImGui.setNextWindowPos(0,0, ImGuiCond.Always);
ImGui.setNextWindowSize(500,500); ImGui.setNextWindowSize(500,500);
ImGui.begin("Test Window"); ImGui.begin("Test Window");
ImGui.image(guiTexture.ID(),new ImVec2(300,300)); ImGui.image(PrimaryRuntime.GetRenderThread().GetRenderer().GetGuiTexture(guiTexture.ID()),300,300);
Logger.debug(PrimaryRuntime.GetRenderThread().GetRenderer().GetGuiTexture(guiTexture.ID()));
ImGui.end(); ImGui.end();
} else if (GUI_MODE == 2){ } else if (GUI_MODE == 2){
} }
@ -393,13 +288,6 @@ public class GameCore implements GameLogic {
@Override @Override
public void Update(EngineInstance engineInstance, long FrameDiffNanoSeconds) { public void Update(EngineInstance engineInstance, long FrameDiffNanoSeconds) {
float DeltaTime = (float)(FrameDiffNanoSeconds/16000000.0); float DeltaTime = (float)(FrameDiffNanoSeconds/16000000.0);
for(int i = 0; i < angles.size()/2; i++) {
}
Ticks++;
if(Ticks == 1000){
}
} }
@Override @Override
@ -411,6 +299,10 @@ public class GameCore implements GameLogic {
CubeActors.get(i).GetPosition().add((Velocities.get(i).x/100.0f) * DeltaTime,(Velocities.get(i).y/100.0f) * DeltaTime,(Velocities.get(i).z/100.0f) * DeltaTime); CubeActors.get(i).GetPosition().add((Velocities.get(i).x/100.0f) * DeltaTime,(Velocities.get(i).y/100.0f) * DeltaTime,(Velocities.get(i).z/100.0f) * DeltaTime);
CubeActors.get(i).UpdateModelMatrix(); CubeActors.get(i).UpdateModelMatrix();
} }
Ticks++;
if(Ticks == 1000){
engineInstance.scene().StartCameraTrack("Default","Second",24000);
}
for(int i = 0; i < entities.size(); i++){ for(int i = 0; i < entities.size(); i++){
JackOfAllTradesActor entity = entities.get(i); JackOfAllTradesActor entity = entities.get(i);
entity.tick(engineInstance.scene()); entity.tick(engineInstance.scene());

View file

@ -1,7 +1,9 @@
package net.halbear.Terrain4J.EngineCore.Main.Scene; package net.halbear.Terrain4J.EngineCore.Main.Scene;
import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig;
import org.joml.Matrix4f; import org.joml.Matrix4f;
import org.joml.Vector3f; import org.joml.Vector3f;
import org.tinylog.Logger;
public class Camera { public class Camera {
private final Vector3f Direction; private final Vector3f Direction;
@ -10,7 +12,9 @@ public class Camera {
private final Vector3f Rotation; private final Vector3f Rotation;
private final Vector3f Up; private final Vector3f Up;
private final Matrix4f ViewMatrix; private final Matrix4f ViewMatrix;
private float FOV = (float) (60 * EngineConfig.DegToRad);
private boolean Sprint; private boolean Sprint;
int i = 0;
public Camera(){ public Camera(){
Direction = new Vector3f(); Direction = new Vector3f();
@ -21,72 +25,97 @@ public class Camera {
ViewMatrix = new Matrix4f(); ViewMatrix = new Matrix4f();
} }
public Camera SetFOV(float FOVdegrees){
FOV = (float) (FOVdegrees * EngineConfig.DegToRad);
return this;
}
public void SetCameraFrame(CameraFrame frameIn){
FOV = frameIn.FOV();
SetPosition(frameIn.Position().x,frameIn.Position().y,frameIn.Position().z);
SetRotation((float) (frameIn.Rotation().x * EngineConfig.DegToRad), (float) (frameIn.Rotation().y * EngineConfig.DegToRad), (float) (frameIn.Rotation().z * EngineConfig.DegToRad));
}
public float GetFOV(){return FOV;}
public void Sprint(boolean sprint){ public void Sprint(boolean sprint){
this.Sprint = sprint; this.Sprint = sprint;
} }
public void SetRotation(float x, float y, float z){Rotation.set(x,y,z); Recalculate();} public void SetRotation(float x, float y, float z){Rotation.set(x,y,z);Recalculate();}
public void AddRotation(float x, float y, float z){Rotation.add(x,y,z); Recalculate();} public void AddRotation(float x, float y, float z){Rotation.add(x,y,z);Recalculate(); }
public void AddRotX(float x){Rotation.x += x; Recalculate();} public void AddRotX(float x){Rotation.x += x; Recalculate();}
public void AddRotY(float y){Rotation.y += y; Recalculate();} public void AddRotY(float y){Rotation.y += y; Recalculate();}
public void AddRotZ(float z){Rotation.z += z; Recalculate();} public void AddRotZ(float z){Rotation.z += z; Recalculate();}
public Vector3f GetRotation(){return Rotation;} public Vector3f GetRotation(){return Rotation;}
public void SetPosition(float x, float y, float z){Position.set(x,y,z); Recalculate();} public void SetPosition(float x, float y, float z){Position.set(x,y,z);Recalculate();}
public void AddPosition(float x, float y, float z){Position.add(x,y,z);Recalculate(); } public void AddPosition(float x, float y, float z){Position.add(x,y,z);Recalculate();}
public void AddPosX(float x){Position.x += x;Recalculate();} public void AddPosX(float x){Position.x += x;Recalculate();}
public void AddPosY(float y){Position.y += y;Recalculate();} public void AddPosY(float y){Position.y += y;Recalculate();}
public void AddPosZ(float z){Position.z += z;Recalculate();} public void AddPosZ(float z){Position.z += z;Recalculate();}
public Vector3f GetPosition(){return Position;} public Vector3f GetPosition(){
return Position;}
public Matrix4f GetViewMatrix(){ public Matrix4f GetViewMatrix(){
return ViewMatrix; return ViewMatrix;
} }
public void MoveForward(float Distance){ public void MoveForward(float Distance){
if(Sprint) Distance *=2; if(Sprint) Distance *= 2;
ViewMatrix.positiveZ(Direction).negate().mul(Distance); Matrix4f rotationMatrix = new Matrix4f().rotateX(Rotation.x).rotateY(Rotation.y).rotateZ(Rotation.z);
rotationMatrix.positiveZ(Direction).negate().mul(Distance);
Position.add(Direction); Position.add(Direction);
Recalculate(); Recalculate();
} }
public void MoveBackward(float Distance){ public void MoveBackward(float Distance){
if(Sprint) Distance *=2; if(Sprint) Distance *= 2;
ViewMatrix.positiveZ(Direction).negate().mul(Distance); Matrix4f rotationMatrix = new Matrix4f().rotateX(Rotation.x).rotateY(Rotation.y).rotateZ(Rotation.z);
rotationMatrix.positiveZ(Direction).negate().mul(Distance);
Position.sub(Direction); Position.sub(Direction);
Recalculate(); Recalculate();
} }
public void MoveUp(float Distance){
if(Sprint) Distance *=2;
ViewMatrix.positiveY(Up).negate().mul(Distance);
Position.sub(Up);
Recalculate();
}
public void MoveDown(float Distance){
if(Sprint) Distance *=2;
ViewMatrix.positiveY(Up).negate().mul(Distance);
Position.add(Up);
Recalculate();
}
public void MoveLeft(float Distance){ public void MoveLeft(float Distance){
if(Sprint) Distance *=2; if(Sprint) Distance *= 2;
ViewMatrix.positiveX(Right).negate().mul(Distance); Matrix4f rotationMatrix = new Matrix4f().rotateX(Rotation.x).rotateY(Rotation.y).rotateZ(Rotation.z);
rotationMatrix.positiveX(Right).negate().mul(Distance);
Position.add(Right); Position.add(Right);
Recalculate(); Recalculate();
} }
public void MoveRight(float Distance){ public void MoveRight(float Distance){
if(Sprint) Distance *=2; if(Sprint) Distance *= 2;
ViewMatrix.positiveX(Right).negate().mul(Distance); Matrix4f rotationMatrix = new Matrix4f().rotateX(Rotation.x).rotateY(Rotation.y).rotateZ(Rotation.z);
rotationMatrix.positiveX(Right).negate().mul(Distance);
Position.sub(Right); Position.sub(Right);
Recalculate(); Recalculate();
} }
public void MoveUp(float Distance){
if(Sprint) Distance *= 2;
Matrix4f rotationMatrix = new Matrix4f().rotateX(Rotation.x).rotateY(Rotation.y).rotateZ(Rotation.z);
rotationMatrix.positiveY(Up).negate().mul(Distance);
Position.sub(Up);
Recalculate();
}
public void MoveDown(float Distance){
if(Sprint) Distance *= 2;
Matrix4f rotationMatrix = new Matrix4f().rotateX(Rotation.x).rotateY(Rotation.y).rotateZ(Rotation.z);
rotationMatrix.positiveY(Up).negate().mul(Distance);
Position.add(Up);
Recalculate();
}
public void Recalculate(){ public void Recalculate(){
ViewMatrix.identity() ViewMatrix.identity()
.rotateX(Rotation.x) .rotateX(Rotation.x)
.rotateY(Rotation.y) .rotateY(Rotation.y)
//.rotateZ(Rotation.z) .rotateZ(Rotation.z)
.translate(-Position.x, -Position.y, -Position.z); .translate(-Position.x, -Position.y, -Position.z);
} }
} }

View file

@ -0,0 +1,20 @@
package net.halbear.Terrain4J.EngineCore.Main.Scene;
import org.joml.Math;
import org.joml.Vector3f;
public record CameraFrame(Vector3f Position, Vector3f Rotation, float FOV, String NextFrame) {
public CameraFrame Lerp(CameraFrame EndFrame, int CurrentTick, int TotalTickTime){
double t = (double)CurrentTick/(double)TotalTickTime;
Vector3f newPosition = new Vector3f(0,0,0);
Vector3f newRotation = new Vector3f(0,0,0);
float newFOV = (float)Math.lerp(FOV, EndFrame.FOV(), t);
newPosition.x = (float)Math.lerp(Position.x, EndFrame.Position().x, t);
newPosition.y = (float)Math.lerp(Position.y, EndFrame.Position().y, t);
newPosition.z = (float)Math.lerp(Position.z, EndFrame.Position().z, t);
newRotation.x = (float)Math.lerp(Rotation.x, EndFrame.Rotation().x, t);
newRotation.y = (float)Math.lerp(Rotation.y, EndFrame.Rotation().y, t);
newRotation.z = (float)Math.lerp(Rotation.z, EndFrame.Rotation().z, t);
return new CameraFrame(newPosition, newRotation, newFOV, "NO_FRAME");
}
}

View file

@ -0,0 +1,8 @@
package net.halbear.Terrain4J.EngineCore.Main.Scene;
import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance;
import net.halbear.Terrain4J.EngineCore.Main.GameCore;
public interface GUIOverlay {
void RenderGUI(EngineInstance engineInstance, long FrameTimeNS, GameCore parent);
}

View file

@ -0,0 +1,154 @@
package net.halbear.Terrain4J.EngineCore.Main.Scene.GUIs;
import imgui.ImGui;
import imgui.flag.ImGuiCond;
import imgui.flag.ImGuiWindowFlags;
import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig;
import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance;
import net.halbear.Terrain4J.EngineCore.Main.GameCore;
import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime;
import net.halbear.Terrain4J.EngineCore.Main.Scene.GUIOverlay;
import net.halbear.Terrain4J.EngineCore.Main.Scene.JackOfAllTradesActor;
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DisplayToScreen.SceneRender;
import org.joml.Vector3f;
public class PerformanceOverlay implements GUIOverlay {
@Override
public void RenderGUI(EngineInstance engineInstance, long frameTimeNS, GameCore parent) {
int windowFlags = ImGuiWindowFlags.NoDecoration
| ImGuiWindowFlags.AlwaysAutoResize
| ImGuiWindowFlags.NoSavedSettings
| ImGuiWindowFlags.NoFocusOnAppearing
| ImGuiWindowFlags.NoNav
| ImGuiWindowFlags.NoMove;
double FrameTimeMS = (frameTimeNS/1000000.0);
double AverageGPUTimeMS = EngineConfig.LAST_AVERAGE_GPU_TIME/1000000.0;
ImGui.setNextWindowPos(0,0, ImGuiCond.Always);
//ImGui.setNextWindowSize(300,100);
ImGui.begin("FPS overlay",windowFlags);
ImGui.text("PERFORMANCE METRICS:");
ImGui.separator();
ImGui.text(String.format("Vulkan FPS: " + EngineConfig.FrameRate_RENDERTHREAD + "fps | FrameTime: %.2f" + "ms | Avg. GPU Time: %.3f" + "ms | TPS: " + EngineConfig.TPS_RENDERTHREAD,FrameTimeMS,AverageGPUTimeMS));
ImGui.text(String.format("Primary Thread FPS: " + EngineConfig.FrameRate_PRIMARYTHREAD + "fps | GLFW Window FrameRate:" + EngineConfig.FrameRate_WINDOW + "fps | TPS: " + EngineConfig.TPS_PRIMARYTHREAD));
ImGui.text(String.format("Main Thread FPS: " + EngineConfig.FrameRate_MAINENGINETHREAD + "fps | TPS: " + EngineConfig.TPS_MAINENGINETHREAD));
ImGui.text(String.format("Fast Thread FPS: " + EngineConfig.FrameRate_FASTENGINETHREAD + "fps | TPS: " + EngineConfig.TPS_FASTENGINETHREAD));
ImGui.separator();
ImGui.text("GRAPHICS SETTINGS:");
ImGui.text(" ");
ImGui.text("Presets:");
if(ImGui.button("Lowest")){
parent.ChangeGraphicsSettings = true;
parent.CoolDown = 2000;
parent.NextAAMode = (0);
SceneRender.SetDualPassRendering(false);
EngineConfig.getInstance().SetAlphaToCoverage(false);
PrimaryRuntime.GetRenderThread().GetRenderer().GetSceneRender().RebuildPipelines(PrimaryRuntime.GetRenderThread().GetRenderer().GetVulkanContext());
}
ImGui.sameLine();
if(ImGui.button("Medium")){
parent.ChangeGraphicsSettings = true;
parent.CoolDown = 2000;
parent.NextAAMode = (1);
SceneRender.SetDualPassRendering(true);
EngineConfig.getInstance().SetAlphaToCoverage(true);
PrimaryRuntime.GetRenderThread().GetRenderer().GetSceneRender().RebuildPipelines(PrimaryRuntime.GetRenderThread().GetRenderer().GetVulkanContext());
}
ImGui.sameLine();
if(ImGui.button("Highest")){
parent.ChangeGraphicsSettings = true;
parent.CoolDown = 2000;
parent.NextAAMode = (4);
SceneRender.SetDualPassRendering(true);
EngineConfig.getInstance().SetAlphaToCoverage(false);
PrimaryRuntime.GetRenderThread().GetRenderer().GetSceneRender().RebuildPipelines(PrimaryRuntime.GetRenderThread().GetRenderer().GetVulkanContext());
}
ImGui.text(" ");
ImGui.text("anti aliasing:");
if(ImGui.button("No AA")){
parent.ChangeGraphicsSettings = true;
parent.CoolDown = 2000;
parent.NextAAMode = (0);
}
ImGui.sameLine();
if(ImGui.button("FXAA")){
parent.ChangeGraphicsSettings = true;
parent.CoolDown = 2000;
parent.NextAAMode = (1);
}
ImGui.sameLine();
if(ImGui.button("MSAAx2")){
parent.ChangeGraphicsSettings = true;
parent.CoolDown = 2000;
parent.NextAAMode = (2);
}
ImGui.sameLine();
if(ImGui.button("MSAAx4")){
parent.ChangeGraphicsSettings = true;
parent.CoolDown = 2000;
parent.NextAAMode = (3);
}
ImGui.sameLine();
if(ImGui.button("MSAAx8")){
parent.ChangeGraphicsSettings = true;
parent.CoolDown = 2000;
parent.NextAAMode = 4;
}
ImGui.text("pipeline:");
if(ImGui.button("Single Pass")){
parent.ChangeGraphicsSettings = true;
parent.CoolDown = 500;
SceneRender.SetDualPassRendering(false);
}
ImGui.sameLine();
if(ImGui.button("dual Pass")){
parent.ChangeGraphicsSettings = true;
parent.CoolDown = 500;
SceneRender.SetDualPassRendering(true);
}
if(ImGui.button("Forward Rendering")){
parent.ChangeGraphicsSettings = true;
parent.CoolDown = 500;
EngineConfig.getInstance().SetRenderer(EngineConfig.Renderer.Forward);
}
ImGui.sameLine();
if(ImGui.button("Deferred Rendering")){
parent.ChangeGraphicsSettings = true;
parent.CoolDown = 500;
EngineConfig.getInstance().SetRenderer(EngineConfig.Renderer.Deferred);
}
if(ImGui.button("AlphaToCoverage False")){
parent.ChangeGraphicsSettings = true;
parent.CoolDown = 500;
EngineConfig.getInstance().SetAlphaToCoverage(false);
PrimaryRuntime.GetRenderThread().GetRenderer().GetSceneRender().RebuildPipelines(PrimaryRuntime.GetRenderThread().GetRenderer().GetVulkanContext());
}
ImGui.sameLine();
if(ImGui.button("AlphaToCoverage True")){
parent.ChangeGraphicsSettings = true;
parent.CoolDown = 500;
EngineConfig.getInstance().SetAlphaToCoverage(true);
PrimaryRuntime.GetRenderThread().GetRenderer().GetSceneRender().RebuildPipelines(PrimaryRuntime.GetRenderThread().GetRenderer().GetVulkanContext());
}
ImGui.separator();
ImGui.text("Level Tools:");
if(ImGui.button("Spawn Radio")){
JackOfAllTradesActor newJackentity = new JackOfAllTradesActor("Radio" + parent.entities.size(), parent.radio.ID(), new Vector3f(engineInstance.scene().GetCamera().GetPosition()),parent.MusicParticle).SetAudio(engineInstance, "resources/EngineResources/audio/sounds/youusedtocallmeonyourcellphone.ogg").SetScale(0.01f);
parent.entities.add(newJackentity);
engineInstance.scene().AddActor(newJackentity);
}
if(parent.PerformanceMetrics.size() > 0) {
ImGui.text(" ");
ImGui.separator();
for (int i = 0; i < parent.PerformanceMetrics.size(); i++) {
String[] memoryUsageMetrics = parent.PerformanceMetrics.get(i);
for(int j = 0; j < memoryUsageMetrics.length; j++){
ImGui.text(memoryUsageMetrics[j]);
}
ImGui.separator();
ImGui.text(" ");
}
}
ImGui.end();
}
}

View file

@ -3,23 +3,88 @@ package net.halbear.Terrain4J.EngineCore.Main.Scene;
import net.halbear.Terrain4J.EngineCore.Display.Window; import net.halbear.Terrain4J.EngineCore.Display.Window;
import net.halbear.Terrain4J.EngineCore.Logic.*; import net.halbear.Terrain4J.EngineCore.Logic.*;
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Projection.Project3D; import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Projection.Project3D;
import org.joml.Vector3f;
import java.util.ArrayList; import java.util.*;
import java.util.List;
public class Scene { public class Scene {
private final List<Actor> Actors; private final List<Actor> Actors;
private final Map<String, CameraFrame> CameraFrames;
private final Project3D Projection; private final Project3D Projection;
private final Camera camera; private final Camera camera;
private String ActiveCameraFrame = "NO_FRAME";
private String SetCameraFrame = "NO_FRAME";
private boolean TransitionCameraFrame = false;
private CameraFrame LastCameraFrame;
private int TotalTransitionTicks = 1000;
private float CurrentTransitionTick = 0;
public Scene(Window window) { public Scene(Window window) {
Actors = new ArrayList<>(); Actors = new ArrayList<>();
CameraFrames = new HashMap<>();
var EngConfig = EngineConfig.getInstance(); var EngConfig = EngineConfig.getInstance();
Projection = new Project3D(EngConfig.GetFOV(),EngConfig.GetZNearPlane(), EngConfig.GetZFarPlane(),
window.getWidth(), window.getHeight());
camera = new Camera(); camera = new Camera();
LastCameraFrame = new CameraFrame(camera.GetPosition(),camera.GetRotation(),camera.GetFOV(), "NO_FRAME");
Projection = new Project3D(camera.GetFOV(),EngConfig.GetZNearPlane(), EngConfig.GetZFarPlane(),
window.getWidth(), window.getHeight());
} }
public void CameraTick(long FrameDiffNanoSeconds){
float FrameTimeMS = FrameDiffNanoSeconds/1000000.0f;
float DeltaTime = FrameTimeMS/(60.0f/240.0f);
if(TransitionCameraFrame && TotalTransitionTicks > CurrentTransitionTick && !Objects.equals(SetCameraFrame, "NO_FRAME")){
float StartFOV = LastCameraFrame.FOV();
Vector3f StartPos = LastCameraFrame.Position();
Vector3f StartRot = LastCameraFrame.Rotation();
CameraFrame StartFrame;
if(CameraFrames.containsKey(ActiveCameraFrame)){
StartFrame = CameraFrames.get(ActiveCameraFrame);
} else StartFrame = new CameraFrame(StartPos,StartRot,StartFOV, "NO_FRAME");
float EndFOV = camera.GetFOV();
Vector3f EndPos = camera.GetPosition();
Vector3f EndRot = camera.GetRotation();
CameraFrame EndFrame;
if(CameraFrames.containsKey(SetCameraFrame)){
EndFrame = CameraFrames.get(SetCameraFrame);
} else EndFrame = new CameraFrame(EndPos,EndRot,EndFOV, "NO_FRAME");
CameraFrame LerpedFrame = StartFrame.Lerp(EndFrame, (int)CurrentTransitionTick, TotalTransitionTicks);
camera.SetCameraFrame(LerpedFrame);
if(LastCameraFrame.FOV() != LerpedFrame.FOV()){
Projection.ChangeFOV(LerpedFrame.FOV());
}
CurrentTransitionTick+= DeltaTime;
} else if (TransitionCameraFrame){
CurrentTransitionTick = 0;
ActiveCameraFrame = SetCameraFrame;
if(!Objects.equals(CameraFrames.get(ActiveCameraFrame).NextFrame(), "NO_FRAME") && CameraFrames.containsKey(CameraFrames.get(ActiveCameraFrame).NextFrame())){
SetCameraFrame = CameraFrames.get(ActiveCameraFrame).NextFrame();
} else{
TotalTransitionTicks = 1000;
TransitionCameraFrame = false;
}
} else{
if(!Objects.equals(ActiveCameraFrame, SetCameraFrame) && !Objects.equals(SetCameraFrame, "NO_FRAME")){
LastCameraFrame = new CameraFrame(camera.GetPosition(),camera.GetRotation(),camera.GetFOV(), "NO_FRAME");
CurrentTransitionTick = 0;
TransitionCameraFrame = true;
}
}
}
public Map<String, CameraFrame> GetCameraFrameReg(){return CameraFrames;}
public CameraFrame GetCameraFrame(String Name){return CameraFrames.get(Name);}
public Scene AddCameraFrame(String Name, CameraFrame frame){
CameraFrames.put(Name,frame);
return this;
}
public void StartCameraTrack(String StartFrame, String EndFrame, int TickAmount){
ActiveCameraFrame = StartFrame;
CurrentTransitionTick = 0;
TotalTransitionTicks = TickAmount;
SetCameraFrame = EndFrame;
}
public void SetActiveCameraFrame(String frameName){SetCameraFrame = frameName;}
public Camera GetCamera(){return camera;} public Camera GetCamera(){return camera;}
public void AddActor(Actor NewActor){Actors.add(NewActor);} public void AddActor(Actor NewActor){Actors.add(NewActor);}
public List<Actor> GetActors(){return Actors;} public List<Actor> GetActors(){return Actors;}

View file

@ -50,7 +50,7 @@ public class RenderThread extends EngineThread {
EngineConfig.getInstance().SetMemoryProfiling(Profiling); EngineConfig.getInstance().SetMemoryProfiling(Profiling);
EngineConfig.FrameRate_RENDERTHREAD = Frames; EngineConfig.FrameRate_RENDERTHREAD = Frames;
EngineConfig.TPS_RENDERTHREAD = TickFrames; EngineConfig.TPS_RENDERTHREAD = TickFrames;
if(render.GetCurrentAAMode() != EngineConfig.getInstance().RenderAAType()){ if(render.GetCurrentAAMode() != EngineConfig.getInstance().RenderAAType() || render.GetSceneRender().GetCurrentDeferred() != EngineConfig.getInstance().DeferredRendering()){
render.cleanup(); render.cleanup();
render = new Render(PrimaryRuntime.GetEngineInstance()); render = new Render(PrimaryRuntime.GetEngineInstance());
render.Initialise(initData); render.Initialise(initData);

View file

@ -149,7 +149,6 @@ public class GuiRenderer {
DescriptorSet descriptorSet = descriptorAllocator.AddDescriptorSets(device, descriptorID, 1, TextDescriptorSetLayout)[0]; DescriptorSet descriptorSet = descriptorAllocator.AddDescriptorSets(device, descriptorID, 1, TextDescriptorSetLayout)[0];
Texture texture = textureCache.GetTexture(guiTexture.TexturePath()); Texture texture = textureCache.GetTexture(guiTexture.TexturePath());
descriptorSet.SetImage(device,texture.GetImageView(),FontsTextureSampler,TextDescriptorSetLayout.GetLayoutInfo().Binding()); 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()); GuiTexturesMap.put(guiTexture.ID(),descriptorSet.GetVkDescriptorSet());
} }
} }
@ -167,7 +166,6 @@ public class GuiRenderer {
ByteBuffer buffer = imGuiIO.getFonts().getTexDataAsRGBA32(textureWidth,textureHeight); ByteBuffer buffer = imGuiIO.getFonts().getTexDataAsRGBA32(textureWidth,textureHeight);
ImageSrc imageSrc = new ImageSrc(buffer,textureWidth.get(),textureHeight.get(),4); ImageSrc imageSrc = new ImageSrc(buffer,textureWidth.get(),textureHeight.get(),4);
Texture FontsTexture = new Texture(VkCtx, "GUI_TEXTURE",imageSrc,VK_FORMAT_R8G8B8A8_SRGB); Texture FontsTexture = new Texture(VkCtx, "GUI_TEXTURE",imageSrc,VK_FORMAT_R8G8B8A8_SRGB);
var commandPool = new CommandPool(VkCtx, queue.GetQueueFamilyIndex(), false); var commandPool = new CommandPool(VkCtx, queue.GetQueueFamilyIndex(), false);
var commandBuffer = new CommandBuffer(VkCtx, commandPool, true, true); var commandBuffer = new CommandBuffer(VkCtx, commandPool, true, true);
commandBuffer.BeginRecording(); commandBuffer.BeginRecording();

View file

@ -0,0 +1,213 @@
package net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Deferred;
import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig;
import net.halbear.Terrain4J.EngineCore.Logic.Rendering.VulkanContext;
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.EmptyVertexBufferStruct;
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.Pipeline;
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.PipelineBuildInfo;
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.PostProcessing.SpecializationConstants;
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Shader.*;
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.CommandBuffer;
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.Device;
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DisplayToScreen.ImageView;
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.SwapChain.SwapChain;
import net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanUtils;
import org.lwjgl.system.MemoryStack;
import org.lwjgl.util.shaderc.Shaderc;
import org.lwjgl.vulkan.*;
import java.nio.LongBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static org.lwjgl.vulkan.VK13.*;
public class LightRenderer {
private static final int COLOUR_FORMAT = VK_FORMAT_R32G32B32A32_SFLOAT;
private static final String DESCRIPTOR_ID_ATTACHMENT = "LIGHT_DESC_ID_ATT";
private static final String FRAGMENT_SHADER_FILE_GLSL = "resources/EngineResources/shaders/lighting_frag.glsl";
private static final String FRAGMENT_SHADER_FILE_SPV = FRAGMENT_SHADER_FILE_GLSL + ".spv";
private static final String VERTEX_SHADER_FILE_GLSL = "resources/EngineResources/shaders/lighting_vertex.glsl";
private static final String VERTEX_SHADER_FILE_SPV = VERTEX_SHADER_FILE_GLSL + ".spv";
private final DescriptorSetLayout AttachmentDescriptorSetLayout;
private final VkClearValue ClearValueColour;
private final Pipeline pipeline;
private final TextureSampler textureSampler;
private Attachment AttachmentColour;
private VkRenderingAttachmentInfo.Buffer AttachmentInfoColour;
private VkRenderingInfo RenderingInfo;
public LightRenderer(VulkanContext VkCtx, List<Attachment> attachmentList){
ClearValueColour=VkClearValue.calloc().color(
c->c.float32(0,0.0f).float32(1,0.0f).float32(2,0.0f).float32(3,0.0f));
AttachmentColour = CreateColourAttachment(VkCtx);
AttachmentInfoColour = CreateColourAttachmentInfo(AttachmentColour,ClearValueColour);
RenderingInfo = CreateRenderInfo(AttachmentColour,AttachmentInfoColour);
ShaderModule[] shaderModules = CreateShaderModules(VkCtx);
var textureSamplerInfo = new TextureSamplerInfo(VK_SAMPLER_ADDRESS_MODE_REPEAT,VK_BORDER_COLOR_INT_OPAQUE_BLACK,1,true);
textureSampler = new TextureSampler(VkCtx, textureSamplerInfo);
int AttachmentCount = attachmentList.size();
DescriptorSetLayout.LayoutInformation[] descriptorSetLayouts = new DescriptorSetLayout.LayoutInformation[AttachmentCount];
for(int i = 0; i < AttachmentCount; i++){
descriptorSetLayouts[i] = new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, i,1,VK_SHADER_STAGE_FRAGMENT_BIT);
}
AttachmentDescriptorSetLayout = new DescriptorSetLayout(VkCtx, descriptorSetLayouts);
CreateAttachmentDescriptorSet(VkCtx, AttachmentDescriptorSetLayout, attachmentList, textureSampler);
pipeline = CreatePipeline(VkCtx,shaderModules,new DescriptorSetLayout[]{AttachmentDescriptorSetLayout});
Arrays.asList(shaderModules).forEach(s->{s.CleanUp(VkCtx);});
}
private static Attachment CreateColourAttachment(VulkanContext VkCtx){
SwapChain swapChain = VkCtx.GetSwapChain();
VkExtent2D SwapChainExtent = swapChain.GetSwapChainExtent();
return new Attachment(VkCtx,SwapChainExtent.width(),SwapChainExtent.height(),
COLOUR_FORMAT,VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
}
private static VkRenderingAttachmentInfo.Buffer CreateColourAttachmentInfo(Attachment SrcAttachment, VkClearValue ClearValue){
return VkRenderingAttachmentInfo.calloc(1)
.sType$Default()
.imageView(SrcAttachment.GetVkImageView().GetVulkanImageView())
.imageLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)
.loadOp(VK_ATTACHMENT_LOAD_OP_CLEAR)
.storeOp(VK_ATTACHMENT_STORE_OP_STORE)
.clearValue(ClearValue);
}
private static Pipeline CreatePipeline(VulkanContext VkCtx, ShaderModule[] shaderModules, DescriptorSetLayout[] descriptorSetLayouts){
var VertexBufferStruct = new EmptyVertexBufferStruct();
var BuildInfo = new PipelineBuildInfo(shaderModules,VertexBufferStruct.GetVertexInput(),COLOUR_FORMAT)
.SetDescriptorSetLayouts(descriptorSetLayouts)
.BlendingIsUsed(true)
.SetDepthWrite(false)
.SetDepthTest(false);
var PipeLine = new DefaultPipeline(VkCtx,BuildInfo);
VertexBufferStruct.CleanUp();
return PipeLine;
}
private static VkRenderingInfo CreateRenderInfo(Attachment ColourAttachment, VkRenderingAttachmentInfo.Buffer ColourAttachmentInfo){
VkRenderingInfo renderingInfo;
try(var MemStack = MemoryStack.stackPush()){
Image image = ColourAttachment.GetVkImage();
VkExtent2D extent2D = VkExtent2D.calloc(MemStack).width(image.GetWidth()).height(image.GetHeight());
var RenderArea = VkRect2D.calloc(MemStack).extent(extent2D);
renderingInfo = VkRenderingInfo.calloc()
.sType$Default()
.renderArea(RenderArea)
.layerCount(1)
.pColorAttachments(ColourAttachmentInfo);
}
return renderingInfo;
}
private static void CreateAttachmentDescriptorSet(VulkanContext VkCtx, DescriptorSetLayout descriptorSetLayout, List<Attachment> attachments, TextureSampler textureSampler){
DescriptorAllocator descriptorAllocator = VkCtx.GetDescriptorAllocator();
Device device = VkCtx.GetDevice();
DescriptorSet descriptorSet = descriptorAllocator.AddDescriptorSet(device, DESCRIPTOR_ID_ATTACHMENT, descriptorSetLayout);
List<ImageView> imageViews = new ArrayList<>();
attachments.forEach(a->imageViews.add(a.GetVkImageView()));
descriptorSet.SetImages(device, imageViews, textureSampler, 0);
}
private static ShaderModule[] CreateShaderModules(VulkanContext VkCtx){
if(EngineConfig.getInstance().RecompileShaders()){
ShaderCompiler.CompileGLSLShaderOnChange(VERTEX_SHADER_FILE_GLSL, Shaderc.shaderc_glsl_vertex_shader);
ShaderCompiler.CompileGLSLShaderOnChange(FRAGMENT_SHADER_FILE_GLSL, Shaderc.shaderc_glsl_fragment_shader);
}
return new ShaderModule[]{
new ShaderModule(VkCtx,VK_SHADER_STAGE_VERTEX_BIT,VERTEX_SHADER_FILE_SPV,null),
new ShaderModule(VkCtx,VK_SHADER_STAGE_FRAGMENT_BIT,FRAGMENT_SHADER_FILE_SPV,null)
};
}
public Attachment GetColourAttachment(){
return AttachmentColour;
}
public void Render(VulkanContext VkCtx, CommandBuffer commandBuffer, MultiRenderTargetAttachments MRTAttachments){
try(var MemStack = MemoryStack.stackPush()){
VkCommandBuffer CommandHandle = commandBuffer.GetVulkanCommandBuffer();
VulkanUtils.ImageBarrier(MemStack, CommandHandle, AttachmentColour.GetVkImage().getVulkanImage(),
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT,
VK_ACCESS_2_NONE, VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT, VK_IMAGE_ASPECT_COLOR_BIT);
List<Attachment> ColourAttachments = MRTAttachments.GetColourAttachments();
int AttachmentCount = ColourAttachments.size();
for(int i = 0; i < AttachmentCount; i++) {
Attachment colourAttachment = ColourAttachments.get(i);
VulkanUtils.ImageBarrier(MemStack, CommandHandle, colourAttachment.GetVkImage().getVulkanImage(),
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT,
VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_2_SHADER_READ_BIT, VK_IMAGE_ASPECT_COLOR_BIT);
}
VulkanUtils.ImageBarrier(MemStack, CommandHandle, MRTAttachments.GetDepthAttachment().GetVkImage().getVulkanImage(),
VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT,
VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT,VK_ACCESS_2_SHADER_READ_BIT,
VK_IMAGE_ASPECT_DEPTH_BIT);
vkCmdBeginRendering(CommandHandle, RenderingInfo);
vkCmdBindPipeline(CommandHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.GetVulkanPipeline());
Image colourImage = AttachmentColour.GetVkImage();
int width = colourImage.GetWidth();
int height = colourImage.GetHeight();
var Viewport = VkViewport.calloc(1,MemStack)
.x(0)
.y(height)
.height(-height)
.width(width)
.minDepth(0.0F)
.maxDepth(1.0F);
vkCmdSetViewport(CommandHandle, 0, Viewport);
var Scissor = VkRect2D.calloc(1,MemStack)
.extent(it -> it.width(width).height(height))
.offset(it->it.x(0).y(0));
vkCmdSetScissor(CommandHandle, 0, Scissor);
DescriptorAllocator descriptorAllocator = VkCtx.GetDescriptorAllocator();
LongBuffer DescriptorSets = MemStack.mallocLong(1)
.put(0,descriptorAllocator.GetDescriptorSet(DESCRIPTOR_ID_ATTACHMENT).GetVkDescriptorSet());
vkCmdBindDescriptorSets(CommandHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.GetVulkanPipelineLayout(),0,DescriptorSets,null);
vkCmdDraw(CommandHandle,3,1,0,0);
vkCmdEndRendering(CommandHandle);
}
}
public void Resize(VulkanContext VkCtx, List<Attachment> attachments){
RenderingInfo.free();
AttachmentInfoColour.free();
AttachmentColour.CleanUp(VkCtx);
AttachmentColour = CreateColourAttachment(VkCtx);
AttachmentInfoColour = CreateColourAttachmentInfo(AttachmentColour, ClearValueColour);
RenderingInfo = CreateRenderInfo(AttachmentColour, AttachmentInfoColour);
DescriptorSet descriptorSet = VkCtx.GetDescriptorAllocator().GetDescriptorSet(DESCRIPTOR_ID_ATTACHMENT);
var ImageViews = new ArrayList<ImageView>();
attachments.forEach(a->ImageViews.add(a.GetVkImageView()));
descriptorSet.SetImages(VkCtx.GetDevice(),ImageViews,textureSampler,0);
}
public void CleanUp(VulkanContext VkCtx){
pipeline.CleanUp(VkCtx);
AttachmentDescriptorSetLayout.CleanUp(VkCtx);
textureSampler.CleanUp(VkCtx);
RenderingInfo.free();
AttachmentColour.CleanUp(VkCtx);
AttachmentInfoColour.free();
ClearValueColour.free();
}
}

View file

@ -0,0 +1,51 @@
package net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Deferred;
import net.halbear.Terrain4J.EngineCore.Logic.Rendering.VulkanContext;
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Images.Attachment;
import org.lwjgl.vulkan.VkExtent2D;
import java.util.ArrayList;
import java.util.List;
import static org.lwjgl.vulkan.VK13.*;
//multiple render target attachments
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;
private final List<Attachment> ColourAttachments;
private final Attachment DepthAttachment;
private final int Height;
private final int Width;
public MultiRenderTargetAttachments(VulkanContext VkCtx){
VkExtent2D extent2D = VkCtx.GetSwapChain().GetSwapChainExtent();
Width = extent2D.width();
Height = extent2D.height();
ColourAttachments = new ArrayList<>();
var AlbedoAttachment = new Attachment(VkCtx, Width, Height, ALBEDO_FORMAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
ColourAttachments.add(AlbedoAttachment);
DepthAttachment = new Attachment(VkCtx, Width, Height, DEPTH_FORMAT, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT);
}
public int GetWidth(){return Width;}
public int GetHeight(){return Height;}
public Attachment GetDepthAttachment(){return DepthAttachment;}
public List<Attachment> GetColourAttachments(){return ColourAttachments;}
public List<Attachment> GetAllAttachments(){
List<Attachment> attachments = new ArrayList<>(ColourAttachments);
attachments.add(DepthAttachment);
return attachments;
}
public void CleanUp(VulkanContext VkCtx){
ColourAttachments.forEach(cA -> cA.CleanUp(VkCtx));
DepthAttachment.CleanUp(VkCtx);
}
}

View file

@ -88,7 +88,7 @@ public class DefaultPipeline implements Pipeline {
if(BuildInfo.GetDepthFormat() != VK_FORMAT_UNDEFINED){ if(BuildInfo.GetDepthFormat() != VK_FORMAT_UNDEFINED){
DepthStencil = VkPipelineDepthStencilStateCreateInfo.calloc(MemStack) DepthStencil = VkPipelineDepthStencilStateCreateInfo.calloc(MemStack)
.sType(VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO) .sType(VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO)
.depthTestEnable(true) .depthTestEnable(BuildInfo.performDepthTest())
.depthWriteEnable(BuildInfo.performDepthWrite()) .depthWriteEnable(BuildInfo.performDepthWrite())
.depthCompareOp(VK_COMPARE_OP_GREATER_OR_EQUAL) .depthCompareOp(VK_COMPARE_OP_GREATER_OR_EQUAL)
.depthBoundsTestEnable(false) .depthBoundsTestEnable(false)

View file

@ -12,19 +12,20 @@ public class Attachment {
private boolean DepthAttachment; private boolean DepthAttachment;
public Attachment(VulkanContext VkCtx, int Width, int Height, int Format, int Usage){ public Attachment(VulkanContext VkCtx, int Width, int Height, int Format, int Usage){
var ImageData = new Image.ImageData().Width(Width).Height(Height) var ImageData = new Image.ImageData().Width(Width).Height(Height).Format(Format).MemoryUsage(VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT).SampleCount(EngineConfig.getInstance().GetRenderSampleCount());
.Usage(Usage | VK_IMAGE_USAGE_SAMPLED_BIT).Format(Format).MemoryUsage(VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT).SampleCount(EngineConfig.getInstance().GetRenderSampleCount());
VkImage = new Image(VkCtx, ImageData);
int AspectMask = 0; int AspectMask = 0;
if((Usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) > 0){ if((Usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) > 0){
AspectMask = VK_IMAGE_ASPECT_COLOR_BIT; AspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
ImageData.Usage(Usage | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
DepthAttachment = false; DepthAttachment = false;
} }
if((Usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) > 0){ if((Usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) > 0){
ImageData.Usage(Usage | VK_IMAGE_USAGE_SAMPLED_BIT);
AspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; AspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
DepthAttachment = true; DepthAttachment = true;
} }
VkImage = new Image(VkCtx, ImageData);
var ImageViewData = new ImageView.ImageViewData().Format(VkImage.GetFormat()).AspectMask(AspectMask); var ImageViewData = new ImageView.ImageViewData().Format(VkImage.GetFormat()).AspectMask(AspectMask);
VkImageView = new ImageView(VkCtx.GetDevice(), VkImage.getVulkanImage(), ImageViewData,DepthAttachment); VkImageView = new ImageView(VkCtx.GetDevice(), VkImage.getVulkanImage(), ImageViewData,DepthAttachment);
} }

View file

@ -17,6 +17,7 @@ public class PipelineBuildInfo {
private DescriptorSetLayout[] DescriptorSetLayouts; private DescriptorSetLayout[] DescriptorSetLayouts;
private boolean useBlend; private boolean useBlend;
private boolean DepthWrite = true; private boolean DepthWrite = true;
private boolean DepthTest = true;
private boolean DualPass = false; private boolean DualPass = false;
private boolean alphaToCoverage = false; private boolean alphaToCoverage = false;
@ -36,6 +37,14 @@ public class PipelineBuildInfo {
this.DualPass = DualPass; this.DualPass = DualPass;
return this; return this;
} }
public PipelineBuildInfo SetDepthTest(boolean DepthTest){
this.DepthTest = DepthTest;
return this;
}
public boolean performDepthTest(){return DepthTest;}
public PipelineBuildInfo SetDepthWrite(boolean DepthWrite){ public PipelineBuildInfo SetDepthWrite(boolean DepthWrite){
this.DepthWrite = DepthWrite; this.DepthWrite = DepthWrite;
return this; return this;

View file

@ -116,10 +116,12 @@ public class PostProcess {
} }
private static void CreateAttachmentDescriptorSet(VulkanContext VkCtx, DescriptorSetLayout descriptorSetLayout, Attachment attachment, TextureSampler textureSampler){ private static void CreateAttachmentDescriptorSet(VulkanContext VkCtx, DescriptorSetLayout descriptorSetLayout, Attachment attachment, TextureSampler textureSampler){
if(!EngineConfig.getInstance().DeferredRendering() && attachment != null) {
DescriptorAllocator descriptorAllocator = VkCtx.GetDescriptorAllocator(); DescriptorAllocator descriptorAllocator = VkCtx.GetDescriptorAllocator();
Device device = VkCtx.GetDevice(); Device device = VkCtx.GetDevice();
DescriptorSet descriptorSet = descriptorAllocator.AddDescriptorSets(device,DESCRIPTOR_ID_ATTACHMENT,1 , descriptorSetLayout)[0]; DescriptorSet descriptorSet = descriptorAllocator.AddDescriptorSets(device, DESCRIPTOR_ID_ATTACHMENT, 1, descriptorSetLayout)[0];
descriptorSet.SetImage(device,attachment.GetVkImageView(),textureSampler,0); descriptorSet.SetImage(device, attachment.GetVkImageView(), textureSampler, 0);
}
} }
private static ShaderModule[] CreateShaderModules(VulkanContext VkCtx, SpecializationConstants specConstants){ private static ShaderModule[] CreateShaderModules(VulkanContext VkCtx, SpecializationConstants specConstants){
@ -138,45 +140,49 @@ public class PostProcess {
} }
public void Render(VulkanContext VkCtx, CommandBuffer commandBuffer, Attachment SrcAttachment){ public void Render(VulkanContext VkCtx, CommandBuffer commandBuffer, Attachment SrcAttachment){
try(var MemStack = MemoryStack.stackPush()){ if(SrcAttachment != null) {
try (var MemStack = MemoryStack.stackPush()) {
SwapChain swapChain = VkCtx.GetSwapChain(); SwapChain swapChain = VkCtx.GetSwapChain();
VkCommandBuffer CommandHandle = commandBuffer.GetVulkanCommandBuffer(); VkCommandBuffer CommandHandle = commandBuffer.GetVulkanCommandBuffer();
VulkanUtils.ImageBarrier(MemStack, CommandHandle, SrcAttachment.GetVkImage().getVulkanImage(), VulkanUtils.ImageBarrier(MemStack, CommandHandle, SrcAttachment.GetVkImage().getVulkanImage(),
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT,
VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT,VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT,VK_ACCESS_2_SHADER_READ_BIT,VK_IMAGE_ASPECT_COLOR_BIT); VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT, VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_2_SHADER_READ_BIT, VK_IMAGE_ASPECT_COLOR_BIT);
VulkanUtils.ImageBarrier(MemStack,CommandHandle,ColourAttachment.GetVkImage().getVulkanImage(), VulkanUtils.ImageBarrier(MemStack, CommandHandle, ColourAttachment.GetVkImage().getVulkanImage(),
VK_IMAGE_LAYOUT_UNDEFINED,VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT,VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT,
VK_ACCESS_2_NONE,VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT,VK_IMAGE_ASPECT_COLOR_BIT); VK_ACCESS_2_NONE, VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT, VK_IMAGE_ASPECT_COLOR_BIT);
vkCmdBeginRendering(CommandHandle,RenderingInfo); vkCmdBeginRendering(CommandHandle, RenderingInfo);
vkCmdBindPipeline(CommandHandle,VK_PIPELINE_BIND_POINT_GRAPHICS,pipeline.GetVulkanPipeline()); vkCmdBindPipeline(CommandHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.GetVulkanPipeline());
VkExtent2D SwapChainExtent = swapChain.GetSwapChainExtent(); VkExtent2D SwapChainExtent = swapChain.GetSwapChainExtent();
int Width = SwapChainExtent.width(); int Width = SwapChainExtent.width();
int Height = SwapChainExtent.height(); int Height = SwapChainExtent.height();
var Viewport = VkViewport.calloc(1,MemStack) var Viewport = VkViewport.calloc(1, MemStack)
.x(0) .x(0)
.y(Height) .y(Height)
.height(-Height) .height(-Height)
.width(Width) .width(Width)
.minDepth(0.0f) .minDepth(0.0f)
.maxDepth(1.0f); .maxDepth(1.0f);
vkCmdSetViewport(CommandHandle,0,Viewport); vkCmdSetViewport(CommandHandle, 0, Viewport);
var Scissor = VkRect2D.calloc(1,MemStack) var Scissor = VkRect2D.calloc(1, MemStack)
.extent(it->it.width(Width).height(Height)) .extent(it -> it.width(Width).height(Height))
.offset(it->it.x(0).y(0)); .offset(it -> it.x(0).y(0));
vkCmdSetScissor(CommandHandle,0,Scissor); vkCmdSetScissor(CommandHandle, 0, Scissor);
DescriptorAllocator descriptorAllocator = VkCtx.GetDescriptorAllocator(); DescriptorAllocator descriptorAllocator = VkCtx.GetDescriptorAllocator();
if(descriptorAllocator.GetDescriptorSet(DESCRIPTOR_ID_ATTACHMENT) != null && descriptorAllocator.GetDescriptorSet(DESCRIPTOR_ID_SCREEN_SIZE) != null) {
LongBuffer DescriptorSets = MemStack.mallocLong(2) LongBuffer DescriptorSets = MemStack.mallocLong(2)
.put(0,descriptorAllocator.GetDescriptorSet(DESCRIPTOR_ID_ATTACHMENT).GetVkDescriptorSet()) .put(0, descriptorAllocator.GetDescriptorSet(DESCRIPTOR_ID_ATTACHMENT).GetVkDescriptorSet())
.put(1,descriptorAllocator.GetDescriptorSet(DESCRIPTOR_ID_SCREEN_SIZE).GetVkDescriptorSet()); .put(1, descriptorAllocator.GetDescriptorSet(DESCRIPTOR_ID_SCREEN_SIZE).GetVkDescriptorSet());
vkCmdBindDescriptorSets(CommandHandle,VK_PIPELINE_BIND_POINT_GRAPHICS,pipeline.GetVulkanPipelineLayout(),0,DescriptorSets,null); vkCmdBindDescriptorSets(CommandHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.GetVulkanPipelineLayout(), 0, DescriptorSets, null);
vkCmdDraw(CommandHandle,3,1,0,0); vkCmdDraw(CommandHandle, 3, 1, 0, 0);
}
vkCmdEndRendering(CommandHandle); vkCmdEndRendering(CommandHandle);
} }
} }
}
public void Resize(VulkanContext VkCtx, Attachment SrcAttachment){ public void Resize(VulkanContext VkCtx, Attachment SrcAttachment){
RenderingInfo.free();; RenderingInfo.free();;

View file

@ -3,11 +3,13 @@ package net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Projection;
import org.joml.Matrix4f; import org.joml.Matrix4f;
public class Project3D { public class Project3D {
private final float FOV; // IT IS IN RADIANS!! REMEEEEMMMBER RADIANS!!!! PI/180!!!!! private float FOV; // IT IS IN RADIANS!! REMEEEEMMMBER RADIANS!!!! PI/180!!!!!
// there is a universal DegToRad conversion variable one can use in EngineConfig if they need to convert it // there is a universal DegToRad conversion variable one can use in EngineConfig if they need to convert it
private final Matrix4f ProjectionMatrix; private final Matrix4f ProjectionMatrix;
private final float ZFarPlane; private final float ZFarPlane;
private final float ZNearPlane; private final float ZNearPlane;
private int LastWidth;
private int LastHeight;
public Project3D(float FOV, float zNear, float zFar, int Width, int Height){ public Project3D(float FOV, float zNear, float zFar, int Width, int Height){
this.FOV = FOV; this.FOV = FOV;
@ -15,6 +17,13 @@ public class Project3D {
this.ZNearPlane = zNear; this.ZNearPlane = zNear;
ProjectionMatrix = new Matrix4f(); ProjectionMatrix = new Matrix4f();
Resize(Width, Height); Resize(Width, Height);
LastWidth = Width;
LastHeight = Height;
}
public void ChangeFOV(float newFOV){
FOV = newFOV;
Resize(LastWidth,LastHeight);
} }
public float GetFOV(){ public float GetFOV(){
@ -32,5 +41,7 @@ public class Project3D {
public void Resize(int Width, int Height){ public void Resize(int Width, int Height){
ProjectionMatrix.identity(); ProjectionMatrix.identity();
ProjectionMatrix.perspective(FOV, (float)Width/(float)Height, ZNearPlane, ZFarPlane, true); ProjectionMatrix.perspective(FOV, (float)Width/(float)Height, ZNearPlane, ZFarPlane, true);
LastWidth = Width;
LastHeight = Height;
} }
} }

View file

@ -6,6 +6,7 @@ import net.halbear.Terrain4J.EngineCore.Logic.Rendering.VulkanContext;
import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime; import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime;
import net.halbear.Terrain4J.EngineCore.Main.Scene.Actor; import net.halbear.Terrain4J.EngineCore.Main.Scene.Actor;
import net.halbear.Terrain4J.EngineCore.Main.Scene.Scene; import net.halbear.Terrain4J.EngineCore.Main.Scene.Scene;
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Deferred.MultiRenderTargetAttachments;
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.DefaultPipeline; 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.Attachment;
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Images.Image; import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Images.Image;
@ -38,6 +39,14 @@ import static org.lwjgl.vulkan.VK13.*;
public class SceneRender implements SceneRenderer {//dynamic rendering public class SceneRender implements SceneRenderer {//dynamic rendering
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";
private static final String FRAGMENT_SHADER_FILE_SPV = FRAGMENT_SHADER_FILE_GLSL + ".spv";
private static final String FRAGMENT_TRANSLUCENT_SHADER_FILE_SPV = FRAGMENT_TRANSLUCENT_SHADER_FILE_GLSL + ".spv";
private static final String FRAGMENT_OPAQUE_SHADER_FILE_SPV = FRAGMENT_OPAQUE_SHADER_FILE_GLSL + ".spv";
private static final String VERTEX_SHADER_FILE_GLSL = "resources/EngineResources/shaders/scene_vertex.glsl";
private static final String VERTEX_SHADER_FILE_SPV = VERTEX_SHADER_FILE_GLSL + ".spv";
private static final String DESCRIPTOR_ID_MAT = "SCN_DESC_ID_MAT"; private static final String DESCRIPTOR_ID_MAT = "SCN_DESC_ID_MAT";
private static final String DESCRIPTOR_ID_PRJ = "SCN_DESC_ID_PRJ"; 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_TEXT = "SCN_DESC_ID_TEXT";
@ -48,7 +57,6 @@ public class SceneRender implements SceneRenderer {//dynamic rendering
private final DescriptorSetLayout descriptorLayoutTexture; private final DescriptorSetLayout descriptorLayoutTexture;
private final DescriptorSetLayout descriptorLayoutVertexUniform; private final DescriptorSetLayout descriptorLayoutVertexUniform;
private final TextureSampler textureSampler; private final TextureSampler textureSampler;
private static final int COLOUR_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT; 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_S8_UINT;
private final VkClearValue ClearValueDepth; private final VkClearValue ClearValueDepth;
@ -70,20 +78,13 @@ public class SceneRender implements SceneRenderer {//dynamic rendering
public static long GPUTIME = 0; public static long GPUTIME = 0;
public static long CYCLES = 0; public static long CYCLES = 0;
private static boolean DualPassRendering = false; private static boolean DualPassRendering = false;
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";
private static final String FRAGMENT_SHADER_FILE_SPV = FRAGMENT_SHADER_FILE_GLSL + ".spv";
private static final String FRAGMENT_TRANSLUCENT_SHADER_FILE_SPV = FRAGMENT_TRANSLUCENT_SHADER_FILE_GLSL + ".spv";
private static final String FRAGMENT_OPAQUE_SHADER_FILE_SPV = FRAGMENT_OPAQUE_SHADER_FILE_GLSL + ".spv";
private static final String VERTEX_SHADER_FILE_GLSL = "resources/EngineResources/shaders/scene_vertex.glsl";
private static final String VERTEX_SHADER_FILE_SPV = VERTEX_SHADER_FILE_GLSL + ".spv";
private final VulkanBuffer[] BufferViewMatrices; private final VulkanBuffer[] BufferViewMatrices;
private Pipeline VkPipeline; private Pipeline VkPipeline;
private Pipeline VkPipelineOpaque; private Pipeline VkPipelineOpaque;
private Pipeline VkPipelineTranslucent; private Pipeline VkPipelineTranslucent;
private Matrix4f ProjectionMatrix; private Matrix4f ProjectionMatrix;
private MultiRenderTargetAttachments MRTAttachments;
private boolean Deferred = false;
public static long GetGPUTimeNS(){ public static long GetGPUTimeNS(){
long time = 0; long time = 0;
@ -95,15 +96,29 @@ public class SceneRender implements SceneRenderer {//dynamic rendering
return time; return time;
} }
public boolean GetCurrentDeferred(){return Deferred;}
public void UpdateDeferred(VulkanContext vulkanContext){
Deferred = EngineConfig.getInstance().DeferredRendering();
CreateRenderAttachments(vulkanContext);
CreatePipelines(vulkanContext);
}
public void CreateRenderAttachments(VulkanContext vulkanContext){
MRTAttachments = new MultiRenderTargetAttachments(vulkanContext);
AttachmentColour = CreateColourAttachment(vulkanContext);
AttachmentDepth = CreateDepthAttachment(vulkanContext);
AttachmentInfoDepth = Deferred ? CreateDeferredDepthAttachmentInfo(MRTAttachments, ClearValueDepth) : CreateDepthAttachmentInfo(AttachmentDepth, ClearValueDepth);
AttachmentInfoColour = Deferred ? CreateDeferredColourAttachmentInfo(MRTAttachments, ClearValueDepth) : CreateColourAttachmentInfo(AttachmentColour,ClearValueColour);
RenderInfo = Deferred ? CreateDeferredRenderInfo(vulkanContext, AttachmentInfoColour, AttachmentInfoDepth) : CreateRenderInfo(AttachmentColour, AttachmentInfoColour, AttachmentInfoDepth);
}
public SceneRender(VulkanContext vulkanContext){ public SceneRender(VulkanContext vulkanContext){
Deferred = EngineConfig.getInstance().DeferredRendering();
ClearValueColour = VkClearValue.calloc().color( ClearValueColour = VkClearValue.calloc().color(
c -> c.float32(0, R).float32(1, G).float32(2, B).float32(3, 1.0f)); c -> c.float32(0, R).float32(1, G).float32(2, B).float32(3, 1.0f));
ClearValueDepth = VkClearValue.calloc().color(c -> c.float32(0, 0.0f)); ClearValueDepth = VkClearValue.calloc().color(c -> c.float32(0, 0.0f));
AttachmentColour = CreateColourAttachment(vulkanContext); CreateRenderAttachments(vulkanContext);
AttachmentDepth = CreateDepthAttachment(vulkanContext);
AttachmentInfoDepth = CreateDepthAttachmentInfo(AttachmentDepth, ClearValueDepth);
AttachmentInfoColour = CreateColourAttachmentInfo(AttachmentColour,ClearValueColour);
RenderInfo = CreateRenderInfo(AttachmentColour, AttachmentInfoColour, AttachmentInfoDepth);
PushConstBuffer = (MemoryUtil.memAlloc(PUSH_CONSTANTS_SIZE)); PushConstBuffer = (MemoryUtil.memAlloc(PUSH_CONSTANTS_SIZE));
@ -126,6 +141,7 @@ public class SceneRender implements SceneRenderer {//dynamic rendering
} }
public void CreatePipelines(VulkanContext vulkanContext){ public void CreatePipelines(VulkanContext vulkanContext){
DescriptorSetLayout[] layouts = new DescriptorSetLayout[]{ DescriptorSetLayout[] layouts = new DescriptorSetLayout[]{
descriptorLayoutVertexUniform, descriptorLayoutVertexUniform,
descriptorLayoutVertexUniform, descriptorLayoutVertexUniform,
@ -134,11 +150,11 @@ public class SceneRender implements SceneRenderer {//dynamic rendering
}; };
ShaderModule[] shaderModules = SceneRender.CreateShaderModules(vulkanContext,0); ShaderModule[] shaderModules = SceneRender.CreateShaderModules(vulkanContext,0);
VkPipeline = CreatePipeline(vulkanContext, shaderModules, layouts, true, false,EngineConfig.getInstance().AlphaToCoverage()); VkPipeline = Deferred ? CreateDeferredPipeline(vulkanContext, shaderModules, layouts, true, false,EngineConfig.getInstance().AlphaToCoverage()) : CreatePipeline(vulkanContext, shaderModules, layouts, true, false,EngineConfig.getInstance().AlphaToCoverage());
shaderModules = SceneRender.CreateShaderModules(vulkanContext,1); shaderModules = SceneRender.CreateShaderModules(vulkanContext,1);
VkPipelineOpaque = CreatePipeline(vulkanContext, shaderModules, layouts, true, true,EngineConfig.getInstance().AlphaToCoverage()); VkPipelineOpaque = Deferred ? CreateDeferredPipeline(vulkanContext, shaderModules, layouts, true, true,EngineConfig.getInstance().AlphaToCoverage()) : CreatePipeline(vulkanContext, shaderModules, layouts, true, true,EngineConfig.getInstance().AlphaToCoverage());
shaderModules = SceneRender.CreateShaderModules(vulkanContext,2); shaderModules = SceneRender.CreateShaderModules(vulkanContext,2);
VkPipelineTranslucent = CreatePipeline(vulkanContext, shaderModules, layouts, false, true,EngineConfig.getInstance().AlphaToCoverage()); VkPipelineTranslucent = Deferred ? CreateDeferredPipeline(vulkanContext, shaderModules, layouts, false, true,EngineConfig.getInstance().AlphaToCoverage()) : CreatePipeline(vulkanContext, shaderModules, layouts, false, true,EngineConfig.getInstance().AlphaToCoverage());
Arrays.asList(shaderModules).forEach(shaderModule -> shaderModule.CleanUp(vulkanContext)); Arrays.asList(shaderModules).forEach(shaderModule -> shaderModule.CleanUp(vulkanContext));
} }
@ -158,6 +174,22 @@ public class SceneRender implements SceneRenderer {//dynamic rendering
return new Attachment(VkCtx, SwapChainExtent.width(), SwapChainExtent.height(), COLOUR_FORMAT,VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT); return new Attachment(VkCtx, SwapChainExtent.width(), SwapChainExtent.height(), COLOUR_FORMAT,VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
} }
private static VkRenderingAttachmentInfo.Buffer CreateDeferredColourAttachmentInfo(MultiRenderTargetAttachments attachment, VkClearValue ClearValue){
List<Attachment> colourAttachments = attachment.GetColourAttachments();
int AttachmentCount = colourAttachments.size();
VkRenderingAttachmentInfo.Buffer result = VkRenderingAttachmentInfo.calloc(AttachmentCount);
for(int i = 0; i < AttachmentCount; i++) {
result.get(i).sType$Default()
.imageView(attachment.GetColourAttachments().get(i).GetVkImageView().GetVulkanImageView())
.imageLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)
.loadOp(VK_ATTACHMENT_LOAD_OP_CLEAR)
.storeOp(VK_ATTACHMENT_STORE_OP_STORE)
.clearValue(ClearValue);
}
return result;
}
private static VkRenderingAttachmentInfo.Buffer CreateColourAttachmentInfo(Attachment attachment, VkClearValue ClearValue){ private static VkRenderingAttachmentInfo.Buffer CreateColourAttachmentInfo(Attachment attachment, VkClearValue ClearValue){
return VkRenderingAttachmentInfo.calloc(1) return VkRenderingAttachmentInfo.calloc(1)
.sType$Default() .sType$Default()
@ -176,6 +208,16 @@ public class SceneRender implements SceneRenderer {//dynamic rendering
} }
private static VkRenderingAttachmentInfo CreateDeferredDepthAttachmentInfo(MultiRenderTargetAttachments DepthAttachment, VkClearValue clearValue){
return VkRenderingAttachmentInfo.calloc()
.sType$Default()
.imageView(DepthAttachment.GetDepthAttachment().GetVkImageView().GetVulkanImageView())
.imageLayout(VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)
.loadOp(VK_ATTACHMENT_LOAD_OP_CLEAR)
.storeOp(VK_ATTACHMENT_STORE_OP_DONT_CARE)
.clearValue(clearValue);
}
private static VkRenderingAttachmentInfo CreateDepthAttachmentInfo(Attachment DepthAttachment, VkClearValue clearValue){ private static VkRenderingAttachmentInfo CreateDepthAttachmentInfo(Attachment DepthAttachment, VkClearValue clearValue){
return VkRenderingAttachmentInfo.calloc() return VkRenderingAttachmentInfo.calloc()
.sType$Default() .sType$Default()
@ -186,34 +228,6 @@ public class SceneRender implements SceneRenderer {//dynamic rendering
.clearValue(clearValue); .clearValue(clearValue);
} }
private static Attachment[] createDepthAttachments(VulkanContext VkCtx){
SwapChain swapChain = VkCtx.GetSwapChain();
int ImageCount = swapChain.GetImageCount();
VkExtent2D swapChainExtent = swapChain.GetSwapChainExtent();
Attachment[] DepthAttachments = new Attachment[ImageCount];
for(int i = 0; i < ImageCount; i++){
DepthAttachments[i] = new Attachment(VkCtx, swapChainExtent.width(), swapChainExtent.height(),
DEPTH_FORMAT,VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT);
}
return DepthAttachments;
}
private static VkRenderingAttachmentInfo[] createDepthAttachmentsInfo(VulkanContext VkCtx, Attachment[] DepthAttachments, VkClearValue clearValue){
SwapChain swapChain = VkCtx.GetSwapChain();
int ImageCount = swapChain.GetImageCount();
var Result = new VkRenderingAttachmentInfo[ImageCount];
for(int i = 0; i < ImageCount; i++){
var Attachments = VkRenderingAttachmentInfo.calloc()
.sType$Default()
.imageView(DepthAttachments[i].GetVkImageView().GetVulkanImageView())
.imageLayout(VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)
.loadOp(VK_ATTACHMENT_LOAD_OP_CLEAR)
.storeOp(VK_ATTACHMENT_STORE_OP_DONT_CARE)
.clearValue(clearValue);
Result[i] = Attachments;
}
return Result;
}
private static ShaderModule[] CreateShaderModules(VulkanContext VkCtx, int Translucent){ private static ShaderModule[] CreateShaderModules(VulkanContext VkCtx, int Translucent){
if(EngineConfig.getInstance().RecompileShaders()){ if(EngineConfig.getInstance().RecompileShaders()){
@ -226,6 +240,25 @@ public class SceneRender implements SceneRenderer {//dynamic rendering
}; };
} }
private static Pipeline CreateDeferredPipeline(VulkanContext VkCtx, ShaderModule[] ShaderModules, DescriptorSetLayout[] DescriptorSetLayouts, boolean DepthWrite, boolean DualRender, boolean AlphaToCoverage){
var vertexBufferStructure = new VertexBufferStructure();
var BuildInfo = new PipelineBuildInfo(ShaderModules,vertexBufferStructure.getVertexInput(),MultiRenderTargetAttachments.ALBEDO_FORMAT)
.SetDepthFormat(MultiRenderTargetAttachments.DEPTH_FORMAT)
.SetDepthWrite(DepthWrite)
.SetPushConstantRanges(
new PushConstantsRange[]{
new PushConstantsRange(VK_SHADER_STAGE_VERTEX_BIT,0,VulkanUtils.MATRIX4X4_SIZE),
new PushConstantsRange(VK_SHADER_STAGE_FRAGMENT_BIT,VulkanUtils.MATRIX4X4_SIZE,VulkanUtils.INT_SIZE)
})
.SetDescriptorSetLayouts(DescriptorSetLayouts)
.BlendingIsUsed(DualRender ? !DepthWrite : true)
.SetDualPass(DualRender)
.SetAlphaToCoverage(AlphaToCoverage);
var pipeline = new DefaultPipeline(VkCtx, BuildInfo);
vertexBufferStructure.cleanup();
return pipeline;
}
private static Pipeline CreatePipeline(VulkanContext VkCtx, ShaderModule[] ShaderModules, DescriptorSetLayout[] DescriptorSetLayouts, boolean DepthWrite, boolean DualRender, boolean AlphaToCoverage){ private static Pipeline CreatePipeline(VulkanContext VkCtx, ShaderModule[] ShaderModules, DescriptorSetLayout[] DescriptorSetLayouts, boolean DepthWrite, boolean DualRender, boolean AlphaToCoverage){
var vertexBufferStructure = new VertexBufferStructure(); var vertexBufferStructure = new VertexBufferStructure();
var BuildInfo = new PipelineBuildInfo(ShaderModules,vertexBufferStructure.getVertexInput(),COLOUR_FORMAT) var BuildInfo = new PipelineBuildInfo(ShaderModules,vertexBufferStructure.getVertexInput(),COLOUR_FORMAT)
@ -246,7 +279,7 @@ public class SceneRender implements SceneRenderer {//dynamic rendering
} }
public void Render(EngineInstance engineInstance,VulkanContext vulkanContext, CommandBuffer commandBuffer, ModelsCache modelsCache,MaterialsCache materialsCache, int CurrentFrame){ public void ForwardRender(EngineInstance engineInstance,VulkanContext vulkanContext, CommandBuffer commandBuffer, ModelsCache modelsCache,MaterialsCache materialsCache, int CurrentFrame){
try(var MemStack = MemoryStack.stackPush()){ try(var MemStack = MemoryStack.stackPush()){
VkCommandBuffer CommandHandle = commandBuffer.GetVulkanCommandBuffer(); VkCommandBuffer CommandHandle = commandBuffer.GetVulkanCommandBuffer();
VulkanUtils.ImageBarrier(MemStack, CommandHandle, AttachmentColour.GetVkImage().getVulkanImage(), VulkanUtils.ImageBarrier(MemStack, CommandHandle, AttachmentColour.GetVkImage().getVulkanImage(),
@ -304,6 +337,80 @@ public class SceneRender implements SceneRenderer {//dynamic rendering
CYCLES++; CYCLES++;
} }
} }
public void DeferredRender(EngineInstance engineInstance,VulkanContext vulkanContext, CommandBuffer commandBuffer, ModelsCache modelsCache,MaterialsCache materialsCache, int CurrentFrame){
try(var MemStack = MemoryStack.stackPush()){
VkCommandBuffer CommandHandle = commandBuffer.GetVulkanCommandBuffer();
List<Attachment> ColourAttachments = MRTAttachments.GetColourAttachments();
int AttachmentCount = ColourAttachments.size();
for(int i = 0; i < AttachmentCount; i++) {
Attachment colourAttachment = ColourAttachments.get(i);
VulkanUtils.ImageBarrier(MemStack, CommandHandle, colourAttachment.GetVkImage().getVulkanImage(),
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT,
VK_ACCESS_NONE, VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT,
VK_IMAGE_ASPECT_COLOR_BIT);
}
VulkanUtils.ImageBarrier(MemStack, CommandHandle, MRTAttachments.GetDepthAttachment().GetVkImage().getVulkanImage(),
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL,
VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT,
VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT,
VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
VK_IMAGE_ASPECT_DEPTH_BIT);
long InitialTime = System.nanoTime();
vkCmdBeginRendering(CommandHandle, RenderInfo);
vkCmdBindPipeline(CommandHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, DualPassRendering ? VkPipelineOpaque.GetVulkanPipeline() : VkPipeline.GetVulkanPipeline());
int width = MRTAttachments.GetWidth();
int height = MRTAttachments.GetHeight();
var Viewport = VkViewport.calloc(1,MemStack)
.x(0)
.y(height)
.height(-height)
.width(width)
.minDepth(0.0F)
.maxDepth(1.0F);
vkCmdSetViewport(CommandHandle, 0, Viewport);
var Scissor = VkRect2D.calloc(1,MemStack)
.extent(it -> it.width(width).height(height))
.offset(it->it.x(0).y(0));
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())
.put(1,descriptorAllocator.GetDescriptorSet(DESCRIPTOR_ID_VIEW, CurrentFrame).GetVkDescriptorSet())
.put(2,descriptorAllocator.GetDescriptorSet(DESCRIPTOR_ID_MAT).GetVkDescriptorSet())
.put(3,descriptorAllocator.GetDescriptorSet(DESCRIPTOR_ID_TEXT).GetVkDescriptorSet());
vkCmdBindDescriptorSets(CommandHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, DualPassRendering ? VkPipelineOpaque.GetVulkanPipelineLayout() : VkPipeline.GetVulkanPipelineLayout(),0,DescriptorSets,null);
RenderActors(engineInstance, CommandHandle, modelsCache, materialsCache, false);
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);
}
RenderActors(engineInstance, CommandHandle, modelsCache, materialsCache, true);
vkCmdEndRendering(CommandHandle);
GPUTIME += System.nanoTime() - InitialTime;
CYCLES++;
}
}
public MultiRenderTargetAttachments GetMRTAttachments(){
return MRTAttachments;
}
public void Render(EngineInstance engineInstance,VulkanContext vulkanContext, CommandBuffer commandBuffer, ModelsCache modelsCache,MaterialsCache materialsCache, int CurrentFrame){
if(Deferred) DeferredRender(engineInstance,vulkanContext,commandBuffer,modelsCache,materialsCache,CurrentFrame);
else ForwardRender(engineInstance,vulkanContext,commandBuffer,modelsCache,materialsCache,CurrentFrame);
}
private void RenderActors(EngineInstance instance, VkCommandBuffer CommandHandle, ModelsCache modelsCache, MaterialsCache materialsCache, boolean Transparent){ private void RenderActors(EngineInstance instance, VkCommandBuffer CommandHandle, ModelsCache modelsCache, MaterialsCache materialsCache, boolean Transparent){
try(var MemStack = MemoryStack.stackPush()){ try(var MemStack = MemoryStack.stackPush()){
@ -312,7 +419,6 @@ public class SceneRender implements SceneRenderer {//dynamic rendering
Scene scene = instance.scene(); Scene scene = instance.scene();
List<Actor> Actors = scene.GetActors(); List<Actor> Actors = scene.GetActors();
int ActorCount = Actors.size(); int ActorCount = Actors.size();
List<Actor> translucentObjects = new ArrayList<>();
for(int i = 0; i < ActorCount; i++){ for(int i = 0; i < ActorCount; i++){
if(i < Actors.size()) { if(i < Actors.size()) {
var Actor = Actors.get(i); var Actor = Actors.get(i);
@ -352,17 +458,16 @@ public class SceneRender implements SceneRenderer {//dynamic rendering
PushConstBuffer.slice(VulkanUtils.MATRIX4X4_SIZE, VulkanUtils.INT_SIZE)); PushConstBuffer.slice(VulkanUtils.MATRIX4X4_SIZE, VulkanUtils.INT_SIZE));
} }
public void Resize(EngineInstance instance, VulkanContext VkCtx){ public void Resize(EngineInstance instance, VulkanContext VkCtx){
RenderInfo.free(); RenderInfo.free();
AttachmentInfoColour.free(); AttachmentInfoDepth.free();
MRTAttachments.CleanUp(VkCtx);
if(Deferred)Arrays.asList(AttachmentInfoColour).forEach(VkRenderingAttachmentInfo.Buffer::free);
else AttachmentInfoColour.free();
AttachmentColour.CleanUp(VkCtx); AttachmentColour.CleanUp(VkCtx);
AttachmentDepth.CleanUp(VkCtx); AttachmentDepth.CleanUp(VkCtx);
AttachmentInfoDepth.free(); CreateRenderAttachments(VkCtx);
AttachmentColour = CreateColourAttachment(VkCtx);
AttachmentDepth = CreateDepthAttachment(VkCtx);
AttachmentInfoColour = CreateColourAttachmentInfo(AttachmentColour, ClearValueColour);
AttachmentInfoDepth = CreateDepthAttachmentInfo(AttachmentDepth, ClearValueDepth);
RenderInfo = CreateRenderInfo(AttachmentColour, AttachmentInfoColour, AttachmentInfoDepth);
VulkanUtils.CopyMatrixToBuffer(VkCtx, BufferProjectionMatrix, instance.scene().GetProjection().GetProjectionMatrix(),0); VulkanUtils.CopyMatrixToBuffer(VkCtx, BufferProjectionMatrix, instance.scene().GetProjection().GetProjectionMatrix(),0);
} }
@ -378,6 +483,21 @@ public class SceneRender implements SceneRenderer {//dynamic rendering
descriptorSet.SetImageArray(device,imageViews,textureSampler,0); descriptorSet.SetImageArray(device,imageViews,textureSampler,0);
} }
private static VkRenderingInfo CreateDeferredRenderInfo(VulkanContext VkCtx, VkRenderingAttachmentInfo.Buffer ColourAttachmentInfo, VkRenderingAttachmentInfo DepthAttachmentInfo){
VkRenderingInfo Result = VkRenderingInfo.calloc();
SwapChain swapChain = VkCtx.GetSwapChain();
VkExtent2D Extent = swapChain.GetSwapChainExtent();
try(var MemStack = MemoryStack.stackPush()){
var RenderArea = VkRect2D.calloc(MemStack).extent(Extent);
Result.sType$Default()
.renderArea(RenderArea)
.layerCount(1)
.pColorAttachments(ColourAttachmentInfo)
.pDepthAttachment(DepthAttachmentInfo);
}
return Result;
}
private static VkRenderingInfo CreateRenderInfo(Attachment ColourAttachment, VkRenderingAttachmentInfo.Buffer ColourAttachmentInfo, VkRenderingAttachmentInfo DepthAttachmentInfo){ private static VkRenderingInfo CreateRenderInfo(Attachment ColourAttachment, VkRenderingAttachmentInfo.Buffer ColourAttachmentInfo, VkRenderingAttachmentInfo DepthAttachmentInfo){
VkRenderingInfo Result; VkRenderingInfo Result;
try(var MemStack = MemoryStack.stackPush()){ try(var MemStack = MemoryStack.stackPush()){
@ -394,23 +514,8 @@ public class SceneRender implements SceneRenderer {//dynamic rendering
} }
return Result; return Result;
} }
private static VkRenderingAttachmentInfo.Buffer[] CreateColourAttachmentsInfo(VulkanContext vulkanContext, VkClearValue CLearValue){
SwapChain swapChain = vulkanContext.GetSwapChain();
int ImageCount = swapChain.GetImageCount();
var result = new VkRenderingAttachmentInfo.Buffer[ImageCount];
for(int i = 0; i < ImageCount; i++){
var Attachments = VkRenderingAttachmentInfo.calloc(1)
.sType$Default()
.imageView(swapChain.GetVulkanImageView(i).GetVulkanImageView())
.imageLayout(VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR)
.loadOp(VK_ATTACHMENT_LOAD_OP_CLEAR)
.storeOp(VK_ATTACHMENT_STORE_OP_STORE)
.clearValue(CLearValue);
result[i] = Attachments;
}
return result;
}
public void cleanup(VulkanContext VkCtx){ public void cleanup(VulkanContext VkCtx){
VkPipeline.CleanUp(VkCtx); VkPipeline.CleanUp(VkCtx);
Arrays.asList(BufferViewMatrices).forEach(buffer -> buffer.cleanup(VkCtx)); Arrays.asList(BufferViewMatrices).forEach(buffer -> buffer.cleanup(VkCtx));
RenderInfo.free(); RenderInfo.free();
@ -418,6 +523,7 @@ public class SceneRender implements SceneRenderer {//dynamic rendering
AttachmentColour.CleanUp(VkCtx); AttachmentColour.CleanUp(VkCtx);
AttachmentDepth.CleanUp(VkCtx); AttachmentDepth.CleanUp(VkCtx);
AttachmentInfoDepth.free(); AttachmentInfoDepth.free();
MRTAttachments.CleanUp(VkCtx);
MemoryUtil.memFree(PushConstBuffer); MemoryUtil.memFree(PushConstBuffer);
ClearValueDepth.free(); ClearValueDepth.free();
ClearValueColour.free(); ClearValueColour.free();

View file

@ -2,6 +2,7 @@ package net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DisplayToScreen;
import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance; import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance;
import net.halbear.Terrain4J.EngineCore.Logic.Rendering.VulkanContext; import net.halbear.Terrain4J.EngineCore.Logic.Rendering.VulkanContext;
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Deferred.MultiRenderTargetAttachments;
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Images.Attachment; import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Images.Attachment;
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Images.TextureCache; import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Images.TextureCache;
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Pipeline; import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Pipeline;
@ -21,4 +22,6 @@ public interface SceneRenderer {
public void LoadMaterials(VulkanContext VkCtx, MaterialsCache materialsCache, TextureCache textureCache); public void LoadMaterials(VulkanContext VkCtx, MaterialsCache materialsCache, TextureCache textureCache);
public void cleanup(VulkanContext VkCtx); public void cleanup(VulkanContext VkCtx);
public Attachment GetAttachmentColour(); public Attachment GetAttachmentColour();
public MultiRenderTargetAttachments GetMRTAttachments();
public boolean GetCurrentDeferred();
} }

View file

@ -21,13 +21,21 @@ cap_main_to_tickrate=true
cap_fast_to_tickrate=true cap_fast_to_tickrate=true
#Renderer Properties #Renderer Properties
#this is for devices that can't render more than 64 textures
compatibility_mode=false
#Renderer Settings
#0 = Forward rendering
#1 = Deferred rendering
Renderer=0
AlphaToCoverage=false
DualPassRendering=true
#AA settings #AA settings
#0=No AA #0=No AA
#1=FXAA #1=FXAA
#2=MSAAx2 #2=MSAAx2
#3=MSAAx4 #3=MSAAx4
#4=MSAAx8 #4=MSAAx8
anti_alias_mode=1 anti_alias_mode=2
Debug_Shaders = false Debug_Shaders = false
ShaderRecompiling = true ShaderRecompiling = true
#Vulkan Debugging toggle #Vulkan Debugging toggle