Shadows, broke OpenGL, broke graphics settings, Exception raised when closing software

This commit is contained in:
Halbear 2026-08-30 01:06:23 +01:00
parent f7127e0878
commit 0d41f3e15b
36 changed files with 1187 additions and 219 deletions

View file

@ -9,8 +9,10 @@ import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.GUI.GuiRenderer;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.GUI.GuiTexture;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.DeferredRendering.LightRenderer;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.Images.Attachment;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.Images.TextureCache;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.PostProcessing.PostProcess;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Shadows.ShadowRenderer;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.VkModel.*;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.SpriteRendering.SpriteRenderer;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DeviceLayers.CommandBuffer;
@ -53,6 +55,7 @@ public class VulkanRenderer implements Renderer {
private final LightRenderer lightRenderer;
private final PostProcess PostProcessor;
private final SwapChainRender swapChainRender;
private final ShadowRenderer shadowRender;
private final GuiRenderer GuiRender;
private int CurrentFrame;
private final VulkanContext RendererContext;
@ -99,12 +102,17 @@ public class VulkanRenderer implements Renderer {
}
if(Deferred) {
sceneRender = new DeferredSceneRender(RendererContext, engineInstance);
lightRenderer = new LightRenderer(RendererContext, sceneRender.GetMRTAttachments().GetAllAttachments());
shadowRender = new ShadowRenderer(RendererContext);
List<Attachment> attachments = new ArrayList<>(sceneRender.GetMRTAttachments().GetColourAttachments());
attachments.add(shadowRender.getShadowAttachment());
lightRenderer = new LightRenderer(RendererContext, attachments);
PostProcessor = new PostProcess(RendererContext, lightRenderer.getAttachment());
} else{
sceneRender = new ForwardSceneRender(RendererContext);
PostProcessor = new PostProcess(RendererContext, sceneRender.GetAttachmentColour());
lightRenderer = null;
shadowRender = null;
}
spriteRenderer= new SpriteRenderer(engineInstance, RendererContext, PostProcessor.GetAttachment());
GuiRender = new GuiRenderer(engineInstance, RendererContext, GraphicsQueue, PostProcessor.GetAttachment());
@ -152,6 +160,7 @@ public class VulkanRenderer implements Renderer {
Logger.debug("Loaded {} models", Models.size());
sceneRender.LoadMaterials(RendererContext,materialsCache,textureCache);
shadowRender.loadMaterials(RendererContext, materialsCache, textureCache);
spriteRenderer.CompileSprites(RendererContext,modelsCache, textureCache);
spriteRenderer.LoadMaterials(RendererContext,materialsCache,textureCache);
GuiRender.LoadTextures(RendererContext,initData.GuiTextures(),textureCache);
@ -173,6 +182,7 @@ public class VulkanRenderer implements Renderer {
RendererContext.GetDevice().waitIdle();
Logger.debug("Waiting Vulkan Context");
sceneRender.cleanup(RendererContext);
if(shadowRender != null)shadowRender.cleanup(RendererContext);
if(lightRenderer != null)lightRenderer.cleanup(RendererContext);
PostProcessor.CleanUp(RendererContext);
swapChainRender.CleanUp(RendererContext);
@ -206,7 +216,9 @@ public class VulkanRenderer implements Renderer {
RecordingStart(CommandPool, CommandBuffer);
sceneRender.Render(engineInstance,RendererContext,CommandBuffer, modelsCache,materialsCache,CurrentFrame);
lightRenderer.render(engineInstance, RendererContext, CommandBuffer, sceneRender.GetMRTAttachments(), CurrentFrame);
shadowRender.render(engineInstance, RendererContext, CommandBuffer, modelsCache, materialsCache, CurrentFrame);
lightRenderer.render(engineInstance, RendererContext, CommandBuffer, sceneRender.GetMRTAttachments(), shadowRender.getShadowAttachment(), CurrentFrame,
shadowRender.getCascadeShadows(CurrentFrame));
PostProcessor.Render(RendererContext,CommandBuffer,lightRenderer.getAttachment());
spriteRenderer.Render(engineInstance,RendererContext,CommandBuffer,PostProcessor.GetAttachment(),modelsCache,CurrentFrame);
GuiRender.Render(RendererContext,CommandBuffer,CurrentFrame,PostProcessor.GetAttachment());
@ -280,7 +292,9 @@ public class VulkanRenderer implements Renderer {
engineInstance.scene().GetProjection().Resize(extend.width(),extend.height());
sceneRender.Resize(engineInstance,RendererContext);
if(Deferred) {
lightRenderer.resize(RendererContext, sceneRender.GetMRTAttachments().GetAllAttachments());
List<Attachment> attachments = new ArrayList<>(sceneRender.GetMRTAttachments().GetColourAttachments());
attachments.add(shadowRender.getShadowAttachment());
lightRenderer.resize(RendererContext, attachments);
PostProcessor.Resize(RendererContext, lightRenderer.getAttachment());
} else{
PostProcessor.Resize(RendererContext, sceneRender.GetAttachmentColour());

View file

@ -76,7 +76,7 @@ public class EngineConfig {
public boolean AlphaToCoverage = false;
public boolean CompatibilityMode = false;
public Renderer renderer = Renderer.Forward;
public int ShadowMapSize = 16;
public int ShadowMapSize = 4096;
public float Gamma = 0.8545f;
public int MaxVulkanCrashesAllowed = 10;
public boolean RenderCollisionMesh = true;
@ -322,7 +322,7 @@ public class EngineConfig {
zFarPlane = (Float.parseFloat(EngineConfigVar.getOrDefault("z_far_plane", 100.0f).toString()));
AAValue = (Integer.parseInt(EngineConfigVar.getOrDefault("anti_alias_mode", 1).toString()));
renderer = Integer.parseInt(EngineConfigVar.getOrDefault("Renderer", 1).toString()) == 0 ? Renderer.Forward: Renderer.Deferred;
ShadowMapSize = Integer.parseInt(EngineConfigVar.getOrDefault("ShadowMapSize", 16).toString());
ShadowMapSize = Integer.parseInt(EngineConfigVar.getOrDefault("ShadowMapSize", 4096).toString());
MaxVulkanCrashesAllowed = Integer.parseInt(EngineConfigVar.getOrDefault("MaxAllowedVulkanCrashes", 10).toString());
ServerPort = Integer.parseInt(EngineConfigVar.getOrDefault("server_port", 25565).toString());
CompatibilityMode = Boolean.parseBoolean(EngineConfigVar.getOrDefault("compatibility_mode", false).toString());
@ -385,6 +385,7 @@ public class EngineConfig {
EngineConfigVar.setProperty("MaxDescriptors","1000");
EngineConfigVar.setProperty("anti_alias_mode","1");
EngineConfigVar.setProperty("server","false");
EngineConfigVar.setProperty("ShadowMapSize","4096");
EngineConfigVar.setProperty("LoadingScreenLocation",LoadingScreenLocation);
EngineConfigVar.store(new FileWriter(path.toAbsolutePath().toString() + "/" + FILENAME), "created new properties file");
Logger.debug("Wrote New Config File [{}]", ConfigFile.getAbsolutePath());

View file

@ -1,6 +1,7 @@
package net.halbear.Terrain4J.EngineCore.Logic.Physics.RigidBody;
import net.halbear.Terrain4J.EngineCore.Logic.Physics.IPhysicsController;
import net.halbear.Terrain4J.EngineCore.Logic.Physics.StaticSpatialHashGrid;
import org.joml.Matrix3f;
import org.joml.Quaternionf;
import org.joml.Vector3f;
@ -80,6 +81,7 @@ public class RigidBody {
InverseMassKG = 0f;
InverseInertiaLocal.zero();
IsStatic = true;
StaticSpatialHashGrid.Insert(RigidBodyID, shape.GetWorldAABB());
} else {
InverseMassKG = 1.0f / mass;
IsStatic = false;

View file

@ -31,6 +31,18 @@ public class SpatialHashGrid {
}
}
public static Map<Long, List<String>> Cells(){
return Cells;
}
public static List<String> GetFromKey(long key){
return Cells.getOrDefault(key, Collections.emptyList());
}
public static List<String> GetAtXYZ(int x, int y, int z){
long key = HashCell(x, y, z);
return Cells.getOrDefault(key, Collections.emptyList());
}
private static long HashCell(int x, int y, int z) {
long xi = ((long) x) & 0x1FFFFFL;
long yi = ((long) y) & 0x1FFFFFL;

View file

@ -5,7 +5,7 @@ import org.joml.primitives.AABBf;
import java.util.*;
public class StaticSpatialHashGrid {
public static float CellSize = 16f;
public static float CellSize = 3f;
private static final Map<Long, List<String>> Cells = new HashMap<>();
@ -31,6 +31,19 @@ public class StaticSpatialHashGrid {
}
}
public static Map<Long, List<String>> Cells(){
return Cells;
}
public static List<String> GetFromKey(long key){
return Cells.getOrDefault(key, Collections.emptyList());
}
public static List<String> GetAtXYZ(int x, int y, int z){
long key = HashCell(x, y, z);
return Cells.getOrDefault(key, Collections.emptyList());
}
private static long HashCell(int x, int y, int z) {
long xi = ((long) x) & 0x1FFFFFL;
long yi = ((long) y) & 0x1FFFFFL;

View file

@ -117,6 +117,23 @@ public class WorldPhysicsManager {
Set<String> testedPairs = new HashSet<>();
// SpatialHashGrid.Cells().forEach((key, bucket)->{
// int size = bucket.size();
// for (int i = 0; i < size; i++) {
// RigidBody a = RigidBody.RigidBodyRegister.get(bucket.get(i));
// if (a == null) continue;
// for (int j = i + 1; j < size; j++) {
// RigidBody b = RigidBody.RigidBodyRegister.get(bucket.get(j));
// if (b == null || a == b) continue;
// TryResolve(a, b, worldBounds, testedPairs);
// }
// StaticSpatialHashGrid.GetFromKey(key).forEach((id)->{
// RigidBody b = RigidBody.RigidBodyRegister.get(id);
// if (b == null || a == b) return;
// TryResolve(a, b, worldBounds, testedPairs);
// });
// }
// });
for (List<String> bucket : SpatialHashGrid.Buckets()) {
int size = bucket.size();
for (int i = 0; i < size; i++) {

View file

@ -47,13 +47,12 @@ import org.tinylog.Logger;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import static org.lwjgl.glfw.GLFW.GLFW_KEY_ESCAPE;
import static org.lwjgl.glfw.GLFW.GLFW_KEY_F3;
import static org.lwjgl.glfw.GLFW.*;
public class GameCore implements GameLogic {
private static final float MOUSE_SENSITIVITY = 0.1f;
private static final float MOVEMENT_SPEED = 0.01f;
private static final float MOVEMENT_SPEED = 0.1f;
public static boolean LoadingLevel = false;
private Vector2f LastMousePos = new Vector2f(0,0);
@ -99,19 +98,31 @@ public class GameCore implements GameLogic {
public InitData Initialise(EngineInstance engineInstance) {
Scene scene = (Scene) engineInstance.scene();
List<ModelData> models = new ArrayList<>();
ModelData SponzaData = ModelLoader.LoadModel("resources/models/Cafe/exterior.json");
List<MaterialData> SponzaMaterial = ModelLoader.LoadMaterials("resources/models/Cafe/exterior_mat.json");
ModelData SponzaData1 = ModelLoader.LoadModel("resources/models/Cafe/interior.json");
List<MaterialData> SponzaMaterial1= ModelLoader.LoadMaterials("resources/models/Cafe/interior_mat.json");
scene.AddActor(new Actor3D("Sponza1", SponzaData.ID(), new Vector3f(0,0f,-5f)).SetScale(0.1f));
scene.AddActor(new Actor3D("Sponza2", SponzaData1.ID(), new Vector3f(0,0f,-5f)).SetScale(0.1f));
List<MaterialData> materials = new ArrayList<>();
// ModelData SponzaData = ModelLoader.LoadModel("resources/models/Cafe/exterior.json");
// List<MaterialData> SponzaMaterial = ModelLoader.LoadMaterials("resources/models/Cafe/exterior_mat.json");
// ModelData SponzaData1 = ModelLoader.LoadModel("resources/models/Cafe/interior.json");
// List<MaterialData> SponzaMaterial1= ModelLoader.LoadMaterials("resources/models/Cafe/interior_mat.json");
// scene.AddActor(new Actor3D("Sponza1", SponzaData.ID(), new Vector3f(0,0f,-5f)).SetScale(0.1f));
// scene.AddActor(new Actor3D("Sponza2", SponzaData1.ID(), new Vector3f(0,0f,-5f)).SetScale(0.1f));
// ModelData treeModel = ModelLoader.LoadModel("resources/models/tree/tree.json");
// models.add(treeModel);
// Actor3D treeEntity = new Actor3D("treeEntity", treeModel.ID(), new Vector3f(0.0f, 0.0f, 0.0f));
// treeEntity.SetScale(0.05f);
// scene.AddActor(treeEntity);
// materials.addAll(ModelLoader.LoadMaterials("resources/models/tree/tree_mat.json"));
// ModelData treeModel = ModelLoader.LoadModel("resources/models/Forest/forest.json");
// models.add(treeModel);
// Actor3D treeEntity = new Actor3D("treeEntity", treeModel.ID(), new Vector3f(0.0f, 0.0f, 0.0f));
// treeEntity.SetScale(10f);
// scene.AddActor(treeEntity);
// materials.addAll(ModelLoader.LoadMaterials("resources/models/Forest/forest_mat.json"));
MelonaData = ModelLoader.LoadModel("resources/models/cube/Cube.json");
CubeModelID = MelonaData.ID();
List<MaterialData> MelonaMat = ModelLoader.LoadMaterials("resources/models/cube/Cube_mat.json");
var CollisionVisualisationData = ModelLoader.LoadModel("resources/models/VisualCollision/CollisionCube.json");
VisualisedCollisionActor3D.CollisionCubeModelID = CollisionVisualisationData.ID();
List<MaterialData> CollisionVisualisationMat = ModelLoader.LoadMaterials("resources/models/VisualCollision/CollisionCube_mat.json");
List<MaterialData> materials = new ArrayList<>();
var Melona = ModelLoader.LoadModel("resources/models/melona/melona.json");
List<MaterialData> MelonaMaterial = ModelLoader.LoadMaterials("resources/models/melona/melona_mat.json");
@ -147,10 +158,10 @@ public class GameCore implements GameLogic {
}
boolean createOfflinePlayer = !PrimaryRuntime.IsServer && !ClientSideNetworkUtils.Connected;
materials.addAll(SponzaMaterial);
materials.addAll(SponzaMaterial1);
models.add(SponzaData);
models.add(SponzaData1);
// materials.addAll(SponzaMaterial);
// materials.addAll(SponzaMaterial1);
// models.add(SponzaData);
// models.add(SponzaData1);
materials.addAll(MelonaMat);
materials.addAll(CollisionVisualisationMat);
materials.addAll(MelonaMaterial);
@ -179,47 +190,50 @@ public class GameCore implements GameLogic {
guiTextures.add(guiTexture);
}
//scene.GetLightingManager().GetAmbientLightColour().set(1.0f, 0.9f, 0.75f);
//scene.GetLightingManager().SetAmbientLightIntensity(0.6f);
scene.GetLightingManager().GetAmbientLightColour().set(0.3f, 0.35f, 0.5f);
scene.GetLightingManager().SetAmbientLightIntensity(0.01f);
// SkyLight = new Light(new Vector3f(1.5f, 1.20f, 1.0f),new Vector3f(0.0f, -1.0f, 0.3f), true, 2.00f);
SkyLight = new Light(new Vector3f(0.25f, 1.0f, 1.5f),new Vector3f(0.0f, -1.0f, 0.0f), true, 1.70f);
scene.GetLightingManager().GetAmbientLightColour().set(1.0f, 0.9f, 0.75f);
scene.GetLightingManager().SetAmbientLightIntensity(0.3f);
// scene.GetLightingManager().GetAmbientLightColour().set(0.3f, 0.35f, 0.5f);
// scene.GetLightingManager().SetAmbientLightIntensity(0.075f);
//
SkyLight = new Light(new Vector3f(1.5f, 1.20f, 1.0f),new Vector3f(0.0f, -1.0f, 0.3f), true, 2.00f);
// SkyLight = new Light(new Vector3f(0.25f, 1.0f, 1.5f),new Vector3f(0.0f, -1.0f, 0.0f), true, 6.0f);
SkyLight.SetType(Light.LightType.Directional);
List<ILight> lights = new ArrayList<>();
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-433, 445f, -424f).div(10.0f),false,3000.0f+ (float)(Math.random() * 100.0)));
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-210, 445f, 460f).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-966, 445f, 204f).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-176, 445f, 1000f).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(777, 445f, 858).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(376, 445f, -2136).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,2.0f),new Vector3f(2163, 445f, 1880).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(3334, 445f, 2405).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(3509, 445f, 1825).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(3877, 445f, 3378).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(4925, 445f, 3430).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-2083, 445f, -1826).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
// lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-433, 445f, -424f).div(10.0f),false,3000.0f+ (float)(Math.random() * 100.0)));
// lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-210, 445f, 460f).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
// lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-966, 445f, 204f).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
// lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-176, 445f, 1000f).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
// lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(777, 445f, 858).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
// lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(376, 445f, -2136).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
// lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,2.0f),new Vector3f(2163, 445f, 1880).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
// lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(3334, 445f, 2405).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
// lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(3509, 445f, 1825).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
// lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(3877, 445f, 3378).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
// lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(4925, 445f, 3430).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
// lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-2083, 445f, -1826).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
//
// lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(2076, 410, 1272).div(10.0f),false,100.0f));
// lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(2446, 465, 2303).div(10.0f),false,100.0f));
// lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-842, 410, -1141).div(10.0f),false,100.0f));
// lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-207, 410, -1830).div(10.0f),false,100.0f));
// lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(899, 460, -2015).div(10.0f),false,100.0f));
// lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(1775, 460, -3448).div(10.0f),false,100.0f));
// lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(1800, 460, -4154).div(10.0f),false,1000.0f));
// lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-1727, 410, -387).div(10.0f),false,100.0f));
// lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-1198, 410, -964).div(10.0f),false,100.0f));
// lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-1778, 410, -1502).div(10.0f),false,100.0f));
// lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-2692, 333, -2109).div(10.0f),false,100.0f));
// lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-2849, 333, -1724).div(10.0f),false,100.0f));
// lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-2019, 410, -729).div(10.0f),false,100.0f));
// lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-1727, 410, -389).div(10.0f),false,100.0f));
// lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-1337, 410, 122).div(10.0f),false,100.0f));
//
//
// lights.add(new Light(new Vector3f(0.75f,2.0f,0.75f),new Vector3f(1086, 425, -3375).div(10.0f),false,500.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(2076, 410, 1272).div(10.0f),false,100.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(2446, 465, 2303).div(10.0f),false,100.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-842, 410, -1141).div(10.0f),false,100.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-207, 410, -1830).div(10.0f),false,100.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(899, 460, -2015).div(10.0f),false,100.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(1775, 460, -3448).div(10.0f),false,100.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(1800, 460, -4154).div(10.0f),false,1000.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-1727, 410, -387).div(10.0f),false,100.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-1198, 410, -964).div(10.0f),false,100.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-1778, 410, -1502).div(10.0f),false,100.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-2692, 333, -2109).div(10.0f),false,100.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-2849, 333, -1724).div(10.0f),false,100.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-2019, 410, -729).div(10.0f),false,100.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-1727, 410, -389).div(10.0f),false,100.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-1337, 410, 122).div(10.0f),false,100.0f));
lights.add(new Light(new Vector3f(0.75f,2.0f,0.75f),new Vector3f(1086, 425, -3375).div(10.0f),false,500.0f));
//lights.add(new Light(new Vector3f(3.0f,2.25f,0.0f),new Vector3f(350.0f, 1525.0f, -420.0f),false,4000.0f));
//lights.add(new Light(new Vector3f(3.0f,2.25f,0.0f),new Vector3f(400.0f, 1570.0f, -350.0f),false,1000.0f));
lights.add(SkyLight);
ILight[] lightArr = new ILight[lights.size()];
@ -232,7 +246,12 @@ public class GameCore implements GameLogic {
}
//if(PrimaryRuntime.IsServer) {
permutation.GeneratePermutationArray(5783904701859L);
//GenerateChunk(new Vector3i(0, 0, 0), 16);
for(int x = -1; x < 2; x++){
for(int y = -1; y < 2; y++){
GenerateChunk(new Vector3i(x, 0, y), 16);
}
}
for(int i = 0; i < 20; i++){
SpawnNewActor(engineInstance, new Vector3f(-5 + (float)Math.random() * 10,10 + (float)Math.random() * 10, -5 + (float)Math.random() * 10), new Vector3f(0, 0, 0), new Vector3f(1, 1, 1));
}
@ -241,6 +260,18 @@ public class GameCore implements GameLogic {
Settings.UsernameBuffer.set("Player");
return new InitData(models,materials,guiTextures);
}
public static float lightAngle = 70;
private void updateDirLight() {
float zValue = (float) Math.cos(Math.toRadians(lightAngle));
float yValue = (float) Math.sin(Math.toRadians(lightAngle));
Vector3f lightDirection = SkyLight.GetPosition();
lightDirection.x = 0;
lightDirection.y = yValue;
lightDirection.z = zValue;
lightDirection.normalize();
SkyLight.GetPosition().set(lightDirection);
}
public void Reset(){
EngineInstance instance = PrimaryRuntime.GetEngineInstance();
@ -465,6 +496,8 @@ public class GameCore implements GameLogic {
}
if(CumulativeFrameTime >= 16_000_000) {
HandleGui(engineInstance, FrameDiffNanoSeconds);
// lightAngle = (lightAngle + 0.15f) % 360;
// updateDirLight();
CumulativeFrameTime = 0;
}
}
@ -479,6 +512,14 @@ public class GameCore implements GameLogic {
if(input.keySinglePress(GLFW_KEY_F3)){
Scene.GUI_MODE = (Scene.GUI_MODE + 1) % 2;
}
if(input.keyPressed(GLFW_KEY_UP)){
lightAngle = (lightAngle + 0.5f) % 360;
updateDirLight();
}
if(input.keyPressed(GLFW_KEY_DOWN)){
lightAngle = (lightAngle - 0.5f) % 360;
updateDirLight();
}
if (input.keySinglePress(GLFW_KEY_ESCAPE)) {
StartMenuActive = !StartMenuActive;
StartMenu.GameStarted = StartMenuActive;

View file

@ -10,6 +10,8 @@ public class Light implements ILight{
public void SetType(LightType type) {
this.type = type;
if(type == LightType.Directional)
Directional = true;
}
public enum LightType{

View file

@ -156,7 +156,7 @@ public class Scene implements IScene {
if(!PrimaryRuntime.IsServer && !RenderThread.Headless) {
GUIReg.put("PerformanceOverlay",new PerformanceOverlay());
// ActiveGUIs.add("PerformanceOverlay");
ActiveGUIs.add("PerformanceOverlay");
GUIReg.put("ChatLog",new GameChat());
ActiveGUIs.add("ChatLog");
}

View file

@ -7,7 +7,7 @@ import java.util.Arrays;
import java.util.List;
public class SceneLightingManager implements ISceneLightingManager {
public static int SHADOW_MAP_CASCADE_COUNT = 10;
public static int SHADOW_MAP_CASCADE_COUNT = 6;
public static int MaxLights;
private Vector3f AmbientLightingColour;
private float AmbientLightIntensity;

View file

@ -18,8 +18,8 @@ public class Project3D {
this.FOV = FOV;
OriginalNear = zNear;
OriginalFar = zFar;
this.ZFarPlane = EngineConfig.getInstance().GetRenderingAPI() == EngineConfig.RenderAPI.OpenGL ? zNear : zFar;
this.ZNearPlane = EngineConfig.getInstance().GetRenderingAPI() == EngineConfig.RenderAPI.OpenGL ? zFar : zNear;
this.ZFarPlane = zFar;
this.ZNearPlane = zNear;
ProjectionMatrix = new Matrix4f();
Resize(Width, Height);
LastWidth = Width;
@ -27,8 +27,8 @@ public class Project3D {
}
public void SetFarPlanes(){
ZFarPlane = EngineConfig.getInstance().GetRenderingAPI() == EngineConfig.RenderAPI.OpenGL ? OriginalNear : OriginalFar;
ZNearPlane = EngineConfig.getInstance().GetRenderingAPI() == EngineConfig.RenderAPI.OpenGL ? OriginalFar : OriginalNear;
ZFarPlane =OriginalFar;
ZNearPlane = OriginalNear;
Resize(LastWidth,LastHeight);
}

View file

@ -13,6 +13,8 @@ import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.I
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.Pipeline;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.PipelineBuildInfo;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Shader.*;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Shadows.CascadeData;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Shadows.CascadeShadows;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DeviceLayers.CommandBuffer;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DeviceLayers.Device;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DisplayToScreen.ImageView;
@ -31,15 +33,18 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static org.lwjgl.util.vma.Vma.VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT;
import static org.lwjgl.util.vma.Vma.VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE;
import static org.lwjgl.vulkan.VK10.*;
import static org.lwjgl.vulkan.VK13.*;
public class LightRenderer {
private static final int COLOUR_FORMAT = VK_FORMAT_R32G32B32A32_SFLOAT;
private static final String DESC_ID_ATT = "LIGHT_DESC_ID_ATT";
private static final String DESC_ID_SHADOW_MATRICES = "LIGHT_DESC_ID_SHADOW_MATRICES";
private static final String DESC_ID_LIGHTS = "LIGHT_DESC_ID_LIGHTS";
private static final String DESC_ID_SCENE = "LIGHT_DESC_ID_SCENE ";
private static final String FRAGMENT_SHADER_FILE_GLSL = "resources/EngineResources/shaders/lighting_frag.glsl";
private static final String FRAGMENT_SHADER_FILE_GLSL = "resources/EngineResources/shaders/lighting_with_shadows_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";
@ -53,8 +58,10 @@ public class LightRenderer {
private VkRenderingInfo RenderInfo;
private final VulkanBuffer[] LightBuffer;
private final VulkanBuffer[] SceneBuffer;
private final LightSpecConsts lightSpecConsts;
private final DescriptorSetLayout SceneDescriptorSetLayout;
private final DescriptorSetLayout StorageDescriptorSetLayout;
private final VulkanBuffer[] shadowMatrices;
public LightRenderer(VulkanContext VkCtx, List<Attachment> attachments){
ClearValueColour = VkClearValue.calloc().color(
@ -64,18 +71,18 @@ public class LightRenderer {
AttachmentInfoColour = CreateColourAttachmentInfo(AttachmentColour, ClearValueColour);
RenderInfo = CreateRenderInfo(AttachmentColour, AttachmentInfoColour);
ShaderModule[] shaderModules = CreateShaderModules(VkCtx);
lightSpecConsts = new LightSpecConsts();
ShaderModule[] shaderModules = CreateShaderModules(VkCtx, lightSpecConsts);
var textureSamplerInfo = new TextureSamplerInfo(VK_SAMPLER_ADDRESS_MODE_REPEAT,
VK_BORDER_COLOR_INT_OPAQUE_BLACK, 1, true);
textureSampler = new TextureSampler(VkCtx, textureSamplerInfo);
int numAttachments = attachments.size();
DescriptorSetLayout.LayoutInformation[] descSetLayouts = new DescriptorSetLayout.LayoutInformation[numAttachments];
for (int i = 0; i < numAttachments; i++) {
DescriptorSetLayout.LayoutInformation[] descSetLayouts = new DescriptorSetLayout.LayoutInformation[numAttachments + 1];
for (int i = 0; i < numAttachments + 1; i++) {
descSetLayouts[i] = new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, i, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
}
AttachmentDescriptorSetLayout = new DescriptorSetLayout(VkCtx, descSetLayouts);
CreateAttachmentDescriptorSet(VkCtx, AttachmentDescriptorSetLayout, attachments, textureSampler);
StorageDescriptorSetLayout = new DescriptorSetLayout(VkCtx, new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 0, 1,
@ -86,16 +93,32 @@ public class LightRenderer {
SceneDescriptorSetLayout = new DescriptorSetLayout(VkCtx, new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0, 1,
VK_SHADER_STAGE_FRAGMENT_BIT));
buffSize = VulkanUtils.VEC3_SIZE * 2 + VulkanUtils.FLOAT_SIZE + VulkanUtils.INT_SIZE;
buffSize = VulkanUtils.VEC3_SIZE * 2 + VulkanUtils.FLOAT_SIZE + VulkanUtils.INT_SIZE + VulkanUtils.MATRIX4X4_SIZE;
SceneBuffer = VulkanUtils.CreateHostVisibleBuffers(VkCtx, buffSize, VulkanUtils.MAX_IN_FLIGHT,
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, DESC_ID_SCENE, SceneDescriptorSetLayout);
shadowMatrices = CreateShadowMatrixBuffers(VkCtx, StorageDescriptorSetLayout);
pipeline = createPipeline(VkCtx, shaderModules, new DescriptorSetLayout[]{AttachmentDescriptorSetLayout, StorageDescriptorSetLayout,
SceneDescriptorSetLayout});
StorageDescriptorSetLayout, SceneDescriptorSetLayout});
Logger.debug("Light Renderer Pipeline -> [{}]",pipeline.GetVulkanPipeline());
Arrays.asList(shaderModules).forEach(s -> s.CleanUp(VkCtx));
}
private static VulkanBuffer[] CreateShadowMatrixBuffers(VulkanContext vkCtx, DescriptorSetLayout layout) {
int numBuffs = VulkanUtils.MAX_IN_FLIGHT;
VulkanBuffer[] buffers = new VulkanBuffer[numBuffs];
Device device = vkCtx.GetDevice();
DescriptorSet[] descSets = vkCtx.GetDescriptorAllocator().AddDescriptorSets(device, DESC_ID_SHADOW_MATRICES, numBuffs, layout);
for (int i = 0; i < numBuffs; i++) {
long buffSize = (long) (VulkanUtils.MATRIX4X4_SIZE + VulkanUtils.VEC4_SIZE) * SceneLightingManager.SHADOW_MAP_CASCADE_COUNT;
buffers[i] = new VulkanBuffer(vkCtx, buffSize,
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE,
VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
descSets[i].SetBuffer(device, buffers[i], buffers[i].GetRequestedSize(),
layout.GetLayoutInfo().Binding(), layout.GetLayoutInfo().DescriptorType());
}
return buffers;
}
private static void CreateAttachmentDescriptorSet(VulkanContext VkCtx, DescriptorSetLayout descSetLayout, List<Attachment> attachments,
TextureSampler sampler) {
DescriptorAllocator descAllocator = VkCtx.GetDescriptorAllocator();
@ -110,7 +133,7 @@ public class LightRenderer {
SwapChain swapChain = VkCtx.GetSwapChain();
VkExtent2D swapChainExtent = swapChain.GetSwapChainExtent();
return new Attachment(VkCtx, swapChainExtent.width(), swapChainExtent.height(),
COLOUR_FORMAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
COLOUR_FORMAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,1);
}
private static VkRenderingAttachmentInfo.Buffer CreateColourAttachmentInfo(Attachment attachment, VkClearValue clearValue) {
@ -153,19 +176,19 @@ public class LightRenderer {
return result;
}
private static ShaderModule[] CreateShaderModules(VulkanContext VkCtx) {
private static ShaderModule[] CreateShaderModules(VulkanContext VkCtx, LightSpecConsts lightSpecConsts) {
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),
new ShaderModule(VkCtx, VK_SHADER_STAGE_FRAGMENT_BIT, FRAGMENT_SHADER_FILE_SPV, lightSpecConsts.getSpecInfo()),
};
}
public void render(EngineInstance engineInstance, VulkanContext VkCtx, CommandBuffer cmdBuffer, MultiRenderTargetAttachments mrtAttachments,int CurrentFrame) {
public void render(EngineInstance engineInstance, VulkanContext VkCtx, CommandBuffer cmdBuffer, MultiRenderTargetAttachments mrtAttachments,Attachment shadowAttachment, int CurrentFrame, CascadeShadows cascadeShadows) {
try (var stack = MemoryStack.stackPush()) {
VkCommandBuffer cmdHandle = cmdBuffer.GetVulkanCommandBuffer();
@ -176,7 +199,6 @@ public class LightRenderer {
VK_IMAGE_ASPECT_COLOR_BIT);
List<Attachment> attachments = mrtAttachments.GetColourAttachments();
// Logger.debug("Colour Attachments -> \n1: [{}]\n 2:[{}] \n3:[{}]\n 4:[{}]",attachments.get(0),attachments.get(1),attachments.get(2),attachments.get(3));
int numAttachments = attachments.size();
for (int i = 0; i < numAttachments; i++) {
Attachment attachment = attachments.get(i);
@ -187,11 +209,19 @@ public class LightRenderer {
VK_IMAGE_ASPECT_COLOR_BIT);
}
VulkanUtils.ImageBarrier(stack, cmdHandle, mrtAttachments.GetDepthAttachment().GetVkImage().getVulkanImage(),
VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
VK_IMAGE_LAYOUT_DEPTH_STENCIL_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);
VulkanUtils.ImageBarrier(stack, cmdHandle, shadowAttachment.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);
UpdateCascadeShadowMatrices(VkCtx, cascadeShadows, CurrentFrame);
vkCmdBeginRendering(cmdHandle, RenderInfo);
vkCmdBindPipeline(cmdHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.GetVulkanPipeline());
@ -215,10 +245,11 @@ public class LightRenderer {
vkCmdSetScissor(cmdHandle, 0, scissor);
DescriptorAllocator descAllocator = VkCtx.GetDescriptorAllocator();
LongBuffer descriptorSets = stack.mallocLong(3)
LongBuffer descriptorSets = stack.mallocLong(4)
.put(0, descAllocator.GetDescriptorSet(DESC_ID_ATT).GetVkDescriptorSet())
.put(1, descAllocator.GetDescriptorSet(DESC_ID_LIGHTS, CurrentFrame).GetVkDescriptorSet())
.put(2, descAllocator.GetDescriptorSet(DESC_ID_SCENE, CurrentFrame).GetVkDescriptorSet());
.put(2, descAllocator.GetDescriptorSet(DESC_ID_SHADOW_MATRICES, CurrentFrame).GetVkDescriptorSet())
.put(3, descAllocator.GetDescriptorSet(DESC_ID_SCENE, CurrentFrame).GetVkDescriptorSet());
IScene scene = engineInstance.scene();
UpdateSceneInfo(VkCtx, scene, CurrentFrame);
UpdateLights(VkCtx, scene, CurrentFrame);
@ -231,6 +262,22 @@ public class LightRenderer {
}
}
private void UpdateCascadeShadowMatrices(VulkanContext vkCtx, CascadeShadows cascadeShadows, int currentFrame) {
VulkanBuffer buff = shadowMatrices[currentFrame];
long mappedMemory = buff.MapMemory(vkCtx);
ByteBuffer dataBuff = MemoryUtil.memByteBuffer(mappedMemory, (int) buff.GetRequestedSize());
int offset = 0;
List<CascadeData> cascadeDataList = cascadeShadows.GetCascadeData();
int numCascades = cascadeDataList.size();
for (int i = 0; i < numCascades; i++) {
CascadeData cascadeData = cascadeDataList.get(i);
cascadeData.GetProjViewMatrix().get(offset, dataBuff);
dataBuff.putFloat(offset + VulkanUtils.MATRIX4X4_SIZE, cascadeData.GetSplitDistance());
offset += VulkanUtils.MATRIX4X4_SIZE + VulkanUtils.VEC4_SIZE;
}
buff.UnMapMemory(vkCtx);
}
public void UpdateSceneInfo(VulkanContext VkCtx, IScene scene, int CurrentFrame){
VulkanBuffer buffer = SceneBuffer[CurrentFrame];
long MappedMemory = buffer.MapMemory(VkCtx);
@ -249,6 +296,10 @@ public class LightRenderer {
ILight[] lights = scene.GetLightingManager().GetLights();
int LightCount = lights != null ? lights.length : 0;
dataBuffer.putInt(Offset, LightCount);
Offset += VulkanUtils.INT_SIZE;
scene.GetCamera().GetViewMatrix().get(Offset, dataBuffer);
buffer.UnMapMemory(VkCtx);
}
public void UpdateLights(VulkanContext VkCtx, IScene scene, int CurrentFrame){
@ -291,11 +342,13 @@ public class LightRenderer {
public void cleanup(VulkanContext VkCtx) {
StorageDescriptorSetLayout.CleanUp(VkCtx);
Arrays.asList(LightBuffer).forEach(b -> b.cleanup(VkCtx));
Arrays.asList(shadowMatrices).forEach(b -> b.cleanup(VkCtx));
SceneDescriptorSetLayout.CleanUp(VkCtx);
Arrays.asList(SceneBuffer).forEach(b -> b.cleanup(VkCtx));
pipeline.CleanUp(VkCtx);
AttachmentDescriptorSetLayout.CleanUp(VkCtx);
textureSampler.CleanUp(VkCtx);
lightSpecConsts.cleanup();
RenderInfo.free();
AttachmentColour.CleanUp(VkCtx);
AttachmentInfoColour.free();

View file

@ -0,0 +1,56 @@
package net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.DeferredRendering;
import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig;
import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance;
import net.halbear.Terrain4J.EngineCore.Main.Scene.SceneLightingManager;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Util.VulkanUtils;
import org.lwjgl.system.MemoryUtil;
import org.lwjgl.vulkan.VkSpecializationInfo;
import org.lwjgl.vulkan.VkSpecializationMapEntry;
import java.nio.ByteBuffer;
public class LightSpecConsts {
private final ByteBuffer data;
private final VkSpecializationMapEntry.Buffer specEntryMap;
private final VkSpecializationInfo specInfo;
public LightSpecConsts() {
var engCfg = EngineConfig.getInstance();
data = MemoryUtil.memAlloc(VulkanUtils.INT_SIZE * 2);
data.putInt(SceneLightingManager.SHADOW_MAP_CASCADE_COUNT);
data.putInt(engCfg.DebugShaders() ? 1 : 0);
data.flip();
specEntryMap = VkSpecializationMapEntry.calloc(2);
int offset = 0;
int pos = 0;
int size = VulkanUtils.INT_SIZE;
specEntryMap.get(pos)
.constantID(pos)
.size(size)
.offset(offset);
offset += size;
pos++;
size = VulkanUtils.INT_SIZE;
specEntryMap.get(pos)
.constantID(pos)
.size(size)
.offset(offset);
specInfo = VkSpecializationInfo.calloc();
specInfo.pData(data)
.pMapEntries(specEntryMap);
}
public void cleanup() {
MemoryUtil.memFree(specEntryMap);
specInfo.free();
MemoryUtil.memFree(data);
}
public VkSpecializationInfo getSpecInfo() {
return specInfo;
}
}

View file

@ -28,18 +28,18 @@ public class MultiRenderTargetAttachments {
ColourAttachments = new ArrayList<>();
//Position
var Attachment = new Attachment(VkCtx, Width, Height, POSITION_FORMAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
var Attachment = new Attachment(VkCtx, Width, Height, POSITION_FORMAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 1);
ColourAttachments.add(Attachment);
//albedo
Attachment = new Attachment(VkCtx, Width, Height, ALBEDO_FORMAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
Attachment = new Attachment(VkCtx, Width, Height, ALBEDO_FORMAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 1);
ColourAttachments.add(Attachment);
//Normals
Attachment = new Attachment(VkCtx, Width, Height, NORMAL_FORMAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
Attachment = new Attachment(VkCtx, Width, Height, NORMAL_FORMAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 1);
ColourAttachments.add(Attachment);
//PBR
Attachment = new Attachment(VkCtx, Width, Height, PBR_FORMAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
Attachment = new Attachment(VkCtx, Width, Height, PBR_FORMAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 1);
ColourAttachments.add(Attachment);
DepthAttachment = new Attachment(VkCtx, Width, Height, DEPTH_FORMAT, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT);
DepthAttachment = new Attachment(VkCtx, Width, Height, DEPTH_FORMAT, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, 1);
}
public int GetWidth(){return Width;}

View file

@ -67,10 +67,11 @@ public class DefaultPipeline implements Pipeline {
.viewportCount(1)
.scissorCount(1);
var RasterizationStateCreateInfo = VkPipelineRasterizationStateCreateInfo.calloc(MemStack)
.sType(VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO)
.sType$Default()
.polygonMode(VK_POLYGON_MODE_FILL)
.cullMode(VK_CULL_MODE_NONE)
.frontFace(VK_FRONT_FACE_CLOCKWISE)
.depthClampEnable(BuildInfo.DepthClamp())
.lineWidth(1.0f);
int sampleCount = EngineConfig.getInstance().GetRenderSampleCount();
var MultisampleStateCreateInfo = VkPipelineMultisampleStateCreateInfo.calloc(MemStack)
@ -88,7 +89,7 @@ public class DefaultPipeline implements Pipeline {
.sType(VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO)
.depthTestEnable(BuildInfo.GetDepthTest())
.depthWriteEnable(BuildInfo.performDepthWrite())
.depthCompareOp(VK_COMPARE_OP_GREATER_OR_EQUAL)
.depthCompareOp(VK_COMPARE_OP_LESS_OR_EQUAL)
.depthBoundsTestEnable(false)
.stencilTestEnable(false);
}

View file

@ -9,24 +9,85 @@ public class Attachment {
private final Image VkImage;
private final ImageView VkImageView;
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, boolean MultiSamples){
var ImageData = new Image.ImageData().Width(Width).Height(Height).Format(Format).SampleCount(EngineConfig.getInstance().GetRenderSampleCount());
int AspectMask = 0;
if((Usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) > 0){
AspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
int aspectMask = 0;
if ((Usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) > 0) {
aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
ImageData.Usage(Usage | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
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;
}
int layers = 1;
if (layers > 0) {
ImageData.ArrayLayers(layers);
}
VkImage = new Image(VkCtx, ImageData);
var ImageViewData = new ImageView.ImageViewData().Format(VkImage.GetFormat()).AspectMask(AspectMask);
VkImageView = new ImageView(VkCtx.GetDevice(), VkImage.getVulkanImage(), ImageViewData,DepthAttachment);
var imageViewData = new ImageView.ImageViewData().Format(VkImage.GetFormat()).AspectMask(aspectMask);
if (layers > 1) {
imageViewData.ViewType(VK_IMAGE_VIEW_TYPE_2D_ARRAY);
imageViewData.LayerCount(layers);
}
VkImageView = new ImageView(VkCtx.GetDevice(), VkImage.getVulkanImage(), imageViewData, DepthAttachment);
}
public Attachment(VulkanContext VkCtx, int Width, int Height, int Format, int Usage){
var ImageData = new Image.ImageData().Width(Width).Height(Height).Format(Format).SampleCount(VK_SAMPLE_COUNT_1_BIT);
int aspectMask = 0;
if ((Usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) > 0) {
aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
ImageData.Usage(Usage | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
DepthAttachment = false;
}
if ((Usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) > 0) {
ImageData.Usage(Usage | VK_IMAGE_USAGE_SAMPLED_BIT);
aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
DepthAttachment = true;
}
int layers = 1;
if (layers > 0) {
ImageData.ArrayLayers(layers);
}
VkImage = new Image(VkCtx, ImageData);
var imageViewData = new ImageView.ImageViewData().Format(VkImage.GetFormat()).AspectMask(aspectMask);
if (layers > 1) {
imageViewData.ViewType(VK_IMAGE_VIEW_TYPE_2D_ARRAY);
imageViewData.LayerCount(layers);
}
VkImageView = new ImageView(VkCtx.GetDevice(), VkImage.getVulkanImage(), imageViewData, DepthAttachment);
}
public Attachment(VulkanContext VkCtx, int Width, int Height, int Format, int Usage,int layers){
var ImageData = new Image.ImageData().Width(Width).Height(Height).Format(Format).SampleCount(VK_SAMPLE_COUNT_1_BIT);
int aspectMask = 0;
if ((Usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) > 0) {
aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
ImageData.Usage(Usage | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
DepthAttachment = false;
}
if ((Usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) > 0) {
ImageData.Usage(Usage | VK_IMAGE_USAGE_SAMPLED_BIT);
aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
DepthAttachment = true;
}
if (layers > 0) {
ImageData.ArrayLayers(layers);
}
VkImage = new Image(VkCtx, ImageData);
var imageViewData = new ImageView.ImageViewData().Format(VkImage.GetFormat()).AspectMask(aspectMask);
if (layers > 1) {
imageViewData.ViewType(VK_IMAGE_VIEW_TYPE_2D_ARRAY);
imageViewData.LayerCount(layers);
}
VkImageView = new ImageView(VkCtx.GetDevice(), VkImage.getVulkanImage(), imageViewData, DepthAttachment);
}
public Image GetVkImage(){return VkImage;}

View file

@ -14,6 +14,7 @@ public class PipelineBuildInfo {
private DescriptorSetLayout[] DescriptorSetLayouts;
private boolean useBlend;
private boolean DepthWrite = true;
private boolean DepthClamp = false;
private boolean DepthTest = true;
private boolean DualPass = false;
private boolean alphaToCoverage = false;
@ -27,6 +28,13 @@ public class PipelineBuildInfo {
DepthFormat = VK_FORMAT_UNDEFINED;
useBlend = true;
}
public boolean DepthClamp() {
return DepthClamp;
}
public PipelineBuildInfo SetDepthClamp(boolean depthClamp) {
this.DepthClamp = depthClamp;
return this;
}
public PipelineBuildInfo SetBlendingMethod(int in){
BlendingMethod = in;

View file

@ -3,19 +3,26 @@ package net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Shadows;
import org.joml.Matrix4f;
public class CascadeData {
private final Matrix4f ProjectionViewMatrix;
private float SplitDistance;
private final Matrix4f projViewMatrix;
private float splitDistance;
public CascadeData(){
ProjectionViewMatrix = new Matrix4f();
public CascadeData() {
projViewMatrix = new Matrix4f();
}
public Matrix4f GetProjectionViewMatrix(){return ProjectionViewMatrix;}
public float GetSplitDistance(){return SplitDistance;}
public void SetProjectionViewMatrix(Matrix4f ProjViewMat){
this.ProjectionViewMatrix.set(ProjViewMat);
public Matrix4f GetProjViewMatrix() {
return projViewMatrix;
}
public void SetSplitDistance(float splitDistance){
this.SplitDistance = splitDistance;
public float GetSplitDistance() {
return splitDistance;
}
public void SetProjectionViewMatrix(Matrix4f projViewMatrix) {
this.projViewMatrix.set(projViewMatrix);
}
public void SetSplitDistance(float splitDistance) {
this.splitDistance = splitDistance;
}
}

View file

@ -1,9 +1,70 @@
package net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Shadows;
import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig;
import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance;
import net.halbear.Terrain4J.EngineCore.Logic.Rendering.VulkanContext;
import net.halbear.Terrain4J.EngineCore.Main.Scene.Actor.Actor3D;
import net.halbear.Terrain4J.EngineCore.Main.Scene.IScene;
import net.halbear.Terrain4J.EngineCore.Main.Scene.SceneLightingManager;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.DefaultPipeline;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.Images.Attachment;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.Images.ITexture;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.Images.Texture;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.Images.TextureCache;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.Pipeline;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.PipelineBuildInfo;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.PushConstantsRange;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Shader.*;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.VertexBufferStructure;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.VkModel.*;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DeviceLayers.CommandBuffer;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DeviceLayers.Device;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DisplayToScreen.ImageView;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Util.VulkanBuffer;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Util.VulkanUtils;
import org.joml.Matrix4f;
import org.lwjgl.system.MemoryStack;
import org.lwjgl.system.MemoryUtil;
import org.lwjgl.util.shaderc.Shaderc;
import org.lwjgl.vulkan.*;
import org.tinylog.Logger;
import static org.lwjgl.vulkan.VK10.VK_FORMAT_D32_SFLOAT;
import static org.lwjgl.vulkan.VK10.VK_FORMAT_R32G32_SFLOAT;
import java.nio.ByteBuffer;
import java.nio.LongBuffer;
import java.util.Arrays;
import java.util.List;
import static org.lwjgl.vulkan.VK10.*;
import static org.lwjgl.vulkan.VK10.VK_ATTACHMENT_LOAD_OP_CLEAR;
import static org.lwjgl.vulkan.VK10.VK_ATTACHMENT_STORE_OP_DONT_CARE;
import static org.lwjgl.vulkan.VK10.VK_ATTACHMENT_STORE_OP_STORE;
import static org.lwjgl.vulkan.VK10.VK_BORDER_COLOR_INT_OPAQUE_BLACK;
import static org.lwjgl.vulkan.VK10.VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
import static org.lwjgl.vulkan.VK10.VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
import static org.lwjgl.vulkan.VK10.VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
import static org.lwjgl.vulkan.VK10.VK_IMAGE_ASPECT_COLOR_BIT;
import static org.lwjgl.vulkan.VK10.VK_IMAGE_ASPECT_DEPTH_BIT;
import static org.lwjgl.vulkan.VK10.VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
import static org.lwjgl.vulkan.VK10.VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
import static org.lwjgl.vulkan.VK10.VK_IMAGE_LAYOUT_UNDEFINED;
import static org.lwjgl.vulkan.VK10.VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
import static org.lwjgl.vulkan.VK10.VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
import static org.lwjgl.vulkan.VK10.VK_INDEX_TYPE_UINT32;
import static org.lwjgl.vulkan.VK10.VK_PIPELINE_BIND_POINT_GRAPHICS;
import static org.lwjgl.vulkan.VK10.VK_SAMPLER_ADDRESS_MODE_REPEAT;
import static org.lwjgl.vulkan.VK10.VK_SHADER_STAGE_FRAGMENT_BIT;
import static org.lwjgl.vulkan.VK10.VK_SHADER_STAGE_GEOMETRY_BIT;
import static org.lwjgl.vulkan.VK10.VK_SHADER_STAGE_VERTEX_BIT;
import static org.lwjgl.vulkan.VK10.vkCmdBindDescriptorSets;
import static org.lwjgl.vulkan.VK10.vkCmdBindIndexBuffer;
import static org.lwjgl.vulkan.VK10.vkCmdBindPipeline;
import static org.lwjgl.vulkan.VK10.vkCmdBindVertexBuffers;
import static org.lwjgl.vulkan.VK10.vkCmdDrawIndexed;
import static org.lwjgl.vulkan.VK10.vkCmdPushConstants;
import static org.lwjgl.vulkan.VK10.vkCmdSetScissor;
import static org.lwjgl.vulkan.VK10.vkCmdSetViewport;
import static org.lwjgl.vulkan.VK12.VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL;
import static org.lwjgl.vulkan.VK13.*;
public class ShadowRenderer {
public static final int DEPTH_FORMAT = VK_FORMAT_D32_SFLOAT;
@ -19,4 +80,281 @@ public class ShadowRenderer {
private static final String VERTEX_SHADER_FILE_GLSL = "resources/EngineResources/shaders/shadow_vertex.glsl";
private static final String VERTEX_SHADER_FILE_SPV = VERTEX_SHADER_FILE_GLSL + ".spv";
private final CascadeShadows[] cascadeShadows;
private final VkClearValue ClearValueColour;
private final VkClearValue ClearValueDepth;
private final Attachment colorAttachment;
private final VkRenderingAttachmentInfo.Buffer colorAttachmentInfo;
private final Attachment depthAttachment;
private final VkRenderingAttachmentInfo depthAttachmentInfo;
private final DescriptorSetLayout descLayoutFrgStorage;
private final Pipeline pipeline;
private final VulkanBuffer[] prjBuffers;
private final ByteBuffer pushConstBuff;
private final VkRenderingInfo renderingInfo;
private final DescriptorSetLayout textDescriptorSetLayout;
private final TextureSampler textureSampler;
private final DescriptorSetLayout uniformGeomDescriptorSetLayout;
public ShadowRenderer(VulkanContext VulkanContext) {
ClearValueColour = VkClearValue.calloc().color(
c -> c.float32(0, 0.0f).float32(1, 0.0f).float32(2, 0.0f).float32(3, 0.0f));
ClearValueDepth = VkClearValue.calloc().color(c -> c.float32(0, 1.0f));
depthAttachment = createDepthAttachment(VulkanContext);
depthAttachmentInfo = createDepthAttachmentInfo(depthAttachment, ClearValueDepth);
colorAttachment = createColorAttachment(VulkanContext);
colorAttachmentInfo = createColorAttachmentInfo(colorAttachment, ClearValueColour);
pushConstBuff = MemoryUtil.memAlloc(PUSH_CONSTANTS_SIZE);
renderingInfo = createRenderInfo(colorAttachmentInfo, depthAttachmentInfo);
ShaderModule[] shaderModules = createShaderModules(VulkanContext);
uniformGeomDescriptorSetLayout = new DescriptorSetLayout(VulkanContext, new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
0, 1, VK_SHADER_STAGE_GEOMETRY_BIT));
long buffSize = (long) VulkanUtils.MATRIX4X4_SIZE * SceneLightingManager.SHADOW_MAP_CASCADE_COUNT;
prjBuffers = VulkanUtils.CreateHostVisibleBuffers(VulkanContext, buffSize, VulkanUtils.MAX_IN_FLIGHT,
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, DESCRIPTOR_ID_PRJ, uniformGeomDescriptorSetLayout);
descLayoutFrgStorage = new DescriptorSetLayout(VulkanContext, new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
0, 1, VK_SHADER_STAGE_FRAGMENT_BIT));
var textureSamplerInfo = new TextureSamplerInfo(VK_SAMPLER_ADDRESS_MODE_REPEAT,
VK_BORDER_COLOR_INT_OPAQUE_BLACK, 1, true);
textureSampler = new TextureSampler(VulkanContext, textureSamplerInfo);
textDescriptorSetLayout = new DescriptorSetLayout(VulkanContext, new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
0, TextureCache.MAX_TEXTURES, VK_SHADER_STAGE_FRAGMENT_BIT));
pipeline = createPipeline(VulkanContext, shaderModules, new DescriptorSetLayout[]{uniformGeomDescriptorSetLayout, textDescriptorSetLayout,
descLayoutFrgStorage});
Arrays.asList(shaderModules).forEach(s -> s.CleanUp(VulkanContext));
cascadeShadows = new CascadeShadows[VulkanUtils.MAX_IN_FLIGHT];
for (int i = 0; i < VulkanUtils.MAX_IN_FLIGHT; i++) {
cascadeShadows[i] = new CascadeShadows();
}
}
private static Attachment createColorAttachment(VulkanContext VulkanContext) {
int shadowMapSize = EngineConfig.getInstance().GetShadowMapSize();
return new Attachment(VulkanContext, shadowMapSize, shadowMapSize,
ATTACHMENT_FORMATT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, SceneLightingManager.SHADOW_MAP_CASCADE_COUNT);
}
private static VkRenderingAttachmentInfo.Buffer createColorAttachmentInfo(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 Attachment createDepthAttachment(VulkanContext VulkanContext) {
int shadowMapSize = EngineConfig.getInstance().GetShadowMapSize();
return new Attachment(VulkanContext, shadowMapSize, shadowMapSize,
DEPTH_FORMAT, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, SceneLightingManager.SHADOW_MAP_CASCADE_COUNT);
}
private static VkRenderingAttachmentInfo createDepthAttachmentInfo(Attachment depthAttachment, VkClearValue clearValue) {
return VkRenderingAttachmentInfo.calloc()
.sType$Default()
.imageView(depthAttachment.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 Pipeline createPipeline(VulkanContext VulkanContext, ShaderModule[] shaderModules, DescriptorSetLayout[] DescriptorSetLayouts) {
var vtxBuffStruct = new VertexBufferStructure();
var buildInfo = new PipelineBuildInfo(shaderModules, vtxBuffStruct.getVertexInput(), new int[]{ATTACHMENT_FORMATT})
.SetDepthFormat(DEPTH_FORMAT)
.SetPushConstantRanges(
new PushConstantsRange[]{
new PushConstantsRange(VK_SHADER_STAGE_VERTEX_BIT, 0, PUSH_CONSTANTS_SIZE)
})
.SetDescriptorSetLayouts(DescriptorSetLayouts)
.SetDescriptorSetLayouts(DescriptorSetLayouts)
.SetDepthClamp(VulkanContext.GetDevice().getDepthClamp());
var pipeline = new DefaultPipeline(VulkanContext, buildInfo);
vtxBuffStruct.cleanup();
return pipeline;
}
private static VkRenderingInfo createRenderInfo(VkRenderingAttachmentInfo.Buffer colorAttachmentInfo,
VkRenderingAttachmentInfo depthAttachments) {
var result = VkRenderingInfo.calloc().sType$Default();
try (var stack = MemoryStack.stackPush()) {
int shadowMapSize = EngineConfig.getInstance().GetShadowMapSize();
VkExtent2D extent = VkExtent2D.calloc(stack);
extent.width(shadowMapSize);
extent.height(shadowMapSize);
var renderArea = VkRect2D.calloc(stack).extent(extent);
result.renderArea(renderArea)
.layerCount(SceneLightingManager.SHADOW_MAP_CASCADE_COUNT)
.pColorAttachments(colorAttachmentInfo)
.pDepthAttachment(depthAttachments);
}
return result;
}
private static ShaderModule[] createShaderModules(VulkanContext VulkanContext) {
if (EngineConfig.getInstance().RecompileShaders()) {
ShaderCompiler.CompileGLSLShaderOnChange(VERTEX_SHADER_FILE_GLSL, Shaderc.shaderc_glsl_vertex_shader);
ShaderCompiler.CompileGLSLShaderOnChange(SHADOW_GEOMETRY_SHADER_FILE_GLSL, Shaderc.shaderc_glsl_geometry_shader);
ShaderCompiler.CompileGLSLShaderOnChange(FRAGMENT_SHADER_FILE_GLSL, Shaderc.shaderc_glsl_fragment_shader);
}
return new ShaderModule[]{
new ShaderModule(VulkanContext, VK_SHADER_STAGE_VERTEX_BIT, VERTEX_SHADER_FILE_SPV, null),
new ShaderModule(VulkanContext, VK_SHADER_STAGE_GEOMETRY_BIT, SHADOW_GEOMETRY_SHADER_FILE_SPV, null),
new ShaderModule(VulkanContext, VK_SHADER_STAGE_FRAGMENT_BIT, FRAGMENT_SHADER_FILE_SPV, null),
};
}
public void cleanup(VulkanContext VulkanContext) {
pipeline.CleanUp(VulkanContext);
uniformGeomDescriptorSetLayout.CleanUp(VulkanContext);
descLayoutFrgStorage.CleanUp(VulkanContext);
textDescriptorSetLayout.CleanUp(VulkanContext);
textureSampler.CleanUp(VulkanContext);
Arrays.asList(prjBuffers).forEach(b -> b.cleanup(VulkanContext));
renderingInfo.free();
depthAttachmentInfo.free();
depthAttachment.CleanUp(VulkanContext);
colorAttachmentInfo.free();
colorAttachment.CleanUp(VulkanContext);
MemoryUtil.memFree(pushConstBuff);
ClearValueColour.free();
ClearValueDepth.free();
}
public CascadeShadows getCascadeShadows(int currentFrame) {
return cascadeShadows[currentFrame];
}
public Attachment getShadowAttachment() {
return colorAttachment;
}
public void loadMaterials(VulkanContext VulkanContext, MaterialsCache materialsCache, TextureCache textureCache) {
DescriptorAllocator descAllocator = VulkanContext.GetDescriptorAllocator();
Device device = VulkanContext.GetDevice();
DescriptorSet descSet = descAllocator.AddDescriptorSet(device, DESCRIPTOR_ID_MAT, descLayoutFrgStorage);
DescriptorSetLayout.LayoutInformation layoutInfo = descLayoutFrgStorage.GetLayoutInfo();
var buffer = materialsCache.GetMaterialsBuffer();
descSet.SetBuffer(device, buffer, buffer.GetRequestedSize(), layoutInfo.Binding(), layoutInfo.DescriptorType());
List<ImageView> imageViews = textureCache.GetTextureList().stream().map(ITexture::GetImageView).toList();
descSet = VulkanContext.GetDescriptorAllocator().AddDescriptorSet(device, DESCRIPTOR_ID_TEXT, textDescriptorSetLayout);
descSet.SetImageArray(device, imageViews, textureSampler, 0);
}
public void render(EngineInstance engCtx, VulkanContext VulkanContext, CommandBuffer cmdBuffer, ModelsCache modelsCache,
MaterialsCache materialsCache, int currentFrame) {
try (var stack = MemoryStack.stackPush()) {
IScene scene = engCtx.scene();
ShadowUtils.updateCascadeShadows(cascadeShadows[currentFrame], scene);
VkCommandBuffer cmdHandle = cmdBuffer.GetVulkanCommandBuffer();
VulkanUtils.ImageBarrier(stack, cmdHandle, colorAttachment.GetVkImage().getVulkanImage(),
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT,
VK_ACCESS_2_NONE, VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT,
VK_IMAGE_ASPECT_COLOR_BIT);
VulkanUtils.ImageBarrier(stack, cmdHandle, depthAttachment.GetVkImage().getVulkanImage(),
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL,
VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT,
VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT,
VK_ACCESS_2_NONE,
VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
VK_IMAGE_ASPECT_DEPTH_BIT);
vkCmdBeginRendering(cmdHandle, renderingInfo);
vkCmdBindPipeline(cmdHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.GetVulkanPipeline());
int shadowMapSize = EngineConfig.getInstance().GetShadowMapSize();
int width = shadowMapSize;
int height = shadowMapSize;
var viewport = VkViewport.calloc(1, stack)
.x(0)
.y(height)
.height(-height)
.width(width)
.minDepth(0.0f)
.maxDepth(1.0f);
vkCmdSetViewport(cmdHandle, 0, viewport);
var scissor = VkRect2D.calloc(1, stack)
.extent(it -> it.width(width).height(height))
.offset(it -> it.x(0).y(0));
vkCmdSetScissor(cmdHandle, 0, scissor);
updateProjBuffer(VulkanContext, currentFrame);
DescriptorAllocator descAllocator = VulkanContext.GetDescriptorAllocator();
LongBuffer descriptorSets = stack.mallocLong(3)
.put(0, descAllocator.GetDescriptorSet(DESCRIPTOR_ID_PRJ, currentFrame).GetVkDescriptorSet())
.put(1, descAllocator.GetDescriptorSet(DESCRIPTOR_ID_TEXT).GetVkDescriptorSet())
.put(2, descAllocator.GetDescriptorSet(DESCRIPTOR_ID_MAT).GetVkDescriptorSet());
vkCmdBindDescriptorSets(cmdHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.GetVulkanPipelineLayout(),
0, descriptorSets, null);
LongBuffer vertexBuffer = stack.mallocLong(1);
LongBuffer offsets = stack.mallocLong(1).put(0, 0L);
List<Actor3D> entities = scene.GetActors();
int numEntities = entities.size();
for (int i = 0; i < numEntities; i++) {
var entity = entities.get(i);
VulkanModel model = modelsCache.GetModel(entity.GetModelID());
List<VulkanMesh> vulkanMeshList = model.GetVkMeshList();
int numMeshes = vulkanMeshList.size();
for (int j = 0; j < numMeshes; j++) {
var vulkanMesh = vulkanMeshList.get(j);
String materialId = vulkanMesh.MaterialID();
int materialIdx = materialsCache.GetPosition(materialId);
VulkanMaterial vulkanMaterial = materialsCache.GetMaterial(materialId);
if (vulkanMaterial == null) {
Logger.warn("Mesh [{}] in model [{}] does not have material", j, model.GetID());
continue;
}
setPushConstants(cmdHandle, entity.GetModelMatrix(), materialIdx);
vertexBuffer.put(0, vulkanMesh.VerticesBuffer().GetBuffer());
vkCmdBindVertexBuffers(cmdHandle, 0, vertexBuffer, offsets);
vkCmdBindIndexBuffer(cmdHandle, vulkanMesh.IndicesBuffer().GetBuffer(), 0, VK_INDEX_TYPE_UINT32);
vkCmdDrawIndexed(cmdHandle, vulkanMesh.IndicesCount(), 1, 0, 0, 0);
}
}
vkCmdEndRendering(cmdHandle);
}
}
private void setPushConstants(VkCommandBuffer cmdHandle, Matrix4f modelMatrix, int materialIdx) {
modelMatrix.get(0, pushConstBuff);
pushConstBuff.putInt(VulkanUtils.MATRIX4X4_SIZE, materialIdx);
vkCmdPushConstants(cmdHandle, pipeline.GetVulkanPipelineLayout(), VK_SHADER_STAGE_VERTEX_BIT, 0, pushConstBuff);
}
private void updateProjBuffer(VulkanContext VulkanContext, int currentFrame) {
int offset = 0;
List<CascadeData> cascadeDataList = cascadeShadows[currentFrame].GetCascadeData();
int numCascades = cascadeDataList.size();
VulkanBuffer vkBuffer = prjBuffers[currentFrame];
long mappedMemory = vkBuffer.MapMemory(VulkanContext);
ByteBuffer buff = MemoryUtil.memByteBuffer(mappedMemory, (int) vkBuffer.GetRequestedSize());
for (int i = 0; i < numCascades; i++) {
CascadeData cascadeData = cascadeDataList.get(i);
cascadeData.GetProjViewMatrix().get(offset, buff);
offset += VulkanUtils.MATRIX4X4_SIZE;
}
vkBuffer.UnMapMemory(VulkanContext);
}
}

View file

@ -15,58 +15,65 @@ import java.util.List;
public class ShadowUtils {
private static final float LAMBDA = 0.95f;
private static final Vector3f Up = new Vector3f(0.0f,1.0f,0.0f);
private static final Vector3f UpAlt = new Vector3f(0.0f,0.0f,1.0f);
private ShadowUtils(){
private static final Vector3f UP = new Vector3f(0.0f, 1.0f, 0.0f);
private static final Vector3f UP_ALT = new Vector3f(0.0f, 0.0f, 1.0f);
private ShadowUtils() {
}
public static void UpdateCascadeShadows(CascadeShadows shadows, IScene scene){
public static void updateCascadeShadows(CascadeShadows cascadeShadows, IScene scene) {
Camera camera = scene.GetCamera();
Matrix4f ViewMatrix = camera.GetViewMatrix();
Matrix4f viewMatrix = camera.GetViewMatrix();
Project3D projection = scene.GetProjection();
Matrix4f ProjectionMatrix = projection.GetProjectionMatrix();
Matrix4f projMatrix = projection.GetProjectionMatrix();
ILight[] lights = scene.GetLightingManager().GetLights();
int LightCount = lights.length;
ILight SkyLight = null;
for(int i = 0; i < LightCount; i++){
if(lights[i].IsDirectional()){
SkyLight = lights[i];
int numLights = lights.length;
ILight dirLight = null;
for (int i = 0; i < numLights; i++) {
if (lights[i].IsDirectional()) {
dirLight = lights[i];
break;
}
}
if(SkyLight == null){
throw new RuntimeException("No SkyLight on scene");
if (dirLight == null) {
throw new RuntimeException("Could not find directional light");
}
Vector4f LightPosition = new Vector4f(SkyLight.GetPosition(),0.0f);
float[] CascadeSplits = new float[SceneLightingManager.SHADOW_MAP_CASCADE_COUNT];
float NearClip = Math.min(projection.GetNearZ(), projection.GetFarZ());
float FarClip = Math.max(projection.GetNearZ(), projection.GetFarZ());
float ClipRange = FarClip - NearClip;
Vector3f lightPos = dirLight.GetPosition();
float MinZ = NearClip;
float MaxZ = NearClip + ClipRange;
float[] cascadeSplits = new float[SceneLightingManager.SHADOW_MAP_CASCADE_COUNT];
float Range = MaxZ - MinZ;
float Ratio = MaxZ/MinZ;
float nearClip = projection.GetNearZ();
float farClip = projection.GetFarZ();
float clipRange = farClip - nearClip;
List<CascadeData> cascadeDataList = shadows.GetCascadeData();
int CascadeCount = cascadeDataList.size();
if (nearClip <= 0.0f || farClip <= nearClip) {
//throw new IllegalStateException("Invalid projection near/far planes for shadow cascades: near=" + nearClip + ", far=" + farClip);
}
for(int i = 0; i < CascadeCount; i++){
float minZ = nearClip;
float maxZ = nearClip + clipRange;
float range = maxZ - minZ;
float ratio = maxZ / minZ;
List<CascadeData> cascadeDataList = cascadeShadows.GetCascadeData();
int numCascades = cascadeDataList.size();
// Calculate split depths based on view camera frustum
// Based on method presented in https://developer.nvidia.com/gpugems/GPUGems3/gpugems3_ch10.html
for (int i = 0; i < numCascades; i++) {
float p = (i + 1) / (float) (SceneLightingManager.SHADOW_MAP_CASCADE_COUNT);
float Log = (float) (MinZ * Math.pow(Ratio, p));
float Uniform = MinZ + Range * p;
float d = LAMBDA * (Log - Uniform) + Uniform;
CascadeSplits[i] = (d - NearClip) / ClipRange;
float log = (float) (minZ * java.lang.Math.pow(ratio, p));
float uniform = minZ + range * p;
float d = LAMBDA * (log - uniform) + uniform;
cascadeSplits[i] = (d - nearClip) / clipRange;
}
float LastSplitDist = 0.0f;
for(int i = 0; i < CascadeCount; i++){
float SplitDist = CascadeSplits[i];
float lastSplitDist = 0.0f;
for (int i = 0; i < numCascades; i++) {
float splitDist = cascadeSplits[i];
Vector3f[] FustrumCorners = new Vector3f[]{
Vector3f[] frustumCorners = new Vector3f[]{
new Vector3f(-1.0f, 1.0f, 0.0f),
new Vector3f(1.0f, 1.0f, 0.0f),
new Vector3f(1.0f, -1.0f, 0.0f),
@ -74,70 +81,73 @@ public class ShadowUtils {
new Vector3f(-1.0f, 1.0f, 1.0f),
new Vector3f(1.0f, 1.0f, 1.0f),
new Vector3f(1.0f, -1.0f, 1.0f),
new Vector3f(-1.0f, -1.0f, 1.0f)
new Vector3f(-1.0f, -1.0f, 1.0f),
};
var InvertedCam = (new Matrix4f(ProjectionMatrix).mul(ViewMatrix)).invert();
for(int j = 0; j < 8; j++){
Vector4f InvertedCorner = new Vector4f(FustrumCorners[j],1.0f).mul(InvertedCam);
FustrumCorners[j] = new Vector3f(InvertedCorner.x,InvertedCorner.y,InvertedCorner.z).div(InvertedCorner.w);
// Project frustum corners into world space
var invCam = (new Matrix4f(projMatrix).mul(viewMatrix)).invert();
for (int j = 0; j < 8; j++) {
Vector4f invCorner = new Vector4f(frustumCorners[j], 1.0f).mul(invCam);
frustumCorners[j] = new Vector3f(invCorner.x, invCorner.y, invCorner.z).div(invCorner.w);
}
for(int j = 0; j < 4; j++){
var Distance = new Vector3f(FustrumCorners[j + 4]).sub(FustrumCorners[j]);
FustrumCorners[j + 4] = new Vector3f(FustrumCorners[j]).add(new Vector3f(Distance).mul(SplitDist));
FustrumCorners[j] = new Vector3f(FustrumCorners[j]).add(new Vector3f(Distance).mul(LastSplitDist));
for (int j = 0; j < 4; j++) {
var dist = new Vector3f(frustumCorners[j + 4]).sub(frustumCorners[j]);
frustumCorners[j + 4] = new Vector3f(frustumCorners[j]).add(new Vector3f(dist).mul(splitDist));
frustumCorners[j] = new Vector3f(frustumCorners[j]).add(new Vector3f(dist).mul(lastSplitDist));
}
var FustrumCenter = new Vector3f(0.0f);
for(int j = 0; j < 8; j++){
FustrumCenter.add(FustrumCorners[j]);
var frustumCenter = new Vector3f(0.0f);
for (int j = 0; j < 8; j++) {
frustumCenter.add(frustumCorners[j]);
}
FustrumCenter.div(8);
frustumCenter.div(8.0f);
var up = Up;
float SphereRadius = 0.0f;
for(int j = 0; j < 8; j++){
float Distance = new Vector3f(FustrumCorners[j]).sub(FustrumCenter).length();
SphereRadius = Math.max(SphereRadius,Distance);
var up = UP;
float sphereRadius = 0.0f;
for (int j = 0; j < 8; j++) {
float dist = new Vector3f(frustumCorners[j]).sub(frustumCenter).length();
sphereRadius = java.lang.Math.max(sphereRadius, dist);
}
SphereRadius = (float)Math.ceil(SphereRadius * 16.0f) / 16.0f;
sphereRadius = (float) java.lang.Math.ceil(sphereRadius * 16.0f) / 16.0f;
var MaxExtents = new Vector3f(SphereRadius);
var MinExtents = new Vector3f(-SphereRadius);
var maxExtents = new Vector3f(sphereRadius, sphereRadius, sphereRadius);
var minExtents = new Vector3f(maxExtents).mul(-1.0f);
var LightDirection = new Vector3f(LightPosition.x, LightPosition.y, LightPosition.z);
var ShadowCamPosition = new Vector3f(FustrumCenter).add(LightDirection.mul(MinExtents.z));
var lightDir = new Vector3f(lightPos.x, lightPos.y, lightPos.z);
var shadowCameraPos = new Vector3f(frustumCenter).add(lightDir.mul(minExtents.z));
float Dot = Math.abs(new Vector3f(LightPosition.x, LightPosition.y, LightPosition.z).dot(up));
if(Dot == 1.0f){
up = UpAlt;
float dot = java.lang.Math.abs(new Vector3f(lightPos.x, lightPos.y, lightPos.z).dot(up));
if (dot == 1.0f) {
up = UP_ALT;
}
var LightViewMatrix = new Matrix4f().lookAt(ShadowCamPosition,FustrumCenter,up);
var LightOrthoMatrix = new Matrix4f().ortho(MinExtents.x,MaxExtents.x,MinExtents.y,MaxExtents.y,0.0f,MaxExtents.z - MinExtents.z,true);
var lightViewMatrix = new Matrix4f().lookAt(shadowCameraPos, frustumCenter, up);
var lightOrthoMatrix = new Matrix4f().ortho
(minExtents.x, maxExtents.x, minExtents.y, maxExtents.y, 0.0f, maxExtents.z - minExtents.z, true);
int ShadowMapSize = EngineConfig.getInstance().GetShadowMapSize();
Vector4f ShadowOrigin = new Vector4f(0f,0f,0f,1f);
LightViewMatrix.transform(ShadowOrigin);
ShadowOrigin.mul(ShadowMapSize/2.0f);
int shadowMapSize = EngineConfig.getInstance().GetShadowMapSize();
Vector4f shadowOrigin = new Vector4f(0.0f, 0.0f, 0.0f, 1.0f);
lightViewMatrix.transform(shadowOrigin);
shadowOrigin.mul(shadowMapSize / 2.0f);
Vector4f RoundedOrigin = new Vector4f(ShadowOrigin).round();
Vector4f RoundOffset = RoundedOrigin.sub(ShadowOrigin);
RoundOffset.mul(2.0f/ShadowMapSize);
RoundOffset.z = 0.0f;
RoundOffset.w = 0.0f;
Vector4f roundedOrigin = new Vector4f(shadowOrigin).round();
Vector4f roundOffset = roundedOrigin.sub(shadowOrigin);
roundOffset.mul(2.0f / shadowMapSize);
roundOffset.z = 0.0f;
roundOffset.w = 0.0f;
LightOrthoMatrix.m30(LightOrthoMatrix.m30() + RoundOffset.x);
LightOrthoMatrix.m31(LightOrthoMatrix.m31() + RoundOffset.y);
LightOrthoMatrix.m32(LightOrthoMatrix.m32() + RoundOffset.z);
LightOrthoMatrix.m33(LightOrthoMatrix.m33() + RoundOffset.w);
lightOrthoMatrix.m30(lightOrthoMatrix.m30() + roundOffset.x);
lightOrthoMatrix.m31(lightOrthoMatrix.m31() + roundOffset.y);
lightOrthoMatrix.m32(lightOrthoMatrix.m32() + roundOffset.z);
lightOrthoMatrix.m33(lightOrthoMatrix.m33() + roundOffset.w);
// Store split distance and matrix in cascade
CascadeData cascadeData = cascadeDataList.get(i);
cascadeData.SetSplitDistance((NearClip + SplitDist * ClipRange) * -1.0f);
cascadeData.SetProjectionViewMatrix(LightOrthoMatrix.mul(LightViewMatrix));
cascadeData.SetSplitDistance((nearClip + splitDist * clipRange) * -1.0f);
cascadeData.SetProjectionViewMatrix(lightOrthoMatrix.mul(lightViewMatrix));
LastSplitDist = CascadeSplits[i];
lastSplitDist = cascadeSplits[i];
}
}
}

View file

@ -157,10 +157,7 @@ public class SpriteRenderer {
.SetDepthWrite(DepthWrite)
.SetPushConstantRanges(
new PushConstantsRange[]{
new PushConstantsRange(VK_SHADER_STAGE_VERTEX_BIT,0,VulkanUtils.VEC2_SIZE),
new PushConstantsRange(VK_SHADER_STAGE_VERTEX_BIT,VulkanUtils.VEC2_SIZE,VulkanUtils.VEC2_SIZE),
new PushConstantsRange(VK_SHADER_STAGE_VERTEX_BIT,VulkanUtils.VEC2_SIZE * 2,VulkanUtils.VEC2_SIZE),
new PushConstantsRange(VK_SHADER_STAGE_VERTEX_BIT,VulkanUtils.VEC2_SIZE * 3,VulkanUtils.FLOAT_SIZE),
new PushConstantsRange(VK_SHADER_STAGE_VERTEX_BIT,0,VulkanUtils.VEC2_SIZE * 3 + VulkanUtils.FLOAT_SIZE),
new PushConstantsRange(VK_SHADER_STAGE_FRAGMENT_BIT,VulkanUtils.VEC2_SIZE * 3 + VulkanUtils.FLOAT_SIZE,VulkanUtils.INT_SIZE)
})
.SetDescriptorSetLayouts(DescriptorSetLayouts)

View file

@ -20,6 +20,7 @@ import static org.lwjgl.vulkan.KHRPortabilitySubset.VK_KHR_PORTABILITY_SUBSET_EX
import static org.lwjgl.vulkan.VK13.*;
public class Device {
private final boolean depthClamp;
private final VkDevice VulkanDevice;
private final boolean SamplesAnisotropy;
@ -37,14 +38,15 @@ public class Device {
.queueFamilyIndex(i)
.pQueuePriorities(Priorities);
}
var features12 = VkPhysicalDeviceVulkan12Features.calloc(MemStack)
.sType$Default()
.scalarBlockLayout(true);
var features13 = VkPhysicalDeviceVulkan13Features.calloc(MemStack)
.sType$Default()
.dynamicRendering(true)
.synchronization2(true);
var features12 = VkPhysicalDeviceVulkan12Features.calloc(MemStack)
.sType$Default()
.scalarBlockLayout(true);
var features2 = VkPhysicalDeviceFeatures2.calloc(MemStack).sType$Default();
var features = features2.features();
@ -53,8 +55,11 @@ public class Device {
if(SamplesAnisotropy){
features.samplerAnisotropy(true);
}
features2.pNext(features13.address());
features13.pNext(features12.address());
features.geometryShader(true);
depthClamp = SupportedFeatures.depthClamp();
features.depthClamp(depthClamp);
features2.pNext(features12.address());
features12.pNext(features13.address());
var DeviceCreateInfo = VkDeviceCreateInfo.calloc(MemStack)
.sType$Default()
@ -75,6 +80,10 @@ public class Device {
}
}
public boolean getDepthClamp() {
return depthClamp;
}
private static PointerBuffer CreateRequiredExtensions(PhysicalDevice PhysDevice, MemoryStack MemStack){
Set<String> DeviceExtensions = GetDeviceExtensions(PhysDevice);
//cross platform support for that fuckass Metal API mac uses

View file

@ -108,7 +108,7 @@ public class DeferredSceneRender implements SceneRenderer {//dynamic rendering
public DeferredSceneRender(VulkanContext vulkanContext, EngineInstance engineInstance){
ClearValueColour = VkClearValue.calloc().color(
c -> c.float32(0, 0.0f).float32(1, 0.0f).float32(2, 0.0f).float32(3, 0.0f));
ClearValueDepth = VkClearValue.calloc().color(c -> c.float32(0, 0.0f));
ClearValueDepth = VkClearValue.calloc().color(c -> c.float32(0, 1.0f));
MRTAttachments = new MultiRenderTargetAttachments(vulkanContext);
AttachmentInfoColour = CreateColourAttachmentInfo(MRTAttachments, ClearValueColour);
AttachmentInfoDepth = CreateDepthAttachmentInfo(MRTAttachments, ClearValueDepth);
@ -267,7 +267,7 @@ public class DeferredSceneRender implements SceneRenderer {//dynamic rendering
.SetDepthTest(true)
.SetPushConstantRanges(new PushConstantsRange[0])
.SetDescriptorSetLayouts(DescriptorSetLayouts)
.BlendingIsUsed(true)
.BlendingIsUsed(false)
.SetDualPass(false)
.SetAlphaToCoverage(false);
var pipeline = new DefaultPipeline(VkCtx, BuildInfo);

View file

@ -117,7 +117,7 @@ public class ForwardSceneRender implements SceneRenderer {//dynamic rendering
public ForwardSceneRender(VulkanContext vulkanContext){
ClearValueColour = VkClearValue.calloc().color(
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, 1.0f));
CreateRenderAttachments(vulkanContext);
PushConstBuffer = (MemoryUtil.memAlloc(PUSH_CONSTANTS_SIZE));

View file

@ -17,12 +17,14 @@ public class ImageView {
private final long VulkanImage;
private final long VulkanImageView;
private final boolean DepthImage;
private final int layerCount;
public ImageView(Device device, long vulkanImage, ImageViewData imageViewData, boolean DepthImage){
this.AspectMask = imageViewData.AspectMask;
this.MipLevels = imageViewData.MipLevels;
this.VulkanImage = vulkanImage;
this.DepthImage = DepthImage;
this.layerCount = imageViewData.LayerCount;
try(var MemStack = MemoryStack.stackPush()){
LongBuffer LongPointer = MemStack.mallocLong(1);
var ViewCreateInfo = VkImageViewCreateInfo.calloc(MemStack)
@ -46,6 +48,10 @@ public class ImageView {
vkDestroyImageView(device.FetchVulkanDevice(), VulkanImageView, null);
}
public int GetLayerCount() {
return layerCount;
}
public int GetAspectMask(){
return AspectMask;
}

View file

@ -37,15 +37,16 @@ public class RenderThread extends EngineThread {
public InitData GetInitData(){return initData;}
public void RestartCrashedRenderer(){
if(Headless) return;
if(VulkanCrashCount < EngineConfig.getInstance().GetMaxVulkanCrashes()){
RefreshRenderer();
VulkanCrashCount++;
}else{
Logger.error("MAX API CRASHES REACHED, CLOSING SOFTWARE");
PrimaryRuntime.GetEngineInstance().window().setShouldClose();
PrimaryRuntime.CloseRuntime();
}
throw new IllegalStateException("Vulkan device lost; terminating renderer instead of hot-restarting");
// if(Headless) return;
// if(VulkanCrashCount < EngineConfig.getInstance().GetMaxVulkanCrashes()){
// RefreshRenderer();
// VulkanCrashCount++;
// }else{
// Logger.error("MAX API CRASHES REACHED, CLOSING SOFTWARE");
// PrimaryRuntime.GetEngineInstance().window().setShouldClose();
// PrimaryRuntime.CloseRuntime();
// }
}
public Renderer GetRenderer(){return render;}