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
|
#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
|
#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
|
#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;
|
layout(set = 2, binding = 0) uniform samplerCube skyboxSampler;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vec3 textureIn = texture(skyboxSampler, outTexCoords).rgb;
|
outColor = texture(skyboxSampler, outTexCoords);// * vec4(0.0,0.05,0.1,1);
|
||||||
vec3 adjusted =vec3(0.0,textureIn.y/200.0,textureIn.z/150.0);
|
|
||||||
outColor = vec4(adjusted, 1.0);
|
|
||||||
}
|
}
|
||||||
Binary file not shown.
|
|
@ -14,5 +14,5 @@ void main() {
|
||||||
outTexCoords = inPosition;
|
outTexCoords = inPosition;
|
||||||
mat4 skyView = mat4(mat3(uboView.view));
|
mat4 skyView = mat4(mat3(uboView.view));
|
||||||
vec4 pos = uboProj.proj * skyView * vec4(inPosition, 1.0);
|
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.GuiRenderer;
|
||||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.GUI.GuiTexture;
|
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.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.Pipeline.Images.TextureCache;
|
||||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.PostProcessing.PostProcess;
|
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.Rendering.VkModel.*;
|
||||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.SpriteRendering.SpriteRenderer;
|
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.SpriteRendering.SpriteRenderer;
|
||||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DeviceLayers.CommandBuffer;
|
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 LightRenderer lightRenderer;
|
||||||
private final PostProcess PostProcessor;
|
private final PostProcess PostProcessor;
|
||||||
private final SwapChainRender swapChainRender;
|
private final SwapChainRender swapChainRender;
|
||||||
|
private final ShadowRenderer shadowRender;
|
||||||
private final GuiRenderer GuiRender;
|
private final GuiRenderer GuiRender;
|
||||||
private int CurrentFrame;
|
private int CurrentFrame;
|
||||||
private final VulkanContext RendererContext;
|
private final VulkanContext RendererContext;
|
||||||
|
|
@ -99,12 +102,17 @@ public class VulkanRenderer implements Renderer {
|
||||||
}
|
}
|
||||||
if(Deferred) {
|
if(Deferred) {
|
||||||
sceneRender = new DeferredSceneRender(RendererContext, engineInstance);
|
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());
|
PostProcessor = new PostProcess(RendererContext, lightRenderer.getAttachment());
|
||||||
|
|
||||||
} else{
|
} else{
|
||||||
sceneRender = new ForwardSceneRender(RendererContext);
|
sceneRender = new ForwardSceneRender(RendererContext);
|
||||||
PostProcessor = new PostProcess(RendererContext, sceneRender.GetAttachmentColour());
|
PostProcessor = new PostProcess(RendererContext, sceneRender.GetAttachmentColour());
|
||||||
lightRenderer = null;
|
lightRenderer = null;
|
||||||
|
shadowRender = null;
|
||||||
}
|
}
|
||||||
spriteRenderer= new SpriteRenderer(engineInstance, RendererContext, PostProcessor.GetAttachment());
|
spriteRenderer= new SpriteRenderer(engineInstance, RendererContext, PostProcessor.GetAttachment());
|
||||||
GuiRender = new GuiRenderer(engineInstance, RendererContext, GraphicsQueue, 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());
|
Logger.debug("Loaded {} models", Models.size());
|
||||||
|
|
||||||
sceneRender.LoadMaterials(RendererContext,materialsCache,textureCache);
|
sceneRender.LoadMaterials(RendererContext,materialsCache,textureCache);
|
||||||
|
shadowRender.loadMaterials(RendererContext, materialsCache, textureCache);
|
||||||
spriteRenderer.CompileSprites(RendererContext,modelsCache, textureCache);
|
spriteRenderer.CompileSprites(RendererContext,modelsCache, textureCache);
|
||||||
spriteRenderer.LoadMaterials(RendererContext,materialsCache,textureCache);
|
spriteRenderer.LoadMaterials(RendererContext,materialsCache,textureCache);
|
||||||
GuiRender.LoadTextures(RendererContext,initData.GuiTextures(),textureCache);
|
GuiRender.LoadTextures(RendererContext,initData.GuiTextures(),textureCache);
|
||||||
|
|
@ -173,6 +182,7 @@ public class VulkanRenderer implements Renderer {
|
||||||
RendererContext.GetDevice().waitIdle();
|
RendererContext.GetDevice().waitIdle();
|
||||||
Logger.debug("Waiting Vulkan Context");
|
Logger.debug("Waiting Vulkan Context");
|
||||||
sceneRender.cleanup(RendererContext);
|
sceneRender.cleanup(RendererContext);
|
||||||
|
if(shadowRender != null)shadowRender.cleanup(RendererContext);
|
||||||
if(lightRenderer != null)lightRenderer.cleanup(RendererContext);
|
if(lightRenderer != null)lightRenderer.cleanup(RendererContext);
|
||||||
PostProcessor.CleanUp(RendererContext);
|
PostProcessor.CleanUp(RendererContext);
|
||||||
swapChainRender.CleanUp(RendererContext);
|
swapChainRender.CleanUp(RendererContext);
|
||||||
|
|
@ -206,7 +216,9 @@ public class VulkanRenderer implements Renderer {
|
||||||
RecordingStart(CommandPool, CommandBuffer);
|
RecordingStart(CommandPool, CommandBuffer);
|
||||||
|
|
||||||
sceneRender.Render(engineInstance,RendererContext,CommandBuffer, modelsCache,materialsCache,CurrentFrame);
|
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());
|
PostProcessor.Render(RendererContext,CommandBuffer,lightRenderer.getAttachment());
|
||||||
spriteRenderer.Render(engineInstance,RendererContext,CommandBuffer,PostProcessor.GetAttachment(),modelsCache,CurrentFrame);
|
spriteRenderer.Render(engineInstance,RendererContext,CommandBuffer,PostProcessor.GetAttachment(),modelsCache,CurrentFrame);
|
||||||
GuiRender.Render(RendererContext,CommandBuffer,CurrentFrame,PostProcessor.GetAttachment());
|
GuiRender.Render(RendererContext,CommandBuffer,CurrentFrame,PostProcessor.GetAttachment());
|
||||||
|
|
@ -280,7 +292,9 @@ public class VulkanRenderer implements Renderer {
|
||||||
engineInstance.scene().GetProjection().Resize(extend.width(),extend.height());
|
engineInstance.scene().GetProjection().Resize(extend.width(),extend.height());
|
||||||
sceneRender.Resize(engineInstance,RendererContext);
|
sceneRender.Resize(engineInstance,RendererContext);
|
||||||
if(Deferred) {
|
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());
|
PostProcessor.Resize(RendererContext, lightRenderer.getAttachment());
|
||||||
} else{
|
} else{
|
||||||
PostProcessor.Resize(RendererContext, sceneRender.GetAttachmentColour());
|
PostProcessor.Resize(RendererContext, sceneRender.GetAttachmentColour());
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,7 @@ public class EngineConfig {
|
||||||
public boolean AlphaToCoverage = false;
|
public boolean AlphaToCoverage = false;
|
||||||
public boolean CompatibilityMode = false;
|
public boolean CompatibilityMode = false;
|
||||||
public Renderer renderer = Renderer.Forward;
|
public Renderer renderer = Renderer.Forward;
|
||||||
public int ShadowMapSize = 16;
|
public int ShadowMapSize = 4096;
|
||||||
public float Gamma = 0.8545f;
|
public float Gamma = 0.8545f;
|
||||||
public int MaxVulkanCrashesAllowed = 10;
|
public int MaxVulkanCrashesAllowed = 10;
|
||||||
public boolean RenderCollisionMesh = true;
|
public boolean RenderCollisionMesh = true;
|
||||||
|
|
@ -322,7 +322,7 @@ public class EngineConfig {
|
||||||
zFarPlane = (Float.parseFloat(EngineConfigVar.getOrDefault("z_far_plane", 100.0f).toString()));
|
zFarPlane = (Float.parseFloat(EngineConfigVar.getOrDefault("z_far_plane", 100.0f).toString()));
|
||||||
AAValue = (Integer.parseInt(EngineConfigVar.getOrDefault("anti_alias_mode", 1).toString()));
|
AAValue = (Integer.parseInt(EngineConfigVar.getOrDefault("anti_alias_mode", 1).toString()));
|
||||||
renderer = Integer.parseInt(EngineConfigVar.getOrDefault("Renderer", 1).toString()) == 0 ? Renderer.Forward: Renderer.Deferred;
|
renderer = Integer.parseInt(EngineConfigVar.getOrDefault("Renderer", 1).toString()) == 0 ? Renderer.Forward: Renderer.Deferred;
|
||||||
ShadowMapSize = Integer.parseInt(EngineConfigVar.getOrDefault("ShadowMapSize", 16).toString());
|
ShadowMapSize = Integer.parseInt(EngineConfigVar.getOrDefault("ShadowMapSize", 4096).toString());
|
||||||
MaxVulkanCrashesAllowed = Integer.parseInt(EngineConfigVar.getOrDefault("MaxAllowedVulkanCrashes", 10).toString());
|
MaxVulkanCrashesAllowed = Integer.parseInt(EngineConfigVar.getOrDefault("MaxAllowedVulkanCrashes", 10).toString());
|
||||||
ServerPort = Integer.parseInt(EngineConfigVar.getOrDefault("server_port", 25565).toString());
|
ServerPort = Integer.parseInt(EngineConfigVar.getOrDefault("server_port", 25565).toString());
|
||||||
CompatibilityMode = Boolean.parseBoolean(EngineConfigVar.getOrDefault("compatibility_mode", false).toString());
|
CompatibilityMode = Boolean.parseBoolean(EngineConfigVar.getOrDefault("compatibility_mode", false).toString());
|
||||||
|
|
@ -385,6 +385,7 @@ public class EngineConfig {
|
||||||
EngineConfigVar.setProperty("MaxDescriptors","1000");
|
EngineConfigVar.setProperty("MaxDescriptors","1000");
|
||||||
EngineConfigVar.setProperty("anti_alias_mode","1");
|
EngineConfigVar.setProperty("anti_alias_mode","1");
|
||||||
EngineConfigVar.setProperty("server","false");
|
EngineConfigVar.setProperty("server","false");
|
||||||
|
EngineConfigVar.setProperty("ShadowMapSize","4096");
|
||||||
EngineConfigVar.setProperty("LoadingScreenLocation",LoadingScreenLocation);
|
EngineConfigVar.setProperty("LoadingScreenLocation",LoadingScreenLocation);
|
||||||
EngineConfigVar.store(new FileWriter(path.toAbsolutePath().toString() + "/" + FILENAME), "created new properties file");
|
EngineConfigVar.store(new FileWriter(path.toAbsolutePath().toString() + "/" + FILENAME), "created new properties file");
|
||||||
Logger.debug("Wrote New Config File [{}]", ConfigFile.getAbsolutePath());
|
Logger.debug("Wrote New Config File [{}]", ConfigFile.getAbsolutePath());
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package net.halbear.Terrain4J.EngineCore.Logic.Physics.RigidBody;
|
package net.halbear.Terrain4J.EngineCore.Logic.Physics.RigidBody;
|
||||||
|
|
||||||
import net.halbear.Terrain4J.EngineCore.Logic.Physics.IPhysicsController;
|
import net.halbear.Terrain4J.EngineCore.Logic.Physics.IPhysicsController;
|
||||||
|
import net.halbear.Terrain4J.EngineCore.Logic.Physics.StaticSpatialHashGrid;
|
||||||
import org.joml.Matrix3f;
|
import org.joml.Matrix3f;
|
||||||
import org.joml.Quaternionf;
|
import org.joml.Quaternionf;
|
||||||
import org.joml.Vector3f;
|
import org.joml.Vector3f;
|
||||||
|
|
@ -80,6 +81,7 @@ public class RigidBody {
|
||||||
InverseMassKG = 0f;
|
InverseMassKG = 0f;
|
||||||
InverseInertiaLocal.zero();
|
InverseInertiaLocal.zero();
|
||||||
IsStatic = true;
|
IsStatic = true;
|
||||||
|
StaticSpatialHashGrid.Insert(RigidBodyID, shape.GetWorldAABB());
|
||||||
} else {
|
} else {
|
||||||
InverseMassKG = 1.0f / mass;
|
InverseMassKG = 1.0f / mass;
|
||||||
IsStatic = false;
|
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) {
|
private static long HashCell(int x, int y, int z) {
|
||||||
long xi = ((long) x) & 0x1FFFFFL;
|
long xi = ((long) x) & 0x1FFFFFL;
|
||||||
long yi = ((long) y) & 0x1FFFFFL;
|
long yi = ((long) y) & 0x1FFFFFL;
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import org.joml.primitives.AABBf;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class StaticSpatialHashGrid {
|
public class StaticSpatialHashGrid {
|
||||||
public static float CellSize = 16f;
|
public static float CellSize = 3f;
|
||||||
|
|
||||||
private static final Map<Long, List<String>> Cells = new HashMap<>();
|
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) {
|
private static long HashCell(int x, int y, int z) {
|
||||||
long xi = ((long) x) & 0x1FFFFFL;
|
long xi = ((long) x) & 0x1FFFFFL;
|
||||||
long yi = ((long) y) & 0x1FFFFFL;
|
long yi = ((long) y) & 0x1FFFFFL;
|
||||||
|
|
|
||||||
|
|
@ -117,6 +117,23 @@ public class WorldPhysicsManager {
|
||||||
|
|
||||||
Set<String> testedPairs = new HashSet<>();
|
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()) {
|
for (List<String> bucket : SpatialHashGrid.Buckets()) {
|
||||||
int size = bucket.size();
|
int size = bucket.size();
|
||||||
for (int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
|
|
|
||||||
|
|
@ -47,13 +47,12 @@ import org.tinylog.Logger;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
import static org.lwjgl.glfw.GLFW.GLFW_KEY_ESCAPE;
|
import static org.lwjgl.glfw.GLFW.*;
|
||||||
import static org.lwjgl.glfw.GLFW.GLFW_KEY_F3;
|
|
||||||
|
|
||||||
public class GameCore implements GameLogic {
|
public class GameCore implements GameLogic {
|
||||||
|
|
||||||
private static final float MOUSE_SENSITIVITY = 0.1f;
|
private static final float MOUSE_SENSITIVITY = 0.1f;
|
||||||
private static final float MOVEMENT_SPEED = 0.01f;
|
private static final float MOVEMENT_SPEED = 0.1f;
|
||||||
public static boolean LoadingLevel = false;
|
public static boolean LoadingLevel = false;
|
||||||
|
|
||||||
private Vector2f LastMousePos = new Vector2f(0,0);
|
private Vector2f LastMousePos = new Vector2f(0,0);
|
||||||
|
|
@ -99,19 +98,31 @@ public class GameCore implements GameLogic {
|
||||||
public InitData Initialise(EngineInstance engineInstance) {
|
public InitData Initialise(EngineInstance engineInstance) {
|
||||||
Scene scene = (Scene) engineInstance.scene();
|
Scene scene = (Scene) engineInstance.scene();
|
||||||
List<ModelData> models = new ArrayList<>();
|
List<ModelData> models = new ArrayList<>();
|
||||||
ModelData SponzaData = ModelLoader.LoadModel("resources/models/Cafe/exterior.json");
|
List<MaterialData> materials = new ArrayList<>();
|
||||||
List<MaterialData> SponzaMaterial = ModelLoader.LoadMaterials("resources/models/Cafe/exterior_mat.json");
|
// ModelData SponzaData = ModelLoader.LoadModel("resources/models/Cafe/exterior.json");
|
||||||
ModelData SponzaData1 = ModelLoader.LoadModel("resources/models/Cafe/interior.json");
|
// List<MaterialData> SponzaMaterial = ModelLoader.LoadMaterials("resources/models/Cafe/exterior_mat.json");
|
||||||
List<MaterialData> SponzaMaterial1= ModelLoader.LoadMaterials("resources/models/Cafe/interior_mat.json");
|
// ModelData SponzaData1 = ModelLoader.LoadModel("resources/models/Cafe/interior.json");
|
||||||
scene.AddActor(new Actor3D("Sponza1", SponzaData.ID(), new Vector3f(0,0f,-5f)).SetScale(0.1f));
|
// List<MaterialData> SponzaMaterial1= ModelLoader.LoadMaterials("resources/models/Cafe/interior_mat.json");
|
||||||
scene.AddActor(new Actor3D("Sponza2", SponzaData1.ID(), new Vector3f(0,0f,-5f)).SetScale(0.1f));
|
// 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");
|
MelonaData = ModelLoader.LoadModel("resources/models/cube/Cube.json");
|
||||||
CubeModelID = MelonaData.ID();
|
CubeModelID = MelonaData.ID();
|
||||||
List<MaterialData> MelonaMat = ModelLoader.LoadMaterials("resources/models/cube/Cube_mat.json");
|
List<MaterialData> MelonaMat = ModelLoader.LoadMaterials("resources/models/cube/Cube_mat.json");
|
||||||
var CollisionVisualisationData = ModelLoader.LoadModel("resources/models/VisualCollision/CollisionCube.json");
|
var CollisionVisualisationData = ModelLoader.LoadModel("resources/models/VisualCollision/CollisionCube.json");
|
||||||
VisualisedCollisionActor3D.CollisionCubeModelID = CollisionVisualisationData.ID();
|
VisualisedCollisionActor3D.CollisionCubeModelID = CollisionVisualisationData.ID();
|
||||||
List<MaterialData> CollisionVisualisationMat = ModelLoader.LoadMaterials("resources/models/VisualCollision/CollisionCube_mat.json");
|
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");
|
var Melona = ModelLoader.LoadModel("resources/models/melona/melona.json");
|
||||||
List<MaterialData> MelonaMaterial = ModelLoader.LoadMaterials("resources/models/melona/melona_mat.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;
|
boolean createOfflinePlayer = !PrimaryRuntime.IsServer && !ClientSideNetworkUtils.Connected;
|
||||||
|
|
||||||
materials.addAll(SponzaMaterial);
|
// materials.addAll(SponzaMaterial);
|
||||||
materials.addAll(SponzaMaterial1);
|
// materials.addAll(SponzaMaterial1);
|
||||||
models.add(SponzaData);
|
// models.add(SponzaData);
|
||||||
models.add(SponzaData1);
|
// models.add(SponzaData1);
|
||||||
materials.addAll(MelonaMat);
|
materials.addAll(MelonaMat);
|
||||||
materials.addAll(CollisionVisualisationMat);
|
materials.addAll(CollisionVisualisationMat);
|
||||||
materials.addAll(MelonaMaterial);
|
materials.addAll(MelonaMaterial);
|
||||||
|
|
@ -179,47 +190,50 @@ public class GameCore implements GameLogic {
|
||||||
guiTextures.add(guiTexture);
|
guiTextures.add(guiTexture);
|
||||||
}
|
}
|
||||||
|
|
||||||
//scene.GetLightingManager().GetAmbientLightColour().set(1.0f, 0.9f, 0.75f);
|
scene.GetLightingManager().GetAmbientLightColour().set(1.0f, 0.9f, 0.75f);
|
||||||
//scene.GetLightingManager().SetAmbientLightIntensity(0.6f);
|
scene.GetLightingManager().SetAmbientLightIntensity(0.3f);
|
||||||
scene.GetLightingManager().GetAmbientLightColour().set(0.3f, 0.35f, 0.5f);
|
// scene.GetLightingManager().GetAmbientLightColour().set(0.3f, 0.35f, 0.5f);
|
||||||
scene.GetLightingManager().SetAmbientLightIntensity(0.01f);
|
// 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(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);
|
// 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);
|
SkyLight.SetType(Light.LightType.Directional);
|
||||||
|
|
||||||
List<ILight> lights = new ArrayList<>();
|
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(-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(-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(-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(-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(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,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,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(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(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(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(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(-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(3.0f,2.25f,0.0f),new Vector3f(350.0f, 1525.0f, -420.0f),false,4000.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(3.0f,2.25f,0.0f),new Vector3f(400.0f, 1570.0f, -350.0f),false,1000.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(SkyLight);
|
lights.add(SkyLight);
|
||||||
|
|
||||||
ILight[] lightArr = new ILight[lights.size()];
|
ILight[] lightArr = new ILight[lights.size()];
|
||||||
|
|
@ -232,7 +246,12 @@ public class GameCore implements GameLogic {
|
||||||
}
|
}
|
||||||
//if(PrimaryRuntime.IsServer) {
|
//if(PrimaryRuntime.IsServer) {
|
||||||
permutation.GeneratePermutationArray(5783904701859L);
|
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++){
|
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));
|
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");
|
Settings.UsernameBuffer.set("Player");
|
||||||
return new InitData(models,materials,guiTextures);
|
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(){
|
public void Reset(){
|
||||||
EngineInstance instance = PrimaryRuntime.GetEngineInstance();
|
EngineInstance instance = PrimaryRuntime.GetEngineInstance();
|
||||||
|
|
@ -465,6 +496,8 @@ public class GameCore implements GameLogic {
|
||||||
}
|
}
|
||||||
if(CumulativeFrameTime >= 16_000_000) {
|
if(CumulativeFrameTime >= 16_000_000) {
|
||||||
HandleGui(engineInstance, FrameDiffNanoSeconds);
|
HandleGui(engineInstance, FrameDiffNanoSeconds);
|
||||||
|
// lightAngle = (lightAngle + 0.15f) % 360;
|
||||||
|
// updateDirLight();
|
||||||
CumulativeFrameTime = 0;
|
CumulativeFrameTime = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -479,6 +512,14 @@ public class GameCore implements GameLogic {
|
||||||
if(input.keySinglePress(GLFW_KEY_F3)){
|
if(input.keySinglePress(GLFW_KEY_F3)){
|
||||||
Scene.GUI_MODE = (Scene.GUI_MODE + 1) % 2;
|
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)) {
|
if (input.keySinglePress(GLFW_KEY_ESCAPE)) {
|
||||||
StartMenuActive = !StartMenuActive;
|
StartMenuActive = !StartMenuActive;
|
||||||
StartMenu.GameStarted = StartMenuActive;
|
StartMenu.GameStarted = StartMenuActive;
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,8 @@ public class Light implements ILight{
|
||||||
|
|
||||||
public void SetType(LightType type) {
|
public void SetType(LightType type) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
|
if(type == LightType.Directional)
|
||||||
|
Directional = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum LightType{
|
public enum LightType{
|
||||||
|
|
|
||||||
|
|
@ -156,7 +156,7 @@ public class Scene implements IScene {
|
||||||
|
|
||||||
if(!PrimaryRuntime.IsServer && !RenderThread.Headless) {
|
if(!PrimaryRuntime.IsServer && !RenderThread.Headless) {
|
||||||
GUIReg.put("PerformanceOverlay",new PerformanceOverlay());
|
GUIReg.put("PerformanceOverlay",new PerformanceOverlay());
|
||||||
// ActiveGUIs.add("PerformanceOverlay");
|
ActiveGUIs.add("PerformanceOverlay");
|
||||||
GUIReg.put("ChatLog",new GameChat());
|
GUIReg.put("ChatLog",new GameChat());
|
||||||
ActiveGUIs.add("ChatLog");
|
ActiveGUIs.add("ChatLog");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class SceneLightingManager implements ISceneLightingManager {
|
public class SceneLightingManager implements ISceneLightingManager {
|
||||||
public static int SHADOW_MAP_CASCADE_COUNT = 10;
|
public static int SHADOW_MAP_CASCADE_COUNT = 6;
|
||||||
public static int MaxLights;
|
public static int MaxLights;
|
||||||
private Vector3f AmbientLightingColour;
|
private Vector3f AmbientLightingColour;
|
||||||
private float AmbientLightIntensity;
|
private float AmbientLightIntensity;
|
||||||
|
|
|
||||||
|
|
@ -18,8 +18,8 @@ public class Project3D {
|
||||||
this.FOV = FOV;
|
this.FOV = FOV;
|
||||||
OriginalNear = zNear;
|
OriginalNear = zNear;
|
||||||
OriginalFar = zFar;
|
OriginalFar = zFar;
|
||||||
this.ZFarPlane = EngineConfig.getInstance().GetRenderingAPI() == EngineConfig.RenderAPI.OpenGL ? zNear : zFar;
|
this.ZFarPlane = zFar;
|
||||||
this.ZNearPlane = EngineConfig.getInstance().GetRenderingAPI() == EngineConfig.RenderAPI.OpenGL ? zFar : zNear;
|
this.ZNearPlane = zNear;
|
||||||
ProjectionMatrix = new Matrix4f();
|
ProjectionMatrix = new Matrix4f();
|
||||||
Resize(Width, Height);
|
Resize(Width, Height);
|
||||||
LastWidth = Width;
|
LastWidth = Width;
|
||||||
|
|
@ -27,8 +27,8 @@ public class Project3D {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetFarPlanes(){
|
public void SetFarPlanes(){
|
||||||
ZFarPlane = EngineConfig.getInstance().GetRenderingAPI() == EngineConfig.RenderAPI.OpenGL ? OriginalNear : OriginalFar;
|
ZFarPlane =OriginalFar;
|
||||||
ZNearPlane = EngineConfig.getInstance().GetRenderingAPI() == EngineConfig.RenderAPI.OpenGL ? OriginalFar : OriginalNear;
|
ZNearPlane = OriginalNear;
|
||||||
Resize(LastWidth,LastHeight);
|
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.Pipeline;
|
||||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.PipelineBuildInfo;
|
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.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.CommandBuffer;
|
||||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DeviceLayers.Device;
|
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.Structure.DisplayToScreen.ImageView;
|
||||||
|
|
@ -31,15 +33,18 @@ import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
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.VK10.*;
|
||||||
import static org.lwjgl.vulkan.VK13.*;
|
import static org.lwjgl.vulkan.VK13.*;
|
||||||
|
|
||||||
public class LightRenderer {
|
public class LightRenderer {
|
||||||
private static final int COLOUR_FORMAT = VK_FORMAT_R32G32B32A32_SFLOAT;
|
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_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_LIGHTS = "LIGHT_DESC_ID_LIGHTS";
|
||||||
private static final String DESC_ID_SCENE = "LIGHT_DESC_ID_SCENE ";
|
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 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_GLSL = "resources/EngineResources/shaders/lighting_vertex.glsl";
|
||||||
private static final String VERTEX_SHADER_FILE_SPV = VERTEX_SHADER_FILE_GLSL + ".spv";
|
private static final String VERTEX_SHADER_FILE_SPV = VERTEX_SHADER_FILE_GLSL + ".spv";
|
||||||
|
|
@ -53,8 +58,10 @@ public class LightRenderer {
|
||||||
private VkRenderingInfo RenderInfo;
|
private VkRenderingInfo RenderInfo;
|
||||||
private final VulkanBuffer[] LightBuffer;
|
private final VulkanBuffer[] LightBuffer;
|
||||||
private final VulkanBuffer[] SceneBuffer;
|
private final VulkanBuffer[] SceneBuffer;
|
||||||
|
private final LightSpecConsts lightSpecConsts;
|
||||||
private final DescriptorSetLayout SceneDescriptorSetLayout;
|
private final DescriptorSetLayout SceneDescriptorSetLayout;
|
||||||
private final DescriptorSetLayout StorageDescriptorSetLayout;
|
private final DescriptorSetLayout StorageDescriptorSetLayout;
|
||||||
|
private final VulkanBuffer[] shadowMatrices;
|
||||||
|
|
||||||
public LightRenderer(VulkanContext VkCtx, List<Attachment> attachments){
|
public LightRenderer(VulkanContext VkCtx, List<Attachment> attachments){
|
||||||
ClearValueColour = VkClearValue.calloc().color(
|
ClearValueColour = VkClearValue.calloc().color(
|
||||||
|
|
@ -64,18 +71,18 @@ public class LightRenderer {
|
||||||
AttachmentInfoColour = CreateColourAttachmentInfo(AttachmentColour, ClearValueColour);
|
AttachmentInfoColour = CreateColourAttachmentInfo(AttachmentColour, ClearValueColour);
|
||||||
RenderInfo = CreateRenderInfo(AttachmentColour, AttachmentInfoColour);
|
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,
|
var textureSamplerInfo = new TextureSamplerInfo(VK_SAMPLER_ADDRESS_MODE_REPEAT,
|
||||||
VK_BORDER_COLOR_INT_OPAQUE_BLACK, 1, true);
|
VK_BORDER_COLOR_INT_OPAQUE_BLACK, 1, true);
|
||||||
textureSampler = new TextureSampler(VkCtx, textureSamplerInfo);
|
textureSampler = new TextureSampler(VkCtx, textureSamplerInfo);
|
||||||
int numAttachments = attachments.size();
|
int numAttachments = attachments.size();
|
||||||
DescriptorSetLayout.LayoutInformation[] descSetLayouts = new DescriptorSetLayout.LayoutInformation[numAttachments];
|
DescriptorSetLayout.LayoutInformation[] descSetLayouts = new DescriptorSetLayout.LayoutInformation[numAttachments + 1];
|
||||||
for (int i = 0; i < numAttachments; i++) {
|
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);
|
descSetLayouts[i] = new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, i, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||||
}
|
}
|
||||||
AttachmentDescriptorSetLayout = new DescriptorSetLayout(VkCtx, descSetLayouts);
|
AttachmentDescriptorSetLayout = new DescriptorSetLayout(VkCtx, descSetLayouts);
|
||||||
|
|
||||||
CreateAttachmentDescriptorSet(VkCtx, AttachmentDescriptorSetLayout, attachments, textureSampler);
|
CreateAttachmentDescriptorSet(VkCtx, AttachmentDescriptorSetLayout, attachments, textureSampler);
|
||||||
|
|
||||||
StorageDescriptorSetLayout = new DescriptorSetLayout(VkCtx, new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 0, 1,
|
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,
|
SceneDescriptorSetLayout = new DescriptorSetLayout(VkCtx, new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0, 1,
|
||||||
VK_SHADER_STAGE_FRAGMENT_BIT));
|
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,
|
SceneBuffer = VulkanUtils.CreateHostVisibleBuffers(VkCtx, buffSize, VulkanUtils.MAX_IN_FLIGHT,
|
||||||
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, DESC_ID_SCENE, SceneDescriptorSetLayout);
|
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, DESC_ID_SCENE, SceneDescriptorSetLayout);
|
||||||
|
shadowMatrices = CreateShadowMatrixBuffers(VkCtx, StorageDescriptorSetLayout);
|
||||||
pipeline = createPipeline(VkCtx, shaderModules, new DescriptorSetLayout[]{AttachmentDescriptorSetLayout, StorageDescriptorSetLayout,
|
pipeline = createPipeline(VkCtx, shaderModules, new DescriptorSetLayout[]{AttachmentDescriptorSetLayout, StorageDescriptorSetLayout,
|
||||||
SceneDescriptorSetLayout});
|
StorageDescriptorSetLayout, SceneDescriptorSetLayout});
|
||||||
Logger.debug("Light Renderer Pipeline -> [{}]",pipeline.GetVulkanPipeline());
|
Logger.debug("Light Renderer Pipeline -> [{}]",pipeline.GetVulkanPipeline());
|
||||||
Arrays.asList(shaderModules).forEach(s -> s.CleanUp(VkCtx));
|
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,
|
private static void CreateAttachmentDescriptorSet(VulkanContext VkCtx, DescriptorSetLayout descSetLayout, List<Attachment> attachments,
|
||||||
TextureSampler sampler) {
|
TextureSampler sampler) {
|
||||||
DescriptorAllocator descAllocator = VkCtx.GetDescriptorAllocator();
|
DescriptorAllocator descAllocator = VkCtx.GetDescriptorAllocator();
|
||||||
|
|
@ -110,7 +133,7 @@ public class LightRenderer {
|
||||||
SwapChain swapChain = VkCtx.GetSwapChain();
|
SwapChain swapChain = VkCtx.GetSwapChain();
|
||||||
VkExtent2D swapChainExtent = swapChain.GetSwapChainExtent();
|
VkExtent2D swapChainExtent = swapChain.GetSwapChainExtent();
|
||||||
return new Attachment(VkCtx, swapChainExtent.width(), swapChainExtent.height(),
|
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) {
|
private static VkRenderingAttachmentInfo.Buffer CreateColourAttachmentInfo(Attachment attachment, VkClearValue clearValue) {
|
||||||
|
|
@ -153,19 +176,19 @@ public class LightRenderer {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ShaderModule[] CreateShaderModules(VulkanContext VkCtx) {
|
private static ShaderModule[] CreateShaderModules(VulkanContext VkCtx, LightSpecConsts lightSpecConsts) {
|
||||||
if (EngineConfig.getInstance().RecompileShaders()) {
|
if (EngineConfig.getInstance().RecompileShaders()) {
|
||||||
ShaderCompiler.CompileGLSLShaderOnChange(VERTEX_SHADER_FILE_GLSL, Shaderc.shaderc_glsl_vertex_shader);
|
ShaderCompiler.CompileGLSLShaderOnChange(VERTEX_SHADER_FILE_GLSL, Shaderc.shaderc_glsl_vertex_shader);
|
||||||
ShaderCompiler.CompileGLSLShaderOnChange(FRAGMENT_SHADER_FILE_GLSL, Shaderc.shaderc_glsl_fragment_shader);
|
ShaderCompiler.CompileGLSLShaderOnChange(FRAGMENT_SHADER_FILE_GLSL, Shaderc.shaderc_glsl_fragment_shader);
|
||||||
}
|
}
|
||||||
return new ShaderModule[]{
|
return new ShaderModule[]{
|
||||||
new ShaderModule(VkCtx, VK_SHADER_STAGE_VERTEX_BIT, VERTEX_SHADER_FILE_SPV, null),
|
new ShaderModule(VkCtx, VK_SHADER_STAGE_VERTEX_BIT, VERTEX_SHADER_FILE_SPV, null),
|
||||||
new ShaderModule(VkCtx, VK_SHADER_STAGE_FRAGMENT_BIT, 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()) {
|
try (var stack = MemoryStack.stackPush()) {
|
||||||
VkCommandBuffer cmdHandle = cmdBuffer.GetVulkanCommandBuffer();
|
VkCommandBuffer cmdHandle = cmdBuffer.GetVulkanCommandBuffer();
|
||||||
|
|
||||||
|
|
@ -176,7 +199,6 @@ public class LightRenderer {
|
||||||
VK_IMAGE_ASPECT_COLOR_BIT);
|
VK_IMAGE_ASPECT_COLOR_BIT);
|
||||||
|
|
||||||
List<Attachment> attachments = mrtAttachments.GetColourAttachments();
|
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();
|
int numAttachments = attachments.size();
|
||||||
for (int i = 0; i < numAttachments; i++) {
|
for (int i = 0; i < numAttachments; i++) {
|
||||||
Attachment attachment = attachments.get(i);
|
Attachment attachment = attachments.get(i);
|
||||||
|
|
@ -187,11 +209,19 @@ public class LightRenderer {
|
||||||
VK_IMAGE_ASPECT_COLOR_BIT);
|
VK_IMAGE_ASPECT_COLOR_BIT);
|
||||||
}
|
}
|
||||||
VulkanUtils.ImageBarrier(stack, cmdHandle, mrtAttachments.GetDepthAttachment().GetVkImage().getVulkanImage(),
|
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_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_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_2_SHADER_READ_BIT,
|
||||||
VK_IMAGE_ASPECT_DEPTH_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);
|
vkCmdBeginRendering(cmdHandle, RenderInfo);
|
||||||
|
|
||||||
vkCmdBindPipeline(cmdHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.GetVulkanPipeline());
|
vkCmdBindPipeline(cmdHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.GetVulkanPipeline());
|
||||||
|
|
@ -215,10 +245,11 @@ public class LightRenderer {
|
||||||
vkCmdSetScissor(cmdHandle, 0, scissor);
|
vkCmdSetScissor(cmdHandle, 0, scissor);
|
||||||
|
|
||||||
DescriptorAllocator descAllocator = VkCtx.GetDescriptorAllocator();
|
DescriptorAllocator descAllocator = VkCtx.GetDescriptorAllocator();
|
||||||
LongBuffer descriptorSets = stack.mallocLong(3)
|
LongBuffer descriptorSets = stack.mallocLong(4)
|
||||||
.put(0, descAllocator.GetDescriptorSet(DESC_ID_ATT).GetVkDescriptorSet())
|
.put(0, descAllocator.GetDescriptorSet(DESC_ID_ATT).GetVkDescriptorSet())
|
||||||
.put(1, descAllocator.GetDescriptorSet(DESC_ID_LIGHTS, CurrentFrame).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();
|
IScene scene = engineInstance.scene();
|
||||||
UpdateSceneInfo(VkCtx, scene, CurrentFrame);
|
UpdateSceneInfo(VkCtx, scene, CurrentFrame);
|
||||||
UpdateLights(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){
|
public void UpdateSceneInfo(VulkanContext VkCtx, IScene scene, int CurrentFrame){
|
||||||
VulkanBuffer buffer = SceneBuffer[CurrentFrame];
|
VulkanBuffer buffer = SceneBuffer[CurrentFrame];
|
||||||
long MappedMemory = buffer.MapMemory(VkCtx);
|
long MappedMemory = buffer.MapMemory(VkCtx);
|
||||||
|
|
@ -249,6 +296,10 @@ public class LightRenderer {
|
||||||
ILight[] lights = scene.GetLightingManager().GetLights();
|
ILight[] lights = scene.GetLightingManager().GetLights();
|
||||||
int LightCount = lights != null ? lights.length : 0;
|
int LightCount = lights != null ? lights.length : 0;
|
||||||
dataBuffer.putInt(Offset, LightCount);
|
dataBuffer.putInt(Offset, LightCount);
|
||||||
|
Offset += VulkanUtils.INT_SIZE;
|
||||||
|
|
||||||
|
scene.GetCamera().GetViewMatrix().get(Offset, dataBuffer);
|
||||||
|
|
||||||
buffer.UnMapMemory(VkCtx);
|
buffer.UnMapMemory(VkCtx);
|
||||||
}
|
}
|
||||||
public void UpdateLights(VulkanContext VkCtx, IScene scene, int CurrentFrame){
|
public void UpdateLights(VulkanContext VkCtx, IScene scene, int CurrentFrame){
|
||||||
|
|
@ -291,11 +342,13 @@ public class LightRenderer {
|
||||||
public void cleanup(VulkanContext VkCtx) {
|
public void cleanup(VulkanContext VkCtx) {
|
||||||
StorageDescriptorSetLayout.CleanUp(VkCtx);
|
StorageDescriptorSetLayout.CleanUp(VkCtx);
|
||||||
Arrays.asList(LightBuffer).forEach(b -> b.cleanup(VkCtx));
|
Arrays.asList(LightBuffer).forEach(b -> b.cleanup(VkCtx));
|
||||||
|
Arrays.asList(shadowMatrices).forEach(b -> b.cleanup(VkCtx));
|
||||||
SceneDescriptorSetLayout.CleanUp(VkCtx);
|
SceneDescriptorSetLayout.CleanUp(VkCtx);
|
||||||
Arrays.asList(SceneBuffer).forEach(b -> b.cleanup(VkCtx));
|
Arrays.asList(SceneBuffer).forEach(b -> b.cleanup(VkCtx));
|
||||||
pipeline.CleanUp(VkCtx);
|
pipeline.CleanUp(VkCtx);
|
||||||
AttachmentDescriptorSetLayout.CleanUp(VkCtx);
|
AttachmentDescriptorSetLayout.CleanUp(VkCtx);
|
||||||
textureSampler.CleanUp(VkCtx);
|
textureSampler.CleanUp(VkCtx);
|
||||||
|
lightSpecConsts.cleanup();
|
||||||
RenderInfo.free();
|
RenderInfo.free();
|
||||||
AttachmentColour.CleanUp(VkCtx);
|
AttachmentColour.CleanUp(VkCtx);
|
||||||
AttachmentInfoColour.free();
|
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<>();
|
ColourAttachments = new ArrayList<>();
|
||||||
|
|
||||||
//Position
|
//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);
|
ColourAttachments.add(Attachment);
|
||||||
//albedo
|
//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);
|
ColourAttachments.add(Attachment);
|
||||||
//Normals
|
//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);
|
ColourAttachments.add(Attachment);
|
||||||
//PBR
|
//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);
|
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;}
|
public int GetWidth(){return Width;}
|
||||||
|
|
|
||||||
|
|
@ -67,10 +67,11 @@ public class DefaultPipeline implements Pipeline {
|
||||||
.viewportCount(1)
|
.viewportCount(1)
|
||||||
.scissorCount(1);
|
.scissorCount(1);
|
||||||
var RasterizationStateCreateInfo = VkPipelineRasterizationStateCreateInfo.calloc(MemStack)
|
var RasterizationStateCreateInfo = VkPipelineRasterizationStateCreateInfo.calloc(MemStack)
|
||||||
.sType(VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO)
|
.sType$Default()
|
||||||
.polygonMode(VK_POLYGON_MODE_FILL)
|
.polygonMode(VK_POLYGON_MODE_FILL)
|
||||||
.cullMode(VK_CULL_MODE_NONE)
|
.cullMode(VK_CULL_MODE_NONE)
|
||||||
.frontFace(VK_FRONT_FACE_CLOCKWISE)
|
.frontFace(VK_FRONT_FACE_CLOCKWISE)
|
||||||
|
.depthClampEnable(BuildInfo.DepthClamp())
|
||||||
.lineWidth(1.0f);
|
.lineWidth(1.0f);
|
||||||
int sampleCount = EngineConfig.getInstance().GetRenderSampleCount();
|
int sampleCount = EngineConfig.getInstance().GetRenderSampleCount();
|
||||||
var MultisampleStateCreateInfo = VkPipelineMultisampleStateCreateInfo.calloc(MemStack)
|
var MultisampleStateCreateInfo = VkPipelineMultisampleStateCreateInfo.calloc(MemStack)
|
||||||
|
|
@ -88,7 +89,7 @@ public class DefaultPipeline implements Pipeline {
|
||||||
.sType(VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO)
|
.sType(VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO)
|
||||||
.depthTestEnable(BuildInfo.GetDepthTest())
|
.depthTestEnable(BuildInfo.GetDepthTest())
|
||||||
.depthWriteEnable(BuildInfo.performDepthWrite())
|
.depthWriteEnable(BuildInfo.performDepthWrite())
|
||||||
.depthCompareOp(VK_COMPARE_OP_GREATER_OR_EQUAL)
|
.depthCompareOp(VK_COMPARE_OP_LESS_OR_EQUAL)
|
||||||
.depthBoundsTestEnable(false)
|
.depthBoundsTestEnable(false)
|
||||||
.stencilTestEnable(false);
|
.stencilTestEnable(false);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,24 +9,85 @@ public class Attachment {
|
||||||
private final Image VkImage;
|
private final Image VkImage;
|
||||||
private final ImageView VkImageView;
|
private final ImageView VkImageView;
|
||||||
private boolean DepthAttachment;
|
private boolean DepthAttachment;
|
||||||
|
public Attachment(VulkanContext VkCtx, int Width, int Height, int Format, int Usage, boolean MultiSamples){
|
||||||
public Attachment(VulkanContext VkCtx, int Width, int Height, int Format, int Usage){
|
|
||||||
var ImageData = new Image.ImageData().Width(Width).Height(Height).Format(Format).SampleCount(EngineConfig.getInstance().GetRenderSampleCount());
|
var ImageData = new Image.ImageData().Width(Width).Height(Height).Format(Format).SampleCount(EngineConfig.getInstance().GetRenderSampleCount());
|
||||||
|
|
||||||
int AspectMask = 0;
|
int aspectMask = 0;
|
||||||
if((Usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) > 0){
|
if ((Usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) > 0) {
|
||||||
AspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||||
ImageData.Usage(Usage | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
|
ImageData.Usage(Usage | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
|
||||||
DepthAttachment = false;
|
DepthAttachment = false;
|
||||||
}
|
}
|
||||||
if((Usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) > 0){
|
if ((Usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) > 0) {
|
||||||
ImageData.Usage(Usage | VK_IMAGE_USAGE_SAMPLED_BIT);
|
ImageData.Usage(Usage | VK_IMAGE_USAGE_SAMPLED_BIT);
|
||||||
AspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
|
aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||||
DepthAttachment = true;
|
DepthAttachment = true;
|
||||||
}
|
}
|
||||||
|
int layers = 1;
|
||||||
|
if (layers > 0) {
|
||||||
|
ImageData.ArrayLayers(layers);
|
||||||
|
}
|
||||||
VkImage = new Image(VkCtx, ImageData);
|
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;}
|
public Image GetVkImage(){return VkImage;}
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ public class PipelineBuildInfo {
|
||||||
private DescriptorSetLayout[] DescriptorSetLayouts;
|
private DescriptorSetLayout[] DescriptorSetLayouts;
|
||||||
private boolean useBlend;
|
private boolean useBlend;
|
||||||
private boolean DepthWrite = true;
|
private boolean DepthWrite = true;
|
||||||
|
private boolean DepthClamp = false;
|
||||||
private boolean DepthTest = true;
|
private boolean DepthTest = true;
|
||||||
private boolean DualPass = false;
|
private boolean DualPass = false;
|
||||||
private boolean alphaToCoverage = false;
|
private boolean alphaToCoverage = false;
|
||||||
|
|
@ -27,6 +28,13 @@ public class PipelineBuildInfo {
|
||||||
DepthFormat = VK_FORMAT_UNDEFINED;
|
DepthFormat = VK_FORMAT_UNDEFINED;
|
||||||
useBlend = true;
|
useBlend = true;
|
||||||
}
|
}
|
||||||
|
public boolean DepthClamp() {
|
||||||
|
return DepthClamp;
|
||||||
|
}
|
||||||
|
public PipelineBuildInfo SetDepthClamp(boolean depthClamp) {
|
||||||
|
this.DepthClamp = depthClamp;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public PipelineBuildInfo SetBlendingMethod(int in){
|
public PipelineBuildInfo SetBlendingMethod(int in){
|
||||||
BlendingMethod = in;
|
BlendingMethod = in;
|
||||||
|
|
|
||||||
|
|
@ -3,19 +3,26 @@ package net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Shadows;
|
||||||
import org.joml.Matrix4f;
|
import org.joml.Matrix4f;
|
||||||
|
|
||||||
public class CascadeData {
|
public class CascadeData {
|
||||||
private final Matrix4f ProjectionViewMatrix;
|
private final Matrix4f projViewMatrix;
|
||||||
private float SplitDistance;
|
private float splitDistance;
|
||||||
|
|
||||||
public CascadeData(){
|
public CascadeData() {
|
||||||
ProjectionViewMatrix = new Matrix4f();
|
projViewMatrix = new Matrix4f();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Matrix4f GetProjectionViewMatrix(){return ProjectionViewMatrix;}
|
public Matrix4f GetProjViewMatrix() {
|
||||||
public float GetSplitDistance(){return SplitDistance;}
|
return projViewMatrix;
|
||||||
public void SetProjectionViewMatrix(Matrix4f ProjViewMat){
|
|
||||||
this.ProjectionViewMatrix.set(ProjViewMat);
|
|
||||||
}
|
}
|
||||||
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;
|
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 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 java.nio.ByteBuffer;
|
||||||
import static org.lwjgl.vulkan.VK10.VK_FORMAT_R32G32_SFLOAT;
|
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 class ShadowRenderer {
|
||||||
public static final int DEPTH_FORMAT = VK_FORMAT_D32_SFLOAT;
|
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_GLSL = "resources/EngineResources/shaders/shadow_vertex.glsl";
|
||||||
private static final String VERTEX_SHADER_FILE_SPV = VERTEX_SHADER_FILE_GLSL + ".spv";
|
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 {
|
public class ShadowUtils {
|
||||||
|
|
||||||
private static final float LAMBDA = 0.95f;
|
private static final float LAMBDA = 0.95f;
|
||||||
private static final Vector3f Up = new Vector3f(0.0f,1.0f,0.0f);
|
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 static final Vector3f UP_ALT = new Vector3f(0.0f, 0.0f, 1.0f);
|
||||||
|
|
||||||
private ShadowUtils(){
|
|
||||||
|
|
||||||
|
private ShadowUtils() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void UpdateCascadeShadows(CascadeShadows shadows, IScene scene){
|
public static void updateCascadeShadows(CascadeShadows cascadeShadows, IScene scene) {
|
||||||
Camera camera = scene.GetCamera();
|
Camera camera = scene.GetCamera();
|
||||||
Matrix4f ViewMatrix = camera.GetViewMatrix();
|
Matrix4f viewMatrix = camera.GetViewMatrix();
|
||||||
Project3D projection = scene.GetProjection();
|
Project3D projection = scene.GetProjection();
|
||||||
Matrix4f ProjectionMatrix = projection.GetProjectionMatrix();
|
Matrix4f projMatrix = projection.GetProjectionMatrix();
|
||||||
ILight[] lights = scene.GetLightingManager().GetLights();
|
ILight[] lights = scene.GetLightingManager().GetLights();
|
||||||
int LightCount = lights.length;
|
int numLights = lights.length;
|
||||||
ILight SkyLight = null;
|
ILight dirLight = null;
|
||||||
for(int i = 0; i < LightCount; i++){
|
for (int i = 0; i < numLights; i++) {
|
||||||
if(lights[i].IsDirectional()){
|
if (lights[i].IsDirectional()) {
|
||||||
SkyLight = lights[i];
|
dirLight = lights[i];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(SkyLight == null){
|
if (dirLight == null) {
|
||||||
throw new RuntimeException("No SkyLight on scene");
|
throw new RuntimeException("Could not find directional light");
|
||||||
}
|
}
|
||||||
Vector4f LightPosition = new Vector4f(SkyLight.GetPosition(),0.0f);
|
Vector3f lightPos = dirLight.GetPosition();
|
||||||
float[] CascadeSplits = new float[SceneLightingManager.SHADOW_MAP_CASCADE_COUNT];
|
|
||||||
float NearClip = Math.min(projection.GetNearZ(), projection.GetFarZ());
|
|
||||||
float FarClip = Math.max(projection.GetNearZ(), projection.GetFarZ());
|
|
||||||
float ClipRange = FarClip - NearClip;
|
|
||||||
|
|
||||||
float MinZ = NearClip;
|
float[] cascadeSplits = new float[SceneLightingManager.SHADOW_MAP_CASCADE_COUNT];
|
||||||
float MaxZ = NearClip + ClipRange;
|
|
||||||
|
|
||||||
float Range = MaxZ - MinZ;
|
float nearClip = projection.GetNearZ();
|
||||||
float Ratio = MaxZ/MinZ;
|
float farClip = projection.GetFarZ();
|
||||||
|
float clipRange = farClip - nearClip;
|
||||||
|
|
||||||
List<CascadeData> cascadeDataList = shadows.GetCascadeData();
|
if (nearClip <= 0.0f || farClip <= nearClip) {
|
||||||
int CascadeCount = cascadeDataList.size();
|
//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 p = (i + 1) / (float) (SceneLightingManager.SHADOW_MAP_CASCADE_COUNT);
|
||||||
float Log = (float) (MinZ * Math.pow(Ratio, p));
|
float log = (float) (minZ * java.lang.Math.pow(ratio, p));
|
||||||
float Uniform = MinZ + Range * p;
|
float uniform = minZ + range * p;
|
||||||
float d = LAMBDA * (Log - Uniform) + Uniform;
|
float d = LAMBDA * (log - uniform) + uniform;
|
||||||
CascadeSplits[i] = (d - NearClip) / ClipRange;
|
cascadeSplits[i] = (d - nearClip) / clipRange;
|
||||||
}
|
}
|
||||||
|
|
||||||
float LastSplitDist = 0.0f;
|
float lastSplitDist = 0.0f;
|
||||||
for(int i = 0; i < CascadeCount; i++){
|
for (int i = 0; i < numCascades; i++) {
|
||||||
float SplitDist = CascadeSplits[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),
|
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),
|
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();
|
// Project frustum corners into world space
|
||||||
for(int j = 0; j < 8; j++){
|
var invCam = (new Matrix4f(projMatrix).mul(viewMatrix)).invert();
|
||||||
Vector4f InvertedCorner = new Vector4f(FustrumCorners[j],1.0f).mul(InvertedCam);
|
for (int j = 0; j < 8; j++) {
|
||||||
FustrumCorners[j] = new Vector3f(InvertedCorner.x,InvertedCorner.y,InvertedCorner.z).div(InvertedCorner.w);
|
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++){
|
for (int j = 0; j < 4; j++) {
|
||||||
var Distance = new Vector3f(FustrumCorners[j + 4]).sub(FustrumCorners[j]);
|
var dist = new Vector3f(frustumCorners[j + 4]).sub(frustumCorners[j]);
|
||||||
FustrumCorners[j + 4] = new Vector3f(FustrumCorners[j]).add(new Vector3f(Distance).mul(SplitDist));
|
frustumCorners[j + 4] = new Vector3f(frustumCorners[j]).add(new Vector3f(dist).mul(splitDist));
|
||||||
FustrumCorners[j] = new Vector3f(FustrumCorners[j]).add(new Vector3f(Distance).mul(LastSplitDist));
|
frustumCorners[j] = new Vector3f(frustumCorners[j]).add(new Vector3f(dist).mul(lastSplitDist));
|
||||||
}
|
}
|
||||||
|
|
||||||
var FustrumCenter = new Vector3f(0.0f);
|
var frustumCenter = new Vector3f(0.0f);
|
||||||
for(int j = 0; j < 8; j++){
|
for (int j = 0; j < 8; j++) {
|
||||||
FustrumCenter.add(FustrumCorners[j]);
|
frustumCenter.add(frustumCorners[j]);
|
||||||
}
|
}
|
||||||
FustrumCenter.div(8);
|
frustumCenter.div(8.0f);
|
||||||
|
|
||||||
var up = Up;
|
var up = UP;
|
||||||
float SphereRadius = 0.0f;
|
float sphereRadius = 0.0f;
|
||||||
for(int j = 0; j < 8; j++){
|
for (int j = 0; j < 8; j++) {
|
||||||
float Distance = new Vector3f(FustrumCorners[j]).sub(FustrumCenter).length();
|
float dist = new Vector3f(frustumCorners[j]).sub(frustumCenter).length();
|
||||||
SphereRadius = Math.max(SphereRadius,Distance);
|
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 maxExtents = new Vector3f(sphereRadius, sphereRadius, sphereRadius);
|
||||||
var MinExtents = new Vector3f(-SphereRadius);
|
var minExtents = new Vector3f(maxExtents).mul(-1.0f);
|
||||||
|
|
||||||
var LightDirection = new Vector3f(LightPosition.x, LightPosition.y, LightPosition.z);
|
var lightDir = new Vector3f(lightPos.x, lightPos.y, lightPos.z);
|
||||||
var ShadowCamPosition = new Vector3f(FustrumCenter).add(LightDirection.mul(MinExtents.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));
|
float dot = java.lang.Math.abs(new Vector3f(lightPos.x, lightPos.y, lightPos.z).dot(up));
|
||||||
if(Dot == 1.0f){
|
if (dot == 1.0f) {
|
||||||
up = UpAlt;
|
up = UP_ALT;
|
||||||
}
|
}
|
||||||
|
|
||||||
var LightViewMatrix = new Matrix4f().lookAt(ShadowCamPosition,FustrumCenter,up);
|
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);
|
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();
|
int shadowMapSize = EngineConfig.getInstance().GetShadowMapSize();
|
||||||
Vector4f ShadowOrigin = new Vector4f(0f,0f,0f,1f);
|
Vector4f shadowOrigin = new Vector4f(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
LightViewMatrix.transform(ShadowOrigin);
|
lightViewMatrix.transform(shadowOrigin);
|
||||||
ShadowOrigin.mul(ShadowMapSize/2.0f);
|
shadowOrigin.mul(shadowMapSize / 2.0f);
|
||||||
|
|
||||||
Vector4f RoundedOrigin = new Vector4f(ShadowOrigin).round();
|
Vector4f roundedOrigin = new Vector4f(shadowOrigin).round();
|
||||||
Vector4f RoundOffset = RoundedOrigin.sub(ShadowOrigin);
|
Vector4f roundOffset = roundedOrigin.sub(shadowOrigin);
|
||||||
RoundOffset.mul(2.0f/ShadowMapSize);
|
roundOffset.mul(2.0f / shadowMapSize);
|
||||||
RoundOffset.z = 0.0f;
|
roundOffset.z = 0.0f;
|
||||||
RoundOffset.w = 0.0f;
|
roundOffset.w = 0.0f;
|
||||||
|
|
||||||
LightOrthoMatrix.m30(LightOrthoMatrix.m30() + RoundOffset.x);
|
lightOrthoMatrix.m30(lightOrthoMatrix.m30() + roundOffset.x);
|
||||||
LightOrthoMatrix.m31(LightOrthoMatrix.m31() + RoundOffset.y);
|
lightOrthoMatrix.m31(lightOrthoMatrix.m31() + roundOffset.y);
|
||||||
LightOrthoMatrix.m32(LightOrthoMatrix.m32() + RoundOffset.z);
|
lightOrthoMatrix.m32(lightOrthoMatrix.m32() + roundOffset.z);
|
||||||
LightOrthoMatrix.m33(LightOrthoMatrix.m33() + RoundOffset.w);
|
lightOrthoMatrix.m33(lightOrthoMatrix.m33() + roundOffset.w);
|
||||||
|
|
||||||
|
// Store split distance and matrix in cascade
|
||||||
CascadeData cascadeData = cascadeDataList.get(i);
|
CascadeData cascadeData = cascadeDataList.get(i);
|
||||||
cascadeData.SetSplitDistance((NearClip + SplitDist * ClipRange) * -1.0f);
|
cascadeData.SetSplitDistance((nearClip + splitDist * clipRange) * -1.0f);
|
||||||
cascadeData.SetProjectionViewMatrix(LightOrthoMatrix.mul(LightViewMatrix));
|
cascadeData.SetProjectionViewMatrix(lightOrthoMatrix.mul(lightViewMatrix));
|
||||||
|
|
||||||
LastSplitDist = CascadeSplits[i];
|
lastSplitDist = cascadeSplits[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -157,10 +157,7 @@ public class SpriteRenderer {
|
||||||
.SetDepthWrite(DepthWrite)
|
.SetDepthWrite(DepthWrite)
|
||||||
.SetPushConstantRanges(
|
.SetPushConstantRanges(
|
||||||
new PushConstantsRange[]{
|
new PushConstantsRange[]{
|
||||||
new PushConstantsRange(VK_SHADER_STAGE_VERTEX_BIT,0,VulkanUtils.VEC2_SIZE),
|
new PushConstantsRange(VK_SHADER_STAGE_VERTEX_BIT,0,VulkanUtils.VEC2_SIZE * 3 + VulkanUtils.FLOAT_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_FRAGMENT_BIT,VulkanUtils.VEC2_SIZE * 3 + VulkanUtils.FLOAT_SIZE,VulkanUtils.INT_SIZE)
|
new PushConstantsRange(VK_SHADER_STAGE_FRAGMENT_BIT,VulkanUtils.VEC2_SIZE * 3 + VulkanUtils.FLOAT_SIZE,VulkanUtils.INT_SIZE)
|
||||||
})
|
})
|
||||||
.SetDescriptorSetLayouts(DescriptorSetLayouts)
|
.SetDescriptorSetLayouts(DescriptorSetLayouts)
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ import static org.lwjgl.vulkan.KHRPortabilitySubset.VK_KHR_PORTABILITY_SUBSET_EX
|
||||||
import static org.lwjgl.vulkan.VK13.*;
|
import static org.lwjgl.vulkan.VK13.*;
|
||||||
|
|
||||||
public class Device {
|
public class Device {
|
||||||
|
private final boolean depthClamp;
|
||||||
private final VkDevice VulkanDevice;
|
private final VkDevice VulkanDevice;
|
||||||
private final boolean SamplesAnisotropy;
|
private final boolean SamplesAnisotropy;
|
||||||
|
|
||||||
|
|
@ -37,14 +38,15 @@ public class Device {
|
||||||
.queueFamilyIndex(i)
|
.queueFamilyIndex(i)
|
||||||
.pQueuePriorities(Priorities);
|
.pQueuePriorities(Priorities);
|
||||||
}
|
}
|
||||||
|
var features12 = VkPhysicalDeviceVulkan12Features.calloc(MemStack)
|
||||||
|
.sType$Default()
|
||||||
|
.scalarBlockLayout(true);
|
||||||
|
|
||||||
var features13 = VkPhysicalDeviceVulkan13Features.calloc(MemStack)
|
var features13 = VkPhysicalDeviceVulkan13Features.calloc(MemStack)
|
||||||
.sType$Default()
|
.sType$Default()
|
||||||
.dynamicRendering(true)
|
.dynamicRendering(true)
|
||||||
.synchronization2(true);
|
.synchronization2(true);
|
||||||
var features12 = VkPhysicalDeviceVulkan12Features.calloc(MemStack)
|
|
||||||
.sType$Default()
|
|
||||||
.scalarBlockLayout(true);
|
|
||||||
var features2 = VkPhysicalDeviceFeatures2.calloc(MemStack).sType$Default();
|
var features2 = VkPhysicalDeviceFeatures2.calloc(MemStack).sType$Default();
|
||||||
var features = features2.features();
|
var features = features2.features();
|
||||||
|
|
||||||
|
|
@ -53,8 +55,11 @@ public class Device {
|
||||||
if(SamplesAnisotropy){
|
if(SamplesAnisotropy){
|
||||||
features.samplerAnisotropy(true);
|
features.samplerAnisotropy(true);
|
||||||
}
|
}
|
||||||
features2.pNext(features13.address());
|
features.geometryShader(true);
|
||||||
features13.pNext(features12.address());
|
depthClamp = SupportedFeatures.depthClamp();
|
||||||
|
features.depthClamp(depthClamp);
|
||||||
|
features2.pNext(features12.address());
|
||||||
|
features12.pNext(features13.address());
|
||||||
|
|
||||||
var DeviceCreateInfo = VkDeviceCreateInfo.calloc(MemStack)
|
var DeviceCreateInfo = VkDeviceCreateInfo.calloc(MemStack)
|
||||||
.sType$Default()
|
.sType$Default()
|
||||||
|
|
@ -75,6 +80,10 @@ public class Device {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean getDepthClamp() {
|
||||||
|
return depthClamp;
|
||||||
|
}
|
||||||
|
|
||||||
private static PointerBuffer CreateRequiredExtensions(PhysicalDevice PhysDevice, MemoryStack MemStack){
|
private static PointerBuffer CreateRequiredExtensions(PhysicalDevice PhysDevice, MemoryStack MemStack){
|
||||||
Set<String> DeviceExtensions = GetDeviceExtensions(PhysDevice);
|
Set<String> DeviceExtensions = GetDeviceExtensions(PhysDevice);
|
||||||
//cross platform support for that fuckass Metal API mac uses
|
//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){
|
public DeferredSceneRender(VulkanContext vulkanContext, EngineInstance engineInstance){
|
||||||
ClearValueColour = VkClearValue.calloc().color(
|
ClearValueColour = VkClearValue.calloc().color(
|
||||||
c -> c.float32(0, 0.0f).float32(1, 0.0f).float32(2, 0.0f).float32(3, 0.0f));
|
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);
|
MRTAttachments = new MultiRenderTargetAttachments(vulkanContext);
|
||||||
AttachmentInfoColour = CreateColourAttachmentInfo(MRTAttachments, ClearValueColour);
|
AttachmentInfoColour = CreateColourAttachmentInfo(MRTAttachments, ClearValueColour);
|
||||||
AttachmentInfoDepth = CreateDepthAttachmentInfo(MRTAttachments, ClearValueDepth);
|
AttachmentInfoDepth = CreateDepthAttachmentInfo(MRTAttachments, ClearValueDepth);
|
||||||
|
|
@ -267,7 +267,7 @@ public class DeferredSceneRender implements SceneRenderer {//dynamic rendering
|
||||||
.SetDepthTest(true)
|
.SetDepthTest(true)
|
||||||
.SetPushConstantRanges(new PushConstantsRange[0])
|
.SetPushConstantRanges(new PushConstantsRange[0])
|
||||||
.SetDescriptorSetLayouts(DescriptorSetLayouts)
|
.SetDescriptorSetLayouts(DescriptorSetLayouts)
|
||||||
.BlendingIsUsed(true)
|
.BlendingIsUsed(false)
|
||||||
.SetDualPass(false)
|
.SetDualPass(false)
|
||||||
.SetAlphaToCoverage(false);
|
.SetAlphaToCoverage(false);
|
||||||
var pipeline = new DefaultPipeline(VkCtx, BuildInfo);
|
var pipeline = new DefaultPipeline(VkCtx, BuildInfo);
|
||||||
|
|
|
||||||
|
|
@ -117,7 +117,7 @@ public class ForwardSceneRender implements SceneRenderer {//dynamic rendering
|
||||||
public ForwardSceneRender(VulkanContext vulkanContext){
|
public ForwardSceneRender(VulkanContext vulkanContext){
|
||||||
ClearValueColour = VkClearValue.calloc().color(
|
ClearValueColour = VkClearValue.calloc().color(
|
||||||
c -> c.float32(0, R).float32(1, G).float32(2, B).float32(3, 1.0f));
|
c -> c.float32(0, R).float32(1, G).float32(2, B).float32(3, 1.0f));
|
||||||
ClearValueDepth = VkClearValue.calloc().color(c -> c.float32(0, 0.0f));
|
ClearValueDepth = VkClearValue.calloc().color(c -> c.float32(0, 1.0f));
|
||||||
CreateRenderAttachments(vulkanContext);
|
CreateRenderAttachments(vulkanContext);
|
||||||
|
|
||||||
PushConstBuffer = (MemoryUtil.memAlloc(PUSH_CONSTANTS_SIZE));
|
PushConstBuffer = (MemoryUtil.memAlloc(PUSH_CONSTANTS_SIZE));
|
||||||
|
|
|
||||||
|
|
@ -17,12 +17,14 @@ public class ImageView {
|
||||||
private final long VulkanImage;
|
private final long VulkanImage;
|
||||||
private final long VulkanImageView;
|
private final long VulkanImageView;
|
||||||
private final boolean DepthImage;
|
private final boolean DepthImage;
|
||||||
|
private final int layerCount;
|
||||||
|
|
||||||
public ImageView(Device device, long vulkanImage, ImageViewData imageViewData, boolean DepthImage){
|
public ImageView(Device device, long vulkanImage, ImageViewData imageViewData, boolean DepthImage){
|
||||||
this.AspectMask = imageViewData.AspectMask;
|
this.AspectMask = imageViewData.AspectMask;
|
||||||
this.MipLevels = imageViewData.MipLevels;
|
this.MipLevels = imageViewData.MipLevels;
|
||||||
this.VulkanImage = vulkanImage;
|
this.VulkanImage = vulkanImage;
|
||||||
this.DepthImage = DepthImage;
|
this.DepthImage = DepthImage;
|
||||||
|
this.layerCount = imageViewData.LayerCount;
|
||||||
try(var MemStack = MemoryStack.stackPush()){
|
try(var MemStack = MemoryStack.stackPush()){
|
||||||
LongBuffer LongPointer = MemStack.mallocLong(1);
|
LongBuffer LongPointer = MemStack.mallocLong(1);
|
||||||
var ViewCreateInfo = VkImageViewCreateInfo.calloc(MemStack)
|
var ViewCreateInfo = VkImageViewCreateInfo.calloc(MemStack)
|
||||||
|
|
@ -46,6 +48,10 @@ public class ImageView {
|
||||||
vkDestroyImageView(device.FetchVulkanDevice(), VulkanImageView, null);
|
vkDestroyImageView(device.FetchVulkanDevice(), VulkanImageView, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int GetLayerCount() {
|
||||||
|
return layerCount;
|
||||||
|
}
|
||||||
|
|
||||||
public int GetAspectMask(){
|
public int GetAspectMask(){
|
||||||
return AspectMask;
|
return AspectMask;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -37,15 +37,16 @@ public class RenderThread extends EngineThread {
|
||||||
public InitData GetInitData(){return initData;}
|
public InitData GetInitData(){return initData;}
|
||||||
|
|
||||||
public void RestartCrashedRenderer(){
|
public void RestartCrashedRenderer(){
|
||||||
if(Headless) return;
|
throw new IllegalStateException("Vulkan device lost; terminating renderer instead of hot-restarting");
|
||||||
if(VulkanCrashCount < EngineConfig.getInstance().GetMaxVulkanCrashes()){
|
// if(Headless) return;
|
||||||
RefreshRenderer();
|
// if(VulkanCrashCount < EngineConfig.getInstance().GetMaxVulkanCrashes()){
|
||||||
VulkanCrashCount++;
|
// RefreshRenderer();
|
||||||
}else{
|
// VulkanCrashCount++;
|
||||||
Logger.error("MAX API CRASHES REACHED, CLOSING SOFTWARE");
|
// }else{
|
||||||
PrimaryRuntime.GetEngineInstance().window().setShouldClose();
|
// Logger.error("MAX API CRASHES REACHED, CLOSING SOFTWARE");
|
||||||
PrimaryRuntime.CloseRuntime();
|
// PrimaryRuntime.GetEngineInstance().window().setShouldClose();
|
||||||
}
|
// PrimaryRuntime.CloseRuntime();
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
public Renderer GetRenderer(){return render;}
|
public Renderer GetRenderer(){return render;}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ Renderer=1
|
||||||
RenderingAPI=Vulkan
|
RenderingAPI=Vulkan
|
||||||
RequestedImages=3
|
RequestedImages=3
|
||||||
ShaderRecompiling=true
|
ShaderRecompiling=true
|
||||||
ShadowMapSize=2048
|
ShadowMapSize=4096
|
||||||
Software_Icon=ProgramIcon.png
|
Software_Icon=ProgramIcon.png
|
||||||
Software_Icon_Path=/WindowResources/Icon/
|
Software_Icon_Path=/WindowResources/Icon/
|
||||||
Software_Title=Terrain4J Game Engine
|
Software_Title=Terrain4J Game Engine
|
||||||
|
|
@ -35,5 +35,5 @@ throttle_on_unfocus=false
|
||||||
user_display_name=TheSigma
|
user_display_name=TheSigma
|
||||||
vkValidated=true
|
vkValidated=true
|
||||||
vsync=false
|
vsync=false
|
||||||
z_far_plane=0.1f
|
z_near_plane=0.1f
|
||||||
z_near_plane=10000.0f
|
z_far_plane=10000.0f
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue