This commit is contained in:
Harrison Corlett 2026-06-23 13:20:43 +01:00
parent eb01ec4877
commit f135d99d74
60 changed files with 924 additions and 90 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

View file

@ -0,0 +1,2 @@
Sky texture:
kaori669 on deviant art

Binary file not shown.

After

Width:  |  Height:  |  Size: 217 KiB

View file

@ -149,4 +149,9 @@ void main() {
vec3 color = ambient + Lo; vec3 color = ambient + Lo;
outFragColor = vec4(color, 1.0f); outFragColor = vec4(color, 1.0f);
if (length(normal) < 0.001) {
outFragColor = vec4(albedo,1.0f);
return;
}
} }

View file

@ -2,7 +2,7 @@
layout(constant_id = 0) const int USE_AA = 0; layout(constant_id = 0) const int USE_AA = 0;
const float GAMMA_CONST = 0.8545; const float GAMMA_CONST = 0.6545;
const float SPAN_MAX = 8.0; const float SPAN_MAX = 8.0;
const float REDUCE_MIN = 1.0/128.0; const float REDUCE_MIN = 1.0/128.0;
const float REDUCE_MUL = 1.0/32.0; const float REDUCE_MUL = 1.0/32.0;

View file

@ -2,7 +2,7 @@
layout(constant_id = 0) const int USE_AA = 0; layout(constant_id = 0) const int USE_AA = 0;
const float GAMMA_CONST = 0.8545; const float GAMMA_CONST = 0.4545;
const float SPAN_MAX = 8.0; const float SPAN_MAX = 8.0;
const float REDUCE_MIN = 1.0/128.0; const float REDUCE_MIN = 1.0/128.0;
const float REDUCE_MUL = 1.0/32.0; const float REDUCE_MUL = 1.0/32.0;

View file

@ -1,6 +1,6 @@
#version 450 #version 450
const int MAX_TEXTURES = 512; const int MAX_TEXTURES = 128;
layout(location = 0) in vec4 inPos; layout(location = 0) in vec4 inPos;
layout(location = 1) in vec3 inNormal; layout(location = 1) in vec3 inNormal;

View file

@ -1,6 +1,6 @@
#version 450 #version 450
const int MAX_TEXTURES = 512; const int MAX_TEXTURES = 128;
layout(location = 0) in vec4 inPos; layout(location = 0) in vec4 inPos;
layout(location = 1) in vec3 inNormal; layout(location = 1) in vec3 inNormal;

View file

@ -1,6 +1,6 @@
#version 450 #version 450
const int MAX_TEXTURES = 512; const int MAX_TEXTURES = 128;
layout(location = 0) in vec4 inPos; layout(location = 0) in vec4 inPos;
layout(location = 1) in vec3 inNormal; layout(location = 1) in vec3 inNormal;

View file

@ -1,6 +1,6 @@
#version 450 #version 450
const int MAX_TEXTURES = 512; const int MAX_TEXTURES = 128;
layout(location = 0) in vec4 inPos; layout(location = 0) in vec4 inPos;
layout(location = 1) in vec3 inNormal; layout(location = 1) in vec3 inNormal;
@ -13,6 +13,13 @@ layout(location = 0) out vec4 outPos;
layout(location = 2) out vec4 outNormal; layout(location = 2) out vec4 outNormal;
layout(location = 3) out vec4 outPBR; layout(location = 3) out vec4 outPBR;
const float bayerMatrix[16] = float[](
0.0 / 16.0, 8.0 / 16.0, 2.0 / 16.0, 10.0 / 16.0,
12.0 / 16.0, 4.0 / 16.0, 14.0 / 16.0, 6.0 / 16.0,
3.0 / 16.0, 11.0 / 16.0, 1.0 / 16.0, 9.0 / 16.0,
15.0 / 16.0, 7.0 / 16.0, 13.0 / 16.0, 5.0 / 16.0
);
struct Material { struct Material {
vec4 diffuseColor; vec4 diffuseColor;
uint hasTexture; uint hasTexture;
@ -55,13 +62,17 @@ void main()
} else { } else {
outAlbedo = material.diffuseColor; outAlbedo = material.diffuseColor;
} }
/*int Intensity = 4;
int x = int(gl_FragCoord.x) % Intensity;
int y = int(gl_FragCoord.y) % Intensity;
float threshold = bayerMatrix[y * Intensity + x];
if(outAlbedo.a < threshold || outAlbedo.a < 0.05f) discard;*/
if(outAlbedo.a < 0.75) discard; if(outAlbedo.a < 0.75) discard;
mat3 TBN = mat3(inTangent, inBitangent, inNormal); mat3 TBN = mat3(inTangent, inBitangent, inNormal);
vec3 newNormal = calcNormal(material, inNormal, inTextCoords, TBN); vec3 newNormal = calcNormal(material, inNormal, inTextCoords, TBN);
outNormal = vec4(newNormal, 1.0f); outNormal = vec4(newNormal, outAlbedo.a);
float ao = 0.5f; float ao = 0.5f;
float roughnessFactor = 0.0f; float roughnessFactor = 0.0f;
@ -75,6 +86,6 @@ void main()
metallicFactor = material.metallicFactor; metallicFactor = material.metallicFactor;
} }
outPBR = vec4(ao, roughnessFactor, metallicFactor, 1.0f); outPBR = vec4(ao, roughnessFactor, metallicFactor, outAlbedo.a);
} }

View file

@ -1,6 +1,6 @@
#version 450 #version 450
const int MAX_TEXTURES = 512; const int MAX_TEXTURES = 128;
layout(location = 0) in vec4 inPos; layout(location = 0) in vec4 inPos;
layout(location = 1) in vec3 inNormal; layout(location = 1) in vec3 inNormal;
@ -37,7 +37,7 @@ void main()
Material material = matUniform.materials[push_constants.materialIdx]; Material material = matUniform.materials[push_constants.materialIdx];
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.9){discard;}
outAlbedo = texColor; outAlbedo = texColor;
} else{ } else{
outAlbedo = material.diffuseColor; outAlbedo = material.diffuseColor;

View file

@ -1,6 +1,6 @@
#version 450 #version 450
const int MAX_TEXTURES = 512; const int MAX_TEXTURES = 128;
layout(location = 0) in vec4 inPos; layout(location = 0) in vec4 inPos;
layout(location = 1) in vec3 inNormal; layout(location = 1) in vec3 inNormal;
@ -13,6 +13,14 @@ layout(location = 0) out vec4 outPos;
layout(location = 2) out vec4 outNormal; layout(location = 2) out vec4 outNormal;
layout(location = 3) out vec4 outPBR; layout(location = 3) out vec4 outPBR;
const float bayerMatrix[16] = float[](
0.0 / 16.0, 8.0 / 16.0, 2.0 / 16.0, 10.0 / 16.0,
12.0 / 16.0, 4.0 / 16.0, 14.0 / 16.0, 6.0 / 16.0,
3.0 / 16.0, 11.0 / 16.0, 1.0 / 16.0, 9.0 / 16.0,
15.0 / 16.0, 7.0 / 16.0, 13.0 / 16.0, 5.0 / 16.0
);
struct Material { struct Material {
vec4 diffuseColor; vec4 diffuseColor;
uint hasTexture; uint hasTexture;
@ -57,7 +65,7 @@ void main()
} }
if(outAlbedo.a < 0.05 || outAlbedo.a >= 0.75) discard; if(outAlbedo.a >= 0.75 || outAlbedo.a < 0.05f) discard;
mat3 TBN = mat3(inTangent, inBitangent, inNormal); mat3 TBN = mat3(inTangent, inBitangent, inNormal);
vec3 newNormal = calcNormal(material, inNormal, inTextCoords, TBN); vec3 newNormal = calcNormal(material, inNormal, inTextCoords, TBN);

View file

@ -0,0 +1,5 @@
#version 450
void main() {
}

View file

@ -0,0 +1,5 @@
#version 450
void main() {
}

View file

@ -0,0 +1,5 @@
#version 450
void main() {
}

View file

@ -0,0 +1,11 @@
#version 450
layout(location = 0) in vec3 outTexCoords;
layout(location = 1) out vec4 outColor;
layout(set = 2, binding = 0) uniform samplerCube skyboxSampler;
void main() {
outColor = vec4(texture(skyboxSampler, outTexCoords).rgb, 1.0);
}

View file

@ -0,0 +1,18 @@
#version 450
layout(location = 0) in vec3 inPosition;
layout(location = 0) out vec3 outTexCoords;
layout(set = 0, binding = 0) uniform ProjectionBuffer {
mat4 proj;
} uboProj;
layout(set = 1, binding = 0) uniform ViewBuffer {
mat4 view;
} uboView;
void main() {
outTexCoords = inPosition;
mat4 skyView = mat4(mat3(uboView.view));
vec4 pos = uboProj.proj * skyView * vec4(inPosition, 1.0);
gl_Position = vec4(pos.xy, 0.0, pos.w);
}

View file

@ -3,7 +3,9 @@ package net.halbear.Terrain4J.EngineCore.Display;
import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig; import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig;
import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance; import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance;
import net.halbear.Terrain4J.EngineCore.Logic.InitData; import net.halbear.Terrain4J.EngineCore.Logic.InitData;
import net.halbear.Terrain4J.EngineCore.Logic.Rendering.SkyBox;
import net.halbear.Terrain4J.EngineCore.Logic.Rendering.VulkanContext; import net.halbear.Terrain4J.EngineCore.Logic.Rendering.VulkanContext;
import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime;
import net.halbear.Terrain4J.EngineCore.Vulkan.GUI.GuiRenderer; import net.halbear.Terrain4J.EngineCore.Vulkan.GUI.GuiRenderer;
import net.halbear.Terrain4J.EngineCore.Vulkan.GUI.GuiTexture; import net.halbear.Terrain4J.EngineCore.Vulkan.GUI.GuiTexture;
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.DeferredRendering.LightRenderer; import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.DeferredRendering.LightRenderer;
@ -58,6 +60,8 @@ public class Render {
private TextureCache textureCache; private TextureCache textureCache;
private EngineConfig.AntiAliasType CurrentAAMode; private EngineConfig.AntiAliasType CurrentAAMode;
private final boolean Deferred; private final boolean Deferred;
private float LastGamma = 0.8545f;
public TextureCache GetTextureCache(){return textureCache;} public TextureCache GetTextureCache(){return textureCache;}
public MaterialsCache GetMaterialsCache(){return materialsCache;} public MaterialsCache GetMaterialsCache(){return materialsCache;}
@ -105,6 +109,7 @@ public class Render {
modelsCache = new ModelsCache(); modelsCache = new ModelsCache();
Resize = false; Resize = false;
CurrentAAMode = EngineConfig.getInstance().RenderAAType(); CurrentAAMode = EngineConfig.getInstance().RenderAAType();
LastGamma = EngineConfig.getInstance().GetGamma();
} }
public void Initialise(InitData initData){ public void Initialise(InitData initData){
@ -115,6 +120,15 @@ public class Render {
Logger.debug("Loaded {} Materials", Materials.size()); Logger.debug("Loaded {} Materials", Materials.size());
List<GuiTexture> guiTextures = initData.GuiTextures(); List<GuiTexture> guiTextures = initData.GuiTextures();
String[] SkyBoxTextures = new String[]{
"resources/EngineResources/SkyBoxTextures/skySide.png",
"resources/EngineResources/SkyBoxTextures/skySide.png",
"resources/EngineResources/SkyBoxTextures/SkyTop.png",
"resources/EngineResources/SkyBoxTextures/SkyTop.png",
"resources/EngineResources/SkyBoxTextures/skySide.png",
"resources/EngineResources/SkyBoxTextures/skySide.png"
};
textureCache.AddCubeMapTexture(RendererContext, DeferredSceneRender.SkyBoxID,SkyBoxTextures,VK_FORMAT_R8G8B8A8_SRGB);
if(guiTextures != null){ if(guiTextures != null){
initData.GuiTextures().forEach(texture -> textureCache.AddTexture(RendererContext, texture.TexturePath(), texture.TexturePath(), VK_FORMAT_R8G8B8A8_SRGB)); initData.GuiTextures().forEach(texture -> textureCache.AddTexture(RendererContext, texture.TexturePath(), texture.TexturePath(), VK_FORMAT_R8G8B8A8_SRGB));
} }
@ -127,6 +141,7 @@ public class Render {
Models.addAll(initData.Models()); Models.addAll(initData.Models());
Logger.debug("Loading {} models", Models.size()); Logger.debug("Loading {} models", Models.size());
//modelsCache.CleanUp(RendererContext); //modelsCache.CleanUp(RendererContext);
modelsCache.CreateSkybox(RendererContext, SkyBox.SkyBoxMesh.VERTICES,DeferredSceneRender.SkyBoxID);
modelsCache.loadModels(RendererContext, Models, CommandPools[0], GraphicsQueue); modelsCache.loadModels(RendererContext, Models, CommandPools[0], GraphicsQueue);
Logger.debug("Loaded {} models", Models.size()); Logger.debug("Loaded {} models", Models.size());
@ -227,6 +242,10 @@ public class Render {
public void render(EngineInstance engineInstance){ public void render(EngineInstance engineInstance){
if(Deferred) DeferredRender(engineInstance); if(Deferred) DeferredRender(engineInstance);
else ForwardRender(engineInstance); else ForwardRender(engineInstance);
// if(LastGamma != EngineConfig.getInstance().GetGamma()){
// vkDeviceWaitIdle(RendererContext.GetDevice().FetchVulkanDevice());
// PrimaryRuntime.GetRenderThread().RefreshRenderer();
// }
} }
private void resize(EngineInstance engineInstance){ private void resize(EngineInstance engineInstance){

View file

@ -41,7 +41,8 @@ public class Window {
glfwDefaultWindowHints(); glfwDefaultWindowHints();
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
glfwWindowHint(GLFW_MAXIMIZED, GLFW_FALSE); glfwWindowHint(GLFW_MAXIMIZED, GLFW_FALSE);
glfwWindowHint(GLFW_ALPHA_BITS, 0);
glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER, GLFW_FALSE);
handle = glfwCreateWindow(width, height, title, MemoryUtil.NULL, MemoryUtil.NULL); handle = glfwCreateWindow(width, height, title, MemoryUtil.NULL, MemoryUtil.NULL);
if (handle == MemoryUtil.NULL) { if (handle == MemoryUtil.NULL) {
//throw new RuntimeException("Failed to create the GLFW window"); //throw new RuntimeException("Failed to create the GLFW window");
@ -72,6 +73,7 @@ public class Window {
IconBuffer.free(); //free the buffer once icon is set so when the program closes there isn't memory still floating around IconBuffer.free(); //free the buffer once icon is set so when the program closes there isn't memory still floating around
Logger.debug("Freeing icon Buffer"); Logger.debug("Freeing icon Buffer");
glfwSetWindowFocusCallback(handle, new GLFWWindowFocusCallback() { glfwSetWindowFocusCallback(handle, new GLFWWindowFocusCallback() {
@Override @Override
public void invoke(long window, boolean focused) { public void invoke(long window, boolean focused) {

View file

@ -55,7 +55,7 @@ public class EngineConfig {
private String PhysicalDeviceName; private String PhysicalDeviceName;
private int RequestedImages; private int RequestedImages;
private String IconPath = "/WindowResources/Icon/"; private String IconPath = "/WindowResources/Icon/";
private String DefaultTexturePath = "resources/EngineResources/Texture/DefaultTexture.png"; private String DefaultTexturePath = "resources/EngineResources/Texture/NoTexture.png";
private String IconName = "ProgramIcon.png"; private String IconName = "ProgramIcon.png";
private float FOV = 60f; private float FOV = 60f;
private float zFarPlane; private float zFarPlane;
@ -73,7 +73,13 @@ public class EngineConfig {
public boolean AlphaToCoverage = false; public boolean AlphaToCoverage = false;
public boolean CompatibilityMode = false; public boolean CompatibilityMode = false;
public Renderer renderer = Renderer.Forward; public Renderer renderer = Renderer.Forward;
public int ShadowMapSize = 16;
public float Gamma = 0.8545f;
public int MaxVulkanCrashesAllowed = 10;
public int GetMaxVulkanCrashes(){return MaxVulkanCrashesAllowed;}
public void SetShadowMapSize(int ShadowSize){this.ShadowMapSize = ShadowSize;}
public int GetShadowMapSize(){return ShadowMapSize;}
public void SetRenderer(Renderer renderer){this.renderer = renderer;} public void SetRenderer(Renderer renderer){this.renderer = renderer;}
public boolean DeferredRendering(){return renderer == Renderer.Deferred;} public boolean DeferredRendering(){return renderer == Renderer.Deferred;}
public boolean AlphaToCoverage(){return AlphaToCoverage;} public boolean AlphaToCoverage(){return AlphaToCoverage;}
@ -85,6 +91,7 @@ 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 float GetGamma(){return Gamma;}
public boolean CompatibilityMode(){return CompatibilityMode;} public boolean CompatibilityMode(){return CompatibilityMode;}
public void SetCompatibilitMode(boolean compatibilityMode){this.CompatibilityMode = compatibilityMode;} public void SetCompatibilitMode(boolean compatibilityMode){this.CompatibilityMode = compatibilityMode;}
public int GetCoreCount(){return CPU_CORE_COUNT;} public int GetCoreCount(){return CPU_CORE_COUNT;}
@ -217,6 +224,8 @@ public class EngineConfig {
zFarPlane = (Float.parseFloat(EngineConfigVar.getOrDefault("z_far_plane", 100.0f).toString())); 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; renderer = Integer.parseInt(EngineConfigVar.getOrDefault("Renderer", 1).toString()) == 0 ? Renderer.Forward: Renderer.Deferred;
ShadowMapSize = Integer.parseInt(EngineConfigVar.getOrDefault("ShadowMapSize", 16).toString());
MaxVulkanCrashesAllowed = Integer.parseInt(EngineConfigVar.getOrDefault("MaxAllowedVulkanCrashes", 10).toString());
CompatibilityMode = Boolean.parseBoolean(EngineConfigVar.getOrDefault("compatibility_mode", false).toString()); CompatibilityMode = Boolean.parseBoolean(EngineConfigVar.getOrDefault("compatibility_mode", false).toString());
AlphaToCoverage = Boolean.parseBoolean(EngineConfigVar.getOrDefault("AlphaToCoverage", false).toString()); AlphaToCoverage = Boolean.parseBoolean(EngineConfigVar.getOrDefault("AlphaToCoverage", false).toString());
ForwardSceneRender.SetDualPassRendering(Boolean.parseBoolean(EngineConfigVar.getOrDefault("DualPassRendering", true).toString())); ForwardSceneRender.SetDualPassRendering(Boolean.parseBoolean(EngineConfigVar.getOrDefault("DualPassRendering", true).toString()));

View file

@ -0,0 +1,32 @@
package net.halbear.Terrain4J.EngineCore.Logic.Rendering;
import net.halbear.Terrain4J.EngineCore.Main.Scene.Camera;
import org.joml.Matrix4f;
import org.joml.Vector3f;
import java.nio.ByteBuffer;
public class SkyBox {
public static class SkyBoxMesh{
public static final float[] VERTICES = {
-1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f,
1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f,
-1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f,
-1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f,
1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f,
-1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f,
-1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f,
-1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f,
1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f
};
}
}

View file

@ -38,7 +38,7 @@ import static org.lwjgl.glfw.GLFW.*;
public class GameCore implements GameLogic { public class GameCore implements GameLogic {
private static final float MOUSE_SENSITIVITY = 0.1f; private static final float MOUSE_SENSITIVITY = 0.1f;
private static final float MOVEMENT_SPEED = 0.525f; private static final float MOVEMENT_SPEED = 0.025f;
private static final String SOUND_BUFFER_MUSIC = "music-sound-buffer"; private static final String SOUND_BUFFER_MUSIC = "music-sound-buffer";
private static final String SOUND_BUFFER_PLAYER = "player-sound-buffer"; private static final String SOUND_BUFFER_PLAYER = "player-sound-buffer";
@ -80,25 +80,25 @@ public class GameCore implements GameLogic {
List<ModelData> models = new ArrayList<>(); List<ModelData> models = new ArrayList<>();
MusicParticle = ModelLoader.LoadModel("resources/models/MusicParticle/MusicParticle.json"); MusicParticle = ModelLoader.LoadModel("resources/models/MusicParticle/MusicParticle.json");
List<MaterialData> MusicParticleMat = ModelLoader.LoadMaterials("resources/models/MusicParticle/MusicParticle_mat.json"); List<MaterialData> MusicParticleMat = ModelLoader.LoadMaterials("resources/models/MusicParticle/MusicParticle_mat.json");
// ModelData SponzaData = ModelLoader.LoadModel("resources/models/room/living_room.json"); ModelData SponzaData = ModelLoader.LoadModel("resources/models/Forest/forest.json");
// List<MaterialData> SponzaMaterial = ModelLoader.LoadMaterials("resources/models/room/living_room_mat.json"); List<MaterialData> SponzaMaterial = ModelLoader.LoadMaterials("resources/models/Forest/forest_mat.json");
radio = ModelLoader.LoadModel("resources/models/radio/radio.json"); radio = ModelLoader.LoadModel("resources/models/radio/radio.json");
List<MaterialData> SponzaMaterial2 = ModelLoader.LoadMaterials("resources/models/radio/radio_mat.json"); List<MaterialData> SponzaMaterial2 = ModelLoader.LoadMaterials("resources/models/radio/radio_mat.json");
ModelData SponzaData = ModelLoader.LoadModel("resources/models/Cafe/exterior.json"); // ModelData SponzaData = ModelLoader.LoadModel("resources/models/Cafe/exterior.json");
List<MaterialData> SponzaMaterial = ModelLoader.LoadMaterials("resources/models/Cafe/exterior_mat.json"); // List<MaterialData> SponzaMaterial = ModelLoader.LoadMaterials("resources/models/Cafe/exterior_mat.json");
ModelData SponzaData1 = ModelLoader.LoadModel("resources/models/Cafe/interior.json"); // ModelData SponzaData1 = ModelLoader.LoadModel("resources/models/Cafe/interior.json");
List<MaterialData> SponzaMaterial1= ModelLoader.LoadMaterials("resources/models/Cafe/interior_mat.json"); // List<MaterialData> SponzaMaterial1= ModelLoader.LoadMaterials("resources/models/Cafe/interior_mat.json");
scene.AddActor(new Actor("Sponza1", SponzaData.ID(), new Vector3f(0,0f,-5f))); scene.AddActor(new Actor("Sponza1", SponzaData.ID(), new Vector3f(0,0f,-5f)));
scene.AddActor(new Actor("Sponza2", SponzaData1.ID(), new Vector3f(0,0f,-5f))); // scene.AddActor(new Actor("Sponza2", SponzaData1.ID(), new Vector3f(0,0f,-5f)));
CubeActors.forEach(scene::AddActor); CubeActors.forEach(scene::AddActor);
List<MaterialData> materials = new ArrayList<>(); List<MaterialData> materials = new ArrayList<>();
materials.addAll(SponzaMaterial); materials.addAll(SponzaMaterial);
materials.addAll(MusicParticleMat); materials.addAll(MusicParticleMat);
materials.addAll(SponzaMaterial1); // materials.addAll(SponzaMaterial1);
materials.addAll(SponzaMaterial2); materials.addAll(SponzaMaterial2);
models.add(SponzaData1); // models.add(SponzaData1);
models.add(SponzaData); models.add(SponzaData);
models.add(MusicParticle); models.add(MusicParticle);
models.add(radio); models.add(radio);
@ -110,26 +110,26 @@ public class GameCore implements GameLogic {
scene.AddCameraFrame("Fifth", new CameraFrame(new Vector3f(64.92f,158.06f,-35.25f),new Vector3f(-11.20f,156.5f,0.0f),scene.GetCamera().GetFOV(),"Sixth")); scene.AddCameraFrame("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")); 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/Billy.png");
Logger.debug("GUI TEXTURE CREATED, ID->[{}], PATH->[{}]",guiTexture.ID(),guiTexture.TexturePath()); 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);
scene.GetLightingManager().GetAmbientLightColour().set(0.5f, 0.5f, 0.5f); scene.GetLightingManager().GetAmbientLightColour().set(1.0f, 0.9f, 0.75f);
scene.GetLightingManager().SetAmbientLightIntensity(0.01f); scene.GetLightingManager().SetAmbientLightIntensity(1.5f);
SkyLight = new Light(new Vector3f(0.25f, 1.0f, 1.5f),new Vector3f(0.0f, -1.0f, 0.0f), true, 0.70f); SkyLight = new Light(new Vector3f(1.5f, 1.20f, 1.0f),new Vector3f(0.0f, -1.0f, 0.0f), true, 10.00f);
List<ILight> lights = new ArrayList<>(); List<ILight> lights = new ArrayList<>();
//lights.add(new Light(new Vector3f(2.9f,2.75f,1.5f),new Vector3f(0.35f,2.69f,-2.11f),false,3.0f)); //lights.add(new Light(new Vector3f(2.9f,2.75f,1.5f),new Vector3f(0.35f,2.69f,-2.11f),false,3.0f));
//lights.add(new Light(new Vector3f(3.0f,2.5f,0.75f),new Vector3f(2.65f,1.57f,-3.31f),false,0.5f)); //lights.add(new Light(new Vector3f(3.0f,2.5f,0.75f),new Vector3f(2.65f,1.57f,-3.31f),false,0.5f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-433, 445f, -424f),false,300000.0f+ (float)(Math.random() * 10000.0))); /*lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-433, 445f, -424f),false,300000.0f+ (float)(Math.random() * 10000.0)));
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-210, 445f, 460f),false,70000.0f + (float)(Math.random() * 15000.0f))); lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-210, 445f, 460f),false,70000.0f + (float)(Math.random() * 15000.0f)));
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-966, 445f, 204f),false,70000.0f + (float)(Math.random() * 15000.0f))); lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-966, 445f, 204f),false,70000.0f + (float)(Math.random() * 15000.0f)));
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-176, 445f, 1000f),false,70000.0f + (float)(Math.random() * 15000.0f))); lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-176, 445f, 1000f),false,70000.0f + (float)(Math.random() * 15000.0f)));
@ -160,9 +160,10 @@ public class GameCore implements GameLogic {
lights.add(new Light(new Vector3f(0.75f,2.0f,0.75f),new Vector3f(1086, 425, -3375),false,50000.0f)); lights.add(new Light(new Vector3f(0.75f,2.0f,0.75f),new Vector3f(1086, 425, -3375),false,50000.0f));
*/
//lights.add(new Light(new Vector3f(3.0f,2.75f,0.0f),new Vector3f(35.0f, 150.0f, -42.0f),false,100.0f)); lights.add(new Light(new Vector3f(3.0f,2.75f,0.0f),new Vector3f(35.0f, 150.0f, -42.0f),false,100.0f));
//lights.add(new Light(new Vector3f(0.0f,3.0f,0.0f),new Vector3f(40.0f, 155.0f, -35.0f),false,20.0f)); lights.add(new Light(new Vector3f(0.0f,3.0f,0.0f),new Vector3f(40.0f, 155.0f, -35.0f),false,20.0f));
lights.add(SkyLight); lights.add(SkyLight);
ILight[] lightArr = new ILight[lights.size()]; ILight[] lightArr = new ILight[lights.size()];

View file

@ -2,7 +2,9 @@ package net.halbear.Terrain4J.EngineCore.Main.Scene.GUIs;
import imgui.ImGui; import imgui.ImGui;
import imgui.flag.ImGuiCond; import imgui.flag.ImGuiCond;
import imgui.flag.ImGuiInputTextFlags;
import imgui.flag.ImGuiWindowFlags; import imgui.flag.ImGuiWindowFlags;
import imgui.type.ImFloat;
import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig; import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig;
import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance; import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance;
import net.halbear.Terrain4J.EngineCore.Main.GameCore; import net.halbear.Terrain4J.EngineCore.Main.GameCore;
@ -15,6 +17,7 @@ import org.joml.Vector3f;
import org.tinylog.Logger; import org.tinylog.Logger;
public class PerformanceOverlay implements GUIOverlay { public class PerformanceOverlay implements GUIOverlay {
private final ImFloat GammaValue = new ImFloat(0.8545f);
@Override @Override
public void RenderGUI(EngineInstance engineInstance, long frameTimeNS, GameCore parent) { public void RenderGUI(EngineInstance engineInstance, long frameTimeNS, GameCore parent) {
int windowFlags = ImGuiWindowFlags.NoDecoration int windowFlags = ImGuiWindowFlags.NoDecoration
@ -139,6 +142,10 @@ public class PerformanceOverlay implements GUIOverlay {
EngineConfig.getInstance().SetAlphaToCoverage(true); EngineConfig.getInstance().SetAlphaToCoverage(true);
PrimaryRuntime.GetRenderThread().GetRenderer().GetSceneRender().RebuildPipelines(PrimaryRuntime.GetRenderThread().GetRenderer().GetVulkanContext()); PrimaryRuntime.GetRenderThread().GetRenderer().GetSceneRender().RebuildPipelines(PrimaryRuntime.GetRenderThread().GetRenderer().GetVulkanContext());
} }
ImGui.inputFloat("Gamma", GammaValue, 0.0025f, 0.22725f, "%.4f");
if (ImGui.isItemDeactivatedAfterEdit()) {
// EngineConfig.getInstance().Gamma = GammaValue.get();
}
ImGui.separator(); ImGui.separator();
ImGui.text("Level Tools:"); ImGui.text("Level Tools:");
if(ImGui.button("Spawn Radio")){ if(ImGui.button("Spawn Radio")){

View file

@ -1,6 +1,7 @@
package net.halbear.Terrain4J.EngineCore.Main.Scene; package net.halbear.Terrain4J.EngineCore.Main.Scene;
import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance; import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance;
import net.halbear.Terrain4J.EngineCore.Logic.Rendering.SkyBox;
import net.halbear.Terrain4J.EngineCore.Main.GameCore; import net.halbear.Terrain4J.EngineCore.Main.GameCore;
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Projection.Project3D; import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Projection.Project3D;
@ -31,4 +32,6 @@ public interface IScene {
public String GetActiveCameraFrame(); public String GetActiveCameraFrame();
public void SetUpAudio(EngineInstance engineInstance); public void SetUpAudio(EngineInstance engineInstance);
public ISceneLightingManager GetLightingManager(); public ISceneLightingManager GetLightingManager();
public SkyBox GetSkyBox();
public void SetSkyBox(SkyBox skyBox);
} }

View file

@ -5,6 +5,7 @@ import net.halbear.Terrain4J.EngineCore.Input.KeyboardInput;
import net.halbear.Terrain4J.EngineCore.Input.MouseListener; import net.halbear.Terrain4J.EngineCore.Input.MouseListener;
import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig; import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig;
import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance; import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance;
import net.halbear.Terrain4J.EngineCore.Logic.Rendering.SkyBox;
import net.halbear.Terrain4J.EngineCore.Main.GameCore; import net.halbear.Terrain4J.EngineCore.Main.GameCore;
import net.halbear.Terrain4J.EngineCore.Main.Scene.GUIs.PerformanceOverlay; import net.halbear.Terrain4J.EngineCore.Main.Scene.GUIs.PerformanceOverlay;
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Projection.Project3D; import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Projection.Project3D;
@ -38,10 +39,17 @@ public class Scene implements IScene {
public float CurrentTransitionTick = 0; public float CurrentTransitionTick = 0;
private Vector2f LastMousePos = new Vector2f(0,0); private Vector2f LastMousePos = new Vector2f(0,0);
private final ISceneLightingManager lightingManager; private final ISceneLightingManager lightingManager;
private SkyBox skyBox;
public List<String> ActiveGUIs = new ArrayList<>(); public List<String> ActiveGUIs = new ArrayList<>();
public Map<String, GUIOverlay> GUIReg = new HashMap<>(); public Map<String, GUIOverlay> GUIReg = new HashMap<>();
public void SetSkyBox(SkyBox skyBox){
this.skyBox = skyBox;
}
public SkyBox GetSkyBox(){return skyBox;}
public Scene(Window window) { public Scene(Window window) {
lightingManager = new SceneLightingManager(1000,new Vector3f(1f,1f,1f), 0.5f); lightingManager = new SceneLightingManager(1000,new Vector3f(1f,1f,1f), 0.5f);
Actors = new ArrayList<>(); Actors = new ArrayList<>();

View file

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

View file

@ -15,6 +15,7 @@ public class RenderThread extends EngineThread {
private Render render; private Render render;
private Window window; private Window window;
private final InitData initData; private final InitData initData;
public static int VulkanCrashCount = 0;
public RenderThread(Window window, EngineInstance engineInstance, InitData initData, GameLogic appLogic) { public RenderThread(Window window, EngineInstance engineInstance, InitData initData, GameLogic appLogic) {
//this.window = window; //this.window = window;
@ -24,6 +25,17 @@ public class RenderThread extends EngineThread {
render.Initialise(initData); render.Initialise(initData);
} }
public void RestartCrashedRenderer(){
if(VulkanCrashCount < EngineConfig.getInstance().GetMaxVulkanCrashes()){
RefreshRenderer();
VulkanCrashCount++;
}else{
Logger.error("MAX VULKAN CRASHES REACHED, CLOSING SOFTWARE");
PrimaryRuntime.GetEngineInstance().window().setShouldClose();
PrimaryRuntime.CloseRuntime();
}
}
public Render GetRenderer(){return render;} public Render GetRenderer(){return render;}
@Override @Override
@ -40,6 +52,7 @@ public class RenderThread extends EngineThread {
} }
public void RefreshRenderer(){ public void RefreshRenderer(){
Logger.debug("REFRESHING RENDERER");
render.cleanup(); render.cleanup();
render = new Render(PrimaryRuntime.GetEngineInstance()); render = new Render(PrimaryRuntime.GetEngineInstance());
render.Initialise(initData); render.Initialise(initData);

View file

@ -145,7 +145,7 @@ public class GuiRenderer {
var guiTexture = GuiTextures.get(i); var guiTexture = GuiTextures.get(i);
String descriptorID = guiTexture.TexturePath(); String descriptorID = guiTexture.TexturePath();
DescriptorSet descriptorSet = descriptorAllocator.AddDescriptorSets(device, descriptorID, 1, TextDescriptorSetLayout)[0]; DescriptorSet descriptorSet = descriptorAllocator.AddDescriptorSets(device, descriptorID, 1, TextDescriptorSetLayout)[0];
Texture texture = textureCache.GetTexture(guiTexture.TexturePath()); ITexture texture = textureCache.GetTexture(guiTexture.TexturePath());
descriptorSet.SetImage(device,texture.GetImageView(),FontsTextureSampler,TextDescriptorSetLayout.GetLayoutInfo().Binding()); 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); //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());

View file

@ -12,7 +12,7 @@ import static org.lwjgl.vulkan.VK10.VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
public class MultiRenderTargetAttachments { public class MultiRenderTargetAttachments {
public static final int ALBEDO_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT; public static final int ALBEDO_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT;
public static final int DEPTH_FORMAT = VK_FORMAT_D32_SFLOAT_S8_UINT; public static final int DEPTH_FORMAT = VK_FORMAT_D32_SFLOAT;
public static final int NORMAL_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT; public static final int NORMAL_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT;
public static final int PBR_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT; public static final int PBR_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT;
public static final int POSITION_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT; public static final int POSITION_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT;

View file

@ -124,6 +124,7 @@ public class DefaultPipeline implements Pipeline {
ppLayout.put(i, descriptorSetLayouts[i].GetVkDescriptorLayout()); ppLayout.put(i, descriptorSetLayouts[i].GetVkDescriptorLayout());
} }
Logger.debug("registered Descriptor sets");
int[] ColourFormats = BuildInfo.GetColourFormat(); int[] ColourFormats = BuildInfo.GetColourFormat();
int ColourFormatCount = ColourFormats.length; int ColourFormatCount = ColourFormats.length;
@ -135,6 +136,8 @@ public class DefaultPipeline implements Pipeline {
.colorAttachmentCount(ColourFormatCount) .colorAttachmentCount(ColourFormatCount)
.pColorAttachmentFormats(ColourFormatsBuffer); .pColorAttachmentFormats(ColourFormatsBuffer);
Logger.debug("created render info");
if(DepthStencil != null){RendererCreateInfo.depthAttachmentFormat(BuildInfo.GetDepthFormat());} if(DepthStencil != null){RendererCreateInfo.depthAttachmentFormat(BuildInfo.GetDepthFormat());}
VkPipelineColorBlendAttachmentState.Buffer BlendAttributeState = VkPipelineColorBlendAttachmentState.calloc(ColourFormatCount,MemStack); VkPipelineColorBlendAttachmentState.Buffer BlendAttributeState = VkPipelineColorBlendAttachmentState.calloc(ColourFormatCount,MemStack);
@ -146,10 +149,11 @@ public class DefaultPipeline implements Pipeline {
.alphaBlendOp(VK_BLEND_OP_ADD) .alphaBlendOp(VK_BLEND_OP_ADD)
.srcColorBlendFactor(VK_BLEND_FACTOR_SRC_ALPHA) .srcColorBlendFactor(VK_BLEND_FACTOR_SRC_ALPHA)
.dstColorBlendFactor(VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA) .dstColorBlendFactor(VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA)
.srcAlphaBlendFactor(BuildInfo.GetBlendingMethod() == 0 ? VK_BLEND_FACTOR_ONE : VK_BLEND_FACTOR_SRC_ALPHA) .srcAlphaBlendFactor(BuildInfo.GetBlendingMethod() == 0 || BuildInfo.GetBlendingMethod() == 2 ? VK_BLEND_FACTOR_ONE : VK_BLEND_FACTOR_SRC_ALPHA)
.dstAlphaBlendFactor(BuildInfo.GetBlendingMethod() == 0 ? VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA : VK_BLEND_FACTOR_ZERO); .dstAlphaBlendFactor(BuildInfo.GetBlendingMethod() == 0 ? VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA : VK_BLEND_FACTOR_ZERO);
} }
} }
Logger.debug("created BlendAttributeStates");
var ColourBlendState = VkPipelineColorBlendStateCreateInfo.calloc(MemStack) var ColourBlendState = VkPipelineColorBlendStateCreateInfo.calloc(MemStack)
.sType$Default() .sType$Default()
@ -157,17 +161,44 @@ public class DefaultPipeline implements Pipeline {
var PipelineLayoutCreateInfoPtr = VkPipelineLayoutCreateInfo.calloc(MemStack) var PipelineLayoutCreateInfoPtr = VkPipelineLayoutCreateInfo.calloc(MemStack)
.sType$Default() .sType$Default()
.pSetLayouts(ppLayout) .pSetLayouts(ppLayout);
.pPushConstantRanges(VkPushConstRangeBuffer); //.pPushConstantRanges(VkPushConstRangeBuffer);
if (PushConstCount > 0 && VkPushConstRangeBuffer != null) {
PipelineLayoutCreateInfoPtr.pPushConstantRanges(VkPushConstRangeBuffer);
} else {
PipelineLayoutCreateInfoPtr.pPushConstantRanges(null);
}
VulkanUtils.vkCheck(vkCreatePipelineLayout(device.FetchVulkanDevice(), PipelineLayoutCreateInfoPtr,null,longPtr) VulkanUtils.vkCheck(vkCreatePipelineLayout(device.FetchVulkanDevice(), PipelineLayoutCreateInfoPtr,null,longPtr)
,"Unable to create new pipeline layout"); ,"Unable to create new pipeline layout");
VulkanPipelineLayout = longPtr.get(0); VulkanPipelineLayout = longPtr.get(0);
Logger.debug("created PipelineLayout");
VkPipelineVertexInputStateCreateInfo vertexInputState;
var originalInputState = BuildInfo.GetVertexInputStateCreateInfo();
if (originalInputState != null) {
vertexInputState = VkPipelineVertexInputStateCreateInfo.calloc(MemStack)
.sType(VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO)
.pVertexBindingDescriptions(originalInputState.pVertexBindingDescriptions())
.pVertexAttributeDescriptions(originalInputState.pVertexAttributeDescriptions());
} else {
// Fix for your cut-off block: Instantiate an explicit, empty state configuration structure
vertexInputState = VkPipelineVertexInputStateCreateInfo.calloc(MemStack)
.sType(VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO)
.pVertexBindingDescriptions(null)
.pVertexAttributeDescriptions(null);
}
Logger.debug("created vertexInputState");
var PipelineCreateInfo = VkGraphicsPipelineCreateInfo.calloc(1,MemStack) var PipelineCreateInfo = VkGraphicsPipelineCreateInfo.calloc(1,MemStack)
.sType$Default() .sType$Default()
.pStages(ShaderStages) .pStages(ShaderStages)
.pVertexInputState(BuildInfo.GetVertexInputStateCreateInfo()) .pVertexInputState(vertexInputState)
.pInputAssemblyState(AssemblyStateCreateInfo) .pInputAssemblyState(AssemblyStateCreateInfo)
.pViewportState(ViewportCreateStateInfo) .pViewportState(ViewportCreateStateInfo)
.pRasterizationState(RasterizationStateCreateInfo) .pRasterizationState(RasterizationStateCreateInfo)
@ -177,12 +208,14 @@ public class DefaultPipeline implements Pipeline {
.layout(VulkanPipelineLayout) .layout(VulkanPipelineLayout)
.pNext(RendererCreateInfo); .pNext(RendererCreateInfo);
Logger.debug("created PipelineCreateInfo");
if(DepthStencil != null){PipelineCreateInfo.pDepthStencilState(DepthStencil);} if(DepthStencil != null){PipelineCreateInfo.pDepthStencilState(DepthStencil);}
VulkanUtils.vkCheck(vkCreateGraphicsPipelines(device.FetchVulkanDevice(), VulkanUtils.vkCheck(vkCreateGraphicsPipelines(device.FetchVulkanDevice(),
VkCtx.GetVkPipelineCache().GetVkPipelineCache(), PipelineCreateInfo, VkCtx.GetVkPipelineCache().GetVkPipelineCache(), PipelineCreateInfo,
null, longPtr),"Could not create new pipeline"); null, longPtr),"Could not create new pipeline");
Logger.debug("created GraphicsPipeline");
VulkanPipeline = longPtr.get(0); VulkanPipeline = longPtr.get(0);
} }
} }

View file

@ -22,7 +22,7 @@ public class Attachment {
} }
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); ImageData.Usage(Usage | VK_IMAGE_USAGE_SAMPLED_BIT);
AspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; AspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
DepthAttachment = true; DepthAttachment = true;
} }
VkImage = new Image(VkCtx, ImageData); VkImage = new Image(VkCtx, ImageData);

View file

@ -0,0 +1,169 @@
package net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Images;
import net.halbear.Terrain4J.EngineCore.Logic.Rendering.VulkanContext;
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.GraphUtils;
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.CommandBuffer;
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DisplayToScreen.ImageView;
import net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanBuffer;
import org.lwjgl.system.MemoryStack;
import org.lwjgl.system.MemoryUtil;
import org.lwjgl.vulkan.*;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.LongBuffer;
import static org.lwjgl.system.MemoryUtil.memByteBuffer;
import static org.lwjgl.util.vma.Vma.VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT;
import static org.lwjgl.util.vma.Vma.VMA_MEMORY_USAGE_AUTO;
import static org.lwjgl.vulkan.VK10.*;
import static org.lwjgl.vulkan.VK13.vkCmdPipelineBarrier2;
public class CubeMapTexture implements ITexture{
private final String id;
private final int Height;
private final int Width;
private final Image image;
private final ImageView imageView;
private boolean RecordedTransition;
private VulkanBuffer stgBuffer;
private final long layerSize;
public CubeMapTexture(VulkanContext vkCtx, String id, String[] facePaths, int format) throws IOException {
this.id = id;
ImageSrc firstFace = GraphUtils.LoadImage(facePaths[0]);
Width = firstFace.Width();
Height = firstFace.Height();
this.layerSize = (long) Width * Height * 4;
long totalBufferSize = layerSize * 6;
GraphUtils.CleanImageData(firstFace);
this.stgBuffer = new VulkanBuffer(vkCtx, totalBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
0, 0, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
long mappedAddress = stgBuffer.MapMemory(vkCtx);
ByteBuffer byteBuffer = memByteBuffer(mappedAddress, (int) totalBufferSize);
for (int i = 0; i < 6; i++) {
ImageSrc currentFace = GraphUtils.LoadImage(facePaths[i]);
ByteBuffer pixelData = currentFace.data();
ByteBuffer targetSlice = byteBuffer.duplicate();
targetSlice.position((int) (i * layerSize));
targetSlice.limit((int) ((i + 1) * layerSize));
targetSlice.put(pixelData);
GraphUtils.CleanImageData(currentFace);
}
CreateStgBuffer(vkCtx, byteBuffer);
stgBuffer.UnMapMemory(vkCtx);
var ImageData = new Image.ImageData().Width(Width).Height(Height)
.Usage(VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT)
.Format(format).MipMapLevels(1).ArrayLayers(6).Flags(VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT);
image = new Image(vkCtx, ImageData);
var ImageViewData = new ImageView.ImageViewData().Format(image.GetFormat())
.AspectMask(VK_IMAGE_ASPECT_COLOR_BIT).MipLevels(1).LayerCount(6).ViewType(VK_IMAGE_VIEW_TYPE_CUBE);
imageView = new ImageView(vkCtx.GetDevice(), image.getVulkanImage(), ImageViewData, false);
}
@Override
public boolean HasTransparency() {
return false;
}
@Override
public void SetTransparency(ByteBuffer data) {
}
public void CreateStgBuffer(VulkanContext VkCtx, ByteBuffer data){
int Size = data.remaining();
stgBuffer = new VulkanBuffer(VkCtx, Size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VMA_MEMORY_USAGE_AUTO,
VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
long MappedMemory = stgBuffer.MapMemory(VkCtx);
ByteBuffer buffer = memByteBuffer(MappedMemory, (int) stgBuffer.GetRequestedSize());
buffer.put(data);
data.flip();
stgBuffer.UnMapMemory(VkCtx);
}
private void RecordImageTransition(MemoryStack stack, CommandBuffer cmd) {
var imageBarrier = VkImageMemoryBarrier2.calloc(1, stack)
.sType$Default()
.oldLayout(VK_IMAGE_LAYOUT_UNDEFINED)
.newLayout(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL)
.srcStageMask(VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT)
.dstStageMask(VK_PIPELINE_STAGE_TRANSFER_BIT)
.srcAccessMask(0)
.dstAccessMask(VK_ACCESS_TRANSFER_WRITE_BIT)
.subresourceRange(it -> it
.aspectMask(VK_IMAGE_ASPECT_COLOR_BIT)
.baseMipLevel(0)
.levelCount(image.GetMipLevels())
.baseArrayLayer(0)
.layerCount(1))
.image(image.getVulkanImage());
VkDependencyInfo depInfo = VkDependencyInfo.calloc(stack)
.sType$Default()
.pImageMemoryBarriers(imageBarrier);
vkCmdPipelineBarrier2(cmd.GetVulkanCommandBuffer(), depInfo);
}
public void RecordTextureTransition(CommandBuffer commandBuffer){
if(stgBuffer != null && !RecordedTransition){
RecordedTransition = true;
try(var MemStack = MemoryStack.stackPush()){
RecordImageTransition(MemStack, commandBuffer);
RecordCopyBuffer(MemStack, commandBuffer, stgBuffer);
}
}
}
private void RecordCopyBuffer(MemoryStack MemStack, CommandBuffer commandBuffer, VulkanBuffer bufferData){
VkBufferImageCopy.Buffer copyRegions = VkBufferImageCopy.calloc(6, MemStack);
for(int i = 0; i < 6; i++) {
int BaseLayer = i;
copyRegions.get(i).bufferOffset(i * layerSize)
.bufferRowLength(0)
.bufferImageHeight(0)
.imageSubresource(it ->
it.aspectMask(VK_IMAGE_ASPECT_COLOR_BIT)
.mipLevel(0)
.baseArrayLayer(BaseLayer)
.layerCount(1)
).imageOffset(it -> it.x(0).y(0).z(0))
.imageExtent().set(Width, Height, 1);
}
vkCmdCopyBufferToImage(commandBuffer.GetVulkanCommandBuffer(), bufferData.GetBuffer(), image.getVulkanImage(),
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, copyRegions);
}
public void CleanUp(VulkanContext VkCtx){
CleanUpStgBuffer(VkCtx);
imageView.cleanup(VkCtx.GetDevice());
image.CleanUp(VkCtx);
}
public void CleanUpStgBuffer(VulkanContext VkCtx){
if(stgBuffer != null){
stgBuffer.cleanup(VkCtx);
stgBuffer = null;
}
}
public int GetHeight(){return Height;}
public int GetWidth(){return Width;}
public String GetID(){return id;}
public ImageView GetImageView(){return imageView;}
@Override
public TextureType getType() {
return TextureType.CubeMap;
}
}

View file

@ -0,0 +1,25 @@
package net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Images;
import net.halbear.Terrain4J.EngineCore.Logic.Rendering.VulkanContext;
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.CommandBuffer;
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DisplayToScreen.ImageView;
import java.nio.ByteBuffer;
public interface ITexture {
public enum TextureType{
FlatImage,
CubeMap
}
public boolean HasTransparency();
public void SetTransparency(ByteBuffer data);
public void CreateStgBuffer(VulkanContext VkCtx, ByteBuffer data);
public void RecordTextureTransition(CommandBuffer commandBuffer);
public void CleanUp(VulkanContext VkCtx);
public void CleanUpStgBuffer(VulkanContext VkCtx);
public int GetHeight();
public int GetWidth();
public String GetID();
public ImageView GetImageView();
public TextureType getType();
}

View file

@ -46,6 +46,7 @@ public class Image {
.height(imageData.Height) .height(imageData.Height)
.depth(1)) .depth(1))
.mipLevels(MipLevels) .mipLevels(MipLevels)
.flags(imageData.Flag)
.arrayLayers(imageData.ArrayLayers) .arrayLayers(imageData.ArrayLayers)
.samples(imageData.SampleCount) .samples(imageData.SampleCount)
.initialLayout(VK_IMAGE_LAYOUT_UNDEFINED) .initialLayout(VK_IMAGE_LAYOUT_UNDEFINED)
@ -83,18 +84,24 @@ public class Image {
private int MipMapLevels; private int MipMapLevels;
private int SampleCount; private int SampleCount;
private int Usage; private int Usage;
private int Flag;
public ImageData(){ public ImageData(){
Format = VK_FORMAT_R8G8B8A8_SRGB; Format = VK_FORMAT_R8G8B8A8_SRGB;
MipMapLevels = 1; MipMapLevels = 1;
SampleCount = 1; SampleCount = 1;
ArrayLayers = 1; ArrayLayers = 1;
Flag = 0;
MemoryUsage = VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT; MemoryUsage = VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT;
} }
public ImageData MemoryUsage(int memoryUsage){ public ImageData MemoryUsage(int memoryUsage){
this.MemoryUsage = memoryUsage; this.MemoryUsage = memoryUsage;
return this; return this;
} }
public ImageData Flags(int flag){
this.Flag = flag;
return this;
}
public ImageData ArrayLayers(int ArrayLayers){ public ImageData ArrayLayers(int ArrayLayers){
this.ArrayLayers = ArrayLayers; this.ArrayLayers = ArrayLayers;
return this; return this;

View file

@ -19,7 +19,7 @@ import static org.lwjgl.vulkan.VK10.*;
import static org.lwjgl.vulkan.VK13.VK_ACCESS_2_NONE; import static org.lwjgl.vulkan.VK13.VK_ACCESS_2_NONE;
import static org.lwjgl.vulkan.VK13.vkCmdPipelineBarrier2; import static org.lwjgl.vulkan.VK13.vkCmdPipelineBarrier2;
public class Texture { public class Texture implements ITexture {
private final String ID; private final String ID;
private final int Height; private final int Height;
@ -212,4 +212,8 @@ public class Texture {
public int GetWidth(){return Width;} public int GetWidth(){return Width;}
public String GetID(){return ID;} public String GetID(){return ID;}
public ImageView GetImageView(){return imageView;} public ImageView GetImageView(){return imageView;}
@Override
public TextureType getType() {
return TextureType.FlatImage;
}
} }

View file

@ -18,8 +18,8 @@ import java.util.UUID;
import static org.lwjgl.vulkan.VK10.VK_FORMAT_R8G8B8A8_SRGB; import static org.lwjgl.vulkan.VK10.VK_FORMAT_R8G8B8A8_SRGB;
public class TextureCache { public class TextureCache {
public static final int MAX_TEXTURES = 512; public static final int MAX_TEXTURES = 128;
private final IndexedLinkedHashMap<String, Texture> TextureMap; private final IndexedLinkedHashMap<String, ITexture> TextureMap;
private final List<String> ActualTextures; private final List<String> ActualTextures;
public TextureCache(){ public TextureCache(){
@ -27,14 +27,28 @@ public class TextureCache {
ActualTextures = new ArrayList<>(); ActualTextures = new ArrayList<>();
} }
public Texture AddTexture(VulkanContext VkCtx, String ID, ImageSrc imageSrc, int Format) { public ITexture AddCubeMapTexture(VulkanContext VkCtx, String ID, String[] FacePaths, int Format) {
ITexture cubemap = TextureMap.get(ID);
if (cubemap == null) {
try {
cubemap = new CubeMapTexture(VkCtx, ID, FacePaths, Format);
TextureMap.put(ID, cubemap);
ActualTextures.add(ID);
} catch (IOException exception) {
Logger.error("Could not load cubemap texture faces, exception: {}", exception.getMessage());
}
}
return cubemap;
}
public ITexture AddTexture(VulkanContext VkCtx, String ID, ImageSrc imageSrc, int Format) {
return AddTexture(VkCtx,ID,imageSrc,Format,false); return AddTexture(VkCtx,ID,imageSrc,Format,false);
} }
public Texture AddTexture(VulkanContext VkCtx, String ID, ImageSrc imageSrc, int Format, boolean PaddingTexture){ public ITexture AddTexture(VulkanContext VkCtx, String ID, ImageSrc imageSrc, int Format, boolean PaddingTexture){
if(TextureMap.size() > MAX_TEXTURES){ if(TextureMap.size() > MAX_TEXTURES){
throw new IllegalArgumentException("Texture Cache Is Full"); throw new IllegalArgumentException("Texture Cache Is Full");
} }
Texture newTexture = TextureMap.get(ID); ITexture newTexture = TextureMap.get(ID);
if(newTexture == null){ if(newTexture == null){
newTexture = new Texture(VkCtx, ID, imageSrc, Format); newTexture = new Texture(VkCtx, ID, imageSrc, Format);
if(!PaddingTexture)ActualTextures.add(ID); if(!PaddingTexture)ActualTextures.add(ID);
@ -42,12 +56,12 @@ public class TextureCache {
} }
return newTexture; return newTexture;
} }
public Texture AddTexture(VulkanContext VkCtx, String ID, String TexturePath, int Format) { public ITexture AddTexture(VulkanContext VkCtx, String ID, String TexturePath, int Format) {
return AddTexture(VkCtx,ID,TexturePath,Format,false); return AddTexture(VkCtx,ID,TexturePath,Format,false);
} }
public Texture AddTexture(VulkanContext VkCtx, String ID, String TexturePath, int Format, boolean PaddingTexture) { public ITexture AddTexture(VulkanContext VkCtx, String ID, String TexturePath, int Format, boolean PaddingTexture) {
ImageSrc imageSrc = null; ImageSrc imageSrc = null;
Texture result = null; ITexture result = null;
try{ try{
imageSrc = GraphUtils.LoadImage(TexturePath); imageSrc = GraphUtils.LoadImage(TexturePath);
result = AddTexture(VkCtx, ID, imageSrc, Format,PaddingTexture); result = AddTexture(VkCtx, ID, imageSrc, Format,PaddingTexture);
@ -63,7 +77,7 @@ public class TextureCache {
public void TransitionTexts(VulkanContext VkCtx, CommandPool CmdPool, Queue queue){ public void TransitionTexts(VulkanContext VkCtx, CommandPool CmdPool, Queue queue){
Logger.debug("Recording Texture Transition"); Logger.debug("Recording Texture Transition");
IndexedLinkedHashMap<String, Texture> NewTextureMap = new IndexedLinkedHashMap<>(); IndexedLinkedHashMap<String, ITexture> NewTextureMap = new IndexedLinkedHashMap<>();
TextureMap.forEach((name,texture)->{ TextureMap.forEach((name,texture)->{
if(ActualTextures.contains(name)){ if(ActualTextures.contains(name)){
NewTextureMap.put(name,texture); NewTextureMap.put(name,texture);
@ -89,12 +103,12 @@ public class TextureCache {
TextureMap.forEach((key,value)->value.CleanUpStgBuffer(VkCtx)); TextureMap.forEach((key,value)->value.CleanUpStgBuffer(VkCtx));
Logger.debug("Recorded Texture Transition"); Logger.debug("Recorded Texture Transition");
} }
public Texture GetTexture(String TexturePath){ public ITexture GetTexture(String TexturePath){
Logger.debug("Fetching Texture -> [{}]",TexturePath.trim()); Logger.debug("Fetching Texture -> [{}]",TexturePath.trim());
return TextureMap.get(TexturePath.trim()); return TextureMap.get(TexturePath.trim());
} }
public IndexedLinkedHashMap<String, Texture> GetTextureCache(){return TextureMap;} public IndexedLinkedHashMap<String, ITexture> GetTextureCache(){return TextureMap;}
public List<Texture> GetTextureList(){return new ArrayList<>(TextureMap.values());} public List<ITexture> GetTextureList(){return new ArrayList<>(TextureMap.values());}
public int GetPosition(String ID){ public int GetPosition(String ID){
int result = -1; int result = -1;
if(ID != null){ if(ID != null){

View file

@ -71,7 +71,6 @@ public class PostProcess {
specConstants = new SpecializationConstants(); specConstants = new SpecializationConstants();
ShaderModule[] shaderModules = CreateShaderModules(VkCtx, specConstants); ShaderModule[] shaderModules = CreateShaderModules(VkCtx, specConstants);
pipeline = CreatePipeline(VkCtx, shaderModules, new DescriptorSetLayout[]{AttachmentDescriptorSetLayout, FragmentUniformDescriptorSetLayout}); pipeline = CreatePipeline(VkCtx, shaderModules, new DescriptorSetLayout[]{AttachmentDescriptorSetLayout, FragmentUniformDescriptorSetLayout});
Arrays.asList(shaderModules).forEach(shader->shader.CleanUp(VkCtx)); Arrays.asList(shaderModules).forEach(shader->shader.CleanUp(VkCtx));
Logger.debug("Post Process Renderer Pipeline -> [{}]",pipeline.GetVulkanPipeline()); Logger.debug("Post Process Renderer Pipeline -> [{}]",pipeline.GetVulkanPipeline());
@ -137,6 +136,7 @@ public class PostProcess {
new ShaderModule(VkCtx,VK_SHADER_STAGE_VERTEX_BIT,VERTEX_SHADER_FILE_SPV,null), new ShaderModule(VkCtx,VK_SHADER_STAGE_VERTEX_BIT,VERTEX_SHADER_FILE_SPV,null),
new ShaderModule(VkCtx,VK_SHADER_STAGE_FRAGMENT_BIT,ShaderPath,specConstants.GetSpecializationInfo()) new ShaderModule(VkCtx,VK_SHADER_STAGE_FRAGMENT_BIT,ShaderPath,specConstants.GetSpecializationInfo())
}; };
} }
public void Render(VulkanContext VkCtx, CommandBuffer commandBuffer, Attachment SrcAttachment){ public void Render(VulkanContext VkCtx, CommandBuffer commandBuffer, Attachment SrcAttachment){

View file

@ -8,6 +8,7 @@ import org.lwjgl.vulkan.VkDescriptorBufferInfo;
import org.lwjgl.vulkan.VkDescriptorImageInfo; import org.lwjgl.vulkan.VkDescriptorImageInfo;
import org.lwjgl.vulkan.VkDescriptorSetAllocateInfo; import org.lwjgl.vulkan.VkDescriptorSetAllocateInfo;
import org.lwjgl.vulkan.VkWriteDescriptorSet; import org.lwjgl.vulkan.VkWriteDescriptorSet;
import org.tinylog.Logger;
import java.nio.LongBuffer; import java.nio.LongBuffer;
import java.util.ArrayList; import java.util.ArrayList;
@ -58,11 +59,24 @@ public class DescriptorSet {
SetImages(device, imageViews, textureSampler, BaseBinding); SetImages(device, imageViews, textureSampler, BaseBinding);
} }
public void SetImages(Device device, List<ImageView> imageViews, TextureSampler textureSampler, int BaseBinding){ public void SetImages(Device device, List<ImageView> imageViews, TextureSampler textureSampler, int BaseBinding){
if(textureSampler == null || textureSampler.GetVkSampler() == VK_NULL_HANDLE){
Logger.error("Null texture sampler during Set Images function");
throw new RuntimeException("yo this texture sampler ain't present");
}
try(var MemStack = MemoryStack.stackPush()){ try(var MemStack = MemoryStack.stackPush()){
int ImageCount = imageViews.size(); int ImageCount = imageViews.size();
var DescriptorBuffer = VkWriteDescriptorSet.calloc(ImageCount,MemStack); var DescriptorBuffer = VkWriteDescriptorSet.calloc(ImageCount,MemStack);
for(int i = 0; i < ImageCount; i++){ for(int i = 0; i < ImageCount; i++){
ImageView imageView = imageViews.get(i); ImageView imageView = imageViews.get(i);
if(imageView == null || imageView.GetVulkanImageView() == VK_NULL_HANDLE){
Logger.error("Null Image View or Image View Handle during Set Images function");
throw new RuntimeException("yo this ImageView ain't present");
}
if(imageView.GetVulkanImage() == VK_NULL_HANDLE){
Logger.error("Null Image Handle during Set Images function");
throw new RuntimeException("yo this Image ain't present");
}
var ImageInfo = VkDescriptorImageInfo.calloc(1,MemStack) var ImageInfo = VkDescriptorImageInfo.calloc(1,MemStack)
.imageView(imageView.GetVulkanImageView()) .imageView(imageView.GetVulkanImageView())
.sampler(textureSampler.GetVkSampler()); .sampler(textureSampler.GetVkSampler());

View file

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

View file

@ -0,0 +1,19 @@
package net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Shadows;
import net.halbear.Terrain4J.EngineCore.Main.Scene.SceneLightingManager;
import java.util.ArrayList;
import java.util.List;
public class CascadeShadows {
private final List<CascadeData> cascadeDataList;
public CascadeShadows(){
this.cascadeDataList = new ArrayList<>();
for(int i = 0; i < SceneLightingManager.SHADOW_MAP_CASCADE_COUNT; i++){
cascadeDataList.add(new CascadeData());
}
}
public List<CascadeData> GetCascadeData(){return cascadeDataList;}
}

View file

@ -0,0 +1,22 @@
package net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Shadows;
import net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanUtils;
import static org.lwjgl.vulkan.VK10.VK_FORMAT_D32_SFLOAT;
import static org.lwjgl.vulkan.VK10.VK_FORMAT_R32G32_SFLOAT;
public class ShadowRenderer {
public static final int DEPTH_FORMAT = VK_FORMAT_D32_SFLOAT;
private static final int ATTACHMENT_FORMATT = VK_FORMAT_R32G32_SFLOAT;
private static final String DESCRIPTOR_ID_MAT = "SHADOW_DESC_ID_MAT";
private static final String DESCRIPTOR_ID_PRJ = "SHADOW_DESC_ID_PRJ";
private static final String DESCRIPTOR_ID_TEXT = "SHADOW_SCN_DESC_ID_TEXT";
private static final String FRAGMENT_SHADER_FILE_GLSL = "resources/EngineResources/shaders/shadow_frag.glsl";
private static final String FRAGMENT_SHADER_FILE_SPV = FRAGMENT_SHADER_FILE_GLSL + ".spv";
private static final int PUSH_CONSTANTS_SIZE = VulkanUtils.MATRIX4X4_SIZE + VulkanUtils.INT_SIZE;
private static final String SHADOW_GEOMETRY_SHADER_FILE_GLSL = "resources/EngineResources/shaders/shadow_geometry.glsl";
private static final String SHADOW_GEOMETRY_SHADER_FILE_SPV = SHADOW_GEOMETRY_SHADER_FILE_GLSL + ".spv";
private static final String VERTEX_SHADER_FILE_GLSL = "resources/EngineResources/shaders/shadow_vertex.glsl";
private static final String VERTEX_SHADER_FILE_SPV = VERTEX_SHADER_FILE_GLSL + ".spv";
}

View file

@ -0,0 +1,144 @@
package net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Shadows;
import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig;
import net.halbear.Terrain4J.EngineCore.Main.Scene.Camera;
import net.halbear.Terrain4J.EngineCore.Main.Scene.ILight;
import net.halbear.Terrain4J.EngineCore.Main.Scene.IScene;
import net.halbear.Terrain4J.EngineCore.Main.Scene.SceneLightingManager;
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Projection.Project3D;
import org.joml.Matrix4f;
import org.joml.Vector3f;
import org.joml.Vector4f;
import javax.swing.text.View;
import java.util.List;
public class ShadowUtils {
private static final float LAMBDA = 0.95f;
private static final Vector3f Up = new Vector3f(0.0f,1.0f,0.0f);
private static final Vector3f UpAlt = new Vector3f(0.0f,0.0f,1.0f);
private ShadowUtils(){
}
public static void UpdateCascadeShadows(CascadeShadows shadows, IScene scene){
Camera camera = scene.GetCamera();
Matrix4f ViewMatrix = camera.GetViewMatrix();
Project3D projection = scene.GetProjection();
Matrix4f ProjectionMatrix = projection.GetProjectionMatrix();
ILight[] lights = scene.GetLightingManager().GetLights();
int LightCount = lights.length;
ILight SkyLight = null;
for(int i = 0; i < LightCount; i++){
if(lights[i].IsDirectional()){
SkyLight = lights[i];
break;
}
}
if(SkyLight == null){
throw new RuntimeException("No SkyLight on scene");
}
Vector4f LightPosition = new Vector4f(SkyLight.GetPosition(),0.0f);
float[] CascadeSplits = new float[SceneLightingManager.SHADOW_MAP_CASCADE_COUNT];
float NearClip = Math.min(projection.GetNearZ(), projection.GetFarZ());
float FarClip = Math.max(projection.GetNearZ(), projection.GetFarZ());
float ClipRange = FarClip - NearClip;
float MinZ = NearClip;
float MaxZ = NearClip + ClipRange;
float Range = MaxZ - MinZ;
float Ratio = MaxZ/MinZ;
List<CascadeData> cascadeDataList = shadows.GetCascadeData();
int CascadeCount = cascadeDataList.size();
for(int i = 0; i < CascadeCount; i++){
float p = (i + 1) / (float) (SceneLightingManager.SHADOW_MAP_CASCADE_COUNT);
float Log = (float) (MinZ * Math.pow(Ratio, p));
float Uniform = MinZ + Range * p;
float d = LAMBDA * (Log - Uniform) + Uniform;
CascadeSplits[i] = (d - NearClip) / ClipRange;
}
float LastSplitDist = 0.0f;
for(int i = 0; i < CascadeCount; i++){
float SplitDist = CascadeSplits[i];
Vector3f[] FustrumCorners = new Vector3f[]{
new Vector3f(-1.0f, 1.0f, 0.0f),
new Vector3f(1.0f, 1.0f, 0.0f),
new Vector3f(1.0f, -1.0f, 0.0f),
new Vector3f(-1.0f, -1.0f, 0.0f),
new Vector3f(-1.0f, 1.0f, 1.0f),
new Vector3f(1.0f, 1.0f, 1.0f),
new Vector3f(1.0f, -1.0f, 1.0f),
new Vector3f(-1.0f, -1.0f, 1.0f)
};
var InvertedCam = (new Matrix4f(ProjectionMatrix).mul(ViewMatrix)).invert();
for(int j = 0; j < 8; j++){
Vector4f InvertedCorner = new Vector4f(FustrumCorners[j],1.0f).mul(InvertedCam);
FustrumCorners[j] = new Vector3f(InvertedCorner.x,InvertedCorner.y,InvertedCorner.z).div(InvertedCorner.w);
}
for(int j = 0; j < 4; j++){
var Distance = new Vector3f(FustrumCorners[j + 4]).sub(FustrumCorners[j]);
FustrumCorners[j + 4] = new Vector3f(FustrumCorners[j]).add(new Vector3f(Distance).mul(SplitDist));
FustrumCorners[j] = new Vector3f(FustrumCorners[j]).add(new Vector3f(Distance).mul(LastSplitDist));
}
var FustrumCenter = new Vector3f(0.0f);
for(int j = 0; j < 8; j++){
FustrumCenter.add(FustrumCorners[j]);
}
FustrumCenter.div(8);
var up = Up;
float SphereRadius = 0.0f;
for(int j = 0; j < 8; j++){
float Distance = new Vector3f(FustrumCorners[j]).sub(FustrumCenter).length();
SphereRadius = Math.max(SphereRadius,Distance);
}
SphereRadius = (float)Math.ceil(SphereRadius * 16.0f) / 16.0f;
var MaxExtents = new Vector3f(SphereRadius);
var MinExtents = new Vector3f(-SphereRadius);
var LightDirection = new Vector3f(LightPosition.x, LightPosition.y, LightPosition.z);
var ShadowCamPosition = new Vector3f(FustrumCenter).add(LightDirection.mul(MinExtents.z));
float Dot = Math.abs(new Vector3f(LightPosition.x, LightPosition.y, LightPosition.z).dot(up));
if(Dot == 1.0f){
up = UpAlt;
}
var LightViewMatrix = new Matrix4f().lookAt(ShadowCamPosition,FustrumCenter,up);
var LightOrthoMatrix = new Matrix4f().ortho(MinExtents.x,MaxExtents.x,MinExtents.y,MaxExtents.y,0.0f,MaxExtents.z - MinExtents.z,true);
int ShadowMapSize = EngineConfig.getInstance().GetShadowMapSize();
Vector4f ShadowOrigin = new Vector4f(0f,0f,0f,1f);
LightViewMatrix.transform(ShadowOrigin);
ShadowOrigin.mul(ShadowMapSize/2.0f);
Vector4f RoundedOrigin = new Vector4f(ShadowOrigin).round();
Vector4f RoundOffset = RoundedOrigin.sub(ShadowOrigin);
RoundOffset.mul(2.0f/ShadowMapSize);
RoundOffset.z = 0.0f;
RoundOffset.w = 0.0f;
LightOrthoMatrix.m30(LightOrthoMatrix.m30() + RoundOffset.x);
LightOrthoMatrix.m31(LightOrthoMatrix.m31() + RoundOffset.y);
LightOrthoMatrix.m32(LightOrthoMatrix.m32() + RoundOffset.z);
LightOrthoMatrix.m33(LightOrthoMatrix.m33() + RoundOffset.w);
CascadeData cascadeData = cascadeDataList.get(i);
cascadeData.SetSplitDistance((NearClip + SplitDist * ClipRange) * -1.0f);
cascadeData.SetProjectionViewMatrix(LightOrthoMatrix.mul(LightViewMatrix));
LastSplitDist = CascadeSplits[i];
}
}
}

View file

@ -1,6 +1,7 @@
package net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel; package net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel;
import net.halbear.Terrain4J.EngineCore.Logic.Rendering.VulkanContext; import net.halbear.Terrain4J.EngineCore.Logic.Rendering.VulkanContext;
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Images.ITexture;
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Images.Texture; import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Images.Texture;
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.IndexedLinkedHashMap; import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.IndexedLinkedHashMap;
@ -56,14 +57,14 @@ public class MaterialsCache {
boolean TransparentTexture; boolean TransparentTexture;
Logger.debug("Material Texture Path -> [{}]",Material.TexturePath()); Logger.debug("Material Texture Path -> [{}]",Material.TexturePath());
if(ValidTexture){ if(ValidTexture){
Texture newTexture = textureCache.AddTexture(VkCtx, TexturePath, TexturePath, VK_FORMAT_R8G8B8A8_SRGB); ITexture newTexture = textureCache.AddTexture(VkCtx, TexturePath, TexturePath, VK_FORMAT_R8G8B8A8_SRGB);
if(newTexture == null) { if(newTexture == null) {
TransparentTexture = false; TransparentTexture = false;
TexturePath = "resources/EngineResources/Texture/DefaultTexture.png"; TexturePath = "resources/EngineResources/Texture/NoTexture.png";
} }
else TransparentTexture = newTexture.HasTransparency(); else TransparentTexture = newTexture.HasTransparency();
} else{ } else{
TexturePath = "resources/EngineResources/Texture/DefaultTexture.png"; TexturePath = "resources/EngineResources/Texture/NoTexture.png";
TransparentTexture = Material.DiffuseColour().w < 1.0f; TransparentTexture = Material.DiffuseColour().w < 1.0f;
} }
VulkanMaterial newMaterial = new VulkanMaterial(Material.ID(),TransparentTexture); VulkanMaterial newMaterial = new VulkanMaterial(Material.ID(),TransparentTexture);

View file

@ -1,18 +1,26 @@
package net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel; package net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel;
import net.halbear.Terrain4J.EngineCore.Logic.Rendering.VulkanContext; import net.halbear.Terrain4J.EngineCore.Logic.Rendering.VulkanContext;
import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime;
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Shader.DescriptorAllocator;
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Shader.DescriptorSet;
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.CommandBuffer; import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.CommandBuffer;
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.CommandPool; import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.CommandPool;
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.GPUSynchronisation.TransferBuffer; import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.GPUSynchronisation.TransferBuffer;
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.Queues.Queue; import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DeviceLayers.Queues.Queue;
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DisplayToScreen.DeferredSceneRender;
import net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanBuffer; import net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanBuffer;
import net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanUtils; import net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanUtils;
import org.lwjgl.PointerBuffer;
import org.lwjgl.system.MemoryStack;
import org.lwjgl.system.MemoryUtil; import org.lwjgl.system.MemoryUtil;
import org.lwjgl.vulkan.VkCommandBuffer;
import org.tinylog.Logger; import org.tinylog.Logger;
import java.io.*; import java.io.*;
import java.nio.FloatBuffer; import java.nio.FloatBuffer;
import java.nio.IntBuffer; import java.nio.IntBuffer;
import java.nio.LongBuffer;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@ -28,6 +36,51 @@ public class ModelsCache {
ModelsMap = new HashMap<>(); ModelsMap = new HashMap<>();
} }
private final java.util.Map<String, Long> SkyboxBuffers = new java.util.HashMap<>();
public String CreateSkybox(VulkanContext vulkanContext, float[] vertices, String SkyBoxID) {
long bufferSize = (long) vertices.length * Float.BYTES; // 36 * 4 bytes = 144 bytes
VulkanBuffer meshBuffer = VulkanUtils.CreateRawVertexAttrBuffer(vulkanContext, bufferSize);
long meshBuffPtr = meshBuffer.MapMemory(vulkanContext);
if (meshBuffPtr == 0 || meshBuffPtr == -1) {
throw new RuntimeException("CRITICAL ERROR: meshBuffer.MapMemory() returned an invalid native address pointer: " + meshBuffPtr
+ ". Check your underlying vkMapMemory/vmaMapMemory configurations.");
}
try {
java.nio.FloatBuffer floatBuffer = org.lwjgl.system.MemoryUtil.memFloatBuffer(meshBuffPtr, vertices.length);
floatBuffer.put(vertices);
floatBuffer.flip();
} catch (Exception e) {
throw new RuntimeException("Failed during FloatBuffer array memory payload copy wrapper pass", e);
} finally {
meshBuffer.UnMapMemory(vulkanContext);
}
this.SkyboxBuffers.put(SkyBoxID, meshBuffer.GetBuffer());
return SkyBoxID;
}
public void bindAndDrawCubeMesh(VkCommandBuffer commandHandle, String skyboxMeshBufferId) {
Long vkBufferHandle = SkyboxBuffers.get(skyboxMeshBufferId);
if (vkBufferHandle == null) {
throw new RuntimeException("Skybox mesh buffer ID [" + skyboxMeshBufferId + "] not loaded in ModelsCache!");
}
try (MemoryStack MemStack = MemoryStack.stackPush()) {
LongBuffer pBuffers = MemStack.longs(vkBufferHandle);
LongBuffer pOffsets = MemStack.longs(0);
vkCmdBindVertexBuffers(commandHandle, 0, pBuffers, pOffsets);
vkCmdDraw(commandHandle, 36, 1, 0, 0);
}
}
public void loadModels(VulkanContext VkCtx, List<ModelData> Models, CommandPool commandPool, Queue queue){ public void loadModels(VulkanContext VkCtx, List<ModelData> Models, CommandPool commandPool, Queue queue){
try { try {
List<VulkanBuffer> StagingBufferList = new ArrayList<>(); List<VulkanBuffer> StagingBufferList = new ArrayList<>();

View file

@ -3,15 +3,11 @@ package net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DisplayToScreen;
import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig; import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig;
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.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.IScene; import net.halbear.Terrain4J.EngineCore.Main.Scene.IScene;
import net.halbear.Terrain4J.EngineCore.Main.Scene.Scene;
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.DeferredRendering.MultiRenderTargetAttachments; import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.DeferredRendering.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.*;
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Images.Texture;
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Images.TextureCache;
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Pipeline; import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Pipeline;
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.PipelineBuildInfo; import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.PipelineBuildInfo;
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.PushConstantsRange; import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.PushConstantsRange;
@ -42,12 +38,16 @@ public class DeferredSceneRender implements SceneRenderer {//dynamic rendering
private static final String DESCRIPTOR_ID_PRJ = "SCN_DESC_ID_PRJ"; private static final String DESCRIPTOR_ID_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";
private static final String DESCRIPTOR_ID_VIEW = "SCN_DESC_ID_VIEW"; private static final String DESCRIPTOR_ID_VIEW = "SCN_DESC_ID_VIEW";
private static final String DESCRIPTOR_ID_SKYBOX_VIEW = "SCN_DESC_ID_SKYBOX_VIEW";
public static final String DESCRIPTOR_ID_SKYBOX_CUBEMAP = "SCN_DESC_ID_SKYBOX_CUBEMAP";
private static final int PUSH_CONSTANTS_SIZE = VulkanUtils.MATRIX4X4_SIZE + VulkanUtils.INT_SIZE; private static final int PUSH_CONSTANTS_SIZE = VulkanUtils.MATRIX4X4_SIZE + VulkanUtils.INT_SIZE;
private final VulkanBuffer BufferProjectionMatrix; private final VulkanBuffer BufferProjectionMatrix;
private final DescriptorSetLayout descriptorLayoutFragStorage; private final DescriptorSetLayout descriptorLayoutFragStorage;
private final DescriptorSetLayout descriptorLayoutTexture; private final DescriptorSetLayout descriptorLayoutTexture;
private final DescriptorSetLayout descriptorLayoutVertexUniform; private final DescriptorSetLayout descriptorLayoutVertexUniform;
private DescriptorSet SkyboxDescriptorSet;
private final TextureSampler textureSampler; private final TextureSampler textureSampler;
public static String SkyBoxID = "SKYBOX_TEXTURE";
public static final int COLOUR_FORMAT = VK_FORMAT_R32G32B32A32_SFLOAT; public static final int COLOUR_FORMAT = VK_FORMAT_R32G32B32A32_SFLOAT;
public static final int DEPTH_FORMAT = VK_FORMAT_D32_SFLOAT; public static final int DEPTH_FORMAT = VK_FORMAT_D32_SFLOAT;
@ -63,6 +63,11 @@ public class DeferredSceneRender implements SceneRenderer {//dynamic rendering
public static long CYCLES = 0; public static long CYCLES = 0;
private static boolean DualPassRendering = false; private static boolean DualPassRendering = false;
private static final String SKYBOX_FRAGMENT_SHADER_FILE_GLSL = "resources/EngineResources/shaders/skybox_fragment.glsl";
private static final String SKYBOX_FRAGMENT_SHADER_FILE_SPV = SKYBOX_FRAGMENT_SHADER_FILE_GLSL + ".spv";
private static final String SKYBOX_VERTEX_SHADER_FILE_GLSL = "resources/EngineResources/shaders/skybox_vertex.glsl";
private static final String SKYBOX_VERTEX_SHADER_FILE_SPV = SKYBOX_VERTEX_SHADER_FILE_GLSL + ".spv";
private static final String FRAGMENT_SHADER_FILE_GLSL = "resources/EngineResources/shaders/scene_fragment_deferred.glsl"; private static final String FRAGMENT_SHADER_FILE_GLSL = "resources/EngineResources/shaders/scene_fragment_deferred.glsl";
private static final String FRAGMENT_TRANSLUCENT_SHADER_FILE_GLSL = "resources/EngineResources/shaders/scene_translucent_fragment_deferred.glsl"; private static final String FRAGMENT_TRANSLUCENT_SHADER_FILE_GLSL = "resources/EngineResources/shaders/scene_translucent_fragment_deferred.glsl";
private static final String FRAGMENT_OPAQUE_SHADER_FILE_GLSL = "resources/EngineResources/shaders/scene_opaque_fragment_deferred.glsl"; private static final String FRAGMENT_OPAQUE_SHADER_FILE_GLSL = "resources/EngineResources/shaders/scene_opaque_fragment_deferred.glsl";
@ -75,12 +80,17 @@ public class DeferredSceneRender implements SceneRenderer {//dynamic rendering
private Pipeline VkPipeline; private Pipeline VkPipeline;
private Pipeline VkPipelineOpaque; private Pipeline VkPipelineOpaque;
private Pipeline VkPipelineTranslucent; private Pipeline VkPipelineTranslucent;
private float R = 0.00f; private float R = 0.4f;
private float G = 0.05f; private float G = 0.75f;
private float B = 0.15f; private float B = 1.0f;
private Matrix4f ProjectionMatrix; private Matrix4f ProjectionMatrix;
private MultiRenderTargetAttachments MRTAttachments; private MultiRenderTargetAttachments MRTAttachments;
private DescriptorSetLayout descriptorLayoutSkyboxTexture;
private VulkanBuffer[] BufferSkyboxViewMatrices;
private Pipeline VkSkyboxPipeline;
private long skyboxMeshBufferId;
public static long GetGPUTimeNS(){ public static long GetGPUTimeNS(){
long time = 0; long time = 0;
if(CYCLES > 0){ if(CYCLES > 0){
@ -93,7 +103,7 @@ public class DeferredSceneRender implements SceneRenderer {//dynamic rendering
public DeferredSceneRender(VulkanContext vulkanContext, EngineInstance engineInstance){ public DeferredSceneRender(VulkanContext vulkanContext, EngineInstance engineInstance){
ClearValueColour = VkClearValue.calloc().color( ClearValueColour = VkClearValue.calloc().color(
c -> c.float32(0, R).float32(1, G).float32(2, B).float32(3, 0.5f)); c -> c.float32(0, 0.0f).float32(1, 0.0f).float32(2, 0.0f).float32(3, 0.0f));
ClearValueDepth = VkClearValue.calloc().color(c -> c.float32(0, 0.0f)); ClearValueDepth = VkClearValue.calloc().color(c -> c.float32(0, 0.0f));
MRTAttachments = new MultiRenderTargetAttachments(vulkanContext); MRTAttachments = new MultiRenderTargetAttachments(vulkanContext);
AttachmentInfoColour = CreateColourAttachmentInfo(MRTAttachments, ClearValueColour); AttachmentInfoColour = CreateColourAttachmentInfo(MRTAttachments, ClearValueColour);
@ -120,6 +130,14 @@ public class DeferredSceneRender implements SceneRenderer {//dynamic rendering
descriptorLayoutTexture = new DescriptorSetLayout(vulkanContext, new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, descriptorLayoutTexture = new DescriptorSetLayout(vulkanContext, new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
0, TextureCache.MAX_TEXTURES, VK_SHADER_STAGE_FRAGMENT_BIT)); 0, TextureCache.MAX_TEXTURES, VK_SHADER_STAGE_FRAGMENT_BIT));
descriptorLayoutSkyboxTexture = new DescriptorSetLayout(vulkanContext,
new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
0, 1, VK_SHADER_STAGE_FRAGMENT_BIT));
BufferSkyboxViewMatrices = VulkanUtils.CreateHostVisibleBuffers(vulkanContext, VulkanUtils.MATRIX4X4_SIZE, VulkanUtils.MAX_IN_FLIGHT,
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, DESCRIPTOR_ID_SKYBOX_VIEW, descriptorLayoutVertexUniform);
CreatePipelines(vulkanContext); CreatePipelines(vulkanContext);
Logger.debug("Deferred Renderer Pipeline -> [{}]",VkPipeline.GetVulkanPipeline()); Logger.debug("Deferred Renderer Pipeline -> [{}]",VkPipeline.GetVulkanPipeline());
@ -134,13 +152,24 @@ public class DeferredSceneRender implements SceneRenderer {//dynamic rendering
}; };
ShaderModule[] shaderModules = DeferredSceneRender.CreateShaderModules(vulkanContext,0); ShaderModule[] shaderModules = DeferredSceneRender.CreateShaderModules(vulkanContext,0);
VkPipeline = CreatePipeline(vulkanContext, shaderModules, layouts, true, false,EngineConfig.getInstance().AlphaToCoverage()); VkPipeline = CreatePipeline(vulkanContext, shaderModules, layouts, true,true, false,EngineConfig.getInstance().AlphaToCoverage(),0);
Arrays.asList(shaderModules).forEach(shaderModule -> shaderModule.CleanUp(vulkanContext)); Arrays.asList(shaderModules).forEach(shaderModule -> shaderModule.CleanUp(vulkanContext));
shaderModules = DeferredSceneRender.CreateShaderModules(vulkanContext,1); shaderModules = DeferredSceneRender.CreateShaderModules(vulkanContext,1);
VkPipelineOpaque = CreatePipeline(vulkanContext, shaderModules, layouts, true, true,EngineConfig.getInstance().AlphaToCoverage()); VkPipelineOpaque = CreatePipeline(vulkanContext, shaderModules, layouts, true,false, true,EngineConfig.getInstance().AlphaToCoverage(),0);
Arrays.asList(shaderModules).forEach(shaderModule -> shaderModule.CleanUp(vulkanContext)); Arrays.asList(shaderModules).forEach(shaderModule -> shaderModule.CleanUp(vulkanContext));
shaderModules = DeferredSceneRender.CreateShaderModules(vulkanContext,2); shaderModules = DeferredSceneRender.CreateShaderModules(vulkanContext,2);
VkPipelineTranslucent = CreatePipeline(vulkanContext, shaderModules, layouts, false, true,EngineConfig.getInstance().AlphaToCoverage()); VkPipelineTranslucent = CreatePipeline(vulkanContext, shaderModules, layouts, false, true,true,EngineConfig.getInstance().AlphaToCoverage(),2);
Arrays.asList(shaderModules).forEach(shaderModule -> shaderModule.CleanUp(vulkanContext));
DescriptorSetLayout[] skyboxLayouts = new DescriptorSetLayout[]{
descriptorLayoutVertexUniform,
descriptorLayoutVertexUniform,
descriptorLayoutSkyboxTexture
};
shaderModules = DeferredSceneRender.CreateSkyboxShaderModules(vulkanContext);
VkSkyboxPipeline = CreateSkyboxPipeline(vulkanContext, shaderModules, skyboxLayouts, false, false, false,false);
Arrays.asList(shaderModules).forEach(shaderModule -> shaderModule.CleanUp(vulkanContext)); Arrays.asList(shaderModules).forEach(shaderModule -> shaderModule.CleanUp(vulkanContext));
} }
@ -181,6 +210,17 @@ public class DeferredSceneRender implements SceneRenderer {//dynamic rendering
.clearValue(clearValue); .clearValue(clearValue);
} }
private static ShaderModule[] CreateSkyboxShaderModules(VulkanContext VkCtx){
if(EngineConfig.getInstance().RecompileShaders()){
ShaderCompiler.CompileGLSLShaderOnChange(SKYBOX_VERTEX_SHADER_FILE_GLSL, Shaderc.shaderc_glsl_vertex_shader);
ShaderCompiler.CompileGLSLShaderOnChange( SKYBOX_FRAGMENT_SHADER_FILE_GLSL, Shaderc.shaderc_glsl_fragment_shader);
}
return new ShaderModule[]{
new ShaderModule(VkCtx, VK_SHADER_STAGE_VERTEX_BIT, SKYBOX_VERTEX_SHADER_FILE_SPV,null),
new ShaderModule(VkCtx, VK_SHADER_STAGE_FRAGMENT_BIT, SKYBOX_FRAGMENT_SHADER_FILE_SPV,null)
};
}
private static ShaderModule[] CreateShaderModules(VulkanContext VkCtx, int Translucent){ private static ShaderModule[] CreateShaderModules(VulkanContext VkCtx, int Translucent){
if(EngineConfig.getInstance().RecompileShaders()){ if(EngineConfig.getInstance().RecompileShaders()){
ShaderCompiler.CompileGLSLShaderOnChange(VERTEX_SHADER_FILE_GLSL, Shaderc.shaderc_glsl_vertex_shader); ShaderCompiler.CompileGLSLShaderOnChange(VERTEX_SHADER_FILE_GLSL, Shaderc.shaderc_glsl_vertex_shader);
@ -192,7 +232,47 @@ public class DeferredSceneRender implements SceneRenderer {//dynamic rendering
}; };
} }
private static Pipeline CreatePipeline(VulkanContext VkCtx, ShaderModule[] ShaderModules, DescriptorSetLayout[] DescriptorSetLayouts, boolean DepthWrite, boolean DualRender, boolean AlphaToCoverage){ private static Pipeline CreateSkyboxPipeline(VulkanContext VkCtx, ShaderModule[] ShaderModules, DescriptorSetLayout[] DescriptorSetLayouts, boolean DepthWrite, boolean DualRender, boolean Blending, boolean AlphaToCoverage){
int[] skyboxFormats = new int[] {
MultiRenderTargetAttachments.POSITION_FORMAT,
MultiRenderTargetAttachments.ALBEDO_FORMAT,
MultiRenderTargetAttachments.NORMAL_FORMAT,
MultiRenderTargetAttachments.PBR_FORMAT
};
try (MemoryStack MemStack = MemoryStack.stackPush()) {
VkVertexInputBindingDescription.Buffer bindingDescription = VkVertexInputBindingDescription.calloc(1, MemStack)
.binding(0)
.stride(3 * Float.BYTES)
.inputRate(VK_VERTEX_INPUT_RATE_VERTEX);
VkVertexInputAttributeDescription.Buffer attributeDescription = VkVertexInputAttributeDescription.calloc(1, MemStack)
.binding(0)
.location(0)
.format(VK_FORMAT_R32G32B32_SFLOAT)
.offset(0);
VkPipelineVertexInputStateCreateInfo skyboxVertexInputState = VkPipelineVertexInputStateCreateInfo.calloc(MemStack)
.sType(VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO)
.pVertexBindingDescriptions(bindingDescription)
.pVertexAttributeDescriptions(attributeDescription);
var BuildInfo = new PipelineBuildInfo(ShaderModules, skyboxVertexInputState, skyboxFormats)
.SetDepthFormat(MultiRenderTargetAttachments.DEPTH_FORMAT)
.SetDepthWrite(false)
.SetDepthTest(true)
.SetPushConstantRanges(new PushConstantsRange[0])
.SetDescriptorSetLayouts(DescriptorSetLayouts)
.BlendingIsUsed(true)
.SetDualPass(false)
.SetAlphaToCoverage(false);
var pipeline = new DefaultPipeline(VkCtx, BuildInfo);
Logger.debug("Skybox Pipeline Created Successfully");
return pipeline;
}
}
private static Pipeline CreatePipeline(VulkanContext VkCtx, ShaderModule[] ShaderModules, DescriptorSetLayout[] DescriptorSetLayouts, boolean DepthWrite, boolean DualRender, boolean Blending, boolean AlphaToCoverage, int BlendingMethod){
var vertexBufferStructure = new VertexBufferStructure(); var vertexBufferStructure = new VertexBufferStructure();
var BuildInfo = new PipelineBuildInfo(ShaderModules,vertexBufferStructure.getVertexInput(),new int[]{ var BuildInfo = new PipelineBuildInfo(ShaderModules,vertexBufferStructure.getVertexInput(),new int[]{
MultiRenderTargetAttachments.POSITION_FORMAT, MultiRenderTargetAttachments.ALBEDO_FORMAT, MultiRenderTargetAttachments.NORMAL_FORMAT, MultiRenderTargetAttachments.PBR_FORMAT}) MultiRenderTargetAttachments.POSITION_FORMAT, MultiRenderTargetAttachments.ALBEDO_FORMAT, MultiRenderTargetAttachments.NORMAL_FORMAT, MultiRenderTargetAttachments.PBR_FORMAT})
@ -204,10 +284,12 @@ public class DeferredSceneRender implements SceneRenderer {//dynamic rendering
new PushConstantsRange(VK_SHADER_STAGE_FRAGMENT_BIT,VulkanUtils.MATRIX4X4_SIZE,VulkanUtils.INT_SIZE) new PushConstantsRange(VK_SHADER_STAGE_FRAGMENT_BIT,VulkanUtils.MATRIX4X4_SIZE,VulkanUtils.INT_SIZE)
}) })
.SetDescriptorSetLayouts(DescriptorSetLayouts) .SetDescriptorSetLayouts(DescriptorSetLayouts)
.BlendingIsUsed(DualRender ? !DepthWrite : true) .SetBlendingMethod(BlendingMethod)
.BlendingIsUsed(Blending)
.SetDualPass(DualRender) .SetDualPass(DualRender)
.SetAlphaToCoverage(AlphaToCoverage); .SetAlphaToCoverage(AlphaToCoverage);
var pipeline = new DefaultPipeline(VkCtx, BuildInfo); var pipeline = new DefaultPipeline(VkCtx, BuildInfo);
Logger.debug("Pipeline Created");
vertexBufferStructure.cleanup(); vertexBufferStructure.cleanup();
return pipeline; return pipeline;
} }
@ -255,6 +337,7 @@ public class DeferredSceneRender implements SceneRenderer {//dynamic rendering
vkCmdSetScissor(CommandHandle, 0, Scissor); vkCmdSetScissor(CommandHandle, 0, Scissor);
VulkanUtils.CopyMatrixToBuffer(vulkanContext, BufferViewMatrices[CurrentFrame],engineInstance.scene().GetCamera().GetViewMatrix(), 0); // here VulkanUtils.CopyMatrixToBuffer(vulkanContext, BufferViewMatrices[CurrentFrame],engineInstance.scene().GetCamera().GetViewMatrix(), 0); // here
DescriptorAllocator descriptorAllocator = vulkanContext.GetDescriptorAllocator(); DescriptorAllocator descriptorAllocator = vulkanContext.GetDescriptorAllocator();
LongBuffer DescriptorSets = MemStack.mallocLong(4) LongBuffer DescriptorSets = MemStack.mallocLong(4)
.put(0,descriptorAllocator.GetDescriptorSet(DESCRIPTOR_ID_PRJ).GetVkDescriptorSet()) .put(0,descriptorAllocator.GetDescriptorSet(DESCRIPTOR_ID_PRJ).GetVkDescriptorSet())
@ -264,14 +347,38 @@ public class DeferredSceneRender implements SceneRenderer {//dynamic rendering
vkCmdBindDescriptorSets(CommandHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, DualPassRendering ? VkPipelineOpaque.GetVulkanPipelineLayout() : VkPipeline.GetVulkanPipelineLayout(),0,DescriptorSets,null); vkCmdBindDescriptorSets(CommandHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, DualPassRendering ? VkPipelineOpaque.GetVulkanPipelineLayout() : VkPipeline.GetVulkanPipelineLayout(),0,DescriptorSets,null);
RenderActors(engineInstance, CommandHandle, modelsCache, materialsCache, false); RenderActors(engineInstance, CommandHandle, modelsCache, materialsCache, false);
Matrix4f skyboxViewMatrix = new Matrix4f().identity();
skyboxViewMatrix.set(engineInstance.scene().GetCamera().GetViewMatrix());
skyboxViewMatrix.m30(0.0f);
skyboxViewMatrix.m31(0.0f);
skyboxViewMatrix.m32(0.0f);
VulkanUtils.CopyMatrixToBuffer(vulkanContext, BufferSkyboxViewMatrices[CurrentFrame], skyboxViewMatrix, 0);
vkCmdBindPipeline(CommandHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, VkSkyboxPipeline.GetVulkanPipeline());
LongBuffer skyboxDescriptorSets = MemStack.mallocLong(3)
.put(0, descriptorAllocator.GetDescriptorSet(DESCRIPTOR_ID_PRJ).GetVkDescriptorSet())
.put(1, descriptorAllocator.GetDescriptorSet(DESCRIPTOR_ID_SKYBOX_VIEW, CurrentFrame).GetVkDescriptorSet())
.put(2, descriptorAllocator.GetDescriptorSet(DESCRIPTOR_ID_SKYBOX_CUBEMAP).GetVkDescriptorSet());
vkCmdBindDescriptorSets(CommandHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, VkSkyboxPipeline.GetVulkanPipelineLayout(), 0, skyboxDescriptorSets, null);
modelsCache.bindAndDrawCubeMesh(CommandHandle, SkyBoxID);
VulkanUtils.CopyMatrixToBuffer(vulkanContext, BufferViewMatrices[CurrentFrame],engineInstance.scene().GetCamera().GetViewMatrix(), 0); // here
if(DualPassRendering) { if(DualPassRendering) {
vkCmdBindPipeline(CommandHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, VkPipelineTranslucent.GetVulkanPipeline()); 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); vkCmdBindDescriptorSets(CommandHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, VkPipelineTranslucent.GetVulkanPipelineLayout(), 0, DescriptorSets, null);
//vkCmdBindPipeline(CommandHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, VkPipelineOpaque.GetVulkanPipeline());
//vkCmdBindDescriptorSets(CommandHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, VkPipelineOpaque.GetVulkanPipelineLayout(), 0, DescriptorSets, null);
} else{
vkCmdBindPipeline(CommandHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, VkPipeline.GetVulkanPipeline());
vkCmdBindDescriptorSets(CommandHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, VkPipeline.GetVulkanPipelineLayout(),0,DescriptorSets,null);
} }
RenderActors(engineInstance, CommandHandle, modelsCache, materialsCache, true); RenderActors(engineInstance, CommandHandle, modelsCache, materialsCache, true);
vkCmdEndRendering(CommandHandle); vkCmdEndRendering(CommandHandle);
GPUTIME += System.nanoTime() - InitialTime; GPUTIME += System.nanoTime() - InitialTime;
@ -346,9 +453,21 @@ public class DeferredSceneRender implements SceneRenderer {//dynamic rendering
var buffer = materialsCache.GetMaterialsBuffer(); var buffer = materialsCache.GetMaterialsBuffer();
descSet.SetBuffer(device, buffer, buffer.GetRequestedSize(), layoutInfo.Binding(), layoutInfo.DescriptorType()); descSet.SetBuffer(device, buffer, buffer.GetRequestedSize(), layoutInfo.Binding(), layoutInfo.DescriptorType());
List<ImageView> imageViews = textureCache.GetTextureList().stream().map(Texture::GetImageView).toList(); List<ImageView> imageViews = textureCache.GetTextureList().stream().map(ITexture::GetImageView).toList();
descSet = VkCtx.GetDescriptorAllocator().AddDescriptorSet(device, DESCRIPTOR_ID_TEXT, descriptorLayoutTexture); descSet = VkCtx.GetDescriptorAllocator().AddDescriptorSet(device, DESCRIPTOR_ID_TEXT, descriptorLayoutTexture);
descSet.SetImageArray(device, imageViews, textureSampler, 0); descSet.SetImageArray(device, imageViews, textureSampler, 0);
DescriptorSet descSetSkyBox = descAllocator.AddDescriptorSet(device, DESCRIPTOR_ID_SKYBOX_CUBEMAP, descriptorLayoutSkyboxTexture);
ITexture SkyBoxTexture = textureCache.GetTexture(SkyBoxID);
if (SkyBoxTexture == null) {
throw new RuntimeException("Skybox texture map was not properly cached before descriptor binding phase!");
}
descSetSkyBox.SetImage(
device,
SkyBoxTexture.GetImageView(),
textureSampler,
descriptorLayoutSkyboxTexture.GetLayoutInfo().Binding()
);
} }
private static VkRenderingInfo CreateRenderInfo(VulkanContext VkCtx, VkRenderingAttachmentInfo.Buffer ColourAttachmentInfo, VkRenderingAttachmentInfo DepthAttachmentInfo){ private static VkRenderingInfo CreateRenderInfo(VulkanContext VkCtx, VkRenderingAttachmentInfo.Buffer ColourAttachmentInfo, VkRenderingAttachmentInfo DepthAttachmentInfo){
@ -368,6 +487,7 @@ public class DeferredSceneRender implements SceneRenderer {//dynamic rendering
public void cleanup(VulkanContext VkCtx){ public void cleanup(VulkanContext VkCtx){
VkPipeline.CleanUp(VkCtx); VkPipeline.CleanUp(VkCtx);
// VkSkyboxPipeline.CleanUp(VkCtx);
VkPipelineOpaque.CleanUp(VkCtx); VkPipelineOpaque.CleanUp(VkCtx);
VkPipelineTranslucent.CleanUp(VkCtx); VkPipelineTranslucent.CleanUp(VkCtx);
Arrays.asList(BufferViewMatrices).forEach(b -> b.cleanup(VkCtx)); Arrays.asList(BufferViewMatrices).forEach(b -> b.cleanup(VkCtx));

View file

@ -9,10 +9,7 @@ import net.halbear.Terrain4J.EngineCore.Main.Scene.IScene;
import net.halbear.Terrain4J.EngineCore.Main.Scene.Scene; import net.halbear.Terrain4J.EngineCore.Main.Scene.Scene;
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.DeferredRendering.MultiRenderTargetAttachments; import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.DeferredRendering.MultiRenderTargetAttachments;
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.DefaultPipeline; import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.DefaultPipeline;
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Images.Attachment; import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Images.*;
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Images.Image;
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Images.Texture;
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Images.TextureCache;
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Pipeline; import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.Pipeline;
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.PipelineBuildInfo; import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.PipelineBuildInfo;
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.PushConstantsRange; import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Pipeline.PushConstantsRange;
@ -60,7 +57,7 @@ public class ForwardSceneRender implements SceneRenderer {//dynamic rendering
private final DescriptorSetLayout descriptorLayoutVertexUniform; private final 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;
private final VkClearValue ClearValueDepth; private final VkClearValue ClearValueDepth;
private final ByteBuffer PushConstBuffer; private final ByteBuffer PushConstBuffer;
private Attachment AttachmentDepth; private Attachment AttachmentDepth;
@ -356,7 +353,7 @@ public class ForwardSceneRender implements SceneRenderer {//dynamic rendering
DescriptorSetLayout.LayoutInformation LayoutInfo = descriptorLayoutFragStorage.GetLayoutInfo(); DescriptorSetLayout.LayoutInformation LayoutInfo = descriptorLayoutFragStorage.GetLayoutInfo();
var Buffer = materialsCache.GetMaterialsBuffer(); var Buffer = materialsCache.GetMaterialsBuffer();
descriptorSet.SetBuffer(device,Buffer,Buffer.GetRequestedSize(),LayoutInfo.Binding(),LayoutInfo.DescriptorType()); descriptorSet.SetBuffer(device,Buffer,Buffer.GetRequestedSize(),LayoutInfo.Binding(),LayoutInfo.DescriptorType());
List<ImageView> imageViews = textureCache.GetTextureList().stream().map(Texture::GetImageView).toList(); List<ImageView> imageViews = textureCache.GetTextureList().stream().map(ITexture::GetImageView).toList();
descriptorSet = VkCtx.GetDescriptorAllocator().AddDescriptorSet(device,DESCRIPTOR_ID_TEXT,descriptorLayoutTexture); descriptorSet = VkCtx.GetDescriptorAllocator().AddDescriptorSet(device,DESCRIPTOR_ID_TEXT,descriptorLayoutTexture);
descriptorSet.SetImageArray(device,imageViews,textureSampler,0); descriptorSet.SetImageArray(device,imageViews,textureSampler,0);
} }

View file

@ -17,6 +17,7 @@ import java.nio.LongBuffer;
import java.util.Arrays; import java.util.Arrays;
import static net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanUtils.vkCheck; import static net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanUtils.vkCheck;
import static org.lwjgl.vulkan.KHRSurface.VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
import static org.lwjgl.vulkan.VK13.*; import static org.lwjgl.vulkan.VK13.*;
public class SwapChain { public class SwapChain {
@ -43,7 +44,7 @@ public class SwapChain {
.imageArrayLayers(1) .imageArrayLayers(1)
.imageUsage(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) .imageUsage(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)
.preTransform(SurfaceCapabilities.currentTransform()) .preTransform(SurfaceCapabilities.currentTransform())
.compositeAlpha(KHRSurface.VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR) .compositeAlpha(VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR)
.clipped(true); .clipped(true);
if (VSYNC){ if (VSYNC){
VulkanSwapChainCreateInfo.presentMode(KHRSurface.VK_PRESENT_MODE_FIFO_KHR); VulkanSwapChainCreateInfo.presentMode(KHRSurface.VK_PRESENT_MODE_FIFO_KHR);

View file

@ -87,7 +87,7 @@ public class SwapChainRender {
} }
private static Pipeline CreatePipeline(VulkanContext VkCtx, ShaderModule[] shaderModules, DescriptorSetLayout[] descriptorSetLayouts){ private static Pipeline CreatePipeline(VulkanContext VkCtx, ShaderModule[] shaderModules, DescriptorSetLayout[] descriptorSetLayouts){
var VertexBufferStruct = new EmptyVertexBufferStruct(); var VertexBufferStruct = new EmptyVertexBufferStruct();
var BuildInfo = new PipelineBuildInfo(shaderModules, VertexBufferStruct.GetVertexInput(),new int[]{VkCtx.GetSurface().GetSurfaceFormat().ImageFormat()}).SetDescriptorSetLayouts(descriptorSetLayouts).BlendingIsUsed(true); var BuildInfo = new PipelineBuildInfo(shaderModules, VertexBufferStruct.GetVertexInput(),new int[]{VkCtx.GetSurface().GetSurfaceFormat().ImageFormat()}).SetDescriptorSetLayouts(descriptorSetLayouts).BlendingIsUsed(false);
var pipeline = new DefaultPipeline(VkCtx,BuildInfo); var pipeline = new DefaultPipeline(VkCtx,BuildInfo);
VertexBufferStruct.CleanUp(); VertexBufferStruct.CleanUp();
return pipeline; return pipeline;
@ -167,9 +167,16 @@ public class SwapChainRender {
vkCmdEndRendering(CommandHandle); vkCmdEndRendering(CommandHandle);
VulkanUtils.ImageBarrier(MemStack,CommandHandle,SwapChainImage,VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, VulkanUtils.ImageBarrier(MemStack,
VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT, VK_ACCESS_2_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT, CommandHandle,
VK_PIPELINE_STAGE_2_NONE, VK_IMAGE_ASPECT_COLOR_BIT); SwapChainImage,
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, // Source Stage
VK_PIPELINE_STAGE_2_NONE, // Destination Stage (Replacing BOTTOM_OF_PIPE)
VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT, // Source Access Mask
VK_ACCESS_2_NONE, // Destination Access Mask (Replacing Stage_2_None)
VK_IMAGE_ASPECT_COLOR_BIT);
} }
} }

View file

@ -1,6 +1,7 @@
package net.halbear.Terrain4J.EngineCore.Vulkan.Util; package net.halbear.Terrain4J.EngineCore.Vulkan.Util;
import net.halbear.Terrain4J.EngineCore.Logic.Rendering.VulkanContext; import net.halbear.Terrain4J.EngineCore.Logic.Rendering.VulkanContext;
import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime;
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Shader.DescriptorAllocator; import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Shader.DescriptorAllocator;
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Shader.DescriptorSet; import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Shader.DescriptorSet;
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Shader.DescriptorSetLayout; import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.Shader.DescriptorSetLayout;
@ -9,6 +10,7 @@ import org.joml.Matrix4f;
import org.lwjgl.system.MemoryStack; import org.lwjgl.system.MemoryStack;
import org.lwjgl.system.MemoryUtil; import org.lwjgl.system.MemoryUtil;
import org.lwjgl.vulkan.*; import org.lwjgl.vulkan.*;
import org.tinylog.Logger;
import java.io.BufferedInputStream; import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
@ -41,7 +43,16 @@ public class VulkanUtils {
matrix.get(Offset, matrixBuffer); matrix.get(Offset, matrixBuffer);
VkBuffer.UnMapMemory(VkCtx); VkBuffer.UnMapMemory(VkCtx);
} }
public static VulkanBuffer CreateRawVertexAttrBuffer(VulkanContext VkCtx, long BufferSize) {
return new VulkanBuffer(
VkCtx,
BufferSize,
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE,
VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
);
}
public static VulkanBuffer[] CreateHostVisibleBuffers(VulkanContext VkCtx, long BufferSize, int BufferCount, int Usage, String ID, DescriptorSetLayout layout){ public static VulkanBuffer[] CreateHostVisibleBuffers(VulkanContext VkCtx, long BufferSize, int BufferCount, int Usage, String ID, DescriptorSetLayout layout){
DescriptorAllocator descriptorAllocator = VkCtx.GetDescriptorAllocator(); DescriptorAllocator descriptorAllocator = VkCtx.GetDescriptorAllocator();
Device device = VkCtx.GetDevice(); Device device = VkCtx.GetDevice();
@ -142,7 +153,12 @@ public class VulkanUtils {
case VK_ERROR_UNKNOWN -> "VK_ERROR_UNKNOWN"; case VK_ERROR_UNKNOWN -> "VK_ERROR_UNKNOWN";
default -> "Not mapped"; default -> "Not mapped";
}; };
throw new RuntimeException(ErrorMessage + ": " + ErrorCode + " [" + Error + "]"); Logger.error("FATAL VULKAN ERROR -> " + ErrorMessage + ": " + ErrorCode + " [" + Error + "]\nAttempting To Restart Vulkan...");
if(PrimaryRuntime.GetRenderThread() != null)PrimaryRuntime.GetRenderThread().RestartCrashedRenderer();
else{
PrimaryRuntime.GetEngineInstance().window().setShouldClose();
PrimaryRuntime.CloseRuntime();
}
} }
} }

View file

@ -27,6 +27,8 @@ compatibility_mode=false
#0 = Forward rendering #0 = Forward rendering
#1 = Deferred rendering #1 = Deferred rendering
Renderer=1 Renderer=1
ShadowMapSize=16
MaxAllowedVulkanCrashes=10
AlphaToCoverage=false AlphaToCoverage=false
DualPassRendering=false DualPassRendering=false
#AA settings #AA settings
@ -43,7 +45,7 @@ vkValidated=true
vsync=false vsync=false
#Swap Chain Images #Swap Chain Images
RequestedImages=3 RequestedImages=3
DefaultTexturePath=resources/EngineResources/Texture/DefaultTexture.png DefaultTexturePath=resources/EngineResources/Texture/NoTexture.png
#This is the name of the GPU you want the engine to use #This is the name of the GPU you want the engine to use
PhysicalDeviceName= PhysicalDeviceName=