Shadows, broke OpenGL, broke graphics settings, Exception raised when closing software
This commit is contained in:
parent
f7127e0878
commit
0d41f3e15b
36 changed files with 1187 additions and 219 deletions
|
|
@ -0,0 +1,233 @@
|
|||
#version 450
|
||||
#extension GL_EXT_scalar_block_layout: require
|
||||
|
||||
// CREDITS: Most of the functions here have been obtained from this link: https://github.com/SaschaWillems/Vulkan
|
||||
// developed by Sascha Willems, https://twitter.com/JoeyDeVriez, and licensed under the terms of the MIT License (MIT)
|
||||
|
||||
layout (constant_id = 0) const int SHADOW_MAP_CASCADE_COUNT = 6;
|
||||
layout (constant_id = 1) const int DEBUG_SHADOWS = 0;
|
||||
const float PI = 3.14159265359;
|
||||
|
||||
struct Light {
|
||||
vec3 position;
|
||||
uint directional;
|
||||
float intensity;
|
||||
vec3 color;
|
||||
};
|
||||
struct CascadeShadow {
|
||||
mat4 projViewMatrix;
|
||||
vec4 splitDistance;
|
||||
};
|
||||
|
||||
layout(location = 0) in vec2 inTextCoord;
|
||||
|
||||
layout(location = 0) out vec4 outFragColor;
|
||||
|
||||
layout(set = 0, binding = 0) uniform sampler2D posSampler;
|
||||
layout(set = 0, binding = 1) uniform sampler2D albedoSampler;
|
||||
layout(set = 0, binding = 2) uniform sampler2D normalsSampler;
|
||||
layout(set = 0, binding = 3) uniform sampler2D pbrSampler;
|
||||
layout(set = 0, binding = 4) uniform sampler2DArray shadowSampler;
|
||||
|
||||
layout(scalar, set = 1, binding = 0) readonly buffer Lights {
|
||||
Light lights[];
|
||||
} lights;
|
||||
layout(set = 2, binding = 0) readonly buffer Shadows {
|
||||
CascadeShadow cascadeshadows[];
|
||||
} shadows;
|
||||
layout(scalar, set = 3, binding = 0) uniform SceneInfo {
|
||||
vec3 camPos;
|
||||
float ambientLightIntensity;
|
||||
vec3 ambientLightColor;
|
||||
uint numLights;
|
||||
mat4 viewMatrix;
|
||||
} sceneInfo;
|
||||
|
||||
float chebyshevUpperBound(vec2 moments, float t) {
|
||||
// Surface is fully lit if the current fragment is before the light occluder
|
||||
if (t <= moments.x)
|
||||
return 1.0;
|
||||
|
||||
// Compute variance
|
||||
float variance = moments.y - (moments.x * moments.x);
|
||||
variance = max(variance, 0.00002); // Small epsilon to avoid divide by zero
|
||||
|
||||
// Compute probabilistic upper bound
|
||||
float d = t - moments.x;
|
||||
float p_max = variance / (variance + d * d);
|
||||
|
||||
// Reduce light bleeding
|
||||
p_max = smoothstep(0.2, 1.0, p_max);
|
||||
|
||||
return p_max;
|
||||
}
|
||||
|
||||
float calcVisibility(vec4 worldPosition, uint cascadeIndex) {
|
||||
vec4 shadowMapPosition = shadows.cascadeshadows[cascadeIndex].projViewMatrix * worldPosition;
|
||||
|
||||
shadowMapPosition.xyz /= shadowMapPosition.w;
|
||||
|
||||
vec2 uv = vec2(
|
||||
shadowMapPosition.x * 0.5 + 0.5,
|
||||
shadowMapPosition.y * -0.5 + 0.5
|
||||
);
|
||||
|
||||
float depth = shadowMapPosition.z;
|
||||
|
||||
if (uv.x < 0.0 || uv.x > 1.0 ||
|
||||
uv.y < 0.0 || uv.y > 1.0 ||
|
||||
depth < 0.0 || depth > 1.0) {
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
vec2 moments = texture(shadowSampler, vec3(uv, cascadeIndex)).rg;
|
||||
|
||||
float visibility = chebyshevUpperBound(moments, depth);
|
||||
return visibility;
|
||||
}
|
||||
|
||||
float distributionGGX(vec3 N, vec3 H, float roughness) {
|
||||
float a = roughness * roughness;
|
||||
float a2 = a * a;
|
||||
float NdotH = max(dot(N, H), 0.0);
|
||||
float NdotH2 = NdotH * NdotH;
|
||||
|
||||
float nom = a2;
|
||||
float denom = (NdotH2 * (a2 - 1.0) + 1.0);
|
||||
denom = PI * denom * denom;
|
||||
|
||||
return nom / denom;
|
||||
}
|
||||
|
||||
float geometrySchlickGGX(float NdotV, float roughness) {
|
||||
float r = (roughness + 1.0);
|
||||
float k = (r * r) / 8.0;
|
||||
|
||||
float nom = NdotV;
|
||||
float denom = NdotV * (1.0 - k) + k;
|
||||
|
||||
return nom / denom;
|
||||
}
|
||||
|
||||
float geometrySmith(vec3 N, vec3 V, vec3 L, float roughness) {
|
||||
float NdotV = max(dot(N, V), 0.0);
|
||||
float NdotL = max(dot(N, L), 0.0);
|
||||
float ggx2 = geometrySchlickGGX(NdotV, roughness);
|
||||
float ggx1 = geometrySchlickGGX(NdotL, roughness);
|
||||
|
||||
return ggx1 * ggx2;
|
||||
}
|
||||
|
||||
vec3 fresnelSchlick(float cosTheta, vec3 F0) {
|
||||
return F0 + (1.0 - F0) * pow(clamp(1.0 - cosTheta, 0.0, 1.0), 5.0);
|
||||
}
|
||||
|
||||
vec3 calculatePointLight(Light light, vec3 worldPos, vec3 V, vec3 N, vec3 F0, vec3 albedo, float metallic, float roughness) {
|
||||
vec3 tmpSub = light.position - worldPos;
|
||||
vec3 L = normalize(tmpSub);
|
||||
vec3 H = normalize(V + L);
|
||||
|
||||
// Calculate distance and attenuation
|
||||
float distance = length(tmpSub);
|
||||
float attenuation = 1.0 / (distance * distance);
|
||||
float intensity = 10.0f;
|
||||
vec3 radiance = light.color * light.intensity * attenuation;
|
||||
|
||||
// Cook-Torrance BRDF
|
||||
float NDF = distributionGGX(N, H, roughness);
|
||||
float G = geometrySmith(N, V, L, roughness);
|
||||
vec3 F = fresnelSchlick(max(dot(H, V), 0.0), F0);
|
||||
|
||||
vec3 numerator = NDF * G * F;
|
||||
float denominator = 4.0 * max(dot(N, V), 0.0) * max(dot(N, L), 0.0) + 0.0001;
|
||||
vec3 specular = numerator / denominator;
|
||||
|
||||
vec3 kS = F;
|
||||
vec3 kD = vec3(1.0) - kS;
|
||||
kD *= 1.0 - metallic;
|
||||
|
||||
float NdotL = max(dot(N, L), 0.0);
|
||||
return (kD * albedo / PI + specular) * radiance * NdotL;
|
||||
}
|
||||
|
||||
vec3 calculateDirectionalLight(Light light, vec3 V, vec3 N, vec3 F0, vec3 albedo, float metallic, float roughness) {
|
||||
vec3 L = normalize(-light.position);
|
||||
vec3 H = normalize(V + L);
|
||||
|
||||
vec3 radiance = light.color * light.intensity;
|
||||
|
||||
// Cook-Torrance BRDF
|
||||
float NDF = distributionGGX(N, H, roughness);
|
||||
float G = geometrySmith(N, V, L, roughness);
|
||||
vec3 F = fresnelSchlick(max(dot(H, V), 0.0), F0);
|
||||
|
||||
vec3 numerator = NDF * G * F;
|
||||
float denominator = 4.0 * max(dot(N, V), 0.0) * max(dot(N, L), 0.0) + 0.0001;
|
||||
vec3 specular = numerator / denominator;
|
||||
|
||||
vec3 kS = F;
|
||||
vec3 kD = vec3(1.0) - kS;
|
||||
kD *= 1.0 - metallic;
|
||||
|
||||
float NdotL = max(dot(N, L), 0.0);
|
||||
return (kD * albedo / PI + specular) * radiance * NdotL;
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec3 albedo = texture(albedoSampler, inTextCoord).rgb;
|
||||
vec3 normal = texture(normalsSampler, inTextCoord).rgb;
|
||||
vec4 worldPosW = texture(posSampler, inTextCoord);
|
||||
vec3 worldPos = worldPosW.xyz;
|
||||
vec3 pbr = texture(pbrSampler, inTextCoord).rgb;
|
||||
|
||||
float roughness = pbr.g;
|
||||
float metallic = pbr.b;
|
||||
|
||||
vec3 N = normalize(normal);
|
||||
vec3 V = normalize(sceneInfo.camPos - worldPos);
|
||||
|
||||
vec3 F0 = vec3(0.04);
|
||||
F0 = mix(F0, albedo, metallic);
|
||||
|
||||
uint cascadeIndex = 0;
|
||||
vec4 viewPos = sceneInfo.viewMatrix * worldPosW;
|
||||
for (uint i = 0; i < SHADOW_MAP_CASCADE_COUNT - 1; ++i) {
|
||||
if (viewPos.z < shadows.cascadeshadows[i].splitDistance.x) {
|
||||
cascadeIndex = i + 1;
|
||||
}
|
||||
}
|
||||
float shadow = calcVisibility(vec4(worldPos, 1), cascadeIndex);
|
||||
|
||||
vec3 Lo = vec3(0.0);
|
||||
for (uint i = 0; i < sceneInfo.numLights; i++) {
|
||||
Light light = lights.lights[i];
|
||||
if (light.directional == 1) {
|
||||
Lo += calculateDirectionalLight(light, V, N, F0, albedo, metallic, roughness) * shadow;
|
||||
} else {
|
||||
Lo += calculatePointLight(light, worldPos, V, N, F0, albedo, metallic, roughness);
|
||||
}
|
||||
}
|
||||
vec3 ambient = sceneInfo.ambientLightColor * albedo * sceneInfo.ambientLightIntensity;
|
||||
outFragColor = vec4(Lo + ambient, 1.0f);
|
||||
|
||||
if (DEBUG_SHADOWS == 1) {
|
||||
switch (cascadeIndex) {
|
||||
case 0:
|
||||
outFragColor.rgb *= vec3(1.0f, 0.25f, 0.25f);
|
||||
break;
|
||||
case 1:
|
||||
outFragColor.rgb *= vec3(0.25f, 1.0f, 0.25f);
|
||||
break;
|
||||
case 2:
|
||||
outFragColor.rgb *= vec3(0.25f, 0.25f, 1.0f);
|
||||
break;
|
||||
default:
|
||||
outFragColor.rgb *= vec3(1.0f, 1.0f, 0.25f);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (length(normal) < 0.001) {
|
||||
outFragColor = vec4(albedo,1.0f);
|
||||
return;
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
|
@ -1,5 +1,51 @@
|
|||
#version 450
|
||||
|
||||
void main() {
|
||||
// Keep in sync manually with Java code
|
||||
const int MAX_TEXTURES = 256;
|
||||
|
||||
layout (location = 0) in vec2 inTextCoords;
|
||||
layout (location = 1) in flat uint inMaterialIdx;
|
||||
|
||||
layout(location = 0) out vec2 outFragColor;
|
||||
|
||||
struct Material {
|
||||
vec4 diffuseColor;
|
||||
uint hasTexture;
|
||||
uint textureIdx;
|
||||
uint hasNormalMap;
|
||||
uint normalMapIdx;
|
||||
uint hasRoughMap;
|
||||
uint roughMapIdx;
|
||||
float roughnessFactor;
|
||||
float metallicFactor;
|
||||
};
|
||||
|
||||
layout(set = 1, binding = 0) uniform sampler2D textSampler[MAX_TEXTURES];
|
||||
layout(set = 2, binding = 0) readonly buffer MaterialUniform {
|
||||
Material materials[];
|
||||
} matUniform;
|
||||
|
||||
void main()
|
||||
{
|
||||
Material material = matUniform.materials[inMaterialIdx];
|
||||
vec4 albedo;
|
||||
if (material.hasTexture == 1) {
|
||||
albedo = texture(textSampler[material.textureIdx], inTextCoords);
|
||||
} else {
|
||||
albedo = material.diffuseColor;
|
||||
}
|
||||
if (albedo.a < 0.5) {
|
||||
discard;
|
||||
}
|
||||
|
||||
float depth = gl_FragCoord.z;
|
||||
float moment1 = depth;
|
||||
float moment2 = depth * depth;
|
||||
|
||||
// Adjust moments to avoid light bleeding
|
||||
float dx = dFdx(depth);
|
||||
float dy = dFdy(depth);
|
||||
moment2 += 0.25 * (dx * dx + dy * dy);
|
||||
|
||||
outFragColor = vec2(moment1, moment2);
|
||||
}
|
||||
|
|
@ -1,5 +1,29 @@
|
|||
#version 450
|
||||
|
||||
void main() {
|
||||
#define SHADOW_MAP_CASCADE_COUNT 6
|
||||
|
||||
layout (triangles, invocations = SHADOW_MAP_CASCADE_COUNT) in;
|
||||
layout (triangle_strip, max_vertices = 3) out;
|
||||
|
||||
layout (location = 0) in vec2 inTextCoords[];
|
||||
layout (location = 1) in flat uint inMaterialIdx[];
|
||||
|
||||
layout (location = 0) out vec2 outTextCoords;
|
||||
layout (location = 1) out flat uint outMaterialIdx;
|
||||
|
||||
layout(set = 0, binding = 0) uniform ProjUniforms {
|
||||
mat4 projViewMatrices[SHADOW_MAP_CASCADE_COUNT];
|
||||
} projUniforms;
|
||||
|
||||
void main()
|
||||
{
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
outTextCoords = inTextCoords[i];
|
||||
outMaterialIdx = inMaterialIdx[i];
|
||||
gl_Layer = gl_InvocationID;
|
||||
gl_Position = projUniforms.projViewMatrices[gl_InvocationID] * gl_in[i].gl_Position;
|
||||
EmitVertex();
|
||||
}
|
||||
EndPrimitive();
|
||||
}
|
||||
|
|
@ -1,5 +1,23 @@
|
|||
#version 450
|
||||
|
||||
void main() {
|
||||
layout(location = 0) in vec3 entityPos;
|
||||
layout(location = 1) in vec3 entityNormal;
|
||||
layout(location = 2) in vec3 entityTangent;
|
||||
layout(location = 3) in vec3 entityBitangent;
|
||||
layout(location = 4) in vec2 entityTextCoords;
|
||||
|
||||
layout(push_constant) uniform matrices {
|
||||
mat4 modelMatrix;
|
||||
uint materialIdx;
|
||||
} push_constants;
|
||||
|
||||
layout (location = 0) out vec2 outTextCoord;
|
||||
layout (location = 1) out flat uint outMaterialIdx;
|
||||
|
||||
void main()
|
||||
{
|
||||
outTextCoord = entityTextCoords;
|
||||
outMaterialIdx = push_constants.materialIdx;
|
||||
|
||||
gl_Position = push_constants.modelMatrix * vec4(entityPos, 1.0f);
|
||||
}
|
||||
|
|
@ -7,7 +7,5 @@ layout(location = 1) out vec4 outColor;
|
|||
layout(set = 2, binding = 0) uniform samplerCube skyboxSampler;
|
||||
|
||||
void main() {
|
||||
vec3 textureIn = texture(skyboxSampler, outTexCoords).rgb;
|
||||
vec3 adjusted =vec3(0.0,textureIn.y/200.0,textureIn.z/150.0);
|
||||
outColor = vec4(adjusted, 1.0);
|
||||
outColor = texture(skyboxSampler, outTexCoords);// * vec4(0.0,0.05,0.1,1);
|
||||
}
|
||||
Binary file not shown.
|
|
@ -14,5 +14,5 @@ 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);
|
||||
gl_Position = vec4(pos.xy, pos.w, pos.w);
|
||||
}
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -9,8 +9,10 @@ import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime;
|
|||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.GUI.GuiRenderer;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.GUI.GuiTexture;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.DeferredRendering.LightRenderer;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.Images.Attachment;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.Images.TextureCache;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.PostProcessing.PostProcess;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Shadows.ShadowRenderer;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.VkModel.*;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.SpriteRendering.SpriteRenderer;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DeviceLayers.CommandBuffer;
|
||||
|
|
@ -53,6 +55,7 @@ public class VulkanRenderer implements Renderer {
|
|||
private final LightRenderer lightRenderer;
|
||||
private final PostProcess PostProcessor;
|
||||
private final SwapChainRender swapChainRender;
|
||||
private final ShadowRenderer shadowRender;
|
||||
private final GuiRenderer GuiRender;
|
||||
private int CurrentFrame;
|
||||
private final VulkanContext RendererContext;
|
||||
|
|
@ -99,12 +102,17 @@ public class VulkanRenderer implements Renderer {
|
|||
}
|
||||
if(Deferred) {
|
||||
sceneRender = new DeferredSceneRender(RendererContext, engineInstance);
|
||||
lightRenderer = new LightRenderer(RendererContext, sceneRender.GetMRTAttachments().GetAllAttachments());
|
||||
shadowRender = new ShadowRenderer(RendererContext);
|
||||
List<Attachment> attachments = new ArrayList<>(sceneRender.GetMRTAttachments().GetColourAttachments());
|
||||
attachments.add(shadowRender.getShadowAttachment());
|
||||
lightRenderer = new LightRenderer(RendererContext, attachments);
|
||||
PostProcessor = new PostProcess(RendererContext, lightRenderer.getAttachment());
|
||||
|
||||
} else{
|
||||
sceneRender = new ForwardSceneRender(RendererContext);
|
||||
PostProcessor = new PostProcess(RendererContext, sceneRender.GetAttachmentColour());
|
||||
lightRenderer = null;
|
||||
shadowRender = null;
|
||||
}
|
||||
spriteRenderer= new SpriteRenderer(engineInstance, RendererContext, PostProcessor.GetAttachment());
|
||||
GuiRender = new GuiRenderer(engineInstance, RendererContext, GraphicsQueue, PostProcessor.GetAttachment());
|
||||
|
|
@ -152,6 +160,7 @@ public class VulkanRenderer implements Renderer {
|
|||
Logger.debug("Loaded {} models", Models.size());
|
||||
|
||||
sceneRender.LoadMaterials(RendererContext,materialsCache,textureCache);
|
||||
shadowRender.loadMaterials(RendererContext, materialsCache, textureCache);
|
||||
spriteRenderer.CompileSprites(RendererContext,modelsCache, textureCache);
|
||||
spriteRenderer.LoadMaterials(RendererContext,materialsCache,textureCache);
|
||||
GuiRender.LoadTextures(RendererContext,initData.GuiTextures(),textureCache);
|
||||
|
|
@ -173,6 +182,7 @@ public class VulkanRenderer implements Renderer {
|
|||
RendererContext.GetDevice().waitIdle();
|
||||
Logger.debug("Waiting Vulkan Context");
|
||||
sceneRender.cleanup(RendererContext);
|
||||
if(shadowRender != null)shadowRender.cleanup(RendererContext);
|
||||
if(lightRenderer != null)lightRenderer.cleanup(RendererContext);
|
||||
PostProcessor.CleanUp(RendererContext);
|
||||
swapChainRender.CleanUp(RendererContext);
|
||||
|
|
@ -206,7 +216,9 @@ public class VulkanRenderer implements Renderer {
|
|||
RecordingStart(CommandPool, CommandBuffer);
|
||||
|
||||
sceneRender.Render(engineInstance,RendererContext,CommandBuffer, modelsCache,materialsCache,CurrentFrame);
|
||||
lightRenderer.render(engineInstance, RendererContext, CommandBuffer, sceneRender.GetMRTAttachments(), CurrentFrame);
|
||||
shadowRender.render(engineInstance, RendererContext, CommandBuffer, modelsCache, materialsCache, CurrentFrame);
|
||||
lightRenderer.render(engineInstance, RendererContext, CommandBuffer, sceneRender.GetMRTAttachments(), shadowRender.getShadowAttachment(), CurrentFrame,
|
||||
shadowRender.getCascadeShadows(CurrentFrame));
|
||||
PostProcessor.Render(RendererContext,CommandBuffer,lightRenderer.getAttachment());
|
||||
spriteRenderer.Render(engineInstance,RendererContext,CommandBuffer,PostProcessor.GetAttachment(),modelsCache,CurrentFrame);
|
||||
GuiRender.Render(RendererContext,CommandBuffer,CurrentFrame,PostProcessor.GetAttachment());
|
||||
|
|
@ -280,7 +292,9 @@ public class VulkanRenderer implements Renderer {
|
|||
engineInstance.scene().GetProjection().Resize(extend.width(),extend.height());
|
||||
sceneRender.Resize(engineInstance,RendererContext);
|
||||
if(Deferred) {
|
||||
lightRenderer.resize(RendererContext, sceneRender.GetMRTAttachments().GetAllAttachments());
|
||||
List<Attachment> attachments = new ArrayList<>(sceneRender.GetMRTAttachments().GetColourAttachments());
|
||||
attachments.add(shadowRender.getShadowAttachment());
|
||||
lightRenderer.resize(RendererContext, attachments);
|
||||
PostProcessor.Resize(RendererContext, lightRenderer.getAttachment());
|
||||
} else{
|
||||
PostProcessor.Resize(RendererContext, sceneRender.GetAttachmentColour());
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ public class EngineConfig {
|
|||
public boolean AlphaToCoverage = false;
|
||||
public boolean CompatibilityMode = false;
|
||||
public Renderer renderer = Renderer.Forward;
|
||||
public int ShadowMapSize = 16;
|
||||
public int ShadowMapSize = 4096;
|
||||
public float Gamma = 0.8545f;
|
||||
public int MaxVulkanCrashesAllowed = 10;
|
||||
public boolean RenderCollisionMesh = true;
|
||||
|
|
@ -322,7 +322,7 @@ public class EngineConfig {
|
|||
zFarPlane = (Float.parseFloat(EngineConfigVar.getOrDefault("z_far_plane", 100.0f).toString()));
|
||||
AAValue = (Integer.parseInt(EngineConfigVar.getOrDefault("anti_alias_mode", 1).toString()));
|
||||
renderer = Integer.parseInt(EngineConfigVar.getOrDefault("Renderer", 1).toString()) == 0 ? Renderer.Forward: Renderer.Deferred;
|
||||
ShadowMapSize = Integer.parseInt(EngineConfigVar.getOrDefault("ShadowMapSize", 16).toString());
|
||||
ShadowMapSize = Integer.parseInt(EngineConfigVar.getOrDefault("ShadowMapSize", 4096).toString());
|
||||
MaxVulkanCrashesAllowed = Integer.parseInt(EngineConfigVar.getOrDefault("MaxAllowedVulkanCrashes", 10).toString());
|
||||
ServerPort = Integer.parseInt(EngineConfigVar.getOrDefault("server_port", 25565).toString());
|
||||
CompatibilityMode = Boolean.parseBoolean(EngineConfigVar.getOrDefault("compatibility_mode", false).toString());
|
||||
|
|
@ -385,6 +385,7 @@ public class EngineConfig {
|
|||
EngineConfigVar.setProperty("MaxDescriptors","1000");
|
||||
EngineConfigVar.setProperty("anti_alias_mode","1");
|
||||
EngineConfigVar.setProperty("server","false");
|
||||
EngineConfigVar.setProperty("ShadowMapSize","4096");
|
||||
EngineConfigVar.setProperty("LoadingScreenLocation",LoadingScreenLocation);
|
||||
EngineConfigVar.store(new FileWriter(path.toAbsolutePath().toString() + "/" + FILENAME), "created new properties file");
|
||||
Logger.debug("Wrote New Config File [{}]", ConfigFile.getAbsolutePath());
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package net.halbear.Terrain4J.EngineCore.Logic.Physics.RigidBody;
|
||||
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.Physics.IPhysicsController;
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.Physics.StaticSpatialHashGrid;
|
||||
import org.joml.Matrix3f;
|
||||
import org.joml.Quaternionf;
|
||||
import org.joml.Vector3f;
|
||||
|
|
@ -80,6 +81,7 @@ public class RigidBody {
|
|||
InverseMassKG = 0f;
|
||||
InverseInertiaLocal.zero();
|
||||
IsStatic = true;
|
||||
StaticSpatialHashGrid.Insert(RigidBodyID, shape.GetWorldAABB());
|
||||
} else {
|
||||
InverseMassKG = 1.0f / mass;
|
||||
IsStatic = false;
|
||||
|
|
|
|||
|
|
@ -31,6 +31,18 @@ public class SpatialHashGrid {
|
|||
}
|
||||
}
|
||||
|
||||
public static Map<Long, List<String>> Cells(){
|
||||
return Cells;
|
||||
}
|
||||
|
||||
public static List<String> GetFromKey(long key){
|
||||
return Cells.getOrDefault(key, Collections.emptyList());
|
||||
}
|
||||
|
||||
public static List<String> GetAtXYZ(int x, int y, int z){
|
||||
long key = HashCell(x, y, z);
|
||||
return Cells.getOrDefault(key, Collections.emptyList());
|
||||
}
|
||||
private static long HashCell(int x, int y, int z) {
|
||||
long xi = ((long) x) & 0x1FFFFFL;
|
||||
long yi = ((long) y) & 0x1FFFFFL;
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import org.joml.primitives.AABBf;
|
|||
import java.util.*;
|
||||
|
||||
public class StaticSpatialHashGrid {
|
||||
public static float CellSize = 16f;
|
||||
public static float CellSize = 3f;
|
||||
|
||||
private static final Map<Long, List<String>> Cells = new HashMap<>();
|
||||
|
||||
|
|
@ -31,6 +31,19 @@ public class StaticSpatialHashGrid {
|
|||
}
|
||||
}
|
||||
|
||||
public static Map<Long, List<String>> Cells(){
|
||||
return Cells;
|
||||
}
|
||||
|
||||
public static List<String> GetFromKey(long key){
|
||||
return Cells.getOrDefault(key, Collections.emptyList());
|
||||
}
|
||||
|
||||
|
||||
public static List<String> GetAtXYZ(int x, int y, int z){
|
||||
long key = HashCell(x, y, z);
|
||||
return Cells.getOrDefault(key, Collections.emptyList());
|
||||
}
|
||||
private static long HashCell(int x, int y, int z) {
|
||||
long xi = ((long) x) & 0x1FFFFFL;
|
||||
long yi = ((long) y) & 0x1FFFFFL;
|
||||
|
|
|
|||
|
|
@ -117,6 +117,23 @@ public class WorldPhysicsManager {
|
|||
|
||||
Set<String> testedPairs = new HashSet<>();
|
||||
|
||||
// SpatialHashGrid.Cells().forEach((key, bucket)->{
|
||||
// int size = bucket.size();
|
||||
// for (int i = 0; i < size; i++) {
|
||||
// RigidBody a = RigidBody.RigidBodyRegister.get(bucket.get(i));
|
||||
// if (a == null) continue;
|
||||
// for (int j = i + 1; j < size; j++) {
|
||||
// RigidBody b = RigidBody.RigidBodyRegister.get(bucket.get(j));
|
||||
// if (b == null || a == b) continue;
|
||||
// TryResolve(a, b, worldBounds, testedPairs);
|
||||
// }
|
||||
// StaticSpatialHashGrid.GetFromKey(key).forEach((id)->{
|
||||
// RigidBody b = RigidBody.RigidBodyRegister.get(id);
|
||||
// if (b == null || a == b) return;
|
||||
// TryResolve(a, b, worldBounds, testedPairs);
|
||||
// });
|
||||
// }
|
||||
// });
|
||||
for (List<String> bucket : SpatialHashGrid.Buckets()) {
|
||||
int size = bucket.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
|
|
|
|||
|
|
@ -47,13 +47,12 @@ import org.tinylog.Logger;
|
|||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import static org.lwjgl.glfw.GLFW.GLFW_KEY_ESCAPE;
|
||||
import static org.lwjgl.glfw.GLFW.GLFW_KEY_F3;
|
||||
import static org.lwjgl.glfw.GLFW.*;
|
||||
|
||||
public class GameCore implements GameLogic {
|
||||
|
||||
private static final float MOUSE_SENSITIVITY = 0.1f;
|
||||
private static final float MOVEMENT_SPEED = 0.01f;
|
||||
private static final float MOVEMENT_SPEED = 0.1f;
|
||||
public static boolean LoadingLevel = false;
|
||||
|
||||
private Vector2f LastMousePos = new Vector2f(0,0);
|
||||
|
|
@ -99,19 +98,31 @@ public class GameCore implements GameLogic {
|
|||
public InitData Initialise(EngineInstance engineInstance) {
|
||||
Scene scene = (Scene) engineInstance.scene();
|
||||
List<ModelData> models = new ArrayList<>();
|
||||
ModelData SponzaData = ModelLoader.LoadModel("resources/models/Cafe/exterior.json");
|
||||
List<MaterialData> SponzaMaterial = ModelLoader.LoadMaterials("resources/models/Cafe/exterior_mat.json");
|
||||
ModelData SponzaData1 = ModelLoader.LoadModel("resources/models/Cafe/interior.json");
|
||||
List<MaterialData> SponzaMaterial1= ModelLoader.LoadMaterials("resources/models/Cafe/interior_mat.json");
|
||||
scene.AddActor(new Actor3D("Sponza1", SponzaData.ID(), new Vector3f(0,0f,-5f)).SetScale(0.1f));
|
||||
scene.AddActor(new Actor3D("Sponza2", SponzaData1.ID(), new Vector3f(0,0f,-5f)).SetScale(0.1f));
|
||||
List<MaterialData> materials = new ArrayList<>();
|
||||
// ModelData SponzaData = ModelLoader.LoadModel("resources/models/Cafe/exterior.json");
|
||||
// List<MaterialData> SponzaMaterial = ModelLoader.LoadMaterials("resources/models/Cafe/exterior_mat.json");
|
||||
// ModelData SponzaData1 = ModelLoader.LoadModel("resources/models/Cafe/interior.json");
|
||||
// List<MaterialData> SponzaMaterial1= ModelLoader.LoadMaterials("resources/models/Cafe/interior_mat.json");
|
||||
// scene.AddActor(new Actor3D("Sponza1", SponzaData.ID(), new Vector3f(0,0f,-5f)).SetScale(0.1f));
|
||||
// scene.AddActor(new Actor3D("Sponza2", SponzaData1.ID(), new Vector3f(0,0f,-5f)).SetScale(0.1f));
|
||||
// ModelData treeModel = ModelLoader.LoadModel("resources/models/tree/tree.json");
|
||||
// models.add(treeModel);
|
||||
// Actor3D treeEntity = new Actor3D("treeEntity", treeModel.ID(), new Vector3f(0.0f, 0.0f, 0.0f));
|
||||
// treeEntity.SetScale(0.05f);
|
||||
// scene.AddActor(treeEntity);
|
||||
// materials.addAll(ModelLoader.LoadMaterials("resources/models/tree/tree_mat.json"));
|
||||
// ModelData treeModel = ModelLoader.LoadModel("resources/models/Forest/forest.json");
|
||||
// models.add(treeModel);
|
||||
// Actor3D treeEntity = new Actor3D("treeEntity", treeModel.ID(), new Vector3f(0.0f, 0.0f, 0.0f));
|
||||
// treeEntity.SetScale(10f);
|
||||
// scene.AddActor(treeEntity);
|
||||
// materials.addAll(ModelLoader.LoadMaterials("resources/models/Forest/forest_mat.json"));
|
||||
MelonaData = ModelLoader.LoadModel("resources/models/cube/Cube.json");
|
||||
CubeModelID = MelonaData.ID();
|
||||
List<MaterialData> MelonaMat = ModelLoader.LoadMaterials("resources/models/cube/Cube_mat.json");
|
||||
var CollisionVisualisationData = ModelLoader.LoadModel("resources/models/VisualCollision/CollisionCube.json");
|
||||
VisualisedCollisionActor3D.CollisionCubeModelID = CollisionVisualisationData.ID();
|
||||
List<MaterialData> CollisionVisualisationMat = ModelLoader.LoadMaterials("resources/models/VisualCollision/CollisionCube_mat.json");
|
||||
List<MaterialData> materials = new ArrayList<>();
|
||||
|
||||
var Melona = ModelLoader.LoadModel("resources/models/melona/melona.json");
|
||||
List<MaterialData> MelonaMaterial = ModelLoader.LoadMaterials("resources/models/melona/melona_mat.json");
|
||||
|
|
@ -147,10 +158,10 @@ public class GameCore implements GameLogic {
|
|||
}
|
||||
boolean createOfflinePlayer = !PrimaryRuntime.IsServer && !ClientSideNetworkUtils.Connected;
|
||||
|
||||
materials.addAll(SponzaMaterial);
|
||||
materials.addAll(SponzaMaterial1);
|
||||
models.add(SponzaData);
|
||||
models.add(SponzaData1);
|
||||
// materials.addAll(SponzaMaterial);
|
||||
// materials.addAll(SponzaMaterial1);
|
||||
// models.add(SponzaData);
|
||||
// models.add(SponzaData1);
|
||||
materials.addAll(MelonaMat);
|
||||
materials.addAll(CollisionVisualisationMat);
|
||||
materials.addAll(MelonaMaterial);
|
||||
|
|
@ -179,47 +190,50 @@ public class GameCore implements GameLogic {
|
|||
guiTextures.add(guiTexture);
|
||||
}
|
||||
|
||||
//scene.GetLightingManager().GetAmbientLightColour().set(1.0f, 0.9f, 0.75f);
|
||||
//scene.GetLightingManager().SetAmbientLightIntensity(0.6f);
|
||||
scene.GetLightingManager().GetAmbientLightColour().set(0.3f, 0.35f, 0.5f);
|
||||
scene.GetLightingManager().SetAmbientLightIntensity(0.01f);
|
||||
|
||||
// SkyLight = new Light(new Vector3f(1.5f, 1.20f, 1.0f),new Vector3f(0.0f, -1.0f, 0.3f), true, 2.00f);
|
||||
SkyLight = new Light(new Vector3f(0.25f, 1.0f, 1.5f),new Vector3f(0.0f, -1.0f, 0.0f), true, 1.70f);
|
||||
scene.GetLightingManager().GetAmbientLightColour().set(1.0f, 0.9f, 0.75f);
|
||||
scene.GetLightingManager().SetAmbientLightIntensity(0.3f);
|
||||
// scene.GetLightingManager().GetAmbientLightColour().set(0.3f, 0.35f, 0.5f);
|
||||
// scene.GetLightingManager().SetAmbientLightIntensity(0.075f);
|
||||
//
|
||||
SkyLight = new Light(new Vector3f(1.5f, 1.20f, 1.0f),new Vector3f(0.0f, -1.0f, 0.3f), true, 2.00f);
|
||||
// SkyLight = new Light(new Vector3f(0.25f, 1.0f, 1.5f),new Vector3f(0.0f, -1.0f, 0.0f), true, 6.0f);
|
||||
SkyLight.SetType(Light.LightType.Directional);
|
||||
|
||||
List<ILight> lights = new ArrayList<>();
|
||||
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-433, 445f, -424f).div(10.0f),false,3000.0f+ (float)(Math.random() * 100.0)));
|
||||
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-210, 445f, 460f).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
|
||||
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-966, 445f, 204f).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
|
||||
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-176, 445f, 1000f).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
|
||||
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(777, 445f, 858).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
|
||||
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(376, 445f, -2136).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
|
||||
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,2.0f),new Vector3f(2163, 445f, 1880).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
|
||||
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(3334, 445f, 2405).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
|
||||
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(3509, 445f, 1825).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
|
||||
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(3877, 445f, 3378).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
|
||||
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(4925, 445f, 3430).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
|
||||
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-2083, 445f, -1826).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
|
||||
// lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-433, 445f, -424f).div(10.0f),false,3000.0f+ (float)(Math.random() * 100.0)));
|
||||
// lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-210, 445f, 460f).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
|
||||
// lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-966, 445f, 204f).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
|
||||
// lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-176, 445f, 1000f).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
|
||||
// lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(777, 445f, 858).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
|
||||
// lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(376, 445f, -2136).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
|
||||
// lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,2.0f),new Vector3f(2163, 445f, 1880).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
|
||||
// lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(3334, 445f, 2405).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
|
||||
// lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(3509, 445f, 1825).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
|
||||
// lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(3877, 445f, 3378).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
|
||||
// lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(4925, 445f, 3430).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
|
||||
// lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-2083, 445f, -1826).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
|
||||
//
|
||||
// lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(2076, 410, 1272).div(10.0f),false,100.0f));
|
||||
// lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(2446, 465, 2303).div(10.0f),false,100.0f));
|
||||
// lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-842, 410, -1141).div(10.0f),false,100.0f));
|
||||
// lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-207, 410, -1830).div(10.0f),false,100.0f));
|
||||
// lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(899, 460, -2015).div(10.0f),false,100.0f));
|
||||
// lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(1775, 460, -3448).div(10.0f),false,100.0f));
|
||||
// lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(1800, 460, -4154).div(10.0f),false,1000.0f));
|
||||
// lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-1727, 410, -387).div(10.0f),false,100.0f));
|
||||
// lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-1198, 410, -964).div(10.0f),false,100.0f));
|
||||
// lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-1778, 410, -1502).div(10.0f),false,100.0f));
|
||||
// lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-2692, 333, -2109).div(10.0f),false,100.0f));
|
||||
// lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-2849, 333, -1724).div(10.0f),false,100.0f));
|
||||
// lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-2019, 410, -729).div(10.0f),false,100.0f));
|
||||
// lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-1727, 410, -389).div(10.0f),false,100.0f));
|
||||
// lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-1337, 410, 122).div(10.0f),false,100.0f));
|
||||
//
|
||||
//
|
||||
// lights.add(new Light(new Vector3f(0.75f,2.0f,0.75f),new Vector3f(1086, 425, -3375).div(10.0f),false,500.0f));
|
||||
|
||||
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(2076, 410, 1272).div(10.0f),false,100.0f));
|
||||
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(2446, 465, 2303).div(10.0f),false,100.0f));
|
||||
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-842, 410, -1141).div(10.0f),false,100.0f));
|
||||
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-207, 410, -1830).div(10.0f),false,100.0f));
|
||||
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(899, 460, -2015).div(10.0f),false,100.0f));
|
||||
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(1775, 460, -3448).div(10.0f),false,100.0f));
|
||||
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(1800, 460, -4154).div(10.0f),false,1000.0f));
|
||||
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-1727, 410, -387).div(10.0f),false,100.0f));
|
||||
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-1198, 410, -964).div(10.0f),false,100.0f));
|
||||
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-1778, 410, -1502).div(10.0f),false,100.0f));
|
||||
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-2692, 333, -2109).div(10.0f),false,100.0f));
|
||||
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-2849, 333, -1724).div(10.0f),false,100.0f));
|
||||
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-2019, 410, -729).div(10.0f),false,100.0f));
|
||||
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-1727, 410, -389).div(10.0f),false,100.0f));
|
||||
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-1337, 410, 122).div(10.0f),false,100.0f));
|
||||
|
||||
|
||||
lights.add(new Light(new Vector3f(0.75f,2.0f,0.75f),new Vector3f(1086, 425, -3375).div(10.0f),false,500.0f));
|
||||
//lights.add(new Light(new Vector3f(3.0f,2.25f,0.0f),new Vector3f(350.0f, 1525.0f, -420.0f),false,4000.0f));
|
||||
//lights.add(new Light(new Vector3f(3.0f,2.25f,0.0f),new Vector3f(400.0f, 1570.0f, -350.0f),false,1000.0f));
|
||||
lights.add(SkyLight);
|
||||
|
||||
ILight[] lightArr = new ILight[lights.size()];
|
||||
|
|
@ -232,7 +246,12 @@ public class GameCore implements GameLogic {
|
|||
}
|
||||
//if(PrimaryRuntime.IsServer) {
|
||||
permutation.GeneratePermutationArray(5783904701859L);
|
||||
//GenerateChunk(new Vector3i(0, 0, 0), 16);
|
||||
for(int x = -1; x < 2; x++){
|
||||
for(int y = -1; y < 2; y++){
|
||||
GenerateChunk(new Vector3i(x, 0, y), 16);
|
||||
|
||||
}
|
||||
}
|
||||
for(int i = 0; i < 20; i++){
|
||||
SpawnNewActor(engineInstance, new Vector3f(-5 + (float)Math.random() * 10,10 + (float)Math.random() * 10, -5 + (float)Math.random() * 10), new Vector3f(0, 0, 0), new Vector3f(1, 1, 1));
|
||||
}
|
||||
|
|
@ -241,6 +260,18 @@ public class GameCore implements GameLogic {
|
|||
Settings.UsernameBuffer.set("Player");
|
||||
return new InitData(models,materials,guiTextures);
|
||||
}
|
||||
public static float lightAngle = 70;
|
||||
|
||||
private void updateDirLight() {
|
||||
float zValue = (float) Math.cos(Math.toRadians(lightAngle));
|
||||
float yValue = (float) Math.sin(Math.toRadians(lightAngle));
|
||||
Vector3f lightDirection = SkyLight.GetPosition();
|
||||
lightDirection.x = 0;
|
||||
lightDirection.y = yValue;
|
||||
lightDirection.z = zValue;
|
||||
lightDirection.normalize();
|
||||
SkyLight.GetPosition().set(lightDirection);
|
||||
}
|
||||
|
||||
public void Reset(){
|
||||
EngineInstance instance = PrimaryRuntime.GetEngineInstance();
|
||||
|
|
@ -465,6 +496,8 @@ public class GameCore implements GameLogic {
|
|||
}
|
||||
if(CumulativeFrameTime >= 16_000_000) {
|
||||
HandleGui(engineInstance, FrameDiffNanoSeconds);
|
||||
// lightAngle = (lightAngle + 0.15f) % 360;
|
||||
// updateDirLight();
|
||||
CumulativeFrameTime = 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -479,6 +512,14 @@ public class GameCore implements GameLogic {
|
|||
if(input.keySinglePress(GLFW_KEY_F3)){
|
||||
Scene.GUI_MODE = (Scene.GUI_MODE + 1) % 2;
|
||||
}
|
||||
if(input.keyPressed(GLFW_KEY_UP)){
|
||||
lightAngle = (lightAngle + 0.5f) % 360;
|
||||
updateDirLight();
|
||||
}
|
||||
if(input.keyPressed(GLFW_KEY_DOWN)){
|
||||
lightAngle = (lightAngle - 0.5f) % 360;
|
||||
updateDirLight();
|
||||
}
|
||||
if (input.keySinglePress(GLFW_KEY_ESCAPE)) {
|
||||
StartMenuActive = !StartMenuActive;
|
||||
StartMenu.GameStarted = StartMenuActive;
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@ public class Light implements ILight{
|
|||
|
||||
public void SetType(LightType type) {
|
||||
this.type = type;
|
||||
if(type == LightType.Directional)
|
||||
Directional = true;
|
||||
}
|
||||
|
||||
public enum LightType{
|
||||
|
|
|
|||
|
|
@ -156,7 +156,7 @@ public class Scene implements IScene {
|
|||
|
||||
if(!PrimaryRuntime.IsServer && !RenderThread.Headless) {
|
||||
GUIReg.put("PerformanceOverlay",new PerformanceOverlay());
|
||||
// ActiveGUIs.add("PerformanceOverlay");
|
||||
ActiveGUIs.add("PerformanceOverlay");
|
||||
GUIReg.put("ChatLog",new GameChat());
|
||||
ActiveGUIs.add("ChatLog");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import java.util.Arrays;
|
|||
import java.util.List;
|
||||
|
||||
public class SceneLightingManager implements ISceneLightingManager {
|
||||
public static int SHADOW_MAP_CASCADE_COUNT = 10;
|
||||
public static int SHADOW_MAP_CASCADE_COUNT = 6;
|
||||
public static int MaxLights;
|
||||
private Vector3f AmbientLightingColour;
|
||||
private float AmbientLightIntensity;
|
||||
|
|
|
|||
|
|
@ -18,8 +18,8 @@ public class Project3D {
|
|||
this.FOV = FOV;
|
||||
OriginalNear = zNear;
|
||||
OriginalFar = zFar;
|
||||
this.ZFarPlane = EngineConfig.getInstance().GetRenderingAPI() == EngineConfig.RenderAPI.OpenGL ? zNear : zFar;
|
||||
this.ZNearPlane = EngineConfig.getInstance().GetRenderingAPI() == EngineConfig.RenderAPI.OpenGL ? zFar : zNear;
|
||||
this.ZFarPlane = zFar;
|
||||
this.ZNearPlane = zNear;
|
||||
ProjectionMatrix = new Matrix4f();
|
||||
Resize(Width, Height);
|
||||
LastWidth = Width;
|
||||
|
|
@ -27,8 +27,8 @@ public class Project3D {
|
|||
}
|
||||
|
||||
public void SetFarPlanes(){
|
||||
ZFarPlane = EngineConfig.getInstance().GetRenderingAPI() == EngineConfig.RenderAPI.OpenGL ? OriginalNear : OriginalFar;
|
||||
ZNearPlane = EngineConfig.getInstance().GetRenderingAPI() == EngineConfig.RenderAPI.OpenGL ? OriginalFar : OriginalNear;
|
||||
ZFarPlane =OriginalFar;
|
||||
ZNearPlane = OriginalNear;
|
||||
Resize(LastWidth,LastHeight);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@ import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.I
|
|||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.Pipeline;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.PipelineBuildInfo;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Shader.*;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Shadows.CascadeData;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Shadows.CascadeShadows;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DeviceLayers.CommandBuffer;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DeviceLayers.Device;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DisplayToScreen.ImageView;
|
||||
|
|
@ -31,15 +33,18 @@ import java.util.ArrayList;
|
|||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static org.lwjgl.util.vma.Vma.VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT;
|
||||
import static org.lwjgl.util.vma.Vma.VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE;
|
||||
import static org.lwjgl.vulkan.VK10.*;
|
||||
import static org.lwjgl.vulkan.VK13.*;
|
||||
|
||||
public class LightRenderer {
|
||||
private static final int COLOUR_FORMAT = VK_FORMAT_R32G32B32A32_SFLOAT;
|
||||
private static final String DESC_ID_ATT = "LIGHT_DESC_ID_ATT";
|
||||
private static final String DESC_ID_SHADOW_MATRICES = "LIGHT_DESC_ID_SHADOW_MATRICES";
|
||||
private static final String DESC_ID_LIGHTS = "LIGHT_DESC_ID_LIGHTS";
|
||||
private static final String DESC_ID_SCENE = "LIGHT_DESC_ID_SCENE ";
|
||||
private static final String FRAGMENT_SHADER_FILE_GLSL = "resources/EngineResources/shaders/lighting_frag.glsl";
|
||||
private static final String FRAGMENT_SHADER_FILE_GLSL = "resources/EngineResources/shaders/lighting_with_shadows_frag.glsl";
|
||||
private static final String FRAGMENT_SHADER_FILE_SPV = FRAGMENT_SHADER_FILE_GLSL + ".spv";
|
||||
private static final String VERTEX_SHADER_FILE_GLSL = "resources/EngineResources/shaders/lighting_vertex.glsl";
|
||||
private static final String VERTEX_SHADER_FILE_SPV = VERTEX_SHADER_FILE_GLSL + ".spv";
|
||||
|
|
@ -53,8 +58,10 @@ public class LightRenderer {
|
|||
private VkRenderingInfo RenderInfo;
|
||||
private final VulkanBuffer[] LightBuffer;
|
||||
private final VulkanBuffer[] SceneBuffer;
|
||||
private final LightSpecConsts lightSpecConsts;
|
||||
private final DescriptorSetLayout SceneDescriptorSetLayout;
|
||||
private final DescriptorSetLayout StorageDescriptorSetLayout;
|
||||
private final VulkanBuffer[] shadowMatrices;
|
||||
|
||||
public LightRenderer(VulkanContext VkCtx, List<Attachment> attachments){
|
||||
ClearValueColour = VkClearValue.calloc().color(
|
||||
|
|
@ -64,18 +71,18 @@ public class LightRenderer {
|
|||
AttachmentInfoColour = CreateColourAttachmentInfo(AttachmentColour, ClearValueColour);
|
||||
RenderInfo = CreateRenderInfo(AttachmentColour, AttachmentInfoColour);
|
||||
|
||||
ShaderModule[] shaderModules = CreateShaderModules(VkCtx);
|
||||
lightSpecConsts = new LightSpecConsts();
|
||||
ShaderModule[] shaderModules = CreateShaderModules(VkCtx, lightSpecConsts);
|
||||
|
||||
var textureSamplerInfo = new TextureSamplerInfo(VK_SAMPLER_ADDRESS_MODE_REPEAT,
|
||||
VK_BORDER_COLOR_INT_OPAQUE_BLACK, 1, true);
|
||||
textureSampler = new TextureSampler(VkCtx, textureSamplerInfo);
|
||||
int numAttachments = attachments.size();
|
||||
DescriptorSetLayout.LayoutInformation[] descSetLayouts = new DescriptorSetLayout.LayoutInformation[numAttachments];
|
||||
for (int i = 0; i < numAttachments; i++) {
|
||||
DescriptorSetLayout.LayoutInformation[] descSetLayouts = new DescriptorSetLayout.LayoutInformation[numAttachments + 1];
|
||||
for (int i = 0; i < numAttachments + 1; i++) {
|
||||
descSetLayouts[i] = new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, i, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
}
|
||||
AttachmentDescriptorSetLayout = new DescriptorSetLayout(VkCtx, descSetLayouts);
|
||||
|
||||
CreateAttachmentDescriptorSet(VkCtx, AttachmentDescriptorSetLayout, attachments, textureSampler);
|
||||
|
||||
StorageDescriptorSetLayout = new DescriptorSetLayout(VkCtx, new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 0, 1,
|
||||
|
|
@ -86,16 +93,32 @@ public class LightRenderer {
|
|||
|
||||
SceneDescriptorSetLayout = new DescriptorSetLayout(VkCtx, new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0, 1,
|
||||
VK_SHADER_STAGE_FRAGMENT_BIT));
|
||||
buffSize = VulkanUtils.VEC3_SIZE * 2 + VulkanUtils.FLOAT_SIZE + VulkanUtils.INT_SIZE;
|
||||
buffSize = VulkanUtils.VEC3_SIZE * 2 + VulkanUtils.FLOAT_SIZE + VulkanUtils.INT_SIZE + VulkanUtils.MATRIX4X4_SIZE;
|
||||
SceneBuffer = VulkanUtils.CreateHostVisibleBuffers(VkCtx, buffSize, VulkanUtils.MAX_IN_FLIGHT,
|
||||
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, DESC_ID_SCENE, SceneDescriptorSetLayout);
|
||||
|
||||
shadowMatrices = CreateShadowMatrixBuffers(VkCtx, StorageDescriptorSetLayout);
|
||||
pipeline = createPipeline(VkCtx, shaderModules, new DescriptorSetLayout[]{AttachmentDescriptorSetLayout, StorageDescriptorSetLayout,
|
||||
SceneDescriptorSetLayout});
|
||||
StorageDescriptorSetLayout, SceneDescriptorSetLayout});
|
||||
Logger.debug("Light Renderer Pipeline -> [{}]",pipeline.GetVulkanPipeline());
|
||||
Arrays.asList(shaderModules).forEach(s -> s.CleanUp(VkCtx));
|
||||
}
|
||||
|
||||
private static VulkanBuffer[] CreateShadowMatrixBuffers(VulkanContext vkCtx, DescriptorSetLayout layout) {
|
||||
int numBuffs = VulkanUtils.MAX_IN_FLIGHT;
|
||||
VulkanBuffer[] buffers = new VulkanBuffer[numBuffs];
|
||||
Device device = vkCtx.GetDevice();
|
||||
DescriptorSet[] descSets = vkCtx.GetDescriptorAllocator().AddDescriptorSets(device, DESC_ID_SHADOW_MATRICES, numBuffs, layout);
|
||||
for (int i = 0; i < numBuffs; i++) {
|
||||
long buffSize = (long) (VulkanUtils.MATRIX4X4_SIZE + VulkanUtils.VEC4_SIZE) * SceneLightingManager.SHADOW_MAP_CASCADE_COUNT;
|
||||
buffers[i] = new VulkanBuffer(vkCtx, buffSize,
|
||||
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE,
|
||||
VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
|
||||
descSets[i].SetBuffer(device, buffers[i], buffers[i].GetRequestedSize(),
|
||||
layout.GetLayoutInfo().Binding(), layout.GetLayoutInfo().DescriptorType());
|
||||
}
|
||||
return buffers;
|
||||
}
|
||||
|
||||
private static void CreateAttachmentDescriptorSet(VulkanContext VkCtx, DescriptorSetLayout descSetLayout, List<Attachment> attachments,
|
||||
TextureSampler sampler) {
|
||||
DescriptorAllocator descAllocator = VkCtx.GetDescriptorAllocator();
|
||||
|
|
@ -110,7 +133,7 @@ public class LightRenderer {
|
|||
SwapChain swapChain = VkCtx.GetSwapChain();
|
||||
VkExtent2D swapChainExtent = swapChain.GetSwapChainExtent();
|
||||
return new Attachment(VkCtx, swapChainExtent.width(), swapChainExtent.height(),
|
||||
COLOUR_FORMAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
|
||||
COLOUR_FORMAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,1);
|
||||
}
|
||||
|
||||
private static VkRenderingAttachmentInfo.Buffer CreateColourAttachmentInfo(Attachment attachment, VkClearValue clearValue) {
|
||||
|
|
@ -153,19 +176,19 @@ public class LightRenderer {
|
|||
return result;
|
||||
}
|
||||
|
||||
private static ShaderModule[] CreateShaderModules(VulkanContext VkCtx) {
|
||||
private static ShaderModule[] CreateShaderModules(VulkanContext VkCtx, LightSpecConsts lightSpecConsts) {
|
||||
if (EngineConfig.getInstance().RecompileShaders()) {
|
||||
ShaderCompiler.CompileGLSLShaderOnChange(VERTEX_SHADER_FILE_GLSL, Shaderc.shaderc_glsl_vertex_shader);
|
||||
ShaderCompiler.CompileGLSLShaderOnChange(FRAGMENT_SHADER_FILE_GLSL, Shaderc.shaderc_glsl_fragment_shader);
|
||||
}
|
||||
return new ShaderModule[]{
|
||||
new ShaderModule(VkCtx, VK_SHADER_STAGE_VERTEX_BIT, VERTEX_SHADER_FILE_SPV, null),
|
||||
new ShaderModule(VkCtx, VK_SHADER_STAGE_FRAGMENT_BIT, FRAGMENT_SHADER_FILE_SPV, null),
|
||||
new ShaderModule(VkCtx, VK_SHADER_STAGE_FRAGMENT_BIT, FRAGMENT_SHADER_FILE_SPV, lightSpecConsts.getSpecInfo()),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public void render(EngineInstance engineInstance, VulkanContext VkCtx, CommandBuffer cmdBuffer, MultiRenderTargetAttachments mrtAttachments,int CurrentFrame) {
|
||||
public void render(EngineInstance engineInstance, VulkanContext VkCtx, CommandBuffer cmdBuffer, MultiRenderTargetAttachments mrtAttachments,Attachment shadowAttachment, int CurrentFrame, CascadeShadows cascadeShadows) {
|
||||
try (var stack = MemoryStack.stackPush()) {
|
||||
VkCommandBuffer cmdHandle = cmdBuffer.GetVulkanCommandBuffer();
|
||||
|
||||
|
|
@ -176,7 +199,6 @@ public class LightRenderer {
|
|||
VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
|
||||
List<Attachment> attachments = mrtAttachments.GetColourAttachments();
|
||||
// Logger.debug("Colour Attachments -> \n1: [{}]\n 2:[{}] \n3:[{}]\n 4:[{}]",attachments.get(0),attachments.get(1),attachments.get(2),attachments.get(3));
|
||||
int numAttachments = attachments.size();
|
||||
for (int i = 0; i < numAttachments; i++) {
|
||||
Attachment attachment = attachments.get(i);
|
||||
|
|
@ -187,11 +209,19 @@ public class LightRenderer {
|
|||
VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
}
|
||||
VulkanUtils.ImageBarrier(stack, cmdHandle, mrtAttachments.GetDepthAttachment().GetVkImage().getVulkanImage(),
|
||||
VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||
VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT,
|
||||
VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_2_SHADER_READ_BIT,
|
||||
VK_IMAGE_ASPECT_DEPTH_BIT);
|
||||
|
||||
VulkanUtils.ImageBarrier(stack, cmdHandle, shadowAttachment.GetVkImage().getVulkanImage(),
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||
VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT,
|
||||
VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_2_SHADER_READ_BIT,
|
||||
VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
|
||||
UpdateCascadeShadowMatrices(VkCtx, cascadeShadows, CurrentFrame);
|
||||
|
||||
vkCmdBeginRendering(cmdHandle, RenderInfo);
|
||||
|
||||
vkCmdBindPipeline(cmdHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.GetVulkanPipeline());
|
||||
|
|
@ -215,10 +245,11 @@ public class LightRenderer {
|
|||
vkCmdSetScissor(cmdHandle, 0, scissor);
|
||||
|
||||
DescriptorAllocator descAllocator = VkCtx.GetDescriptorAllocator();
|
||||
LongBuffer descriptorSets = stack.mallocLong(3)
|
||||
LongBuffer descriptorSets = stack.mallocLong(4)
|
||||
.put(0, descAllocator.GetDescriptorSet(DESC_ID_ATT).GetVkDescriptorSet())
|
||||
.put(1, descAllocator.GetDescriptorSet(DESC_ID_LIGHTS, CurrentFrame).GetVkDescriptorSet())
|
||||
.put(2, descAllocator.GetDescriptorSet(DESC_ID_SCENE, CurrentFrame).GetVkDescriptorSet());
|
||||
.put(2, descAllocator.GetDescriptorSet(DESC_ID_SHADOW_MATRICES, CurrentFrame).GetVkDescriptorSet())
|
||||
.put(3, descAllocator.GetDescriptorSet(DESC_ID_SCENE, CurrentFrame).GetVkDescriptorSet());
|
||||
IScene scene = engineInstance.scene();
|
||||
UpdateSceneInfo(VkCtx, scene, CurrentFrame);
|
||||
UpdateLights(VkCtx, scene, CurrentFrame);
|
||||
|
|
@ -231,6 +262,22 @@ public class LightRenderer {
|
|||
}
|
||||
}
|
||||
|
||||
private void UpdateCascadeShadowMatrices(VulkanContext vkCtx, CascadeShadows cascadeShadows, int currentFrame) {
|
||||
VulkanBuffer buff = shadowMatrices[currentFrame];
|
||||
long mappedMemory = buff.MapMemory(vkCtx);
|
||||
ByteBuffer dataBuff = MemoryUtil.memByteBuffer(mappedMemory, (int) buff.GetRequestedSize());
|
||||
int offset = 0;
|
||||
List<CascadeData> cascadeDataList = cascadeShadows.GetCascadeData();
|
||||
int numCascades = cascadeDataList.size();
|
||||
for (int i = 0; i < numCascades; i++) {
|
||||
CascadeData cascadeData = cascadeDataList.get(i);
|
||||
cascadeData.GetProjViewMatrix().get(offset, dataBuff);
|
||||
dataBuff.putFloat(offset + VulkanUtils.MATRIX4X4_SIZE, cascadeData.GetSplitDistance());
|
||||
offset += VulkanUtils.MATRIX4X4_SIZE + VulkanUtils.VEC4_SIZE;
|
||||
}
|
||||
buff.UnMapMemory(vkCtx);
|
||||
}
|
||||
|
||||
public void UpdateSceneInfo(VulkanContext VkCtx, IScene scene, int CurrentFrame){
|
||||
VulkanBuffer buffer = SceneBuffer[CurrentFrame];
|
||||
long MappedMemory = buffer.MapMemory(VkCtx);
|
||||
|
|
@ -249,6 +296,10 @@ public class LightRenderer {
|
|||
ILight[] lights = scene.GetLightingManager().GetLights();
|
||||
int LightCount = lights != null ? lights.length : 0;
|
||||
dataBuffer.putInt(Offset, LightCount);
|
||||
Offset += VulkanUtils.INT_SIZE;
|
||||
|
||||
scene.GetCamera().GetViewMatrix().get(Offset, dataBuffer);
|
||||
|
||||
buffer.UnMapMemory(VkCtx);
|
||||
}
|
||||
public void UpdateLights(VulkanContext VkCtx, IScene scene, int CurrentFrame){
|
||||
|
|
@ -291,11 +342,13 @@ public class LightRenderer {
|
|||
public void cleanup(VulkanContext VkCtx) {
|
||||
StorageDescriptorSetLayout.CleanUp(VkCtx);
|
||||
Arrays.asList(LightBuffer).forEach(b -> b.cleanup(VkCtx));
|
||||
Arrays.asList(shadowMatrices).forEach(b -> b.cleanup(VkCtx));
|
||||
SceneDescriptorSetLayout.CleanUp(VkCtx);
|
||||
Arrays.asList(SceneBuffer).forEach(b -> b.cleanup(VkCtx));
|
||||
pipeline.CleanUp(VkCtx);
|
||||
AttachmentDescriptorSetLayout.CleanUp(VkCtx);
|
||||
textureSampler.CleanUp(VkCtx);
|
||||
lightSpecConsts.cleanup();
|
||||
RenderInfo.free();
|
||||
AttachmentColour.CleanUp(VkCtx);
|
||||
AttachmentInfoColour.free();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,56 @@
|
|||
package net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.DeferredRendering;
|
||||
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig;
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance;
|
||||
import net.halbear.Terrain4J.EngineCore.Main.Scene.SceneLightingManager;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Util.VulkanUtils;
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
import org.lwjgl.vulkan.VkSpecializationInfo;
|
||||
import org.lwjgl.vulkan.VkSpecializationMapEntry;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public class LightSpecConsts {
|
||||
private final ByteBuffer data;
|
||||
private final VkSpecializationMapEntry.Buffer specEntryMap;
|
||||
private final VkSpecializationInfo specInfo;
|
||||
|
||||
public LightSpecConsts() {
|
||||
var engCfg = EngineConfig.getInstance();
|
||||
data = MemoryUtil.memAlloc(VulkanUtils.INT_SIZE * 2);
|
||||
data.putInt(SceneLightingManager.SHADOW_MAP_CASCADE_COUNT);
|
||||
data.putInt(engCfg.DebugShaders() ? 1 : 0);
|
||||
data.flip();
|
||||
|
||||
specEntryMap = VkSpecializationMapEntry.calloc(2);
|
||||
int offset = 0;
|
||||
int pos = 0;
|
||||
int size = VulkanUtils.INT_SIZE;
|
||||
specEntryMap.get(pos)
|
||||
.constantID(pos)
|
||||
.size(size)
|
||||
.offset(offset);
|
||||
offset += size;
|
||||
pos++;
|
||||
|
||||
size = VulkanUtils.INT_SIZE;
|
||||
specEntryMap.get(pos)
|
||||
.constantID(pos)
|
||||
.size(size)
|
||||
.offset(offset);
|
||||
|
||||
specInfo = VkSpecializationInfo.calloc();
|
||||
specInfo.pData(data)
|
||||
.pMapEntries(specEntryMap);
|
||||
}
|
||||
|
||||
public void cleanup() {
|
||||
MemoryUtil.memFree(specEntryMap);
|
||||
specInfo.free();
|
||||
MemoryUtil.memFree(data);
|
||||
}
|
||||
|
||||
public VkSpecializationInfo getSpecInfo() {
|
||||
return specInfo;
|
||||
}
|
||||
}
|
||||
|
|
@ -28,18 +28,18 @@ public class MultiRenderTargetAttachments {
|
|||
ColourAttachments = new ArrayList<>();
|
||||
|
||||
//Position
|
||||
var Attachment = new Attachment(VkCtx, Width, Height, POSITION_FORMAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
|
||||
var Attachment = new Attachment(VkCtx, Width, Height, POSITION_FORMAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 1);
|
||||
ColourAttachments.add(Attachment);
|
||||
//albedo
|
||||
Attachment = new Attachment(VkCtx, Width, Height, ALBEDO_FORMAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
|
||||
Attachment = new Attachment(VkCtx, Width, Height, ALBEDO_FORMAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 1);
|
||||
ColourAttachments.add(Attachment);
|
||||
//Normals
|
||||
Attachment = new Attachment(VkCtx, Width, Height, NORMAL_FORMAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
|
||||
Attachment = new Attachment(VkCtx, Width, Height, NORMAL_FORMAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 1);
|
||||
ColourAttachments.add(Attachment);
|
||||
//PBR
|
||||
Attachment = new Attachment(VkCtx, Width, Height, PBR_FORMAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
|
||||
Attachment = new Attachment(VkCtx, Width, Height, PBR_FORMAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 1);
|
||||
ColourAttachments.add(Attachment);
|
||||
DepthAttachment = new Attachment(VkCtx, Width, Height, DEPTH_FORMAT, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT);
|
||||
DepthAttachment = new Attachment(VkCtx, Width, Height, DEPTH_FORMAT, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, 1);
|
||||
}
|
||||
|
||||
public int GetWidth(){return Width;}
|
||||
|
|
|
|||
|
|
@ -67,10 +67,11 @@ public class DefaultPipeline implements Pipeline {
|
|||
.viewportCount(1)
|
||||
.scissorCount(1);
|
||||
var RasterizationStateCreateInfo = VkPipelineRasterizationStateCreateInfo.calloc(MemStack)
|
||||
.sType(VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO)
|
||||
.sType$Default()
|
||||
.polygonMode(VK_POLYGON_MODE_FILL)
|
||||
.cullMode(VK_CULL_MODE_NONE)
|
||||
.frontFace(VK_FRONT_FACE_CLOCKWISE)
|
||||
.depthClampEnable(BuildInfo.DepthClamp())
|
||||
.lineWidth(1.0f);
|
||||
int sampleCount = EngineConfig.getInstance().GetRenderSampleCount();
|
||||
var MultisampleStateCreateInfo = VkPipelineMultisampleStateCreateInfo.calloc(MemStack)
|
||||
|
|
@ -88,7 +89,7 @@ public class DefaultPipeline implements Pipeline {
|
|||
.sType(VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO)
|
||||
.depthTestEnable(BuildInfo.GetDepthTest())
|
||||
.depthWriteEnable(BuildInfo.performDepthWrite())
|
||||
.depthCompareOp(VK_COMPARE_OP_GREATER_OR_EQUAL)
|
||||
.depthCompareOp(VK_COMPARE_OP_LESS_OR_EQUAL)
|
||||
.depthBoundsTestEnable(false)
|
||||
.stencilTestEnable(false);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,24 +9,85 @@ public class Attachment {
|
|||
private final Image VkImage;
|
||||
private final ImageView VkImageView;
|
||||
private boolean DepthAttachment;
|
||||
|
||||
public Attachment(VulkanContext VkCtx, int Width, int Height, int Format, int Usage){
|
||||
public Attachment(VulkanContext VkCtx, int Width, int Height, int Format, int Usage, boolean MultiSamples){
|
||||
var ImageData = new Image.ImageData().Width(Width).Height(Height).Format(Format).SampleCount(EngineConfig.getInstance().GetRenderSampleCount());
|
||||
|
||||
int AspectMask = 0;
|
||||
if((Usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) > 0){
|
||||
AspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
int aspectMask = 0;
|
||||
if ((Usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) > 0) {
|
||||
aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
ImageData.Usage(Usage | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
|
||||
DepthAttachment = false;
|
||||
}
|
||||
if((Usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) > 0){
|
||||
if ((Usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) > 0) {
|
||||
ImageData.Usage(Usage | VK_IMAGE_USAGE_SAMPLED_BIT);
|
||||
AspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||
aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||
DepthAttachment = true;
|
||||
}
|
||||
int layers = 1;
|
||||
if (layers > 0) {
|
||||
ImageData.ArrayLayers(layers);
|
||||
}
|
||||
VkImage = new Image(VkCtx, ImageData);
|
||||
var ImageViewData = new ImageView.ImageViewData().Format(VkImage.GetFormat()).AspectMask(AspectMask);
|
||||
VkImageView = new ImageView(VkCtx.GetDevice(), VkImage.getVulkanImage(), ImageViewData,DepthAttachment);
|
||||
|
||||
var imageViewData = new ImageView.ImageViewData().Format(VkImage.GetFormat()).AspectMask(aspectMask);
|
||||
if (layers > 1) {
|
||||
imageViewData.ViewType(VK_IMAGE_VIEW_TYPE_2D_ARRAY);
|
||||
imageViewData.LayerCount(layers);
|
||||
}
|
||||
VkImageView = new ImageView(VkCtx.GetDevice(), VkImage.getVulkanImage(), imageViewData, DepthAttachment);
|
||||
}
|
||||
public Attachment(VulkanContext VkCtx, int Width, int Height, int Format, int Usage){
|
||||
var ImageData = new Image.ImageData().Width(Width).Height(Height).Format(Format).SampleCount(VK_SAMPLE_COUNT_1_BIT);
|
||||
|
||||
int aspectMask = 0;
|
||||
if ((Usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) > 0) {
|
||||
aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
ImageData.Usage(Usage | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
|
||||
DepthAttachment = false;
|
||||
}
|
||||
if ((Usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) > 0) {
|
||||
ImageData.Usage(Usage | VK_IMAGE_USAGE_SAMPLED_BIT);
|
||||
aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||
DepthAttachment = true;
|
||||
}
|
||||
int layers = 1;
|
||||
if (layers > 0) {
|
||||
ImageData.ArrayLayers(layers);
|
||||
}
|
||||
VkImage = new Image(VkCtx, ImageData);
|
||||
|
||||
var imageViewData = new ImageView.ImageViewData().Format(VkImage.GetFormat()).AspectMask(aspectMask);
|
||||
if (layers > 1) {
|
||||
imageViewData.ViewType(VK_IMAGE_VIEW_TYPE_2D_ARRAY);
|
||||
imageViewData.LayerCount(layers);
|
||||
}
|
||||
VkImageView = new ImageView(VkCtx.GetDevice(), VkImage.getVulkanImage(), imageViewData, DepthAttachment);
|
||||
}
|
||||
public Attachment(VulkanContext VkCtx, int Width, int Height, int Format, int Usage,int layers){
|
||||
var ImageData = new Image.ImageData().Width(Width).Height(Height).Format(Format).SampleCount(VK_SAMPLE_COUNT_1_BIT);
|
||||
|
||||
int aspectMask = 0;
|
||||
if ((Usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) > 0) {
|
||||
aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
ImageData.Usage(Usage | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
|
||||
DepthAttachment = false;
|
||||
}
|
||||
if ((Usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) > 0) {
|
||||
ImageData.Usage(Usage | VK_IMAGE_USAGE_SAMPLED_BIT);
|
||||
aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||
DepthAttachment = true;
|
||||
}
|
||||
if (layers > 0) {
|
||||
ImageData.ArrayLayers(layers);
|
||||
}
|
||||
VkImage = new Image(VkCtx, ImageData);
|
||||
|
||||
var imageViewData = new ImageView.ImageViewData().Format(VkImage.GetFormat()).AspectMask(aspectMask);
|
||||
if (layers > 1) {
|
||||
imageViewData.ViewType(VK_IMAGE_VIEW_TYPE_2D_ARRAY);
|
||||
imageViewData.LayerCount(layers);
|
||||
}
|
||||
VkImageView = new ImageView(VkCtx.GetDevice(), VkImage.getVulkanImage(), imageViewData, DepthAttachment);
|
||||
}
|
||||
|
||||
public Image GetVkImage(){return VkImage;}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ public class PipelineBuildInfo {
|
|||
private DescriptorSetLayout[] DescriptorSetLayouts;
|
||||
private boolean useBlend;
|
||||
private boolean DepthWrite = true;
|
||||
private boolean DepthClamp = false;
|
||||
private boolean DepthTest = true;
|
||||
private boolean DualPass = false;
|
||||
private boolean alphaToCoverage = false;
|
||||
|
|
@ -27,6 +28,13 @@ public class PipelineBuildInfo {
|
|||
DepthFormat = VK_FORMAT_UNDEFINED;
|
||||
useBlend = true;
|
||||
}
|
||||
public boolean DepthClamp() {
|
||||
return DepthClamp;
|
||||
}
|
||||
public PipelineBuildInfo SetDepthClamp(boolean depthClamp) {
|
||||
this.DepthClamp = depthClamp;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PipelineBuildInfo SetBlendingMethod(int in){
|
||||
BlendingMethod = in;
|
||||
|
|
|
|||
|
|
@ -3,19 +3,26 @@ package net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Shadows;
|
|||
import org.joml.Matrix4f;
|
||||
|
||||
public class CascadeData {
|
||||
private final Matrix4f ProjectionViewMatrix;
|
||||
private float SplitDistance;
|
||||
private final Matrix4f projViewMatrix;
|
||||
private float splitDistance;
|
||||
|
||||
public CascadeData(){
|
||||
ProjectionViewMatrix = new Matrix4f();
|
||||
public CascadeData() {
|
||||
projViewMatrix = new Matrix4f();
|
||||
}
|
||||
|
||||
public Matrix4f GetProjectionViewMatrix(){return ProjectionViewMatrix;}
|
||||
public float GetSplitDistance(){return SplitDistance;}
|
||||
public void SetProjectionViewMatrix(Matrix4f ProjViewMat){
|
||||
this.ProjectionViewMatrix.set(ProjViewMat);
|
||||
public Matrix4f GetProjViewMatrix() {
|
||||
return projViewMatrix;
|
||||
}
|
||||
public void SetSplitDistance(float splitDistance){
|
||||
this.SplitDistance = splitDistance;
|
||||
|
||||
public float GetSplitDistance() {
|
||||
return splitDistance;
|
||||
}
|
||||
|
||||
public void SetProjectionViewMatrix(Matrix4f projViewMatrix) {
|
||||
this.projViewMatrix.set(projViewMatrix);
|
||||
}
|
||||
|
||||
public void SetSplitDistance(float splitDistance) {
|
||||
this.splitDistance = splitDistance;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,70 @@
|
|||
package net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Shadows;
|
||||
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig;
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance;
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.Rendering.VulkanContext;
|
||||
import net.halbear.Terrain4J.EngineCore.Main.Scene.Actor.Actor3D;
|
||||
import net.halbear.Terrain4J.EngineCore.Main.Scene.IScene;
|
||||
import net.halbear.Terrain4J.EngineCore.Main.Scene.SceneLightingManager;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.DefaultPipeline;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.Images.Attachment;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.Images.ITexture;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.Images.Texture;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.Images.TextureCache;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.Pipeline;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.PipelineBuildInfo;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.PushConstantsRange;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Shader.*;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.VertexBufferStructure;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.VkModel.*;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DeviceLayers.CommandBuffer;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DeviceLayers.Device;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DisplayToScreen.ImageView;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Util.VulkanBuffer;
|
||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Util.VulkanUtils;
|
||||
import org.joml.Matrix4f;
|
||||
import org.lwjgl.system.MemoryStack;
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
import org.lwjgl.util.shaderc.Shaderc;
|
||||
import org.lwjgl.vulkan.*;
|
||||
import org.tinylog.Logger;
|
||||
|
||||
import static org.lwjgl.vulkan.VK10.VK_FORMAT_D32_SFLOAT;
|
||||
import static org.lwjgl.vulkan.VK10.VK_FORMAT_R32G32_SFLOAT;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.LongBuffer;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static org.lwjgl.vulkan.VK10.*;
|
||||
import static org.lwjgl.vulkan.VK10.VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||
import static org.lwjgl.vulkan.VK10.VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||
import static org.lwjgl.vulkan.VK10.VK_ATTACHMENT_STORE_OP_STORE;
|
||||
import static org.lwjgl.vulkan.VK10.VK_BORDER_COLOR_INT_OPAQUE_BLACK;
|
||||
import static org.lwjgl.vulkan.VK10.VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
|
||||
import static org.lwjgl.vulkan.VK10.VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||
import static org.lwjgl.vulkan.VK10.VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
|
||||
import static org.lwjgl.vulkan.VK10.VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
import static org.lwjgl.vulkan.VK10.VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||
import static org.lwjgl.vulkan.VK10.VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
import static org.lwjgl.vulkan.VK10.VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||
import static org.lwjgl.vulkan.VK10.VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
import static org.lwjgl.vulkan.VK10.VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
||||
import static org.lwjgl.vulkan.VK10.VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
|
||||
import static org.lwjgl.vulkan.VK10.VK_INDEX_TYPE_UINT32;
|
||||
import static org.lwjgl.vulkan.VK10.VK_PIPELINE_BIND_POINT_GRAPHICS;
|
||||
import static org.lwjgl.vulkan.VK10.VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||
import static org.lwjgl.vulkan.VK10.VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||
import static org.lwjgl.vulkan.VK10.VK_SHADER_STAGE_GEOMETRY_BIT;
|
||||
import static org.lwjgl.vulkan.VK10.VK_SHADER_STAGE_VERTEX_BIT;
|
||||
import static org.lwjgl.vulkan.VK10.vkCmdBindDescriptorSets;
|
||||
import static org.lwjgl.vulkan.VK10.vkCmdBindIndexBuffer;
|
||||
import static org.lwjgl.vulkan.VK10.vkCmdBindPipeline;
|
||||
import static org.lwjgl.vulkan.VK10.vkCmdBindVertexBuffers;
|
||||
import static org.lwjgl.vulkan.VK10.vkCmdDrawIndexed;
|
||||
import static org.lwjgl.vulkan.VK10.vkCmdPushConstants;
|
||||
import static org.lwjgl.vulkan.VK10.vkCmdSetScissor;
|
||||
import static org.lwjgl.vulkan.VK10.vkCmdSetViewport;
|
||||
import static org.lwjgl.vulkan.VK12.VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL;
|
||||
import static org.lwjgl.vulkan.VK13.*;
|
||||
|
||||
public class ShadowRenderer {
|
||||
public static final int DEPTH_FORMAT = VK_FORMAT_D32_SFLOAT;
|
||||
|
|
@ -19,4 +80,281 @@ public class ShadowRenderer {
|
|||
private static final String VERTEX_SHADER_FILE_GLSL = "resources/EngineResources/shaders/shadow_vertex.glsl";
|
||||
private static final String VERTEX_SHADER_FILE_SPV = VERTEX_SHADER_FILE_GLSL + ".spv";
|
||||
|
||||
private final CascadeShadows[] cascadeShadows;
|
||||
private final VkClearValue ClearValueColour;
|
||||
private final VkClearValue ClearValueDepth;
|
||||
private final Attachment colorAttachment;
|
||||
private final VkRenderingAttachmentInfo.Buffer colorAttachmentInfo;
|
||||
private final Attachment depthAttachment;
|
||||
private final VkRenderingAttachmentInfo depthAttachmentInfo;
|
||||
private final DescriptorSetLayout descLayoutFrgStorage;
|
||||
private final Pipeline pipeline;
|
||||
private final VulkanBuffer[] prjBuffers;
|
||||
private final ByteBuffer pushConstBuff;
|
||||
private final VkRenderingInfo renderingInfo;
|
||||
private final DescriptorSetLayout textDescriptorSetLayout;
|
||||
private final TextureSampler textureSampler;
|
||||
private final DescriptorSetLayout uniformGeomDescriptorSetLayout;
|
||||
|
||||
public ShadowRenderer(VulkanContext VulkanContext) {
|
||||
ClearValueColour = VkClearValue.calloc().color(
|
||||
c -> c.float32(0, 0.0f).float32(1, 0.0f).float32(2, 0.0f).float32(3, 0.0f));
|
||||
ClearValueDepth = VkClearValue.calloc().color(c -> c.float32(0, 1.0f));
|
||||
|
||||
depthAttachment = createDepthAttachment(VulkanContext);
|
||||
depthAttachmentInfo = createDepthAttachmentInfo(depthAttachment, ClearValueDepth);
|
||||
|
||||
colorAttachment = createColorAttachment(VulkanContext);
|
||||
colorAttachmentInfo = createColorAttachmentInfo(colorAttachment, ClearValueColour);
|
||||
|
||||
pushConstBuff = MemoryUtil.memAlloc(PUSH_CONSTANTS_SIZE);
|
||||
|
||||
renderingInfo = createRenderInfo(colorAttachmentInfo, depthAttachmentInfo);
|
||||
ShaderModule[] shaderModules = createShaderModules(VulkanContext);
|
||||
|
||||
uniformGeomDescriptorSetLayout = new DescriptorSetLayout(VulkanContext, new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
||||
0, 1, VK_SHADER_STAGE_GEOMETRY_BIT));
|
||||
long buffSize = (long) VulkanUtils.MATRIX4X4_SIZE * SceneLightingManager.SHADOW_MAP_CASCADE_COUNT;
|
||||
prjBuffers = VulkanUtils.CreateHostVisibleBuffers(VulkanContext, buffSize, VulkanUtils.MAX_IN_FLIGHT,
|
||||
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, DESCRIPTOR_ID_PRJ, uniformGeomDescriptorSetLayout);
|
||||
|
||||
descLayoutFrgStorage = new DescriptorSetLayout(VulkanContext, new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
0, 1, VK_SHADER_STAGE_FRAGMENT_BIT));
|
||||
|
||||
var textureSamplerInfo = new TextureSamplerInfo(VK_SAMPLER_ADDRESS_MODE_REPEAT,
|
||||
VK_BORDER_COLOR_INT_OPAQUE_BLACK, 1, true);
|
||||
textureSampler = new TextureSampler(VulkanContext, textureSamplerInfo);
|
||||
textDescriptorSetLayout = new DescriptorSetLayout(VulkanContext, new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
||||
0, TextureCache.MAX_TEXTURES, VK_SHADER_STAGE_FRAGMENT_BIT));
|
||||
|
||||
pipeline = createPipeline(VulkanContext, shaderModules, new DescriptorSetLayout[]{uniformGeomDescriptorSetLayout, textDescriptorSetLayout,
|
||||
descLayoutFrgStorage});
|
||||
Arrays.asList(shaderModules).forEach(s -> s.CleanUp(VulkanContext));
|
||||
|
||||
cascadeShadows = new CascadeShadows[VulkanUtils.MAX_IN_FLIGHT];
|
||||
for (int i = 0; i < VulkanUtils.MAX_IN_FLIGHT; i++) {
|
||||
cascadeShadows[i] = new CascadeShadows();
|
||||
}
|
||||
}
|
||||
|
||||
private static Attachment createColorAttachment(VulkanContext VulkanContext) {
|
||||
int shadowMapSize = EngineConfig.getInstance().GetShadowMapSize();
|
||||
return new Attachment(VulkanContext, shadowMapSize, shadowMapSize,
|
||||
ATTACHMENT_FORMATT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, SceneLightingManager.SHADOW_MAP_CASCADE_COUNT);
|
||||
}
|
||||
|
||||
private static VkRenderingAttachmentInfo.Buffer createColorAttachmentInfo(Attachment srcAttachment, VkClearValue clearValue) {
|
||||
return VkRenderingAttachmentInfo.calloc(1)
|
||||
.sType$Default()
|
||||
.imageView(srcAttachment.GetVkImageView().GetVulkanImageView())
|
||||
.imageLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)
|
||||
.loadOp(VK_ATTACHMENT_LOAD_OP_CLEAR)
|
||||
.storeOp(VK_ATTACHMENT_STORE_OP_STORE)
|
||||
.clearValue(clearValue);
|
||||
}
|
||||
|
||||
private static Attachment createDepthAttachment(VulkanContext VulkanContext) {
|
||||
int shadowMapSize = EngineConfig.getInstance().GetShadowMapSize();
|
||||
return new Attachment(VulkanContext, shadowMapSize, shadowMapSize,
|
||||
DEPTH_FORMAT, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, SceneLightingManager.SHADOW_MAP_CASCADE_COUNT);
|
||||
}
|
||||
|
||||
private static VkRenderingAttachmentInfo createDepthAttachmentInfo(Attachment depthAttachment, VkClearValue clearValue) {
|
||||
return VkRenderingAttachmentInfo.calloc()
|
||||
.sType$Default()
|
||||
.imageView(depthAttachment.GetVkImageView().GetVulkanImageView())
|
||||
.imageLayout(VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)
|
||||
.loadOp(VK_ATTACHMENT_LOAD_OP_CLEAR)
|
||||
.storeOp(VK_ATTACHMENT_STORE_OP_DONT_CARE)
|
||||
.clearValue(clearValue);
|
||||
}
|
||||
|
||||
private static Pipeline createPipeline(VulkanContext VulkanContext, ShaderModule[] shaderModules, DescriptorSetLayout[] DescriptorSetLayouts) {
|
||||
var vtxBuffStruct = new VertexBufferStructure();
|
||||
var buildInfo = new PipelineBuildInfo(shaderModules, vtxBuffStruct.getVertexInput(), new int[]{ATTACHMENT_FORMATT})
|
||||
.SetDepthFormat(DEPTH_FORMAT)
|
||||
.SetPushConstantRanges(
|
||||
new PushConstantsRange[]{
|
||||
new PushConstantsRange(VK_SHADER_STAGE_VERTEX_BIT, 0, PUSH_CONSTANTS_SIZE)
|
||||
})
|
||||
.SetDescriptorSetLayouts(DescriptorSetLayouts)
|
||||
.SetDescriptorSetLayouts(DescriptorSetLayouts)
|
||||
.SetDepthClamp(VulkanContext.GetDevice().getDepthClamp());
|
||||
var pipeline = new DefaultPipeline(VulkanContext, buildInfo);
|
||||
vtxBuffStruct.cleanup();
|
||||
return pipeline;
|
||||
}
|
||||
|
||||
private static VkRenderingInfo createRenderInfo(VkRenderingAttachmentInfo.Buffer colorAttachmentInfo,
|
||||
VkRenderingAttachmentInfo depthAttachments) {
|
||||
var result = VkRenderingInfo.calloc().sType$Default();
|
||||
try (var stack = MemoryStack.stackPush()) {
|
||||
int shadowMapSize = EngineConfig.getInstance().GetShadowMapSize();
|
||||
VkExtent2D extent = VkExtent2D.calloc(stack);
|
||||
extent.width(shadowMapSize);
|
||||
extent.height(shadowMapSize);
|
||||
var renderArea = VkRect2D.calloc(stack).extent(extent);
|
||||
result.renderArea(renderArea)
|
||||
.layerCount(SceneLightingManager.SHADOW_MAP_CASCADE_COUNT)
|
||||
.pColorAttachments(colorAttachmentInfo)
|
||||
.pDepthAttachment(depthAttachments);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static ShaderModule[] createShaderModules(VulkanContext VulkanContext) {
|
||||
if (EngineConfig.getInstance().RecompileShaders()) {
|
||||
ShaderCompiler.CompileGLSLShaderOnChange(VERTEX_SHADER_FILE_GLSL, Shaderc.shaderc_glsl_vertex_shader);
|
||||
ShaderCompiler.CompileGLSLShaderOnChange(SHADOW_GEOMETRY_SHADER_FILE_GLSL, Shaderc.shaderc_glsl_geometry_shader);
|
||||
ShaderCompiler.CompileGLSLShaderOnChange(FRAGMENT_SHADER_FILE_GLSL, Shaderc.shaderc_glsl_fragment_shader);
|
||||
}
|
||||
return new ShaderModule[]{
|
||||
new ShaderModule(VulkanContext, VK_SHADER_STAGE_VERTEX_BIT, VERTEX_SHADER_FILE_SPV, null),
|
||||
new ShaderModule(VulkanContext, VK_SHADER_STAGE_GEOMETRY_BIT, SHADOW_GEOMETRY_SHADER_FILE_SPV, null),
|
||||
new ShaderModule(VulkanContext, VK_SHADER_STAGE_FRAGMENT_BIT, FRAGMENT_SHADER_FILE_SPV, null),
|
||||
};
|
||||
}
|
||||
|
||||
public void cleanup(VulkanContext VulkanContext) {
|
||||
pipeline.CleanUp(VulkanContext);
|
||||
uniformGeomDescriptorSetLayout.CleanUp(VulkanContext);
|
||||
descLayoutFrgStorage.CleanUp(VulkanContext);
|
||||
textDescriptorSetLayout.CleanUp(VulkanContext);
|
||||
textureSampler.CleanUp(VulkanContext);
|
||||
Arrays.asList(prjBuffers).forEach(b -> b.cleanup(VulkanContext));
|
||||
renderingInfo.free();
|
||||
depthAttachmentInfo.free();
|
||||
depthAttachment.CleanUp(VulkanContext);
|
||||
colorAttachmentInfo.free();
|
||||
colorAttachment.CleanUp(VulkanContext);
|
||||
MemoryUtil.memFree(pushConstBuff);
|
||||
ClearValueColour.free();
|
||||
ClearValueDepth.free();
|
||||
}
|
||||
|
||||
public CascadeShadows getCascadeShadows(int currentFrame) {
|
||||
return cascadeShadows[currentFrame];
|
||||
}
|
||||
|
||||
public Attachment getShadowAttachment() {
|
||||
return colorAttachment;
|
||||
}
|
||||
|
||||
public void loadMaterials(VulkanContext VulkanContext, MaterialsCache materialsCache, TextureCache textureCache) {
|
||||
DescriptorAllocator descAllocator = VulkanContext.GetDescriptorAllocator();
|
||||
Device device = VulkanContext.GetDevice();
|
||||
DescriptorSet descSet = descAllocator.AddDescriptorSet(device, DESCRIPTOR_ID_MAT, descLayoutFrgStorage);
|
||||
DescriptorSetLayout.LayoutInformation layoutInfo = descLayoutFrgStorage.GetLayoutInfo();
|
||||
var buffer = materialsCache.GetMaterialsBuffer();
|
||||
descSet.SetBuffer(device, buffer, buffer.GetRequestedSize(), layoutInfo.Binding(), layoutInfo.DescriptorType());
|
||||
|
||||
List<ImageView> imageViews = textureCache.GetTextureList().stream().map(ITexture::GetImageView).toList();
|
||||
descSet = VulkanContext.GetDescriptorAllocator().AddDescriptorSet(device, DESCRIPTOR_ID_TEXT, textDescriptorSetLayout);
|
||||
descSet.SetImageArray(device, imageViews, textureSampler, 0);
|
||||
}
|
||||
|
||||
public void render(EngineInstance engCtx, VulkanContext VulkanContext, CommandBuffer cmdBuffer, ModelsCache modelsCache,
|
||||
MaterialsCache materialsCache, int currentFrame) {
|
||||
try (var stack = MemoryStack.stackPush()) {
|
||||
IScene scene = engCtx.scene();
|
||||
|
||||
ShadowUtils.updateCascadeShadows(cascadeShadows[currentFrame], scene);
|
||||
|
||||
VkCommandBuffer cmdHandle = cmdBuffer.GetVulkanCommandBuffer();
|
||||
|
||||
VulkanUtils.ImageBarrier(stack, cmdHandle, colorAttachment.GetVkImage().getVulkanImage(),
|
||||
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||
VK_ACCESS_2_NONE, VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
VulkanUtils.ImageBarrier(stack, cmdHandle, depthAttachment.GetVkImage().getVulkanImage(),
|
||||
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL,
|
||||
VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT,
|
||||
VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT,
|
||||
VK_ACCESS_2_NONE,
|
||||
VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
VK_IMAGE_ASPECT_DEPTH_BIT);
|
||||
|
||||
vkCmdBeginRendering(cmdHandle, renderingInfo);
|
||||
|
||||
vkCmdBindPipeline(cmdHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.GetVulkanPipeline());
|
||||
|
||||
int shadowMapSize = EngineConfig.getInstance().GetShadowMapSize();
|
||||
int width = shadowMapSize;
|
||||
int height = shadowMapSize;
|
||||
var viewport = VkViewport.calloc(1, stack)
|
||||
.x(0)
|
||||
.y(height)
|
||||
.height(-height)
|
||||
.width(width)
|
||||
.minDepth(0.0f)
|
||||
.maxDepth(1.0f);
|
||||
vkCmdSetViewport(cmdHandle, 0, viewport);
|
||||
|
||||
var scissor = VkRect2D.calloc(1, stack)
|
||||
.extent(it -> it.width(width).height(height))
|
||||
.offset(it -> it.x(0).y(0));
|
||||
vkCmdSetScissor(cmdHandle, 0, scissor);
|
||||
|
||||
updateProjBuffer(VulkanContext, currentFrame);
|
||||
DescriptorAllocator descAllocator = VulkanContext.GetDescriptorAllocator();
|
||||
LongBuffer descriptorSets = stack.mallocLong(3)
|
||||
.put(0, descAllocator.GetDescriptorSet(DESCRIPTOR_ID_PRJ, currentFrame).GetVkDescriptorSet())
|
||||
.put(1, descAllocator.GetDescriptorSet(DESCRIPTOR_ID_TEXT).GetVkDescriptorSet())
|
||||
.put(2, descAllocator.GetDescriptorSet(DESCRIPTOR_ID_MAT).GetVkDescriptorSet());
|
||||
vkCmdBindDescriptorSets(cmdHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.GetVulkanPipelineLayout(),
|
||||
0, descriptorSets, null);
|
||||
|
||||
LongBuffer vertexBuffer = stack.mallocLong(1);
|
||||
LongBuffer offsets = stack.mallocLong(1).put(0, 0L);
|
||||
|
||||
List<Actor3D> entities = scene.GetActors();
|
||||
int numEntities = entities.size();
|
||||
for (int i = 0; i < numEntities; i++) {
|
||||
var entity = entities.get(i);
|
||||
VulkanModel model = modelsCache.GetModel(entity.GetModelID());
|
||||
List<VulkanMesh> vulkanMeshList = model.GetVkMeshList();
|
||||
int numMeshes = vulkanMeshList.size();
|
||||
for (int j = 0; j < numMeshes; j++) {
|
||||
var vulkanMesh = vulkanMeshList.get(j);
|
||||
String materialId = vulkanMesh.MaterialID();
|
||||
int materialIdx = materialsCache.GetPosition(materialId);
|
||||
VulkanMaterial vulkanMaterial = materialsCache.GetMaterial(materialId);
|
||||
if (vulkanMaterial == null) {
|
||||
Logger.warn("Mesh [{}] in model [{}] does not have material", j, model.GetID());
|
||||
continue;
|
||||
}
|
||||
setPushConstants(cmdHandle, entity.GetModelMatrix(), materialIdx);
|
||||
vertexBuffer.put(0, vulkanMesh.VerticesBuffer().GetBuffer());
|
||||
|
||||
vkCmdBindVertexBuffers(cmdHandle, 0, vertexBuffer, offsets);
|
||||
vkCmdBindIndexBuffer(cmdHandle, vulkanMesh.IndicesBuffer().GetBuffer(), 0, VK_INDEX_TYPE_UINT32);
|
||||
vkCmdDrawIndexed(cmdHandle, vulkanMesh.IndicesCount(), 1, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
vkCmdEndRendering(cmdHandle);
|
||||
}
|
||||
}
|
||||
|
||||
private void setPushConstants(VkCommandBuffer cmdHandle, Matrix4f modelMatrix, int materialIdx) {
|
||||
modelMatrix.get(0, pushConstBuff);
|
||||
pushConstBuff.putInt(VulkanUtils.MATRIX4X4_SIZE, materialIdx);
|
||||
vkCmdPushConstants(cmdHandle, pipeline.GetVulkanPipelineLayout(), VK_SHADER_STAGE_VERTEX_BIT, 0, pushConstBuff);
|
||||
}
|
||||
|
||||
private void updateProjBuffer(VulkanContext VulkanContext, int currentFrame) {
|
||||
int offset = 0;
|
||||
List<CascadeData> cascadeDataList = cascadeShadows[currentFrame].GetCascadeData();
|
||||
int numCascades = cascadeDataList.size();
|
||||
VulkanBuffer vkBuffer = prjBuffers[currentFrame];
|
||||
long mappedMemory = vkBuffer.MapMemory(VulkanContext);
|
||||
ByteBuffer buff = MemoryUtil.memByteBuffer(mappedMemory, (int) vkBuffer.GetRequestedSize());
|
||||
for (int i = 0; i < numCascades; i++) {
|
||||
CascadeData cascadeData = cascadeDataList.get(i);
|
||||
cascadeData.GetProjViewMatrix().get(offset, buff);
|
||||
offset += VulkanUtils.MATRIX4X4_SIZE;
|
||||
}
|
||||
vkBuffer.UnMapMemory(VulkanContext);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,58 +15,65 @@ import java.util.List;
|
|||
public class ShadowUtils {
|
||||
|
||||
private static final float LAMBDA = 0.95f;
|
||||
private static final Vector3f Up = new Vector3f(0.0f,1.0f,0.0f);
|
||||
private static final Vector3f UpAlt = new Vector3f(0.0f,0.0f,1.0f);
|
||||
|
||||
private ShadowUtils(){
|
||||
private static final Vector3f UP = new Vector3f(0.0f, 1.0f, 0.0f);
|
||||
private static final Vector3f UP_ALT = new Vector3f(0.0f, 0.0f, 1.0f);
|
||||
|
||||
private ShadowUtils() {
|
||||
}
|
||||
|
||||
public static void UpdateCascadeShadows(CascadeShadows shadows, IScene scene){
|
||||
public static void updateCascadeShadows(CascadeShadows cascadeShadows, IScene scene) {
|
||||
Camera camera = scene.GetCamera();
|
||||
Matrix4f ViewMatrix = camera.GetViewMatrix();
|
||||
Matrix4f viewMatrix = camera.GetViewMatrix();
|
||||
Project3D projection = scene.GetProjection();
|
||||
Matrix4f ProjectionMatrix = projection.GetProjectionMatrix();
|
||||
Matrix4f projMatrix = projection.GetProjectionMatrix();
|
||||
ILight[] lights = scene.GetLightingManager().GetLights();
|
||||
int LightCount = lights.length;
|
||||
ILight SkyLight = null;
|
||||
for(int i = 0; i < LightCount; i++){
|
||||
if(lights[i].IsDirectional()){
|
||||
SkyLight = lights[i];
|
||||
int numLights = lights.length;
|
||||
ILight dirLight = null;
|
||||
for (int i = 0; i < numLights; i++) {
|
||||
if (lights[i].IsDirectional()) {
|
||||
dirLight = lights[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(SkyLight == null){
|
||||
throw new RuntimeException("No SkyLight on scene");
|
||||
if (dirLight == null) {
|
||||
throw new RuntimeException("Could not find directional light");
|
||||
}
|
||||
Vector4f LightPosition = new Vector4f(SkyLight.GetPosition(),0.0f);
|
||||
float[] CascadeSplits = new float[SceneLightingManager.SHADOW_MAP_CASCADE_COUNT];
|
||||
float NearClip = Math.min(projection.GetNearZ(), projection.GetFarZ());
|
||||
float FarClip = Math.max(projection.GetNearZ(), projection.GetFarZ());
|
||||
float ClipRange = FarClip - NearClip;
|
||||
Vector3f lightPos = dirLight.GetPosition();
|
||||
|
||||
float MinZ = NearClip;
|
||||
float MaxZ = NearClip + ClipRange;
|
||||
float[] cascadeSplits = new float[SceneLightingManager.SHADOW_MAP_CASCADE_COUNT];
|
||||
|
||||
float Range = MaxZ - MinZ;
|
||||
float Ratio = MaxZ/MinZ;
|
||||
float nearClip = projection.GetNearZ();
|
||||
float farClip = projection.GetFarZ();
|
||||
float clipRange = farClip - nearClip;
|
||||
|
||||
List<CascadeData> cascadeDataList = shadows.GetCascadeData();
|
||||
int CascadeCount = cascadeDataList.size();
|
||||
if (nearClip <= 0.0f || farClip <= nearClip) {
|
||||
//throw new IllegalStateException("Invalid projection near/far planes for shadow cascades: near=" + nearClip + ", far=" + farClip);
|
||||
}
|
||||
|
||||
for(int i = 0; i < CascadeCount; i++){
|
||||
float minZ = nearClip;
|
||||
float maxZ = nearClip + clipRange;
|
||||
|
||||
float range = maxZ - minZ;
|
||||
float ratio = maxZ / minZ;
|
||||
|
||||
List<CascadeData> cascadeDataList = cascadeShadows.GetCascadeData();
|
||||
int numCascades = cascadeDataList.size();
|
||||
|
||||
// Calculate split depths based on view camera frustum
|
||||
// Based on method presented in https://developer.nvidia.com/gpugems/GPUGems3/gpugems3_ch10.html
|
||||
for (int i = 0; i < numCascades; i++) {
|
||||
float p = (i + 1) / (float) (SceneLightingManager.SHADOW_MAP_CASCADE_COUNT);
|
||||
float Log = (float) (MinZ * Math.pow(Ratio, p));
|
||||
float Uniform = MinZ + Range * p;
|
||||
float d = LAMBDA * (Log - Uniform) + Uniform;
|
||||
CascadeSplits[i] = (d - NearClip) / ClipRange;
|
||||
float log = (float) (minZ * java.lang.Math.pow(ratio, p));
|
||||
float uniform = minZ + range * p;
|
||||
float d = LAMBDA * (log - uniform) + uniform;
|
||||
cascadeSplits[i] = (d - nearClip) / clipRange;
|
||||
}
|
||||
|
||||
float LastSplitDist = 0.0f;
|
||||
for(int i = 0; i < CascadeCount; i++){
|
||||
float SplitDist = CascadeSplits[i];
|
||||
float lastSplitDist = 0.0f;
|
||||
for (int i = 0; i < numCascades; i++) {
|
||||
float splitDist = cascadeSplits[i];
|
||||
|
||||
Vector3f[] FustrumCorners = new Vector3f[]{
|
||||
Vector3f[] frustumCorners = new Vector3f[]{
|
||||
new Vector3f(-1.0f, 1.0f, 0.0f),
|
||||
new Vector3f(1.0f, 1.0f, 0.0f),
|
||||
new Vector3f(1.0f, -1.0f, 0.0f),
|
||||
|
|
@ -74,70 +81,73 @@ public class ShadowUtils {
|
|||
new Vector3f(-1.0f, 1.0f, 1.0f),
|
||||
new Vector3f(1.0f, 1.0f, 1.0f),
|
||||
new Vector3f(1.0f, -1.0f, 1.0f),
|
||||
new Vector3f(-1.0f, -1.0f, 1.0f)
|
||||
new Vector3f(-1.0f, -1.0f, 1.0f),
|
||||
};
|
||||
|
||||
var InvertedCam = (new Matrix4f(ProjectionMatrix).mul(ViewMatrix)).invert();
|
||||
for(int j = 0; j < 8; j++){
|
||||
Vector4f InvertedCorner = new Vector4f(FustrumCorners[j],1.0f).mul(InvertedCam);
|
||||
FustrumCorners[j] = new Vector3f(InvertedCorner.x,InvertedCorner.y,InvertedCorner.z).div(InvertedCorner.w);
|
||||
// Project frustum corners into world space
|
||||
var invCam = (new Matrix4f(projMatrix).mul(viewMatrix)).invert();
|
||||
for (int j = 0; j < 8; j++) {
|
||||
Vector4f invCorner = new Vector4f(frustumCorners[j], 1.0f).mul(invCam);
|
||||
frustumCorners[j] = new Vector3f(invCorner.x, invCorner.y, invCorner.z).div(invCorner.w);
|
||||
}
|
||||
|
||||
for(int j = 0; j < 4; j++){
|
||||
var Distance = new Vector3f(FustrumCorners[j + 4]).sub(FustrumCorners[j]);
|
||||
FustrumCorners[j + 4] = new Vector3f(FustrumCorners[j]).add(new Vector3f(Distance).mul(SplitDist));
|
||||
FustrumCorners[j] = new Vector3f(FustrumCorners[j]).add(new Vector3f(Distance).mul(LastSplitDist));
|
||||
for (int j = 0; j < 4; j++) {
|
||||
var dist = new Vector3f(frustumCorners[j + 4]).sub(frustumCorners[j]);
|
||||
frustumCorners[j + 4] = new Vector3f(frustumCorners[j]).add(new Vector3f(dist).mul(splitDist));
|
||||
frustumCorners[j] = new Vector3f(frustumCorners[j]).add(new Vector3f(dist).mul(lastSplitDist));
|
||||
}
|
||||
|
||||
var FustrumCenter = new Vector3f(0.0f);
|
||||
for(int j = 0; j < 8; j++){
|
||||
FustrumCenter.add(FustrumCorners[j]);
|
||||
var frustumCenter = new Vector3f(0.0f);
|
||||
for (int j = 0; j < 8; j++) {
|
||||
frustumCenter.add(frustumCorners[j]);
|
||||
}
|
||||
FustrumCenter.div(8);
|
||||
frustumCenter.div(8.0f);
|
||||
|
||||
var up = Up;
|
||||
float SphereRadius = 0.0f;
|
||||
for(int j = 0; j < 8; j++){
|
||||
float Distance = new Vector3f(FustrumCorners[j]).sub(FustrumCenter).length();
|
||||
SphereRadius = Math.max(SphereRadius,Distance);
|
||||
var up = UP;
|
||||
float sphereRadius = 0.0f;
|
||||
for (int j = 0; j < 8; j++) {
|
||||
float dist = new Vector3f(frustumCorners[j]).sub(frustumCenter).length();
|
||||
sphereRadius = java.lang.Math.max(sphereRadius, dist);
|
||||
}
|
||||
SphereRadius = (float)Math.ceil(SphereRadius * 16.0f) / 16.0f;
|
||||
sphereRadius = (float) java.lang.Math.ceil(sphereRadius * 16.0f) / 16.0f;
|
||||
|
||||
var MaxExtents = new Vector3f(SphereRadius);
|
||||
var MinExtents = new Vector3f(-SphereRadius);
|
||||
var maxExtents = new Vector3f(sphereRadius, sphereRadius, sphereRadius);
|
||||
var minExtents = new Vector3f(maxExtents).mul(-1.0f);
|
||||
|
||||
var LightDirection = new Vector3f(LightPosition.x, LightPosition.y, LightPosition.z);
|
||||
var ShadowCamPosition = new Vector3f(FustrumCenter).add(LightDirection.mul(MinExtents.z));
|
||||
var lightDir = new Vector3f(lightPos.x, lightPos.y, lightPos.z);
|
||||
var shadowCameraPos = new Vector3f(frustumCenter).add(lightDir.mul(minExtents.z));
|
||||
|
||||
float Dot = Math.abs(new Vector3f(LightPosition.x, LightPosition.y, LightPosition.z).dot(up));
|
||||
if(Dot == 1.0f){
|
||||
up = UpAlt;
|
||||
float dot = java.lang.Math.abs(new Vector3f(lightPos.x, lightPos.y, lightPos.z).dot(up));
|
||||
if (dot == 1.0f) {
|
||||
up = UP_ALT;
|
||||
}
|
||||
|
||||
var LightViewMatrix = new Matrix4f().lookAt(ShadowCamPosition,FustrumCenter,up);
|
||||
var LightOrthoMatrix = new Matrix4f().ortho(MinExtents.x,MaxExtents.x,MinExtents.y,MaxExtents.y,0.0f,MaxExtents.z - MinExtents.z,true);
|
||||
var lightViewMatrix = new Matrix4f().lookAt(shadowCameraPos, frustumCenter, up);
|
||||
var lightOrthoMatrix = new Matrix4f().ortho
|
||||
(minExtents.x, maxExtents.x, minExtents.y, maxExtents.y, 0.0f, maxExtents.z - minExtents.z, true);
|
||||
|
||||
int ShadowMapSize = EngineConfig.getInstance().GetShadowMapSize();
|
||||
Vector4f ShadowOrigin = new Vector4f(0f,0f,0f,1f);
|
||||
LightViewMatrix.transform(ShadowOrigin);
|
||||
ShadowOrigin.mul(ShadowMapSize/2.0f);
|
||||
int shadowMapSize = EngineConfig.getInstance().GetShadowMapSize();
|
||||
Vector4f shadowOrigin = new Vector4f(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
lightViewMatrix.transform(shadowOrigin);
|
||||
shadowOrigin.mul(shadowMapSize / 2.0f);
|
||||
|
||||
Vector4f RoundedOrigin = new Vector4f(ShadowOrigin).round();
|
||||
Vector4f RoundOffset = RoundedOrigin.sub(ShadowOrigin);
|
||||
RoundOffset.mul(2.0f/ShadowMapSize);
|
||||
RoundOffset.z = 0.0f;
|
||||
RoundOffset.w = 0.0f;
|
||||
Vector4f roundedOrigin = new Vector4f(shadowOrigin).round();
|
||||
Vector4f roundOffset = roundedOrigin.sub(shadowOrigin);
|
||||
roundOffset.mul(2.0f / shadowMapSize);
|
||||
roundOffset.z = 0.0f;
|
||||
roundOffset.w = 0.0f;
|
||||
|
||||
LightOrthoMatrix.m30(LightOrthoMatrix.m30() + RoundOffset.x);
|
||||
LightOrthoMatrix.m31(LightOrthoMatrix.m31() + RoundOffset.y);
|
||||
LightOrthoMatrix.m32(LightOrthoMatrix.m32() + RoundOffset.z);
|
||||
LightOrthoMatrix.m33(LightOrthoMatrix.m33() + RoundOffset.w);
|
||||
lightOrthoMatrix.m30(lightOrthoMatrix.m30() + roundOffset.x);
|
||||
lightOrthoMatrix.m31(lightOrthoMatrix.m31() + roundOffset.y);
|
||||
lightOrthoMatrix.m32(lightOrthoMatrix.m32() + roundOffset.z);
|
||||
lightOrthoMatrix.m33(lightOrthoMatrix.m33() + roundOffset.w);
|
||||
|
||||
// Store split distance and matrix in cascade
|
||||
CascadeData cascadeData = cascadeDataList.get(i);
|
||||
cascadeData.SetSplitDistance((NearClip + SplitDist * ClipRange) * -1.0f);
|
||||
cascadeData.SetProjectionViewMatrix(LightOrthoMatrix.mul(LightViewMatrix));
|
||||
cascadeData.SetSplitDistance((nearClip + splitDist * clipRange) * -1.0f);
|
||||
cascadeData.SetProjectionViewMatrix(lightOrthoMatrix.mul(lightViewMatrix));
|
||||
|
||||
LastSplitDist = CascadeSplits[i];
|
||||
lastSplitDist = cascadeSplits[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -157,10 +157,7 @@ public class SpriteRenderer {
|
|||
.SetDepthWrite(DepthWrite)
|
||||
.SetPushConstantRanges(
|
||||
new PushConstantsRange[]{
|
||||
new PushConstantsRange(VK_SHADER_STAGE_VERTEX_BIT,0,VulkanUtils.VEC2_SIZE),
|
||||
new PushConstantsRange(VK_SHADER_STAGE_VERTEX_BIT,VulkanUtils.VEC2_SIZE,VulkanUtils.VEC2_SIZE),
|
||||
new PushConstantsRange(VK_SHADER_STAGE_VERTEX_BIT,VulkanUtils.VEC2_SIZE * 2,VulkanUtils.VEC2_SIZE),
|
||||
new PushConstantsRange(VK_SHADER_STAGE_VERTEX_BIT,VulkanUtils.VEC2_SIZE * 3,VulkanUtils.FLOAT_SIZE),
|
||||
new PushConstantsRange(VK_SHADER_STAGE_VERTEX_BIT,0,VulkanUtils.VEC2_SIZE * 3 + VulkanUtils.FLOAT_SIZE),
|
||||
new PushConstantsRange(VK_SHADER_STAGE_FRAGMENT_BIT,VulkanUtils.VEC2_SIZE * 3 + VulkanUtils.FLOAT_SIZE,VulkanUtils.INT_SIZE)
|
||||
})
|
||||
.SetDescriptorSetLayouts(DescriptorSetLayouts)
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import static org.lwjgl.vulkan.KHRPortabilitySubset.VK_KHR_PORTABILITY_SUBSET_EX
|
|||
import static org.lwjgl.vulkan.VK13.*;
|
||||
|
||||
public class Device {
|
||||
private final boolean depthClamp;
|
||||
private final VkDevice VulkanDevice;
|
||||
private final boolean SamplesAnisotropy;
|
||||
|
||||
|
|
@ -37,14 +38,15 @@ public class Device {
|
|||
.queueFamilyIndex(i)
|
||||
.pQueuePriorities(Priorities);
|
||||
}
|
||||
var features12 = VkPhysicalDeviceVulkan12Features.calloc(MemStack)
|
||||
.sType$Default()
|
||||
.scalarBlockLayout(true);
|
||||
|
||||
var features13 = VkPhysicalDeviceVulkan13Features.calloc(MemStack)
|
||||
.sType$Default()
|
||||
.dynamicRendering(true)
|
||||
.synchronization2(true);
|
||||
var features12 = VkPhysicalDeviceVulkan12Features.calloc(MemStack)
|
||||
.sType$Default()
|
||||
.scalarBlockLayout(true);
|
||||
|
||||
var features2 = VkPhysicalDeviceFeatures2.calloc(MemStack).sType$Default();
|
||||
var features = features2.features();
|
||||
|
||||
|
|
@ -53,8 +55,11 @@ public class Device {
|
|||
if(SamplesAnisotropy){
|
||||
features.samplerAnisotropy(true);
|
||||
}
|
||||
features2.pNext(features13.address());
|
||||
features13.pNext(features12.address());
|
||||
features.geometryShader(true);
|
||||
depthClamp = SupportedFeatures.depthClamp();
|
||||
features.depthClamp(depthClamp);
|
||||
features2.pNext(features12.address());
|
||||
features12.pNext(features13.address());
|
||||
|
||||
var DeviceCreateInfo = VkDeviceCreateInfo.calloc(MemStack)
|
||||
.sType$Default()
|
||||
|
|
@ -75,6 +80,10 @@ public class Device {
|
|||
}
|
||||
}
|
||||
|
||||
public boolean getDepthClamp() {
|
||||
return depthClamp;
|
||||
}
|
||||
|
||||
private static PointerBuffer CreateRequiredExtensions(PhysicalDevice PhysDevice, MemoryStack MemStack){
|
||||
Set<String> DeviceExtensions = GetDeviceExtensions(PhysDevice);
|
||||
//cross platform support for that fuckass Metal API mac uses
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ public class DeferredSceneRender implements SceneRenderer {//dynamic rendering
|
|||
public DeferredSceneRender(VulkanContext vulkanContext, EngineInstance engineInstance){
|
||||
ClearValueColour = VkClearValue.calloc().color(
|
||||
c -> c.float32(0, 0.0f).float32(1, 0.0f).float32(2, 0.0f).float32(3, 0.0f));
|
||||
ClearValueDepth = VkClearValue.calloc().color(c -> c.float32(0, 0.0f));
|
||||
ClearValueDepth = VkClearValue.calloc().color(c -> c.float32(0, 1.0f));
|
||||
MRTAttachments = new MultiRenderTargetAttachments(vulkanContext);
|
||||
AttachmentInfoColour = CreateColourAttachmentInfo(MRTAttachments, ClearValueColour);
|
||||
AttachmentInfoDepth = CreateDepthAttachmentInfo(MRTAttachments, ClearValueDepth);
|
||||
|
|
@ -267,7 +267,7 @@ public class DeferredSceneRender implements SceneRenderer {//dynamic rendering
|
|||
.SetDepthTest(true)
|
||||
.SetPushConstantRanges(new PushConstantsRange[0])
|
||||
.SetDescriptorSetLayouts(DescriptorSetLayouts)
|
||||
.BlendingIsUsed(true)
|
||||
.BlendingIsUsed(false)
|
||||
.SetDualPass(false)
|
||||
.SetAlphaToCoverage(false);
|
||||
var pipeline = new DefaultPipeline(VkCtx, BuildInfo);
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ public class ForwardSceneRender implements SceneRenderer {//dynamic rendering
|
|||
public ForwardSceneRender(VulkanContext vulkanContext){
|
||||
ClearValueColour = VkClearValue.calloc().color(
|
||||
c -> c.float32(0, R).float32(1, G).float32(2, B).float32(3, 1.0f));
|
||||
ClearValueDepth = VkClearValue.calloc().color(c -> c.float32(0, 0.0f));
|
||||
ClearValueDepth = VkClearValue.calloc().color(c -> c.float32(0, 1.0f));
|
||||
CreateRenderAttachments(vulkanContext);
|
||||
|
||||
PushConstBuffer = (MemoryUtil.memAlloc(PUSH_CONSTANTS_SIZE));
|
||||
|
|
|
|||
|
|
@ -17,12 +17,14 @@ public class ImageView {
|
|||
private final long VulkanImage;
|
||||
private final long VulkanImageView;
|
||||
private final boolean DepthImage;
|
||||
private final int layerCount;
|
||||
|
||||
public ImageView(Device device, long vulkanImage, ImageViewData imageViewData, boolean DepthImage){
|
||||
this.AspectMask = imageViewData.AspectMask;
|
||||
this.MipLevels = imageViewData.MipLevels;
|
||||
this.VulkanImage = vulkanImage;
|
||||
this.DepthImage = DepthImage;
|
||||
this.layerCount = imageViewData.LayerCount;
|
||||
try(var MemStack = MemoryStack.stackPush()){
|
||||
LongBuffer LongPointer = MemStack.mallocLong(1);
|
||||
var ViewCreateInfo = VkImageViewCreateInfo.calloc(MemStack)
|
||||
|
|
@ -46,6 +48,10 @@ public class ImageView {
|
|||
vkDestroyImageView(device.FetchVulkanDevice(), VulkanImageView, null);
|
||||
}
|
||||
|
||||
public int GetLayerCount() {
|
||||
return layerCount;
|
||||
}
|
||||
|
||||
public int GetAspectMask(){
|
||||
return AspectMask;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,15 +37,16 @@ public class RenderThread extends EngineThread {
|
|||
public InitData GetInitData(){return initData;}
|
||||
|
||||
public void RestartCrashedRenderer(){
|
||||
if(Headless) return;
|
||||
if(VulkanCrashCount < EngineConfig.getInstance().GetMaxVulkanCrashes()){
|
||||
RefreshRenderer();
|
||||
VulkanCrashCount++;
|
||||
}else{
|
||||
Logger.error("MAX API CRASHES REACHED, CLOSING SOFTWARE");
|
||||
PrimaryRuntime.GetEngineInstance().window().setShouldClose();
|
||||
PrimaryRuntime.CloseRuntime();
|
||||
}
|
||||
throw new IllegalStateException("Vulkan device lost; terminating renderer instead of hot-restarting");
|
||||
// if(Headless) return;
|
||||
// if(VulkanCrashCount < EngineConfig.getInstance().GetMaxVulkanCrashes()){
|
||||
// RefreshRenderer();
|
||||
// VulkanCrashCount++;
|
||||
// }else{
|
||||
// Logger.error("MAX API CRASHES REACHED, CLOSING SOFTWARE");
|
||||
// PrimaryRuntime.GetEngineInstance().window().setShouldClose();
|
||||
// PrimaryRuntime.CloseRuntime();
|
||||
// }
|
||||
}
|
||||
|
||||
public Renderer GetRenderer(){return render;}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ Renderer=1
|
|||
RenderingAPI=Vulkan
|
||||
RequestedImages=3
|
||||
ShaderRecompiling=true
|
||||
ShadowMapSize=2048
|
||||
ShadowMapSize=4096
|
||||
Software_Icon=ProgramIcon.png
|
||||
Software_Icon_Path=/WindowResources/Icon/
|
||||
Software_Title=Terrain4J Game Engine
|
||||
|
|
@ -35,5 +35,5 @@ throttle_on_unfocus=false
|
|||
user_display_name=TheSigma
|
||||
vkValidated=true
|
||||
vsync=false
|
||||
z_far_plane=0.1f
|
||||
z_near_plane=10000.0f
|
||||
z_near_plane=0.1f
|
||||
z_far_plane=10000.0f
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue