OpenGL works again, Vulkan can be switched to, fixed most of the vulkan validation errors, better shadows, soft shadows, emissive lighting, and multiple different opacity rendering methods

This commit is contained in:
Halbear 2026-08-31 14:13:59 +01:00
parent 0d41f3e15b
commit 5b231d6920
54 changed files with 1102 additions and 268 deletions

View file

@ -9,7 +9,17 @@ buildscript {
plugins {
id 'application'
id 'java'
id 'com.gradleup.shadow' version '9.2.0'
}
jar {
manifest {
attributes(
'Main-Class': 'net.halbear.Executable.Launcher'
)
}
}
project.ext.lwjglVersion = "3.4.1"
project.ext.jomlVersion = "1.10.8"
project.ext.jomlprimitivesVersion = "1.10.0"

View file

@ -23,6 +23,9 @@ 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 sampler2D emissiveSampler;
layout(set = 0, binding = 5) uniform sampler2D TranslucencySampler;
layout(set = 0, binding = 6) uniform sampler2D OpacitySampler;
layout(scalar, set = 1, binding = 0) readonly buffer Lights {
Light lights[];
@ -32,6 +35,7 @@ layout(scalar, set = 2, binding = 0) uniform SceneInfo {
float ambientLightIntensity;
vec3 ambientLightColor;
uint numLights;
mat4 viewMatrix;
} sceneInfo;
float distributionGGX(vec3 N, vec3 H, float roughness) {
@ -126,6 +130,10 @@ void main() {
vec3 normal = texture(normalsSampler, inTextCoord).rgb;
vec3 worldPos = texture(posSampler, inTextCoord).rgb;
vec3 pbr = texture(pbrSampler, inTextCoord).rgb;
vec3 emissive = texture(emissiveSampler, inTextCoord).rgb;
vec3 translucency = texture(TranslucencySampler, inTextCoord).rgb;
float emissiveness = emissive.r;
float roughness = pbr.g;
float metallic = pbr.b;
@ -146,9 +154,9 @@ void main() {
}
}
vec3 ambient = sceneInfo.ambientLightColor * albedo * sceneInfo.ambientLightIntensity;
vec3 color = ambient + Lo;
outFragColor = vec4(Lo + ambient + vec3(emissiveness), 1.0f);
outFragColor = vec4(color, 1.0f);
// outFragColor = vec4(color, 1.0f);
if (length(normal) < 0.001) {
outFragColor = vec4(albedo,1.0f);
return;

View file

@ -27,7 +27,11 @@ 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(set = 0, binding = 4) uniform sampler2D emissiveSampler;
layout(set = 0, binding = 5) uniform sampler2D TranslucencySampler;
layout(set = 0, binding = 6) uniform sampler2D OpacitySampler;
layout(set = 0, binding = 7) uniform sampler2DArray shadowSampler;
layout(scalar, set = 1, binding = 0) readonly buffer Lights {
Light lights[];
@ -62,7 +66,7 @@ float chebyshevUpperBound(vec2 moments, float t) {
return p_max;
}
float calcVisibility(vec4 worldPosition, uint cascadeIndex) {
float calcVisibility(vec4 worldPosition, uint cascadeIndex, float ShadowBias) {
vec4 shadowMapPosition = shadows.cascadeshadows[cascadeIndex].projViewMatrix * worldPosition;
shadowMapPosition.xyz /= shadowMapPosition.w;
@ -76,14 +80,25 @@ float calcVisibility(vec4 worldPosition, uint cascadeIndex) {
if (uv.x < 0.0 || uv.x > 1.0 ||
uv.y < 0.0 || uv.y > 1.0 ||
depth < 0.0 || depth > 1.0) {
depth < ShadowBias || depth > 1.0) {
return 1.0;
}
vec2 moments = texture(shadowSampler, vec3(uv, cascadeIndex)).rg;
float shadow = 0.0;
vec2 texelSize = 1.0 / textureSize(shadowSampler, 0).rg;
for(int x = -1; x <= 1; ++x)
{
for(int y = -1; y <= 1; ++y)
{
vec2 moments = texture(shadowSampler, vec3((uv + vec2(x, y) * texelSize), cascadeIndex)).rg;
float visibility = chebyshevUpperBound(moments, depth);
return visibility;
shadow += depth - ShadowBias > visibility ? 1.0 : 0.0;
}
}
shadow /= 9.0;
return 1 - shadow;
}
float distributionGGX(vec3 N, vec3 H, float roughness) {
@ -150,7 +165,7 @@ vec3 calculatePointLight(Light light, vec3 worldPos, vec3 V, vec3 N, vec3 F0, ve
return (kD * albedo / PI + specular) * radiance * NdotL;
}
vec3 calculateDirectionalLight(Light light, vec3 V, vec3 N, vec3 F0, vec3 albedo, float metallic, float roughness) {
vec3 calculateDirectionalLight(Light light, vec3 V, vec3 N, vec3 F0, vec3 albedo, float metallic, float roughness, float translucency) {
vec3 L = normalize(-light.position);
vec3 H = normalize(V + L);
@ -170,7 +185,9 @@ vec3 calculateDirectionalLight(Light light, vec3 V, vec3 N, vec3 F0, vec3 albedo
kD *= 1.0 - metallic;
float NdotL = max(dot(N, L), 0.0);
return (kD * albedo / PI + specular) * radiance * NdotL;
vec3 shadowValue = (kD * albedo / PI + specular) * radiance * NdotL;
vec3 lightValue = (kD * albedo / PI + specular) * radiance;
return (shadowValue * (1 - translucency)) + (lightValue * translucency);
}
void main() {
@ -179,6 +196,20 @@ void main() {
vec4 worldPosW = texture(posSampler, inTextCoord);
vec3 worldPos = worldPosW.xyz;
vec3 pbr = texture(pbrSampler, inTextCoord).rgb;
vec3 emissive = texture(emissiveSampler, inTextCoord).rgb;
vec3 Opacity = texture(OpacitySampler, inTextCoord).rgb;
vec3 translucency = texture(TranslucencySampler, inTextCoord).rgb;
float emissiveness = emissive.r;
float translucencyf = translucency.r;
// outFragColor = vec4(emissive,1);
// return;
float ShadowBias = 0.05f;
float opacityf = Opacity.x + Opacity.y + Opacity.z;
opacityf = opacityf/3.0;
float roughness = pbr.g;
float metallic = pbr.b;
@ -186,6 +217,8 @@ void main() {
vec3 N = normalize(normal);
vec3 V = normalize(sceneInfo.camPos - worldPos);
vec3 F0 = vec3(0.04);
F0 = mix(F0, albedo, metallic);
@ -196,18 +229,19 @@ void main() {
cascadeIndex = i + 1;
}
}
float shadow = calcVisibility(vec4(worldPos, 1), cascadeIndex);
float shadow = calcVisibility(vec4(worldPos, 1), cascadeIndex,ShadowBias);
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;
Lo += calculateDirectionalLight(light, V, N, F0, albedo, metallic, roughness,translucencyf) * shadow;
} else {
Lo += calculatePointLight(light, worldPos, V, N, F0, albedo, metallic, roughness);
}
}
vec3 ambient = sceneInfo.ambientLightColor * albedo * sceneInfo.ambientLightIntensity;
if(emissive.x > 0 || emissive.y > 0 || emissive.z > 0) ambient = emissive;
outFragColor = vec4(Lo + ambient, 1.0f);
if (DEBUG_SHADOWS == 1) {

View file

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

View file

@ -10,17 +10,25 @@ layout(location = 4) in vec2 inTextCoords;
layout(location = 0) out vec4 outAlbedo;
struct Material {
vec4 diffuseColor;
uint hasTexture;
uint textureIdx;
uint hasNormalMap;
uint normalMapIdx;
uint hasRoughMap;
uint roughMapIdx;
float roughnessFactor;
float metallicFactor;
vec4 diffuseColor; //16
uint hasTexture; //20
uint textureIdx; //24
uint hasNormalMap; //28
uint normalMapIdx; //32
uint hasRoughMap; //36
uint roughMapIdx; //40
float roughnessFactor; //44
float metallicFactor; //48
vec4 emissiveColour; //64
uint hasEmissiveMap; //68
uint emissiveMapIdx; //72
uint hasTranslucencyMap; //76
uint translucencyMapIdx; //80
float translucencyFactor; //84
uint hasOpacityMap; //88
uint OpacityMapIdx; //92
float OpacityFactor; //96
};
layout(set = 2, binding = 0) readonly buffer MaterialUniform{
@ -36,13 +44,23 @@ layout(push_constant) uniform pc{
void main()
{
Material material = matUniform.materials[push_constants.materialIdx];
if(material.hasTexture == 1){
vec4 texColor = texture(textSampler[material.textureIdx],inTextCoords);
if(texColor.a < 0.4){discard;}
outAlbedo = texColor;
} else{
outAlbedo = material.diffuseColor;
}
vec4 Opacity = vec4(outAlbedo.a,outAlbedo.a,outAlbedo.a,1);
if(material.OpacityFactor != 1) Opacity = vec4(material.OpacityFactor, material.OpacityFactor, material.OpacityFactor, 1);
if(material.hasOpacityMap > 0 && material.OpacityMapIdx < MAX_TEXTURES){
Opacity = texture(textSampler[material.OpacityMapIdx], inTextCoords);
}
float opacityf = Opacity.x + Opacity.y + Opacity.z;
opacityf = opacityf/3;
if(opacityf < 0.4){discard;}
outAlbedo = vec4(outAlbedo.rgb, opacityf);
}

View file

@ -12,17 +12,29 @@ layout(location = 1) out vec4 outAlbedo ;
layout(location = 0) out vec4 outPos;
layout(location = 2) out vec4 outNormal;
layout(location = 3) out vec4 outPBR;
layout(location = 4) out vec4 outEmissive;
layout(location = 5) out vec4 outTranslucency;
layout(location = 6) out vec4 outOpacity;
struct Material {
vec4 diffuseColor;
uint hasTexture;
uint textureIdx;
uint hasNormalMap;
uint normalMapIdx;
uint hasRoughMap;
uint roughMapIdx;
float roughnessFactor;
float metallicFactor;
vec4 diffuseColor; //16
uint hasTexture; //20
uint textureIdx; //24
uint hasNormalMap; //28
uint normalMapIdx; //32
uint hasRoughMap; //36
uint roughMapIdx; //40
float roughnessFactor; //44
float metallicFactor; //48
vec4 emissiveColour; //64
uint hasEmissiveMap; //68
uint emissiveMapIdx; //72
uint hasTranslucencyMap; //76
uint translucencyMapIdx; //80
float translucencyFactor; //84
uint hasOpacityMap; //88
uint OpacityMapIdx; //92
float OpacityFactor; //96
};
layout(set = 2, binding = 0) readonly buffer MaterialUniform {
Material materials[];
@ -56,6 +68,17 @@ void main()
outAlbedo = material.diffuseColor;
}
vec4 Opacity = vec4(outAlbedo.a,outAlbedo.a,outAlbedo.a,1);
if(material.OpacityFactor != 1) Opacity = vec4(material.OpacityFactor, material.OpacityFactor, material.OpacityFactor, 1);
if(material.hasOpacityMap > 0 && material.OpacityMapIdx < MAX_TEXTURES){
Opacity = texture(textSampler[material.OpacityMapIdx], inTextCoords);
}
outOpacity = Opacity;
float opacityf = Opacity.x + Opacity.y + Opacity.z;
opacityf = opacityf/3;
outAlbedo = vec4(outAlbedo.rgb, opacityf);
if(outAlbedo.a < 0.5) discard;
@ -75,6 +98,18 @@ void main()
metallicFactor = material.metallicFactor;
}
vec4 emissive = material.emissiveColour;
if (material.hasEmissiveMap > 0 && material.emissiveMapIdx < MAX_TEXTURES) {
emissive = texture(textSampler[material.emissiveMapIdx], inTextCoords);
}
outEmissive = emissive;
vec4 Translucency = vec4(material.translucencyFactor,material.translucencyFactor,material.translucencyFactor,1);
if(material.hasTranslucencyMap > 0 && material.translucencyMapIdx < MAX_TEXTURES){
Translucency = texture(textSampler[material.translucencyMapIdx], inTextCoords);
}
outTranslucency = Translucency;
outPBR = vec4(ao, roughnessFactor, metallicFactor, 1.0f);
}

View file

@ -11,15 +11,24 @@ layout(location = 4) in vec2 inTextCoords;
layout(location = 0) out vec4 outAlbedo;
struct Material {
vec4 diffuseColor;
uint hasTexture;
uint textureIdx;
uint hasNormalMap;
uint normalMapIdx;
uint hasRoughMap;
uint roughMapIdx;
float roughnessFactor;
float metallicFactor;
vec4 diffuseColor; //16
uint hasTexture; //20
uint textureIdx; //24
uint hasNormalMap; //28
uint normalMapIdx; //32
uint hasRoughMap; //36
uint roughMapIdx; //40
float roughnessFactor; //44
float metallicFactor; //48
vec4 emissiveColour; //64
uint hasEmissiveMap; //68
uint emissiveMapIdx; //72
uint hasTranslucencyMap; //76
uint translucencyMapIdx; //80
float translucencyFactor; //84
uint hasOpacityMap; //88
uint OpacityMapIdx; //92
float OpacityFactor; //96
};
layout(set = 2, binding = 0) readonly buffer MaterialUniform{
@ -37,9 +46,18 @@ void main()
Material material = matUniform.materials[push_constants.materialIdx];
if(material.hasTexture == 1){
vec4 texColor = texture(textSampler[material.textureIdx],inTextCoords);
if(texColor.a < 0.9){discard;}
outAlbedo = texColor;
} else{
outAlbedo = material.diffuseColor;
}
vec4 Opacity = vec4(outAlbedo.a,outAlbedo.a,outAlbedo.a,1);
if(material.OpacityFactor != 1) Opacity = vec4(material.OpacityFactor, material.OpacityFactor, material.OpacityFactor, 1);
if(material.hasOpacityMap > 0 && material.OpacityMapIdx < MAX_TEXTURES){
Opacity = texture(textSampler[material.OpacityMapIdx], inTextCoords);
}
float opacityf = Opacity.x + Opacity.y + Opacity.z;
opacityf = opacityf/3;
if(opacityf < 0.9){discard;}
outAlbedo = vec4(outAlbedo.rgb, opacityf);
}

View file

@ -12,6 +12,9 @@ layout(location = 1) out vec4 outAlbedo ;
layout(location = 0) out vec4 outPos;
layout(location = 2) out vec4 outNormal;
layout(location = 3) out vec4 outPBR;
layout(location = 4) out vec4 outEmissive;
layout(location = 5) out vec4 outTranslucency;
layout(location = 6) out vec4 outOpacity;
const float bayerMatrix[16] = float[](
0.0 / 16.0, 8.0 / 16.0, 2.0 / 16.0, 10.0 / 16.0,
@ -21,15 +24,24 @@ const float bayerMatrix[16] = float[](
);
struct Material {
vec4 diffuseColor;
uint hasTexture;
uint textureIdx;
uint hasNormalMap;
uint normalMapIdx;
uint hasRoughMap;
uint roughMapIdx;
float roughnessFactor;
float metallicFactor;
vec4 diffuseColor; //16
uint hasTexture; //20
uint textureIdx; //24
uint hasNormalMap; //28
uint normalMapIdx; //32
uint hasRoughMap; //36
uint roughMapIdx; //40
float roughnessFactor; //44
float metallicFactor; //48
vec4 emissiveColour; //64
uint hasEmissiveMap; //68
uint emissiveMapIdx; //72
uint hasTranslucencyMap; //76
uint translucencyMapIdx; //80
float translucencyFactor; //84
uint hasOpacityMap; //88
uint OpacityMapIdx; //92
float OpacityFactor; //96
};
layout(set = 2, binding = 0) readonly buffer MaterialUniform {
Material materials[];
@ -67,6 +79,19 @@ void main()
int y = int(gl_FragCoord.y) % Intensity;
float threshold = bayerMatrix[y * Intensity + x];
if(outAlbedo.a < threshold || outAlbedo.a < 0.05f) discard;*/
vec4 Opacity = vec4(outAlbedo.a,outAlbedo.a,outAlbedo.a,1);
if(material.OpacityFactor != 1) Opacity = vec4(material.OpacityFactor, material.OpacityFactor, material.OpacityFactor, 1);
if(material.hasOpacityMap > 0 && material.OpacityMapIdx < MAX_TEXTURES){
Opacity = texture(textSampler[material.OpacityMapIdx], inTextCoords);
}
outOpacity = Opacity;
float opacityf = Opacity.x + Opacity.y + Opacity.z;
opacityf = opacityf/3;
outAlbedo = vec4(outAlbedo.rgb, opacityf);
if(outAlbedo.a < 0.75) discard;
@ -86,6 +111,18 @@ void main()
metallicFactor = material.metallicFactor;
}
vec4 emissive = material.emissiveColour;
if (material.hasEmissiveMap > 0 && material.emissiveMapIdx < MAX_TEXTURES) {
emissive = texture(textSampler[material.emissiveMapIdx], inTextCoords);
}
outEmissive = emissive;
vec4 Translucency = vec4(material.translucencyFactor,material.translucencyFactor,material.translucencyFactor,1);
if(material.hasTranslucencyMap > 0 && material.translucencyMapIdx < MAX_TEXTURES){
Translucency = texture(textSampler[material.translucencyMapIdx], inTextCoords);
}
outTranslucency = Translucency;
outPBR = vec4(ao, roughnessFactor, metallicFactor, outAlbedo.a);
}

View file

@ -10,18 +10,26 @@ layout(location = 4) in vec2 inTextCoords;
layout(location = 0) out vec4 outAlbedo;
struct Material{
vec4 diffuseColor;
uint hasTexture;
uint textureIdx;
uint hasNormalMap;
uint normalMapIdx;
uint hasRoughMap;
uint roughMapIdx;
float roughnessFactor;
float metallicFactor;
struct Material {
vec4 diffuseColor; //16
uint hasTexture; //20
uint textureIdx; //24
uint hasNormalMap; //28
uint normalMapIdx; //32
uint hasRoughMap; //36
uint roughMapIdx; //40
float roughnessFactor; //44
float metallicFactor; //48
vec4 emissiveColour; //64
uint hasEmissiveMap; //68
uint emissiveMapIdx; //72
uint hasTranslucencyMap; //76
uint translucencyMapIdx; //80
float translucencyFactor; //84
uint hasOpacityMap; //88
uint OpacityMapIdx; //92
float OpacityFactor; //96
};
layout(set = 2, binding = 0) readonly buffer MaterialUniform{
Material materials[];
} matUniform;
@ -37,9 +45,19 @@ void main()
Material material = matUniform.materials[push_constants.materialIdx];
if(material.hasTexture == 1){
vec4 texColor = texture(textSampler[material.textureIdx],inTextCoords);
if(texColor.a >= 0.9){discard;}
outAlbedo = texColor;
} else{
outAlbedo = material.diffuseColor;
}
vec4 Opacity = vec4(outAlbedo.a,outAlbedo.a,outAlbedo.a,1);
if(material.OpacityFactor != 1) Opacity = vec4(material.OpacityFactor, material.OpacityFactor, material.OpacityFactor, 1);
if(material.hasOpacityMap > 0 && material.OpacityMapIdx < MAX_TEXTURES){
Opacity = texture(textSampler[material.OpacityMapIdx], inTextCoords);
}
float opacityf = Opacity.x + Opacity.y + Opacity.z;
opacityf = opacityf/3;
if(opacityf >= 0.9){discard;}
outAlbedo = vec4(outAlbedo.rgb, opacityf);
}

View file

@ -12,6 +12,9 @@ layout(location = 1) out vec4 outAlbedo ;
layout(location = 0) out vec4 outPos;
layout(location = 2) out vec4 outNormal;
layout(location = 3) out vec4 outPBR;
layout(location = 4) out vec4 outEmissive;
layout(location = 5) out vec4 outTranslucency;
layout(location = 6) out vec4 outOpacity;
const float bayerMatrix[16] = float[](
0.0 / 16.0, 8.0 / 16.0, 2.0 / 16.0, 10.0 / 16.0,
@ -22,16 +25,26 @@ const float bayerMatrix[16] = float[](
struct Material {
vec4 diffuseColor;
uint hasTexture;
uint textureIdx;
uint hasNormalMap;
uint normalMapIdx;
uint hasRoughMap;
uint roughMapIdx;
float roughnessFactor;
float metallicFactor;
vec4 diffuseColor; //16
uint hasTexture; //20
uint textureIdx; //24
uint hasNormalMap; //28
uint normalMapIdx; //32
uint hasRoughMap; //36
uint roughMapIdx; //40
float roughnessFactor; //44
float metallicFactor; //48
vec4 emissiveColour; //64
uint hasEmissiveMap; //68
uint emissiveMapIdx; //72
uint hasTranslucencyMap; //76
uint translucencyMapIdx; //80
float translucencyFactor; //84
uint hasOpacityMap; //88
uint OpacityMapIdx; //92
float OpacityFactor; //96
};
layout(set = 2, binding = 0) readonly buffer MaterialUniform {
Material materials[];
} matUniform;
@ -64,6 +77,17 @@ void main()
outAlbedo = material.diffuseColor;
}
vec4 Opacity = vec4(outAlbedo.a,outAlbedo.a,outAlbedo.a,1);
if(material.OpacityFactor != 1) Opacity = vec4(material.OpacityFactor, material.OpacityFactor, material.OpacityFactor, 1);
if(material.hasOpacityMap > 0 && material.OpacityMapIdx < MAX_TEXTURES){
Opacity = texture(textSampler[material.OpacityMapIdx], inTextCoords);
}
outOpacity = Opacity;
float opacityf = Opacity.x + Opacity.y + Opacity.z;
opacityf = opacityf/3;
outAlbedo = vec4(outAlbedo.rgb, opacityf);
if(outAlbedo.a >= 0.75 || outAlbedo.a < 0.05f) discard;
@ -83,6 +107,18 @@ void main()
metallicFactor = material.metallicFactor;
}
vec4 emissive = material.emissiveColour;
if (material.hasEmissiveMap > 0 && material.emissiveMapIdx < MAX_TEXTURES) {
emissive = texture(textSampler[material.emissiveMapIdx], inTextCoords);
}
outEmissive = emissive;
vec4 Translucency = vec4(material.translucencyFactor,material.translucencyFactor,material.translucencyFactor,1);
if(material.hasTranslucencyMap > 0 && material.translucencyMapIdx < MAX_TEXTURES){
Translucency = texture(textSampler[material.translucencyMapIdx], inTextCoords);
}
outTranslucency = Translucency;
outPBR = vec4(ao, roughnessFactor, metallicFactor, outAlbedo.a);
}

View file

@ -9,17 +9,25 @@ 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;
vec4 diffuseColor; //16
uint hasTexture; //20
uint textureIdx; //24
uint hasNormalMap; //28
uint normalMapIdx; //32
uint hasRoughMap; //36
uint roughMapIdx; //40
float roughnessFactor; //44
float metallicFactor; //48
vec4 emissiveColour; //64
uint hasEmissiveMap; //68
uint emissiveMapIdx; //72
uint hasTranslucencyMap; //76
uint translucencyMapIdx; //80
float translucencyFactor; //84
uint hasOpacityMap; //88
uint OpacityMapIdx; //92
float OpacityFactor; //96
};
layout(set = 1, binding = 0) uniform sampler2D textSampler[MAX_TEXTURES];
layout(set = 2, binding = 0) readonly buffer MaterialUniform {
Material materials[];

View file

@ -12,18 +12,18 @@ 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];
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();
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();
}

View file

@ -7,5 +7,5 @@ layout(location = 1) out vec4 outColor;
layout(set = 2, binding = 0) uniform samplerCube skyboxSampler;
void main() {
outColor = texture(skyboxSampler, outTexCoords);// * vec4(0.0,0.05,0.1,1);
outColor = texture(skyboxSampler, outTexCoords) * vec4(0.0,0.05,0.1,1);
}

View file

@ -14,5 +14,5 @@ void main() {
outTexCoords = inPosition;
mat4 skyView = mat4(mat3(uboView.view));
vec4 pos = uboProj.proj * skyView * vec4(inPosition, 1.0);
gl_Position = vec4(pos.xy, pos.w, pos.w);
gl_Position = vec4(pos.xy, 0.0, pos.w);
}

View file

@ -45,6 +45,12 @@ public class OpenGLRenderer implements Renderer{
private GLCapabilities glCapabilities = null;
private SceneRender sceneRenderer = null;
private OpenGLGuiRenderer GuiRenderer;
private volatile boolean RebuildShadowsRequested = false;
@Override
public void RequestRebuildShadows() {
RebuildShadowsRequested = true;
}
public OpenGLGuiRenderer GetGuiRenderer(){return GuiRenderer;}
@ -108,6 +114,11 @@ public class OpenGLRenderer implements Renderer{
frameTimeNS = newFrameTimeNS;
}
@Override
public void RebuildShadows() {
}
public void Resize(int width, int height) {
GuiRenderer.Resize(width, height);
//sceneRenderer.Resize(width, height);

View file

@ -61,4 +61,8 @@ public interface Renderer {
public void ForwardRender(EngineInstance engineInstance);
public void render(EngineInstance engineInstance);
public void RebuildShadows();
public void RequestRebuildShadows();
}

View file

@ -55,7 +55,7 @@ public class VulkanRenderer implements Renderer {
private final LightRenderer lightRenderer;
private final PostProcess PostProcessor;
private final SwapChainRender swapChainRender;
private final ShadowRenderer shadowRender;
private ShadowRenderer shadowRender;
private final GuiRenderer GuiRender;
private int CurrentFrame;
private final VulkanContext RendererContext;
@ -68,6 +68,13 @@ public class VulkanRenderer implements Renderer {
private final boolean Deferred;
private float LastGamma = 0.8545f;
private volatile boolean RebuildShadowsRequested = false;
@Override
public void RequestRebuildShadows() {
RebuildShadowsRequested = true;
}
public TextureCache GetTextureCache(){return textureCache;}
public MaterialsCache GetMaterialsCache(){return materialsCache;}
@ -160,7 +167,7 @@ public class VulkanRenderer implements Renderer {
Logger.debug("Loaded {} models", Models.size());
sceneRender.LoadMaterials(RendererContext,materialsCache,textureCache);
shadowRender.loadMaterials(RendererContext, materialsCache, textureCache);
if(shadowRender != null) shadowRender.loadMaterials(RendererContext, materialsCache, textureCache);
spriteRenderer.CompileSprites(RendererContext,modelsCache, textureCache);
spriteRenderer.LoadMaterials(RendererContext,materialsCache,textureCache);
GuiRender.LoadTextures(RendererContext,initData.GuiTextures(),textureCache);
@ -213,15 +220,6 @@ public class VulkanRenderer implements Renderer {
var CommandPool = CommandPools[CurrentFrame];
var CommandBuffer = CommandBuffers[CurrentFrame];
RecordingStart(CommandPool, CommandBuffer);
sceneRender.Render(engineInstance,RendererContext,CommandBuffer, modelsCache,materialsCache,CurrentFrame);
shadowRender.render(engineInstance, RendererContext, CommandBuffer, modelsCache, materialsCache, CurrentFrame);
lightRenderer.render(engineInstance, RendererContext, CommandBuffer, sceneRender.GetMRTAttachments(), shadowRender.getShadowAttachment(), CurrentFrame,
shadowRender.getCascadeShadows(CurrentFrame));
PostProcessor.Render(RendererContext,CommandBuffer,lightRenderer.getAttachment());
spriteRenderer.Render(engineInstance,RendererContext,CommandBuffer,PostProcessor.GetAttachment(),modelsCache,CurrentFrame);
GuiRender.Render(RendererContext,CommandBuffer,CurrentFrame,PostProcessor.GetAttachment());
int ImageIndex;
if (Resize || (ImageIndex = swapChain.FetchNextImage(RendererContext.GetDevice(), PresentCompleteSemaphores[imageAcquisitionIndex])) < 0){
@ -229,6 +227,20 @@ public class VulkanRenderer implements Renderer {
return;
}
RecordingStart(CommandPool, CommandBuffer);
sceneRender.Render(engineInstance,RendererContext,CommandBuffer, modelsCache,materialsCache,CurrentFrame);
boolean RenderShadows = ShadowRenderer.AllowShadowRendering() && EngineConfig.getInstance().RenderShadows();
//lightRenderer.render(engineInstance, RendererContext, CommandBuffer, sceneRender.GetMRTAttachments(), shadowRender.getShadowAttachment(), CurrentFrame, shadowRender.getCascadeShadows(CurrentFrame));
if(RenderShadows) {
shadowRender.render(engineInstance, RendererContext, CommandBuffer, modelsCache, materialsCache, CurrentFrame);
lightRenderer.render(engineInstance, RendererContext, CommandBuffer, sceneRender.GetMRTAttachments(), shadowRender.getShadowAttachment(), CurrentFrame, shadowRender.getCascadeShadows(CurrentFrame));
} else lightRenderer.render(engineInstance, RendererContext, CommandBuffer, sceneRender.GetMRTAttachments(),CurrentFrame);
PostProcessor.Render(RendererContext,CommandBuffer,lightRenderer.getAttachment());
spriteRenderer.Render(engineInstance,RendererContext,CommandBuffer,PostProcessor.GetAttachment(),modelsCache,CurrentFrame);
GuiRender.Render(RendererContext,CommandBuffer,CurrentFrame,PostProcessor.GetAttachment());
swapChainRender.Render(RendererContext,CommandBuffer,PostProcessor.GetAttachment(),ImageIndex);
RecordingStop(CommandBuffer);
@ -243,12 +255,6 @@ public class VulkanRenderer implements Renderer {
WaitForFence(CurrentFrame); //problem child found
var CommandPool = CommandPools[CurrentFrame];
var CommandBuffer = CommandBuffers[CurrentFrame];
RecordingStart(CommandPool, CommandBuffer);
sceneRender.Render(engineInstance,RendererContext,CommandBuffer, modelsCache,materialsCache,CurrentFrame);
PostProcessor.Render(RendererContext,CommandBuffer,sceneRender.GetAttachmentColour());
spriteRenderer.Render(engineInstance,RendererContext,CommandBuffer,PostProcessor.GetAttachment(),modelsCache,CurrentFrame);
GuiRender.Render(RendererContext,CommandBuffer,CurrentFrame,PostProcessor.GetAttachment());
int ImageIndex;
if (Resize || (ImageIndex = swapChain.FetchNextImage(RendererContext.GetDevice(), PresentCompleteSemaphores[CurrentFrame])) < 0){
@ -256,6 +262,13 @@ public class VulkanRenderer implements Renderer {
return;
}
RecordingStart(CommandPool, CommandBuffer);
sceneRender.Render(engineInstance,RendererContext,CommandBuffer, modelsCache,materialsCache,CurrentFrame);
PostProcessor.Render(RendererContext,CommandBuffer,sceneRender.GetAttachmentColour());
spriteRenderer.Render(engineInstance,RendererContext,CommandBuffer,PostProcessor.GetAttachment(),modelsCache,CurrentFrame);
GuiRender.Render(RendererContext,CommandBuffer,CurrentFrame,PostProcessor.GetAttachment());
swapChainRender.Render(RendererContext,CommandBuffer,PostProcessor.GetAttachment(),ImageIndex);
RecordingStop(CommandBuffer);
@ -267,9 +280,35 @@ public class VulkanRenderer implements Renderer {
public void render(EngineInstance engineInstance){
if(! RenderThread.AllowRender()) return;
if (RebuildShadowsRequested) {
RebuildShadowsRequested = false;
RebuildShadows();
}
if(Deferred) DeferredRender(engineInstance);
else ForwardRender(engineInstance);
}
@Override
public void RebuildShadows() {
if (!Deferred || shadowRender == null || lightRenderer == null) {
return;
}
ShadowRenderer.AllowShadowRendering(false);
RendererContext.GetDevice().waitIdle();
shadowRender.RebuildPipelineAndRenderingAttachments(RendererContext);
List<Attachment> attachments = new ArrayList<>(sceneRender.GetMRTAttachments().GetColourAttachments());
attachments.add(shadowRender.getShadowAttachment());
lightRenderer.updateAttachmentDescriptors(RendererContext, attachments);
RendererContext.GetDevice().waitIdle();
ShadowRenderer.AllowShadowRendering(true);
}
private void resize(EngineInstance engineInstance){
Window window = engineInstance.window();
if(window.getWidth() == 0 && window.getHeight() == 0){

View file

@ -1,6 +1,7 @@
package net.halbear.Terrain4J.EngineCore.Logic;
import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DisplayToScreen.DeferredSceneRender;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DisplayToScreen.ForwardSceneRender;
import net.halbear.Terrain4J.EngineCore.ServerNetworking.ClientSideNetworkUtils;
@ -92,6 +93,16 @@ public class EngineConfig {
public float SoundVolume = 0.0f;
public float WeaponVolume = 0.0f;
public float AmbientVolume = 0.0f;
public float MaxShadowDistance = 16384.0f;
public float MaxShadowDistance(){return MaxShadowDistance;}
public void MaxShadowDistance(float newDistance){ MaxShadowDistance = newDistance;}
public boolean RenderShadows = true;
public boolean RenderShadows() {return RenderShadows;}
public void RenderShadows(boolean renderShadows) {RenderShadows = renderShadows;}
public float PlayerOnline = 1.0f;
@ -158,7 +169,12 @@ public class EngineConfig {
public String GetLoadingScreenImageLocation(){return LoadingScreenLocation;}
public void SetLoadingScreenImageLocation(String location){this.LoadingScreenLocation = location;}
public int GetMaxVulkanCrashes(){return MaxVulkanCrashesAllowed;}
public void SetShadowMapSize(int ShadowSize){this.ShadowMapSize = ShadowSize;}
public void SetShadowMapSize(int ShadowSize){
this.ShadowMapSize = ShadowSize;
if (PrimaryRuntime.GetRenderThread() != null && PrimaryRuntime.GetRenderThread().GetRenderer() != null) {
PrimaryRuntime.GetRenderThread().GetRenderer().RequestRebuildShadows();
}
}
public int GetShadowMapSize(){return ShadowMapSize;}
public void SetRenderer(Renderer renderer){this.renderer = renderer;}
public boolean DeferredRendering(){return renderer == Renderer.Deferred;}
@ -320,9 +336,11 @@ public class EngineConfig {
FOV = (float)(DegToRad * Float.parseFloat(EngineConfigVar.getOrDefault("field_of_view", 60.0f).toString()));
zNearPlane = (Float.parseFloat(EngineConfigVar.getOrDefault("z_near_plane", 1.0f).toString()));
zFarPlane = (Float.parseFloat(EngineConfigVar.getOrDefault("z_far_plane", 100.0f).toString()));
MaxShadowDistance = (Float.parseFloat(EngineConfigVar.getOrDefault("max_shadow_distance", 16384.0f).toString()));
AAValue = (Integer.parseInt(EngineConfigVar.getOrDefault("anti_alias_mode", 1).toString()));
renderer = Integer.parseInt(EngineConfigVar.getOrDefault("Renderer", 1).toString()) == 0 ? Renderer.Forward: Renderer.Deferred;
ShadowMapSize = Integer.parseInt(EngineConfigVar.getOrDefault("ShadowMapSize", 4096).toString());
ShadowMapSize = Integer.parseInt(EngineConfigVar.getOrDefault("ShadowMapSize", 2048).toString());
RenderShadows = Boolean.parseBoolean(EngineConfigVar.getOrDefault("RenderShadows", true).toString());
MaxVulkanCrashesAllowed = Integer.parseInt(EngineConfigVar.getOrDefault("MaxAllowedVulkanCrashes", 10).toString());
ServerPort = Integer.parseInt(EngineConfigVar.getOrDefault("server_port", 25565).toString());
CompatibilityMode = Boolean.parseBoolean(EngineConfigVar.getOrDefault("compatibility_mode", false).toString());
@ -377,6 +395,7 @@ public class EngineConfig {
EngineConfigVar.setProperty("ShaderRecompiling","true");
EngineConfigVar.setProperty("throttle_accuracy","100000");
EngineConfigVar.setProperty("throttle_on_unfocus","true");
EngineConfigVar.setProperty("RenderShadows","true");
EngineConfigVar.setProperty("field_of_view","60");
EngineConfigVar.setProperty("z_near_plane","1");
EngineConfigVar.setProperty("z_far_plane","100");
@ -384,6 +403,7 @@ public class EngineConfig {
EngineConfigVar.setProperty("DefaultTexturePath",DefaultTexturePath);
EngineConfigVar.setProperty("MaxDescriptors","1000");
EngineConfigVar.setProperty("anti_alias_mode","1");
EngineConfigVar.setProperty("max_shadow_distance","16384");
EngineConfigVar.setProperty("server","false");
EngineConfigVar.setProperty("ShadowMapSize","4096");
EngineConfigVar.setProperty("LoadingScreenLocation",LoadingScreenLocation);

View file

@ -15,7 +15,6 @@ overlap (least "penetration" or intersection amount) is the collision normal,
face contacts are "resolved into a full contact manifold"(whatever that means) by clipping the incident face
against the side planes of the reference face, this is what gives stable multipoint contact (e.g. a box resting flat on a floor gets 4 contact points, not 1)
I'm not gonna lie, I asked Google AI Overview for help on this one, and it did NOT help, but it *did* provide some pretty useful information on how to do it
For a good explanation, visit this https://dyn4j.org/2010/01/sat/*/
public class SeparatingAxisTheoremTester {

View file

@ -82,6 +82,7 @@ public class WorldPhysicsManager {
SweepForTunneling();
ResetGroundedFlags();
ResolveAllCollisions();
SyncRigidBodiesToActors();
Accumulator -= FixedTimeStep;
stepsRun++;
}
@ -117,23 +118,6 @@ public class WorldPhysicsManager {
Set<String> testedPairs = new HashSet<>();
// SpatialHashGrid.Cells().forEach((key, bucket)->{
// int size = bucket.size();
// for (int i = 0; i < size; i++) {
// RigidBody a = RigidBody.RigidBodyRegister.get(bucket.get(i));
// if (a == null) continue;
// for (int j = i + 1; j < size; j++) {
// RigidBody b = RigidBody.RigidBodyRegister.get(bucket.get(j));
// if (b == null || a == b) continue;
// TryResolve(a, b, worldBounds, testedPairs);
// }
// StaticSpatialHashGrid.GetFromKey(key).forEach((id)->{
// RigidBody b = RigidBody.RigidBodyRegister.get(id);
// if (b == null || a == b) return;
// TryResolve(a, b, worldBounds, testedPairs);
// });
// }
// });
for (List<String> bucket : SpatialHashGrid.Buckets()) {
int size = bucket.size();
for (int i = 0; i < size; i++) {
@ -152,6 +136,7 @@ public class WorldPhysicsManager {
TryResolve(dyn, stat, worldBounds, testedPairs);
}
}
}
private static boolean IsClientRemoteNetworkBody(RigidBody body) {

View file

@ -32,8 +32,7 @@ import static org.lwjgl.assimp.Assimp.*;
public class ModelCompiler {
private static final Pattern EMBED_TEXT_ID = Pattern.compile("\\*([0-9)]+)");
private static final int FLAGS = aiProcess_GenSmoothNormals | aiProcess_JoinIdenticalVertices
| aiProcess_Triangulate | aiProcess_FixInfacingNormals | aiProcess_CalcTangentSpace
| aiProcess_PreTransformVertices;
| aiProcess_Triangulate | aiProcess_CalcTangentSpace | aiProcess_PreTransformVertices;
@Parameter(names = "-model", description = "Model Path", required = true)
private String ModelPath;
@ -108,14 +107,23 @@ public class ModelCompiler {
public static MaterialData ProcessMaterial(AIScene aiScene, AIMaterial aiMaterial, String ModelName, String BaseDirectory, int Position) throws IOException{
Vector4f diffuse = new Vector4f();
AIColor4D colour = AIColor4D.create();
AIColor4D emissive_colour = AIColor4D.create();
int Result = aiGetMaterialColor(aiMaterial, AI_MATKEY_COLOR_DIFFUSE, aiTextureType_NONE, 0, colour);
if(Result == aiReturn_SUCCESS){
diffuse.set(colour.r(), colour.g(), colour.b(), colour.a());
}
Vector4f emissiveColour = new Vector4f(1,1,1,0);
Result = aiGetMaterialColor(aiMaterial, AI_MATKEY_COLOR_EMISSIVE, aiTextureType_NONE, 0, emissive_colour);
if(Result == aiReturn_SUCCESS){
emissiveColour.set(emissive_colour.r(), emissive_colour.g(), emissive_colour.b(), emissive_colour.a());
}
String DiffuseTexture = ProcessTexture(aiScene,aiMaterial,BaseDirectory,aiTextureType_DIFFUSE);
String NormalTexture = ProcessTexture(aiScene,aiMaterial,BaseDirectory,aiTextureType_NORMALS);
String EmissiveTexture = ProcessTexture(aiScene,aiMaterial,BaseDirectory,aiTextureType_EMISSIVE);
String TranslucencyTexture = ProcessTexture(aiScene,aiMaterial,BaseDirectory,aiTextureType_TRANSMISSION);
String MetallicRoughTexture = ProcessTexture(aiScene, aiMaterial, BaseDirectory, AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLICROUGHNESS_TEXTURE);
String OpacityTexture = ProcessTexture(aiScene,aiMaterial,BaseDirectory,aiTextureType_OPACITY);
float[] MetallicArray = new float[]{0.0f};
int[] MaxPointer = new int[]{1};
@ -130,8 +138,26 @@ public class ModelCompiler {
RoughnessArray = new float[]{0.0f};
}
float[] EmissiveArray = new float[]{0.0f};
Result = aiGetMaterialFloatArray(aiMaterial,AI_MATKEY_EMISSIVE_INTENSITY,aiTextureType_NONE,0,EmissiveArray,MaxPointer);
if(Result == aiReturn_SUCCESS){
emissiveColour.set(emissiveColour.x,emissiveColour.y,emissiveColour.z,EmissiveArray[0]);
}
return new MaterialData(ModelName + "-mat-" + Position,DiffuseTexture,NormalTexture, MetallicRoughTexture,diffuse,RoughnessArray[0],MetallicArray[0]);
float[] TranslucencyArray = new float[]{0.0f};
Result = aiGetMaterialFloatArray(aiMaterial,AI_MATKEY_TRANSMISSION_FACTOR,aiTextureType_NONE,0,TranslucencyArray,MaxPointer);
if(Result != aiReturn_SUCCESS){
TranslucencyArray = new float[]{0.0f};
}
float[] OpacityArray = new float[]{0.0f};
Result = aiGetMaterialFloatArray(aiMaterial,AI_MATKEY_OPACITY,aiTextureType_NONE,0,OpacityArray,MaxPointer);
if(Result != aiReturn_SUCCESS){
OpacityArray = new float[]{0.0f};
}
return new MaterialData(ModelName + "-mat-" + Position,DiffuseTexture,NormalTexture, MetallicRoughTexture,diffuse,RoughnessArray[0],MetallicArray[0], EmissiveTexture,emissiveColour, TranslucencyTexture, TranslucencyArray[0], OpacityTexture, OpacityArray[0]);
}
public static MeshData ProcessMesh(AIMesh aiMesh, List<MaterialData> MaterialList, int MeshPosition, ModelBinaryData BinaryData) throws IOException {

View file

@ -99,12 +99,12 @@ public class GameCore implements GameLogic {
Scene scene = (Scene) engineInstance.scene();
List<ModelData> models = new ArrayList<>();
List<MaterialData> materials = new ArrayList<>();
// ModelData SponzaData = ModelLoader.LoadModel("resources/models/Cafe/exterior.json");
// List<MaterialData> SponzaMaterial = ModelLoader.LoadMaterials("resources/models/Cafe/exterior_mat.json");
// ModelData SponzaData1 = ModelLoader.LoadModel("resources/models/Cafe/interior.json");
// List<MaterialData> SponzaMaterial1= ModelLoader.LoadMaterials("resources/models/Cafe/interior_mat.json");
// scene.AddActor(new Actor3D("Sponza1", SponzaData.ID(), new Vector3f(0,0f,-5f)).SetScale(0.1f));
// scene.AddActor(new Actor3D("Sponza2", SponzaData1.ID(), new Vector3f(0,0f,-5f)).SetScale(0.1f));
ModelData SponzaData = ModelLoader.LoadModel("resources/models/Cafe/exterior.json");
List<MaterialData> SponzaMaterial = ModelLoader.LoadMaterials("resources/models/Cafe/exterior_mat.json");
ModelData SponzaData1 = ModelLoader.LoadModel("resources/models/Cafe/interior.json");
List<MaterialData> SponzaMaterial1= ModelLoader.LoadMaterials("resources/models/Cafe/interior_mat.json");
scene.AddActor(new Actor3D("Sponza1", SponzaData.ID(), new Vector3f(0,0f,-5f)).SetScale(0.1f));
scene.AddActor(new Actor3D("Sponza2", SponzaData1.ID(), new Vector3f(0,0f,-5f)).SetScale(0.1f));
// ModelData treeModel = ModelLoader.LoadModel("resources/models/tree/tree.json");
// models.add(treeModel);
// Actor3D treeEntity = new Actor3D("treeEntity", treeModel.ID(), new Vector3f(0.0f, 0.0f, 0.0f));
@ -113,7 +113,7 @@ public class GameCore implements GameLogic {
// 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));
// Actor3D treeEntity = new Actor3D("treeEntity", treeModel.ID(), new Vector3f(0.0f, -100.0f, 0.0f));
// treeEntity.SetScale(10f);
// scene.AddActor(treeEntity);
// materials.addAll(ModelLoader.LoadMaterials("resources/models/Forest/forest_mat.json"));
@ -158,10 +158,10 @@ public class GameCore implements GameLogic {
}
boolean createOfflinePlayer = !PrimaryRuntime.IsServer && !ClientSideNetworkUtils.Connected;
// materials.addAll(SponzaMaterial);
// materials.addAll(SponzaMaterial1);
// models.add(SponzaData);
// models.add(SponzaData1);
materials.addAll(SponzaMaterial);
materials.addAll(SponzaMaterial1);
models.add(SponzaData);
models.add(SponzaData1);
materials.addAll(MelonaMat);
materials.addAll(CollisionVisualisationMat);
materials.addAll(MelonaMaterial);
@ -191,49 +191,68 @@ public class GameCore implements GameLogic {
}
scene.GetLightingManager().GetAmbientLightColour().set(1.0f, 0.9f, 0.75f);
scene.GetLightingManager().SetAmbientLightIntensity(0.3f);
// scene.GetLightingManager().GetAmbientLightColour().set(0.3f, 0.35f, 0.5f);
// scene.GetLightingManager().SetAmbientLightIntensity(0.075f);
//
SkyLight = new Light(new Vector3f(1.5f, 1.20f, 1.0f),new Vector3f(0.0f, -1.0f, 0.3f), true, 2.00f);
// SkyLight = new Light(new Vector3f(0.25f, 1.0f, 1.5f),new Vector3f(0.0f, -1.0f, 0.0f), true, 6.0f);
scene.GetLightingManager().SetAmbientLightIntensity(0.15f);
scene.GetLightingManager().GetAmbientLightColour().set(0.3f, 0.35f, 0.5f);
scene.GetLightingManager().SetAmbientLightIntensity(0.05f);
SkyLight = new Light(new Vector3f(1.5f, 1.20f, 1.0f),new Vector3f(0.0f, -1.0f, 0.3f), true, 4.00f);
SkyLight = new Light(new Vector3f(0.25f, 0.75f, 1.3f),new Vector3f(0.0f, -1.0f, 0.0f), true, 4.0f);
SkyLight.SetType(Light.LightType.Directional);
List<ILight> lights = new ArrayList<>();
// lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-433, 445f, -424f).div(10.0f),false,3000.0f+ (float)(Math.random() * 100.0)));
// lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-210, 445f, 460f).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
// lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-966, 445f, 204f).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
// lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-176, 445f, 1000f).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
// lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(777, 445f, 858).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
// lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(376, 445f, -2136).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
// lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,2.0f),new Vector3f(2163, 445f, 1880).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
// lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(3334, 445f, 2405).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
// lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(3509, 445f, 1825).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
// lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(3877, 445f, 3378).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
// lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(4925, 445f, 3430).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
// lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-2083, 445f, -1826).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
//
// lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(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(-433, 445f, -424f).div(10.0f),false,3000.0f+ (float)(Math.random() * 100.0)));
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-210, 445f, 460f).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-966, 445f, 204f).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-176, 445f, 1000f).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(777, 445f, 858).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(376, 445f, -2136).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,2.0f),new Vector3f(2163, 445f, 1880).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(3334, 445f, 2405).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(3509, 445f, 1825).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(3877, 445f, 3378).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(4925, 445f, 3430).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-2083, 445f, -1826).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
//lights.add(new Light(new Vector3f(3.0f,2.25f,0.0f),new Vector3f(350.0f, 1525.0f, -420.0f),false,4000.0f));
//lights.add(new Light(new Vector3f(3.0f,2.25f,0.0f),new Vector3f(400.0f, 1570.0f, -350.0f),false,1000.0f));
lights.add(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(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(615.8f, 305.5f, -904.1f).div(10.0f),false,200.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(425.4f, 305.5f, -541.0f).div(10.0f),false,200.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(501.4f, 305.5f, -102.7f).div(10.0f),false,200.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(803.0f, 305.5f, 50.2f).div(10.0f),false,200.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(720.4f, 261.6f, -329.2f).div(10.0f),false,75.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(879.4f,261.6f,-246.3f).div(10.0f),false,75.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(1037.7f,261.6f,-155.0f).div(10.0f),false,75.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(663.4f,261.6f,-468.9f).div(10.0f),false,75.0f));
lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(772.3f,243.7f,-513.7f).div(10.0f),false,50.0f));
lights.add(new Light(new Vector3f(1.2f + (float)Math.random(),1.1f,1.0f),new Vector3f(193.1f,260.7f,-859.3f).div(10.0f),false,50.0f));
lights.add(new Light(new Vector3f(1.2f + (float)Math.random(),1.1f,1.0f),new Vector3f(51.0f,260.7f,-603.0f).div(10.0f),false,50.0f));
lights.add(new Light(new Vector3f(1.2f + (float)Math.random(),1.1f,1.0f),new Vector3f(-95.0f,260.7f,-334.2f).div(10.0f),false,50.0f));
lights.add(new Light(new Vector3f(1.2f + (float)Math.random(),1.1f,1.0f),new Vector3f(41.5f,260.7f,5.7f).div(10.0f),false,50.0f));
lights.add(new Light(new Vector3f(1.2f + (float)Math.random(),1.1f,1.0f),new Vector3f(335.8f,260.7f,144.6f).div(10.0f),false,50.0f));
lights.add(new Light(new Vector3f(1.2f + (float)Math.random(),1.1f,1.0f),new Vector3f(616.9f,260.7f,255.4f).div(10.0f),false,50.0f));
lights.add(new Light(new Vector3f(0.75f,2.0f,0.75f),new Vector3f(1086, 425, -3375).div(10.0f),false,500.0f));
// lights.add(new Light(new Vector3f(3.0f,2.25f,0.0f),new Vector3f(350.0f, 1500.0f, -420.0f),false,10000.0f));
// lights.add(new Light(new Vector3f(3.0f,2.25f,0.0f),new Vector3f(400.0f, 1550.0f, -350.0f),false,10000.0f));
lights.add(SkyLight);
ILight[] lightArr = new ILight[lights.size()];
@ -246,27 +265,29 @@ public class GameCore implements GameLogic {
}
//if(PrimaryRuntime.IsServer) {
permutation.GeneratePermutationArray(5783904701859L);
for(int x = -1; x < 2; x++){
for(int y = -1; y < 2; y++){
GenerateChunk(new Vector3i(x, 0, y), 16);
}
}
for(int i = 0; i < 20; i++){
SpawnNewActor(engineInstance, new Vector3f(-5 + (float)Math.random() * 10,10 + (float)Math.random() * 10, -5 + (float)Math.random() * 10), new Vector3f(0, 0, 0), new Vector3f(1, 1, 1));
}
// for(int x = -1; x < 2; x++){
// for(int y = -1; y < 2; y++){
// GenerateChunk(new Vector3i(x, 0, y), 16);
//
// }
// }
// for(int i = 0; i < 20; i++){
// SpawnNewActor(engineInstance, new Vector3f(-5 + (float)Math.random() * 10,10 + (float)Math.random() * 10, -5 + (float)Math.random() * 10), new Vector3f(0, 0, 0), new Vector3f(1, 1, 1));
// }
//}
Settings.textBuffer.set(ClientSideNetworkUtils.ServerIP);
Settings.UsernameBuffer.set("Player");
return new InitData(models,materials,guiTextures);
}
public static float lightAngle = 70;
public static float lightAnglex = 0;
private void updateDirLight() {
float zValue = (float) Math.cos(Math.toRadians(lightAngle));
float zValue = (float) Math.cos(Math.toRadians(lightAngle)) + (float) Math.cos(Math.toRadians(lightAnglex));
float yValue = (float) Math.sin(Math.toRadians(lightAngle));
float xValue = (float) Math.sin(Math.toRadians(lightAnglex));
Vector3f lightDirection = SkyLight.GetPosition();
lightDirection.x = 0;
lightDirection.x = xValue;
lightDirection.y = yValue;
lightDirection.z = zValue;
lightDirection.normalize();
@ -502,6 +523,8 @@ public class GameCore implements GameLogic {
}
}
int GUI_MODE = 1;
@Override
public void Input(EngineInstance engineInstance, long FrameDiffNanoSeconds) {
if(PrimaryRuntime.IsServer || RenderThread.Headless) return;
@ -510,7 +533,7 @@ public class GameCore implements GameLogic {
scene.GlobalInput(engineInstance,FrameDiffNanoSeconds, null, MOVEMENT_SPEED,this);
KeyboardInput input = engineInstance.window().getKeyboardInput();
if(input.keySinglePress(GLFW_KEY_F3)){
Scene.GUI_MODE = (Scene.GUI_MODE + 1) % 2;
GUI_MODE = (GUI_MODE + 1) % 3;
}
if(input.keyPressed(GLFW_KEY_UP)){
lightAngle = (lightAngle + 0.5f) % 360;
@ -520,6 +543,14 @@ public class GameCore implements GameLogic {
lightAngle = (lightAngle - 0.5f) % 360;
updateDirLight();
}
if(input.keyPressed(GLFW_KEY_RIGHT)){
lightAnglex = (lightAnglex + 0.5f) % 360;
updateDirLight();
}
if(input.keyPressed(GLFW_KEY_LEFT)){
lightAnglex = (lightAnglex - 0.5f) % 360;
updateDirLight();
}
if (input.keySinglePress(GLFW_KEY_ESCAPE)) {
StartMenuActive = !StartMenuActive;
StartMenu.GameStarted = StartMenuActive;
@ -587,7 +618,7 @@ public class GameCore implements GameLogic {
StartMenuActive = false;
}
} else {
engineInstance.scene().RenderGUIs(engineInstance, frameTimeNS, this);
if(GUI_MODE == 1)engineInstance.scene().RenderGUIs(engineInstance, frameTimeNS, this);
if (ChangeGraphicsSettings) {
ImGuiViewport viewport = ImGui.getMainViewport();
float CenterX = viewport.getWorkPosX() + viewport.getWorkSizeX() / 2.0f;

View file

@ -6,6 +6,7 @@ import imgui.flag.ImGuiWindowFlags;
import imgui.type.ImFloat;
import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig;
import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance;
import net.halbear.Terrain4J.EngineCore.Main.AudioInstance;
import net.halbear.Terrain4J.EngineCore.Main.GameCore;
import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime;
import net.halbear.Terrain4J.EngineCore.Main.Scene.GUIOverlay;
@ -15,6 +16,14 @@ import org.tinylog.Logger;
public class PerformanceOverlay implements GUIOverlay {
private final ImFloat GammaValue = new ImFloat(0.8545f);
public int[] ShadowSize = new int[]{4096};
public int[] ShadowDistance = new int[]{1000};
public PerformanceOverlay(){
ShadowSize[0] = EngineConfig.getInstance().GetShadowMapSize();
ShadowDistance[0] = (int)EngineConfig.getInstance().MaxShadowDistance();
}
@Override
public void RenderGUI(EngineInstance engineInstance, long frameTimeNS, GameCore parent) {
int windowFlags = ImGuiWindowFlags.NoDecoration
@ -48,35 +57,111 @@ public class PerformanceOverlay implements GUIOverlay {
EngineConfig.getInstance().SetRenderingAPI(EngineConfig.RenderAPI.OpenGL);
}
ImGui.text("Presets:");
float ZFarPlane = Math.max(EngineConfig.getInstance().GetZFarPlane(), EngineConfig.getInstance().GetZNearPlane());
if(ImGui.button("Lowest")){
parent.ChangeGraphicsSettings = true;
parent.CoolDown = 2000;
parent.NextAAMode = (0);
ForwardSceneRender.SetDualPassRendering(false);
DeferredSceneRender.SetDualPassRendering(false);
EngineConfig.getInstance().SetRenderer(EngineConfig.Renderer.Forward);
EngineConfig.getInstance().RenderShadows(false);
EngineConfig.getInstance().SetAlphaToCoverage(false);
EngineConfig.getInstance().SetShadowMapSize(1);
EngineConfig.getInstance().MaxShadowDistance(64);
ShadowDistance[0] = (int)Math.clamp(EngineConfig.getInstance().MaxShadowDistance(), 64, (int)(ZFarPlane * 1.5));
ShadowSize[0] = (int)Math.clamp((EngineConfig.getInstance().GetShadowMapSize() / 16) * 16, 16, 8192);
if(engineInstance.window().GetLinkedApi() == EngineConfig.RenderAPI.Vulkan)PrimaryRuntime.GetRenderThread().GetRenderer().GetSceneRender().RebuildPipelines(PrimaryRuntime.GetRenderThread().GetRenderer().GetVulkanContext());
}
ImGui.sameLine();
if(ImGui.button("Low")){
parent.ChangeGraphicsSettings = true;
parent.CoolDown = 2000;
parent.NextAAMode = (0);
ForwardSceneRender.SetDualPassRendering(false);
DeferredSceneRender.SetDualPassRendering(false);
EngineConfig.getInstance().SetRenderer(EngineConfig.Renderer.Deferred);
EngineConfig.getInstance().RenderShadows(true);
EngineConfig.getInstance().SetAlphaToCoverage(false);
EngineConfig.getInstance().SetShadowMapSize(256);
EngineConfig.getInstance().MaxShadowDistance((int)(ZFarPlane/4));
ShadowDistance[0] = (int)Math.clamp(EngineConfig.getInstance().MaxShadowDistance(), 64, (int)(ZFarPlane * 1.5));
ShadowSize[0] = (int)Math.clamp((EngineConfig.getInstance().GetShadowMapSize() / 16) * 16, 16, 8192);
if(engineInstance.window().GetLinkedApi() == EngineConfig.RenderAPI.Vulkan)PrimaryRuntime.GetRenderThread().GetRenderer().GetSceneRender().RebuildPipelines(PrimaryRuntime.GetRenderThread().GetRenderer().GetVulkanContext());
}
ImGui.sameLine();
if(ImGui.button("Medium")){
parent.ChangeGraphicsSettings = true;
parent.CoolDown = 2000;
parent.NextAAMode = (1);
parent.NextAAMode = (0);
ForwardSceneRender.SetDualPassRendering(true);
EngineConfig.getInstance().SetRenderer(EngineConfig.Renderer.Deferred);
DeferredSceneRender.SetDualPassRendering(true);
EngineConfig.getInstance().RenderShadows(true);
EngineConfig.getInstance().SetAlphaToCoverage(true);
EngineConfig.getInstance().SetShadowMapSize(1024);
EngineConfig.getInstance().MaxShadowDistance((int)(ZFarPlane/2));
ShadowDistance[0] = (int)Math.clamp(EngineConfig.getInstance().MaxShadowDistance(), 64, (int)(ZFarPlane * 1.5));
ShadowSize[0] = (int)Math.clamp((EngineConfig.getInstance().GetShadowMapSize() / 16) * 16, 16, 8192);
if(engineInstance.window().GetLinkedApi() == EngineConfig.RenderAPI.Vulkan)PrimaryRuntime.GetRenderThread().GetRenderer().GetSceneRender().RebuildPipelines(PrimaryRuntime.GetRenderThread().GetRenderer().GetVulkanContext());
}
ImGui.sameLine();
if(ImGui.button("Highest")){
if(ImGui.button("High")){
parent.ChangeGraphicsSettings = true;
parent.CoolDown = 2000;
parent.NextAAMode = (4);
parent.NextAAMode = (0);
ForwardSceneRender.SetDualPassRendering(true);
EngineConfig.getInstance().SetRenderer(EngineConfig.Renderer.Deferred);
DeferredSceneRender.SetDualPassRendering(true);
EngineConfig.getInstance().SetAlphaToCoverage(false);
EngineConfig.getInstance().RenderShadows(true);
EngineConfig.getInstance().SetShadowMapSize(4096);
EngineConfig.getInstance().MaxShadowDistance((int)(ZFarPlane));
ShadowDistance[0] = (int)Math.clamp(EngineConfig.getInstance().MaxShadowDistance(), 64, (int)(ZFarPlane * 1.5));
ShadowSize[0] = (int)Math.clamp((EngineConfig.getInstance().GetShadowMapSize() / 16) * 16, 16, 8192);
if(engineInstance.window().GetLinkedApi() == EngineConfig.RenderAPI.Vulkan)PrimaryRuntime.GetRenderThread().GetRenderer().GetSceneRender().RebuildPipelines(PrimaryRuntime.GetRenderThread().GetRenderer().GetVulkanContext());
}
ImGui.sameLine();
if(ImGui.button("Ultra")){
parent.ChangeGraphicsSettings = true;
parent.CoolDown = 2000;
parent.NextAAMode = (0);
ForwardSceneRender.SetDualPassRendering(true);
EngineConfig.getInstance().SetRenderer(EngineConfig.Renderer.Deferred);
DeferredSceneRender.SetDualPassRendering(true);
EngineConfig.getInstance().SetAlphaToCoverage(false);
EngineConfig.getInstance().RenderShadows(true);
EngineConfig.getInstance().SetShadowMapSize(8192);
EngineConfig.getInstance().MaxShadowDistance( (int)(ZFarPlane * 1.5));
ShadowDistance[0] = (int)Math.clamp(EngineConfig.getInstance().MaxShadowDistance(), 64, (int)(ZFarPlane * 1.5));
ShadowSize[0] = (int)Math.clamp((EngineConfig.getInstance().GetShadowMapSize() / 16) * 16, 16, 8192);
if(engineInstance.window().GetLinkedApi() == EngineConfig.RenderAPI.Vulkan)PrimaryRuntime.GetRenderThread().GetRenderer().GetSceneRender().RebuildPipelines(PrimaryRuntime.GetRenderThread().GetRenderer().GetVulkanContext());
}
ImGui.text(" ");
ImGui.text("Shadows:");
if(ImGui.button("No Shadows")){
// parent.ChangeGraphicsSettings = true;
// parent.CoolDown = 2000;
EngineConfig.getInstance().RenderShadows(false);
}
ImGui.sameLine();
if(ImGui.button("Cascading")){
// parent.ChangeGraphicsSettings = true;
// parent.CoolDown = 2000;
EngineConfig.getInstance().RenderShadows(true);
}
if (ImGui.sliderInt("Shadow Map Size", ShadowSize, 16, 8192)) {
ShadowSize[0] = Math.clamp((ShadowSize[0] / 16) * 16, 16, 8192);
parent.ChangeGraphicsSettings = true;
parent.CoolDown = 2000;
EngineConfig.getInstance().SetShadowMapSize(ShadowSize[0]);
}
if (ImGui.sliderInt("Shadow Distance", ShadowDistance, 64, (int)(ZFarPlane * 1.5))) {
ShadowDistance[0] = Math.clamp((ShadowDistance[0] / 64) * 64, 64, (int)(ZFarPlane * 1.5));
parent.ChangeGraphicsSettings = true;
parent.CoolDown = 2000;
EngineConfig.getInstance().MaxShadowDistance(ShadowDistance[0]);
}
ImGui.text(" ");
ImGui.text("anti aliasing:");
if(ImGui.button("No AA")){

View file

@ -22,6 +22,8 @@ public class SettingsMenu implements GUIOverlay {
public int[] SFX = new int[]{100};
public int[] Weapons = new int[]{100};
public int[] Ambient = new int[]{100};
public int[] ShadowSize = new int[]{4096};
public int[] ShadowDistance = new int[]{1000};
public ImInt ServerPort = new ImInt(25565);
public final ImString textBuffer = new ImString(100);
public final ImString UsernameBuffer = new ImString(24);
@ -34,6 +36,8 @@ public class SettingsMenu implements GUIOverlay {
SFX[0] = (int)(EngineConfig.getInstance().SoundVolume * 100);
Weapons[0] = (int)(EngineConfig.getInstance().WeaponVolume * 100);
Ambient[0] = (int)(EngineConfig.getInstance().AmbientVolume * 100);
ShadowSize[0] = EngineConfig.getInstance().GetShadowMapSize();
ShadowDistance[0] = (int)EngineConfig.getInstance().MaxShadowDistance();
AudioInstance.ApplyUniversalVolume();
@ -191,13 +195,36 @@ public class SettingsMenu implements GUIOverlay {
EngineConfig.getInstance().SetRenderingAPI(EngineConfig.RenderAPI.OpenGL);
}
ImGui.text("Presets:");
float ZFarPlane = Math.max(EngineConfig.getInstance().GetZFarPlane(), EngineConfig.getInstance().GetZNearPlane());
if(ImGui.button("Lowest")){
parent.ChangeGraphicsSettings = true;
parent.CoolDown = 2000;
parent.NextAAMode = (0);
ForwardSceneRender.SetDualPassRendering(false);
DeferredSceneRender.SetDualPassRendering(false);
EngineConfig.getInstance().SetRenderer(EngineConfig.Renderer.Forward);
EngineConfig.getInstance().RenderShadows(false);
EngineConfig.getInstance().SetAlphaToCoverage(false);
EngineConfig.getInstance().SetShadowMapSize(1);
EngineConfig.getInstance().MaxShadowDistance(64);
ShadowDistance[0] = (int)Math.clamp(EngineConfig.getInstance().MaxShadowDistance(), 64, (int)(ZFarPlane * 1.5));
ShadowSize[0] = (int)Math.clamp((EngineConfig.getInstance().GetShadowMapSize() / 16) * 16, 16, 8192);
if(engineInstance.window().GetLinkedApi() == EngineConfig.RenderAPI.Vulkan)PrimaryRuntime.GetRenderThread().GetRenderer().GetSceneRender().RebuildPipelines(PrimaryRuntime.GetRenderThread().GetRenderer().GetVulkanContext());
}
ImGui.sameLine();
if(ImGui.button("Low")){
parent.ChangeGraphicsSettings = true;
parent.CoolDown = 2000;
parent.NextAAMode = (0);
ForwardSceneRender.SetDualPassRendering(false);
DeferredSceneRender.SetDualPassRendering(false);
EngineConfig.getInstance().SetRenderer(EngineConfig.Renderer.Deferred);
EngineConfig.getInstance().RenderShadows(true);
EngineConfig.getInstance().SetAlphaToCoverage(false);
EngineConfig.getInstance().SetShadowMapSize(256);
EngineConfig.getInstance().MaxShadowDistance((int)(ZFarPlane/4));
ShadowDistance[0] = (int)Math.clamp(EngineConfig.getInstance().MaxShadowDistance(), 64, (int)(ZFarPlane * 1.5));
ShadowSize[0] = (int)Math.clamp((EngineConfig.getInstance().GetShadowMapSize() / 16) * 16, 16, 8192);
if(engineInstance.window().GetLinkedApi() == EngineConfig.RenderAPI.Vulkan)PrimaryRuntime.GetRenderThread().GetRenderer().GetSceneRender().RebuildPipelines(PrimaryRuntime.GetRenderThread().GetRenderer().GetVulkanContext());
}
ImGui.sameLine();
@ -206,20 +233,74 @@ public class SettingsMenu implements GUIOverlay {
parent.CoolDown = 2000;
parent.NextAAMode = (1);
ForwardSceneRender.SetDualPassRendering(true);
EngineConfig.getInstance().SetRenderer(EngineConfig.Renderer.Deferred);
DeferredSceneRender.SetDualPassRendering(true);
EngineConfig.getInstance().RenderShadows(true);
EngineConfig.getInstance().SetAlphaToCoverage(true);
EngineConfig.getInstance().SetShadowMapSize(1024);
EngineConfig.getInstance().MaxShadowDistance((int)(ZFarPlane/2));
ShadowDistance[0] = (int)Math.clamp(EngineConfig.getInstance().MaxShadowDistance(), 64, (int)(ZFarPlane * 1.5));
ShadowSize[0] = (int)Math.clamp((EngineConfig.getInstance().GetShadowMapSize() / 16) * 16, 16, 8192);
if(engineInstance.window().GetLinkedApi() == EngineConfig.RenderAPI.Vulkan)PrimaryRuntime.GetRenderThread().GetRenderer().GetSceneRender().RebuildPipelines(PrimaryRuntime.GetRenderThread().GetRenderer().GetVulkanContext());
}
ImGui.sameLine();
if(ImGui.button("Highest")){
if(ImGui.button("High")){
parent.ChangeGraphicsSettings = true;
parent.CoolDown = 2000;
parent.NextAAMode = (4);
parent.NextAAMode = (0);
ForwardSceneRender.SetDualPassRendering(true);
EngineConfig.getInstance().SetRenderer(EngineConfig.Renderer.Deferred);
DeferredSceneRender.SetDualPassRendering(true);
EngineConfig.getInstance().SetAlphaToCoverage(false);
EngineConfig.getInstance().RenderShadows(true);
EngineConfig.getInstance().SetShadowMapSize(4096);
EngineConfig.getInstance().MaxShadowDistance((int)(ZFarPlane));
ShadowDistance[0] = (int)Math.clamp(EngineConfig.getInstance().MaxShadowDistance(), 64, (int)(ZFarPlane * 1.5));
ShadowSize[0] = (int)Math.clamp((EngineConfig.getInstance().GetShadowMapSize() / 16) * 16, 16, 8192);
if(engineInstance.window().GetLinkedApi() == EngineConfig.RenderAPI.Vulkan)PrimaryRuntime.GetRenderThread().GetRenderer().GetSceneRender().RebuildPipelines(PrimaryRuntime.GetRenderThread().GetRenderer().GetVulkanContext());
}
ImGui.sameLine();
if(ImGui.button("Ultra")){
parent.ChangeGraphicsSettings = true;
parent.CoolDown = 2000;
parent.NextAAMode = (0);
ForwardSceneRender.SetDualPassRendering(true);
EngineConfig.getInstance().SetRenderer(EngineConfig.Renderer.Deferred);
DeferredSceneRender.SetDualPassRendering(true);
EngineConfig.getInstance().SetAlphaToCoverage(false);
EngineConfig.getInstance().RenderShadows(true);
EngineConfig.getInstance().SetShadowMapSize(8192);
EngineConfig.getInstance().MaxShadowDistance( (int)(ZFarPlane * 1.5));
ShadowDistance[0] = (int)Math.clamp(EngineConfig.getInstance().MaxShadowDistance(), 64, (int)(ZFarPlane * 1.5));
ShadowSize[0] = (int)Math.clamp((EngineConfig.getInstance().GetShadowMapSize() / 16) * 16, 16, 8192);
if(engineInstance.window().GetLinkedApi() == EngineConfig.RenderAPI.Vulkan)PrimaryRuntime.GetRenderThread().GetRenderer().GetSceneRender().RebuildPipelines(PrimaryRuntime.GetRenderThread().GetRenderer().GetVulkanContext());
}
ImGui.text(" ");
ImGui.text("Shadows:");
if(ImGui.button("No Shadows")){
// parent.ChangeGraphicsSettings = true;
// parent.CoolDown = 2000;
EngineConfig.getInstance().RenderShadows(false);
}
ImGui.sameLine();
if(ImGui.button("Cascading")){
// parent.ChangeGraphicsSettings = true;
// parent.CoolDown = 2000;
EngineConfig.getInstance().RenderShadows(true);
}
if (ImGui.sliderInt("Shadow Map Size", ShadowSize, 16, 8192)) {
ShadowSize[0] = Math.clamp((ShadowSize[0] / 16) * 16, 16, 8192);
parent.ChangeGraphicsSettings = true;
parent.CoolDown = 2000;
EngineConfig.getInstance().SetShadowMapSize(ShadowSize[0]);
}
if (ImGui.sliderInt("Shadow Distance", ShadowDistance, 64, (int)(ZFarPlane * 1.5))) {
ShadowDistance[0] = Math.clamp((ShadowDistance[0] / 64) * 64, 64, (int)(ZFarPlane * 1.5));
parent.ChangeGraphicsSettings = true;
parent.CoolDown = 2000;
EngineConfig.getInstance().MaxShadowDistance(ShadowDistance[0]);
}
ImGui.text(" ");
ImGui.text("anti aliasing:");
ImGui.text("Selected AA: " + EngineConfig.getInstance().RenderAAType().name());
if(ImGui.button("No AA")){

View file

@ -158,7 +158,7 @@ public class Scene implements IScene {
GUIReg.put("PerformanceOverlay",new PerformanceOverlay());
ActiveGUIs.add("PerformanceOverlay");
GUIReg.put("ChatLog",new GameChat());
ActiveGUIs.add("ChatLog");
//ActiveGUIs.add("ChatLog");
}
}

View file

@ -32,6 +32,22 @@ public class Project3D {
Resize(LastWidth,LastHeight);
}
public Project3D GetReversedFarPlanes(){
Project3D newProjection;
float zNear = Math.max(ZFarPlane, ZNearPlane);
float zFar = Math.min(ZFarPlane, ZNearPlane);
newProjection = new Project3D(FOV, zNear, zFar, LastWidth, LastHeight);
return newProjection;
}
public Project3D GetNormalFarPlanes(){
Project3D newProjection;
float zNear = Math.min(ZFarPlane, ZNearPlane);
float zFar = Math.max(ZFarPlane, ZNearPlane);
newProjection = new Project3D(FOV, zNear, zFar, LastWidth, LastHeight);
return newProjection;
}
public void ChangeFOV(float newFOV){
FOV = newFOV;
Resize(LastWidth,LastHeight);

View file

@ -15,6 +15,7 @@ import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.P
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.Rendering.Shadows.ShadowRenderer;
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;
@ -41,17 +42,22 @@ import static org.lwjgl.vulkan.VK13.*;
public class LightRenderer {
private static final int COLOUR_FORMAT = VK_FORMAT_R32G32B32A32_SFLOAT;
private static final String DESC_ID_ATT = "LIGHT_DESC_ID_ATT";
private static final String DESC_ID_NOSHADOW_ATT = "LIGHT_DESC_ID_NOSHADOW_ATT";
private static final String DESC_ID_SHADOW_MATRICES = "LIGHT_DESC_ID_SHADOW_MATRICES";
private static final String DESC_ID_LIGHTS = "LIGHT_DESC_ID_LIGHTS";
private static final String DESC_ID_SCENE = "LIGHT_DESC_ID_SCENE ";
private static final String DESC_ID_SCENE = "LIGHT_DESC_ID_SCENE";
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 NO_SHADOWS_FRAGMENT_SHADER_FILE_GLSL = "resources/EngineResources/shaders/lighting_frag.glsl";
private static final String NO_SHADOWS_FRAGMENT_SHADER_FILE_SPV = NO_SHADOWS_FRAGMENT_SHADER_FILE_GLSL + ".spv";
private static final String VERTEX_SHADER_FILE_GLSL = "resources/EngineResources/shaders/lighting_vertex.glsl";
private static final String VERTEX_SHADER_FILE_SPV = VERTEX_SHADER_FILE_GLSL + ".spv";
private final DescriptorSetLayout AttachmentDescriptorSetLayout;
private final DescriptorSetLayout NoShadowsAttachmentDescriptorSetLayout;
private final VkClearValue ClearValueColour;
private final Pipeline pipeline;
private final Pipeline NoShadowsPipeline;
private final TextureSampler textureSampler;
private Attachment AttachmentColour;
private VkRenderingAttachmentInfo.Buffer AttachmentInfoColour;
@ -72,7 +78,7 @@ public class LightRenderer {
RenderInfo = CreateRenderInfo(AttachmentColour, AttachmentInfoColour);
lightSpecConsts = new LightSpecConsts();
ShaderModule[] shaderModules = CreateShaderModules(VkCtx, lightSpecConsts);
ShaderModule[] shaderModules = CreateShaderModules(VkCtx, lightSpecConsts,true);
var textureSamplerInfo = new TextureSamplerInfo(VK_SAMPLER_ADDRESS_MODE_REPEAT,
VK_BORDER_COLOR_INT_OPAQUE_BLACK, 1, true);
@ -83,7 +89,7 @@ public class LightRenderer {
descSetLayouts[i] = new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, i, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
}
AttachmentDescriptorSetLayout = new DescriptorSetLayout(VkCtx, descSetLayouts);
CreateAttachmentDescriptorSet(VkCtx, AttachmentDescriptorSetLayout, attachments, textureSampler);
CreateAttachmentDescriptorSet(VkCtx, AttachmentDescriptorSetLayout, attachments, textureSampler, true);
StorageDescriptorSetLayout = new DescriptorSetLayout(VkCtx, new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 0, 1,
VK_SHADER_STAGE_FRAGMENT_BIT));
@ -99,6 +105,19 @@ public class LightRenderer {
shadowMatrices = CreateShadowMatrixBuffers(VkCtx, StorageDescriptorSetLayout);
pipeline = createPipeline(VkCtx, shaderModules, new DescriptorSetLayout[]{AttachmentDescriptorSetLayout, StorageDescriptorSetLayout,
StorageDescriptorSetLayout, SceneDescriptorSetLayout});
Arrays.asList(shaderModules).forEach(s -> s.CleanUp(VkCtx));
numAttachments = attachments.size();
DescriptorSetLayout.LayoutInformation[] OldDescSetLayouds = new DescriptorSetLayout.LayoutInformation[numAttachments];
for (int i = 0; i < numAttachments; i++) {
OldDescSetLayouds[i] = new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, i, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
}
NoShadowsAttachmentDescriptorSetLayout = new DescriptorSetLayout(VkCtx, OldDescSetLayouds);
CreateAttachmentDescriptorSet(VkCtx, NoShadowsAttachmentDescriptorSetLayout, attachments, textureSampler, false);
shaderModules = CreateShaderModules(VkCtx, lightSpecConsts,false);
NoShadowsPipeline = createPipeline(VkCtx, shaderModules, new DescriptorSetLayout[]{NoShadowsAttachmentDescriptorSetLayout,
StorageDescriptorSetLayout, SceneDescriptorSetLayout});
Logger.debug("Light Renderer Pipeline -> [{}]",pipeline.GetVulkanPipeline());
Arrays.asList(shaderModules).forEach(s -> s.CleanUp(VkCtx));
}
@ -120,10 +139,10 @@ public class LightRenderer {
}
private static void CreateAttachmentDescriptorSet(VulkanContext VkCtx, DescriptorSetLayout descSetLayout, List<Attachment> attachments,
TextureSampler sampler) {
TextureSampler sampler, boolean Shadows) {
DescriptorAllocator descAllocator = VkCtx.GetDescriptorAllocator();
Device device = VkCtx.GetDevice();
DescriptorSet descSet = descAllocator.AddDescriptorSet(device, DESC_ID_ATT, descSetLayout);
DescriptorSet descSet = descAllocator.AddDescriptorSet(device, Shadows ? DESC_ID_ATT : DESC_ID_NOSHADOW_ATT, descSetLayout);
List<ImageView> imageViews = new ArrayList<>();
attachments.forEach(a -> imageViews.add(a.GetVkImageView()));
descSet.SetImages(device, imageViews, sampler, 0);
@ -176,14 +195,16 @@ public class LightRenderer {
return result;
}
private static ShaderModule[] CreateShaderModules(VulkanContext VkCtx, LightSpecConsts lightSpecConsts) {
private static ShaderModule[] CreateShaderModules(VulkanContext VkCtx, LightSpecConsts lightSpecConsts, boolean shadowPipeline) {
if (EngineConfig.getInstance().RecompileShaders()) {
ShaderCompiler.CompileGLSLShaderOnChange(VERTEX_SHADER_FILE_GLSL, Shaderc.shaderc_glsl_vertex_shader);
ShaderCompiler.CompileGLSLShaderOnChange(FRAGMENT_SHADER_FILE_GLSL, Shaderc.shaderc_glsl_fragment_shader);
//ShaderCompiler.CompileGLSLShaderOnChange( FRAGMENT_SHADER_FILE_GLSL, Shaderc.shaderc_glsl_fragment_shader);
ShaderCompiler.CompileGLSLShaderOnChange(shadowPipeline ? FRAGMENT_SHADER_FILE_GLSL : NO_SHADOWS_FRAGMENT_SHADER_FILE_GLSL, Shaderc.shaderc_glsl_fragment_shader);
}
return new ShaderModule[]{
new ShaderModule(VkCtx, VK_SHADER_STAGE_VERTEX_BIT, VERTEX_SHADER_FILE_SPV, null),
new ShaderModule(VkCtx, VK_SHADER_STAGE_FRAGMENT_BIT, FRAGMENT_SHADER_FILE_SPV, lightSpecConsts.getSpecInfo()),
//new ShaderModule(VkCtx, VK_SHADER_STAGE_FRAGMENT_BIT, FRAGMENT_SHADER_FILE_SPV, lightSpecConsts.getSpecInfo()),
new ShaderModule(VkCtx, VK_SHADER_STAGE_FRAGMENT_BIT, shadowPipeline ? FRAGMENT_SHADER_FILE_SPV : NO_SHADOWS_FRAGMENT_SHADER_FILE_SPV, shadowPipeline ? lightSpecConsts.getSpecInfo() : null),
};
}
@ -210,8 +231,10 @@ public class LightRenderer {
}
VulkanUtils.ImageBarrier(stack, cmdHandle, mrtAttachments.GetDepthAttachment().GetVkImage().getVulkanImage(),
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT,
VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_2_SHADER_READ_BIT,
VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT,
VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT,
VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
VK_ACCESS_2_SHADER_READ_BIT,
VK_IMAGE_ASPECT_DEPTH_BIT);
VulkanUtils.ImageBarrier(stack, cmdHandle, shadowAttachment.GetVkImage().getVulkanImage(),
@ -262,6 +285,73 @@ public class LightRenderer {
}
}
public void render(EngineInstance engineInstance, VulkanContext VkCtx, CommandBuffer cmdBuffer, MultiRenderTargetAttachments mrtAttachments, int CurrentFrame) {
try (var stack = MemoryStack.stackPush()) {
VkCommandBuffer cmdHandle = cmdBuffer.GetVulkanCommandBuffer();
VulkanUtils.ImageBarrier(stack, cmdHandle, AttachmentColour.GetVkImage().getVulkanImage(),
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT,
VK_ACCESS_2_NONE, VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT,
VK_IMAGE_ASPECT_COLOR_BIT);
List<Attachment> attachments = mrtAttachments.GetColourAttachments();
int numAttachments = attachments.size();
for (int i = 0; i < numAttachments; i++) {
Attachment attachment = attachments.get(i);
VulkanUtils.ImageBarrier(stack, cmdHandle, attachment.GetVkImage().getVulkanImage(),
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT,
VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_2_SHADER_READ_BIT,
VK_IMAGE_ASPECT_COLOR_BIT);
}
VulkanUtils.ImageBarrier(stack, cmdHandle, mrtAttachments.GetDepthAttachment().GetVkImage().getVulkanImage(),
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT,
VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT,
VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
VK_ACCESS_2_SHADER_READ_BIT,
VK_IMAGE_ASPECT_DEPTH_BIT);
vkCmdBeginRendering(cmdHandle, RenderInfo);
vkCmdBindPipeline(cmdHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, NoShadowsPipeline.GetVulkanPipeline());
Image ColourImage = AttachmentColour.GetVkImage();
int width = ColourImage.GetWidth();
int height = ColourImage.GetHeight();
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);
DescriptorAllocator descAllocator = VkCtx.GetDescriptorAllocator();
LongBuffer descriptorSets = stack.mallocLong(3)
.put(0, descAllocator.GetDescriptorSet(DESC_ID_NOSHADOW_ATT).GetVkDescriptorSet())
.put(1, descAllocator.GetDescriptorSet(DESC_ID_LIGHTS, CurrentFrame).GetVkDescriptorSet())
.put(2, descAllocator.GetDescriptorSet(DESC_ID_SCENE, CurrentFrame).GetVkDescriptorSet());
IScene scene = engineInstance.scene();
UpdateSceneInfo(VkCtx, scene, CurrentFrame);
UpdateLights(VkCtx, scene, CurrentFrame);
vkCmdBindDescriptorSets(cmdHandle, VK_PIPELINE_BIND_POINT_GRAPHICS,
NoShadowsPipeline.GetVulkanPipelineLayout(), 0, descriptorSets, null);
vkCmdDraw(cmdHandle, 3, 1, 0, 0);
vkCmdEndRendering(cmdHandle);
}
}
private void UpdateCascadeShadowMatrices(VulkanContext vkCtx, CascadeShadows cascadeShadows, int currentFrame) {
VulkanBuffer buff = shadowMatrices[currentFrame];
long mappedMemory = buff.MapMemory(vkCtx);
@ -324,6 +414,20 @@ public class LightRenderer {
buffer.UnMapMemory(VkCtx);
}
public void updateAttachmentDescriptors(VulkanContext VkCtx, List<Attachment> attachments) {
DescriptorSet descSet = VkCtx.GetDescriptorAllocator().GetDescriptorSet(DESC_ID_ATT);
var imageViews = new ArrayList<ImageView>();
attachments.forEach(a -> imageViews.add(a.GetVkImageView()));
descSet.SetImages(VkCtx.GetDevice(), imageViews, textureSampler, 0);
DescriptorSet noShadowDescSet = VkCtx.GetDescriptorAllocator().GetDescriptorSet(DESC_ID_NOSHADOW_ATT);
var noShadowImageViews = new ArrayList<ImageView>();
for (int i = 0; i < attachments.size() - 1; i++) {
noShadowImageViews.add(attachments.get(i).GetVkImageView());
}
noShadowDescSet.SetImages(VkCtx.GetDevice(), noShadowImageViews, textureSampler, 0);
}
public void resize(VulkanContext VkCtx, List<Attachment> attachments) {
RenderInfo.free();
AttachmentInfoColour.free();
@ -337,6 +441,13 @@ public class LightRenderer {
var imageViews = new ArrayList<ImageView>();
attachments.forEach(a -> imageViews.add(a.GetVkImageView()));
descSet.SetImages(VkCtx.GetDevice(), imageViews, textureSampler, 0);
DescriptorSet noShadowDescSet = VkCtx.GetDescriptorAllocator().GetDescriptorSet(DESC_ID_NOSHADOW_ATT);
var noShadowImageViews = new ArrayList<ImageView>();
for (int i = 0; i < attachments.size() - 1; i++) {
noShadowImageViews.add(attachments.get(i).GetVkImageView());
}
noShadowDescSet.SetImages(VkCtx.GetDevice(), noShadowImageViews, textureSampler, 0);
}
public void cleanup(VulkanContext VkCtx) {
@ -346,7 +457,9 @@ public class LightRenderer {
SceneDescriptorSetLayout.CleanUp(VkCtx);
Arrays.asList(SceneBuffer).forEach(b -> b.cleanup(VkCtx));
pipeline.CleanUp(VkCtx);
NoShadowsPipeline.CleanUp(VkCtx);
AttachmentDescriptorSetLayout.CleanUp(VkCtx);
NoShadowsAttachmentDescriptorSetLayout.CleanUp(VkCtx);
textureSampler.CleanUp(VkCtx);
lightSpecConsts.cleanup();
RenderInfo.free();

View file

@ -15,6 +15,9 @@ public class MultiRenderTargetAttachments {
public static final int DEPTH_FORMAT = VK_FORMAT_D32_SFLOAT;
public static final int NORMAL_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT;
public static final int PBR_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT;
public static final int EMISSIVE_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT;
public static final int TRANSLUCECNY_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT;
public static final int OPACITY_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT;
public static final int POSITION_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT;
private final List<Attachment> ColourAttachments;
private final Attachment DepthAttachment;
@ -39,6 +42,15 @@ public class MultiRenderTargetAttachments {
//PBR
Attachment = new Attachment(VkCtx, Width, Height, PBR_FORMAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 1);
ColourAttachments.add(Attachment);
//Emissive
Attachment = new Attachment(VkCtx, Width, Height, EMISSIVE_FORMAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 1);
ColourAttachments.add(Attachment);
//Translucency
Attachment = new Attachment(VkCtx, Width, Height, TRANSLUCECNY_FORMAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 1);
ColourAttachments.add(Attachment);
//Opacity
Attachment = new Attachment(VkCtx, Width, Height, OPACITY_FORMAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 1);
ColourAttachments.add(Attachment);
DepthAttachment = new Attachment(VkCtx, Width, Height, DEPTH_FORMAT, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, 1);
}

View file

@ -69,7 +69,7 @@ public class DefaultPipeline implements Pipeline {
var RasterizationStateCreateInfo = VkPipelineRasterizationStateCreateInfo.calloc(MemStack)
.sType$Default()
.polygonMode(VK_POLYGON_MODE_FILL)
.cullMode(VK_CULL_MODE_NONE)
.cullMode(BuildInfo.CullMode())
.frontFace(VK_FRONT_FACE_CLOCKWISE)
.depthClampEnable(BuildInfo.DepthClamp())
.lineWidth(1.0f);
@ -89,7 +89,7 @@ public class DefaultPipeline implements Pipeline {
.sType(VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO)
.depthTestEnable(BuildInfo.GetDepthTest())
.depthWriteEnable(BuildInfo.performDepthWrite())
.depthCompareOp(VK_COMPARE_OP_LESS_OR_EQUAL)
.depthCompareOp(BuildInfo.DepthBuffer())
.depthBoundsTestEnable(false)
.stencilTestEnable(false);
}

View file

@ -20,11 +20,15 @@ import static org.lwjgl.vulkan.VK10.VK_FORMAT_R8G8B8A8_SRGB;
public class TextureCache implements ITextureCache {
public static final int MAX_TEXTURES = 256;
private final IndexedLinkedHashMap<String, ITexture> TextureMap;
private final IndexedLinkedHashMap<String, ITexture> CubemapTextures;
private final List<String> ActualTextures;
private final List<String> ActualCubemapTextures;
public TextureCache(){
TextureMap = new IndexedLinkedHashMap<>();
CubemapTextures = new IndexedLinkedHashMap<>();
ActualTextures = new ArrayList<>();
ActualCubemapTextures = new ArrayList<>();
}
public ITexture AddCubeMapTexture(VulkanContext VkCtx, String ID, String[] FacePaths, int Format) {
@ -109,8 +113,17 @@ public class TextureCache implements ITextureCache {
}
public IndexedLinkedHashMap<String, ITexture> GetTextureCache(){return TextureMap;}
public List<ITexture> GetTextureList(){return new ArrayList<>(TextureMap.values());}
public List<ITexture> GetAll2DTextures(){
List<ITexture> result = new ArrayList<>();
TextureMap.forEach((key,value)->{
if(!(value instanceof CubeMapTexture)){
result.add(value);
}
});
return result;
}
public int GetPosition(String ID){
int result = -1;
int result = 0;
if(ID != null){
result = TextureMap.GetIndexOf(ID);
}

View file

@ -4,7 +4,7 @@ import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Shader.Des
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Shader.ShaderModule;
import org.lwjgl.vulkan.VkPipelineVertexInputStateCreateInfo;
import static org.lwjgl.vulkan.VK10.VK_FORMAT_UNDEFINED;
import static org.lwjgl.vulkan.VK10.*;
public class PipelineBuildInfo {
private final ShaderModule[] ShaderModules;
@ -20,6 +20,14 @@ public class PipelineBuildInfo {
private boolean alphaToCoverage = false;
private final int[] ColourFormats;
private int BlendingMethod = 0;
private int CullMode = VK_CULL_MODE_NONE;
private int DepthBuffer = VK_COMPARE_OP_GREATER_OR_EQUAL;
public int DepthBuffer(){return DepthBuffer;}
public PipelineBuildInfo DepthBuffer(int DepthBuffer){this.DepthBuffer = DepthBuffer;return this;}
public int CullMode(){return CullMode;}
public PipelineBuildInfo CullMode(int CullMode){this.CullMode = CullMode; return this;}
public PipelineBuildInfo(ShaderModule[] shaderModules, VkPipelineVertexInputStateCreateInfo VertexInput, int[] ColourFormat){
this.ColourFormats = ColourFormat;

View file

@ -31,6 +31,7 @@ import org.tinylog.Logger;
import java.nio.ByteBuffer;
import java.nio.LongBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@ -83,19 +84,68 @@ public class ShadowRenderer {
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 Attachment colorAttachment;
private VkRenderingAttachmentInfo.Buffer colorAttachmentInfo;
private Attachment depthAttachment;
private VkRenderingAttachmentInfo depthAttachmentInfo;
private final DescriptorSetLayout descLayoutFrgStorage;
private final Pipeline pipeline;
private Pipeline pipeline;
private final VulkanBuffer[] prjBuffers;
private final ByteBuffer pushConstBuff;
private final VkRenderingInfo renderingInfo;
private VkRenderingInfo renderingInfo;
private final DescriptorSetLayout textDescriptorSetLayout;
private final TextureSampler textureSampler;
private final DescriptorSetLayout uniformGeomDescriptorSetLayout;
public static volatile boolean AllowShadowRendering = false;
public static synchronized boolean AllowShadowRendering(){ return AllowShadowRendering;}
public static synchronized void AllowShadowRendering(boolean AllowShadowRendering){ ShadowRenderer.AllowShadowRendering = AllowShadowRendering;}
public void RebuildPipelineAndRenderingAttachments(VulkanContext VulkanContext){
VkRenderingInfo NewRenderInfo;
Attachment newColourAttachment;
Attachment newDepthAttachment;
VkRenderingAttachmentInfo newDepthAttachmentInfo;
VkRenderingAttachmentInfo.Buffer newColourAttachmentInfo;
Pipeline newPipeline;
newDepthAttachment = createDepthAttachment(VulkanContext);
newDepthAttachmentInfo = createDepthAttachmentInfo(newDepthAttachment, ClearValueDepth);
newColourAttachment = createColorAttachment(VulkanContext);
newColourAttachmentInfo = createColorAttachmentInfo(newColourAttachment, ClearValueColour);
NewRenderInfo = createRenderInfo(newColourAttachmentInfo, newDepthAttachmentInfo);
ShaderModule[] shaderModules = createShaderModules(VulkanContext);
newPipeline = createPipeline(VulkanContext, shaderModules, new DescriptorSetLayout[]{uniformGeomDescriptorSetLayout, textDescriptorSetLayout,
descLayoutFrgStorage});
Arrays.asList(shaderModules).forEach(s -> s.CleanUp(VulkanContext));
VkRenderingInfo OldRenderInfo = renderingInfo;
Attachment OldColourAttachment = colorAttachment;
Attachment OldDepthAttachment = depthAttachment;
VkRenderingAttachmentInfo OldDepthAttachmentInfo = depthAttachmentInfo;
VkRenderingAttachmentInfo.Buffer OldColourAttachmentInfo = colorAttachmentInfo;
Pipeline OldPipeline = pipeline;
renderingInfo = NewRenderInfo;
colorAttachment = newColourAttachment;
depthAttachment = newDepthAttachment;
depthAttachmentInfo = newDepthAttachmentInfo;
colorAttachmentInfo = newColourAttachmentInfo;
pipeline = newPipeline;
OldRenderInfo.free();
OldDepthAttachmentInfo.free();
OldDepthAttachment.CleanUp(VulkanContext);
OldColourAttachmentInfo.free();
OldColourAttachment.CleanUp(VulkanContext);
OldPipeline.CleanUp(VulkanContext);
}
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));
@ -135,6 +185,7 @@ public class ShadowRenderer {
for (int i = 0; i < VulkanUtils.MAX_IN_FLIGHT; i++) {
cascadeShadows[i] = new CascadeShadows();
}
AllowShadowRendering(true);
}
private static Attachment createColorAttachment(VulkanContext VulkanContext) {
@ -179,7 +230,9 @@ public class ShadowRenderer {
})
.SetDescriptorSetLayouts(DescriptorSetLayouts)
.SetDescriptorSetLayouts(DescriptorSetLayouts)
.SetDepthClamp(VulkanContext.GetDevice().getDepthClamp());
.SetDepthClamp(VulkanContext.GetDevice().getDepthClamp())
.CullMode(VK_CULL_MODE_FRONT_BIT)
.DepthBuffer(VK_COMPARE_OP_LESS_OR_EQUAL);
var pipeline = new DefaultPipeline(VulkanContext, buildInfo);
vtxBuffStruct.cleanup();
return pipeline;
@ -216,6 +269,7 @@ public class ShadowRenderer {
}
public void cleanup(VulkanContext VulkanContext) {
AllowShadowRendering(false);
pipeline.CleanUp(VulkanContext);
uniformGeomDescriptorSetLayout.CleanUp(VulkanContext);
descLayoutFrgStorage.CleanUp(VulkanContext);
@ -248,7 +302,12 @@ public class ShadowRenderer {
var buffer = materialsCache.GetMaterialsBuffer();
descSet.SetBuffer(device, buffer, buffer.GetRequestedSize(), layoutInfo.Binding(), layoutInfo.DescriptorType());
List<ImageView> imageViews = textureCache.GetTextureList().stream().map(ITexture::GetImageView).toList();
List<ImageView> imageViews = new ArrayList<>(textureCache.GetAll2DTextures().stream().map(ITexture::GetImageView).toList());
ImageView fallback = textureCache.GetTexture("resources/EngineResources/Texture/NoTexture.png").GetImageView();
while (imageViews.size() < TextureCache.MAX_TEXTURES) {
imageViews.add(fallback);
}
descSet = VulkanContext.GetDescriptorAllocator().AddDescriptorSet(device, DESCRIPTOR_ID_TEXT, textDescriptorSetLayout);
descSet.SetImageArray(device, imageViews, textureSampler, 0);
}
@ -319,6 +378,9 @@ public class ShadowRenderer {
var vulkanMesh = vulkanMeshList.get(j);
String materialId = vulkanMesh.MaterialID();
int materialIdx = materialsCache.GetPosition(materialId);
if(materialIdx == -1) {
continue;
}
VulkanMaterial vulkanMaterial = materialsCache.GetMaterial(materialId);
if (vulkanMaterial == null) {
Logger.warn("Mesh [{}] in model [{}] does not have material", j, model.GetID());

View file

@ -24,7 +24,7 @@ public class ShadowUtils {
public static void updateCascadeShadows(CascadeShadows cascadeShadows, IScene scene) {
Camera camera = scene.GetCamera();
Matrix4f viewMatrix = camera.GetViewMatrix();
Project3D projection = scene.GetProjection();
Project3D projection = scene.GetProjection().GetNormalFarPlanes();
Matrix4f projMatrix = projection.GetProjectionMatrix();
ILight[] lights = scene.GetLightingManager().GetLights();
int numLights = lights.length;
@ -42,14 +42,10 @@ public class ShadowUtils {
float[] cascadeSplits = new float[SceneLightingManager.SHADOW_MAP_CASCADE_COUNT];
float nearClip = projection.GetNearZ();
float farClip = projection.GetFarZ();
float nearClip = projection.GetNearZ();//projection.GetNearZ();
float farClip = EngineConfig.getInstance().MaxShadowDistance();//Math.min(projection.GetFarZ(), EngineConfig.getInstance().MaxShadowDistance());
float clipRange = farClip - nearClip;
if (nearClip <= 0.0f || farClip <= nearClip) {
//throw new IllegalStateException("Invalid projection near/far planes for shadow cascades: near=" + nearClip + ", far=" + farClip);
}
float minZ = nearClip;
float maxZ = nearClip + clipRange;

View file

@ -2,5 +2,5 @@ package net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.VkModel;
import org.joml.Vector4f;
public record MaterialData(String ID, String TexturePath,String NormalTexturePath,String MetalRoughnessMap, Vector4f DiffuseColour,float Roughness, float Metallic) {
public record MaterialData(String ID, String TexturePath,String NormalTexturePath,String MetalRoughnessMap, Vector4f DiffuseColour,float Roughness, float Metallic, String EmissiveTexture,Vector4f EmissiveColour, String TranslucencyTexture, float Translucency, String OpacityTexture, float Opacity) {
}

View file

@ -10,6 +10,7 @@ import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DeviceLaye
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DeviceLayers.Queues.Queue;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Util.VulkanBuffer;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Util.VulkanUtils;
import org.joml.Vector4f;
import org.lwjgl.system.MemoryUtil;
import org.tinylog.Logger;
@ -21,7 +22,8 @@ import static org.lwjgl.util.vma.Vma.VMA_MEMORY_USAGE_AUTO;
import static org.lwjgl.vulkan.VK10.*;
public class MaterialsCache {
private static final int MATERIAL_SIZE = VulkanUtils.VEC4_SIZE * 3;
private static final int MATERIAL_RAW_SIZE = VulkanUtils.VEC4_SIZE * 4 + (VulkanUtils.INT_SIZE * 2 + VulkanUtils.FLOAT_SIZE) * 2 + (VulkanUtils.INT_SIZE * 2);
private static final int MATERIAL_SIZE = 16 * (int)(Math.ceil(MATERIAL_RAW_SIZE/16.0));
private final IndexedLinkedHashMap<String, VulkanMaterial> MaterialsMap;
private VulkanBuffer MaterialsBuffer;
@ -31,6 +33,7 @@ public class MaterialsCache {
//create staging buffer and GPU only accessibly buffer, add any located textures
public void LoadMaterials(VulkanContext VkCtx, List<MaterialData> Materials, TextureCache textureCache, CommandPool commandPool, Queue queue){
Logger.debug("MATERIAL SIZE: [{}], Expected Size: 96, raw size [{}]", MATERIAL_SIZE,MATERIAL_RAW_SIZE);
int MaterialCount = Materials.size();
int BufferSize = MATERIAL_SIZE * MaterialCount;
var SrcBuffer = new VulkanBuffer(VkCtx, BufferSize,
@ -48,20 +51,28 @@ public class MaterialsCache {
int Offset = 0;
for(int i = 0; i < MaterialCount; i++){
int materialBaseOffset = i * MATERIAL_SIZE;
Offset = materialBaseOffset;
var Material = Materials.get(i);
String TexturePath = Material.TexturePath();
boolean ValidTexture = TexturePath != null && !TexturePath.isEmpty();
boolean hasDiffuseTexture = TexturePath != null && !TexturePath.isEmpty();
boolean TransparentTexture;
Logger.debug("Material Texture Path -> [{}]",Material.TexturePath());
if(ValidTexture){
if(hasDiffuseTexture){
ITexture newTexture = textureCache.AddTexture(VkCtx, TexturePath, TexturePath, VK_FORMAT_R8G8B8A8_SRGB);
if(newTexture == null) {
TransparentTexture = false;
TexturePath = "resources/EngineResources/Texture/NoTexture.png";
textureCache.AddTexture(VkCtx, TexturePath, TexturePath, VK_FORMAT_R8G8B8A8_SRGB);
hasDiffuseTexture = false;
TransparentTexture = false;
}
else {
TransparentTexture = newTexture.HasTransparency();
}
else TransparentTexture = newTexture.HasTransparency();
} else{
TexturePath = "resources/EngineResources/Texture/NoTexture.png";
textureCache.AddTexture(VkCtx, TexturePath, TexturePath, VK_FORMAT_R8G8B8A8_SRGB);
TransparentTexture = Material.DiffuseColour().w < 1.0f;
}
VulkanMaterial newMaterial = new VulkanMaterial(Material.ID(),TransparentTexture);
@ -70,7 +81,7 @@ public class MaterialsCache {
Material.DiffuseColour().get(Offset,data);
Offset += VulkanUtils.VEC4_SIZE;
data.putInt(Offset, ValidTexture ? 1 : 0);
data.putInt(Offset, hasDiffuseTexture ? 1 : 0);
Offset += VulkanUtils.INT_SIZE;
data.putInt(Offset, textureCache.GetPosition(TexturePath));
Offset += VulkanUtils.INT_SIZE;
@ -79,17 +90,17 @@ public class MaterialsCache {
boolean hasNormalMap = NormalMap != null && !NormalMap.isEmpty();
if(hasNormalMap){
textureCache.AddTexture(VkCtx,NormalMap,NormalMap,VK_FORMAT_R8G8B8A8_UNORM);
}
}else NormalMap = "resources/EngineResources/Texture/NoTexture.png";
data.putInt(Offset, hasNormalMap ? 1 : 0);
Offset += VulkanUtils.INT_SIZE;
data.putInt(Offset, textureCache.GetPosition(NormalMap));
Offset += VulkanUtils.INT_SIZE;
String RoughnessMap = Material.MetalRoughnessMap();
boolean hasRoughness = RoughnessMap != null && !RoughnessMap.isEmpty();
boolean hasRoughness = RoughnessMap != null && !RoughnessMap.equals("null") && !RoughnessMap.isEmpty();
if(hasRoughness){
textureCache.AddTexture(VkCtx,RoughnessMap,RoughnessMap,VK_FORMAT_R8G8B8A8_UNORM);
}
}else RoughnessMap = "resources/EngineResources/Texture/NoTexture.png";
data.putInt(Offset, hasRoughness ? 1 : 0);
Offset += VulkanUtils.INT_SIZE;
data.putInt(Offset, textureCache.GetPosition(RoughnessMap));
@ -99,6 +110,48 @@ public class MaterialsCache {
Offset += VulkanUtils.FLOAT_SIZE;
data.putFloat(Offset, Material.Metallic());
Offset += VulkanUtils.FLOAT_SIZE;
if(Material.EmissiveColour() != null) {
Material.EmissiveColour().get(Offset, data);
}
else new Vector4f(0,0,0,0).get(Offset,data);
Offset += VulkanUtils.VEC4_SIZE;
String EmissiveMap = Material.EmissiveTexture();
boolean hasEmissiveMap = EmissiveMap != null && !EmissiveMap.equals("null") && !EmissiveMap.isEmpty();
if(hasEmissiveMap){
textureCache.AddTexture(VkCtx,EmissiveMap,EmissiveMap,VK_FORMAT_R8G8B8A8_UNORM);
} else EmissiveMap = "resources/EngineResources/Texture/NoTexture.png";
data.putInt(Offset, hasEmissiveMap ? 1 : 0);
Offset += VulkanUtils.INT_SIZE;
data.putInt(Offset, textureCache.GetPosition(EmissiveMap));
Offset += VulkanUtils.INT_SIZE;
String TranslucencyMap = Material.TranslucencyTexture();
boolean hasTranslucency = TranslucencyMap != null && !TranslucencyMap.equals("null") && !TranslucencyMap.isEmpty();
if(hasTranslucency){
textureCache.AddTexture(VkCtx,TranslucencyMap,TranslucencyMap,VK_FORMAT_R8G8B8A8_UNORM);
}else TranslucencyMap = "resources/EngineResources/Texture/NoTexture.png";
data.putInt(Offset, hasTranslucency ? 1 : 0);
Offset += VulkanUtils.INT_SIZE;
data.putInt(Offset, textureCache.GetPosition(TranslucencyMap));
Offset += VulkanUtils.INT_SIZE;
data.putFloat(Offset, Material.Translucency());
Offset += VulkanUtils.FLOAT_SIZE;
String OpacityMap = Material.OpacityTexture();
boolean hasOpacity = OpacityMap != null && !OpacityMap.equals("null") && !OpacityMap.isEmpty();
if(hasOpacity){
textureCache.AddTexture(VkCtx,OpacityMap,OpacityMap,VK_FORMAT_R8G8B8A8_UNORM);
}else OpacityMap = "resources/EngineResources/Texture/NoTexture.png";
data.putInt(Offset, hasOpacity ? 1 : 0);
Offset += VulkanUtils.INT_SIZE;
data.putInt(Offset, textureCache.GetPosition(OpacityMap));
Offset += VulkanUtils.INT_SIZE;
data.putFloat(Offset, Material.Opacity());
Offset += VulkanUtils.FLOAT_SIZE;
Offset = materialBaseOffset + MATERIAL_SIZE;
}
// data.position(0);

View file

@ -205,7 +205,12 @@ public class SpriteRenderer {
public void LoadMaterials(VulkanContext VkCtx, MaterialsCache materialsCache, TextureCache textureCache){
DescriptorAllocator descriptorAllocator = VkCtx.GetDescriptorAllocator();
Device device = VkCtx.GetDevice();
List<ImageView> imageViews = textureCache.GetTextureList().stream().map(ITexture::GetImageView).toList();
List<ImageView> imageViews = new ArrayList<>(textureCache.GetAll2DTextures().stream().map(ITexture::GetImageView).toList());
ImageView fallback = textureCache.GetTexture("resources/EngineResources/Texture/NoTexture.png").GetImageView();
while (imageViews.size() < TextureCache.MAX_TEXTURES) {
imageViews.add(fallback);
}
DescriptorSet descriptorSet = VkCtx.GetDescriptorAllocator().AddDescriptorSet(device,DESCRIPTOR_ID_TEXTURE,TextDescriptorSetLayout);
descriptorSet.SetImageArray(device,imageViews,TextureSampler,0);
}

View file

@ -108,7 +108,7 @@ public class DeferredSceneRender implements SceneRenderer {//dynamic rendering
public DeferredSceneRender(VulkanContext vulkanContext, EngineInstance engineInstance){
ClearValueColour = VkClearValue.calloc().color(
c -> c.float32(0, 0.0f).float32(1, 0.0f).float32(2, 0.0f).float32(3, 0.0f));
ClearValueDepth = VkClearValue.calloc().color(c -> c.float32(0, 1.0f));
ClearValueDepth = VkClearValue.calloc().color(c -> c.float32(0, 0.0f));
MRTAttachments = new MultiRenderTargetAttachments(vulkanContext);
AttachmentInfoColour = CreateColourAttachmentInfo(MRTAttachments, ClearValueColour);
AttachmentInfoDepth = CreateDepthAttachmentInfo(MRTAttachments, ClearValueDepth);
@ -241,7 +241,10 @@ public class DeferredSceneRender implements SceneRenderer {//dynamic rendering
MultiRenderTargetAttachments.POSITION_FORMAT,
MultiRenderTargetAttachments.ALBEDO_FORMAT,
MultiRenderTargetAttachments.NORMAL_FORMAT,
MultiRenderTargetAttachments.PBR_FORMAT
MultiRenderTargetAttachments.PBR_FORMAT,
MultiRenderTargetAttachments.EMISSIVE_FORMAT,
MultiRenderTargetAttachments.TRANSLUCECNY_FORMAT,
MultiRenderTargetAttachments.OPACITY_FORMAT
};
try (MemoryStack MemStack = MemoryStack.stackPush()) {
@ -279,7 +282,10 @@ public class DeferredSceneRender implements SceneRenderer {//dynamic rendering
private static Pipeline CreatePipeline(VulkanContext VkCtx, ShaderModule[] ShaderModules, DescriptorSetLayout[] DescriptorSetLayouts, boolean DepthWrite, boolean DualRender, boolean Blending, boolean AlphaToCoverage, int BlendingMethod){
var vertexBufferStructure = new VertexBufferStructure();
var BuildInfo = new PipelineBuildInfo(ShaderModules,vertexBufferStructure.getVertexInput(),new int[]{
MultiRenderTargetAttachments.POSITION_FORMAT, MultiRenderTargetAttachments.ALBEDO_FORMAT, MultiRenderTargetAttachments.NORMAL_FORMAT, MultiRenderTargetAttachments.PBR_FORMAT})
MultiRenderTargetAttachments.POSITION_FORMAT, MultiRenderTargetAttachments.ALBEDO_FORMAT,
MultiRenderTargetAttachments.NORMAL_FORMAT, MultiRenderTargetAttachments.PBR_FORMAT,
MultiRenderTargetAttachments.EMISSIVE_FORMAT, MultiRenderTargetAttachments.TRANSLUCECNY_FORMAT,
MultiRenderTargetAttachments.OPACITY_FORMAT})
.SetDepthFormat(MultiRenderTargetAttachments.DEPTH_FORMAT)
.SetDepthWrite(DepthWrite)
.SetPushConstantRanges(
@ -318,10 +324,11 @@ public class DeferredSceneRender implements SceneRenderer {//dynamic rendering
VK_IMAGE_ASPECT_COLOR_BIT);
}
VulkanUtils.ImageBarrier(MemStack, CommandHandle, MRTAttachments.GetDepthAttachment().GetVkImage().getVulkanImage(),
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL,
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_DEPTH_STENCIL_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_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT,
VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
VK_ACCESS_2_NONE,
VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
VK_IMAGE_ASPECT_DEPTH_BIT);
long InitialTime = System.nanoTime();
@ -427,13 +434,17 @@ public class DeferredSceneRender implements SceneRenderer {//dynamic rendering
var VkMesh = VkMeshList.get(j);
String MaterialID = VkMesh.MaterialID();
int MaterialIndex = materialsCache.GetPosition(MaterialID);
if(MaterialIndex == -1) {
continue;
}
VulkanMaterial vulkanMaterial = materialsCache.GetMaterial(MaterialID);
if (vulkanMaterial == null) {
Logger.warn("Mesh [{}] in model [{}] does not have material", j, model.GetID());
continue;
}
if (DualPassRendering || vulkanMaterial.HasTransparency() == Transparent) {
SetPushConstants(CommandHandle, Actor.GetModelMatrix(), MaterialIndex);
if(DualPassRendering) SetDualPassPushConstants(CommandHandle, Actor.GetModelMatrix(), MaterialIndex, Transparent);
else SetPushConstants(CommandHandle, Actor.GetModelMatrix(), MaterialIndex);
vertexBuffer.put(0, VkMesh.VerticesBuffer().GetBuffer());
vkCmdBindVertexBuffers(CommandHandle, 0, vertexBuffer, offsets);
vkCmdBindIndexBuffer(CommandHandle, VkMesh.IndicesBuffer().GetBuffer(), 0, VK_INDEX_TYPE_UINT32);
@ -447,6 +458,15 @@ public class DeferredSceneRender implements SceneRenderer {//dynamic rendering
}
}
private void SetDualPassPushConstants(VkCommandBuffer CmdHandle, Matrix4f ModelMatrix, int MaterialIndex, boolean Transparent){
ModelMatrix.get(0,PushConstBuffer);
PushConstBuffer.putInt(VulkanUtils.MATRIX4X4_SIZE, MaterialIndex);
vkCmdPushConstants(CmdHandle, Transparent? VkPipelineTranslucent.GetVulkanPipelineLayout() : VkPipelineOpaque.GetVulkanPipelineLayout(), VK_SHADER_STAGE_VERTEX_BIT, 0,
PushConstBuffer.slice(0,VulkanUtils.MATRIX4X4_SIZE));
vkCmdPushConstants(CmdHandle, Transparent? VkPipelineTranslucent.GetVulkanPipelineLayout() : VkPipelineOpaque.GetVulkanPipelineLayout(), VK_SHADER_STAGE_FRAGMENT_BIT, VulkanUtils.MATRIX4X4_SIZE,
PushConstBuffer.slice(VulkanUtils.MATRIX4X4_SIZE, VulkanUtils.INT_SIZE));
}
private void SetPushConstants(VkCommandBuffer CmdHandle, Matrix4f ModelMatrix, int MaterialIndex){
ModelMatrix.get(0,PushConstBuffer);
PushConstBuffer.putInt(VulkanUtils.MATRIX4X4_SIZE, MaterialIndex);
@ -477,7 +497,12 @@ public class DeferredSceneRender implements SceneRenderer {//dynamic rendering
var buffer = materialsCache.GetMaterialsBuffer();
descSet.SetBuffer(device, buffer, buffer.GetRequestedSize(), layoutInfo.Binding(), layoutInfo.DescriptorType());
List<ImageView> imageViews = textureCache.GetTextureList().stream().map(ITexture::GetImageView).toList();
List<ImageView> imageViews = new ArrayList<>(textureCache.GetAll2DTextures().stream().map(ITexture::GetImageView).toList());
ImageView fallback = textureCache.GetTexture("resources/EngineResources/Texture/NoTexture.png").GetImageView();
while (imageViews.size() < TextureCache.MAX_TEXTURES) {
imageViews.add(fallback);
}
descSet = VkCtx.GetDescriptorAllocator().AddDescriptorSet(device, DESCRIPTOR_ID_TEXT, descriptorLayoutTexture);
descSet.SetImageArray(device, imageViews, textureSampler, 0);

View file

@ -32,6 +32,7 @@ import org.tinylog.Logger;
import java.nio.ByteBuffer;
import java.nio.LongBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@ -117,7 +118,7 @@ public class ForwardSceneRender implements SceneRenderer {//dynamic rendering
public ForwardSceneRender(VulkanContext vulkanContext){
ClearValueColour = VkClearValue.calloc().color(
c -> c.float32(0, R).float32(1, G).float32(2, B).float32(3, 1.0f));
ClearValueDepth = VkClearValue.calloc().color(c -> c.float32(0, 1.0f));
ClearValueDepth = VkClearValue.calloc().color(c -> c.float32(0, 0.0f));
CreateRenderAttachments(vulkanContext);
PushConstBuffer = (MemoryUtil.memAlloc(PUSH_CONSTANTS_SIZE));
@ -250,10 +251,10 @@ public class ForwardSceneRender implements SceneRenderer {//dynamic rendering
private static Pipeline CreateSkyboxPipeline(VulkanContext VkCtx, ShaderModule[] ShaderModules, DescriptorSetLayout[] DescriptorSetLayouts, boolean DepthWrite, boolean DualRender, boolean Blending, boolean AlphaToCoverage){
int[] skyboxFormats = new int[] {
MultiRenderTargetAttachments.POSITION_FORMAT,
MultiRenderTargetAttachments.ALBEDO_FORMAT,
MultiRenderTargetAttachments.NORMAL_FORMAT,
MultiRenderTargetAttachments.PBR_FORMAT
MultiRenderTargetAttachments.POSITION_FORMAT, MultiRenderTargetAttachments.ALBEDO_FORMAT,
MultiRenderTargetAttachments.NORMAL_FORMAT, MultiRenderTargetAttachments.PBR_FORMAT,
MultiRenderTargetAttachments.EMISSIVE_FORMAT, MultiRenderTargetAttachments.TRANSLUCECNY_FORMAT,
MultiRenderTargetAttachments.OPACITY_FORMAT
};
try (MemoryStack MemStack = MemoryStack.stackPush()) {
@ -292,7 +293,10 @@ public class ForwardSceneRender implements SceneRenderer {//dynamic rendering
private static Pipeline CreatePipeline(VulkanContext VkCtx, ShaderModule[] ShaderModules, DescriptorSetLayout[] DescriptorSetLayouts, boolean DepthWrite, boolean DualRender, boolean Blending, boolean AlphaToCoverage, int BlendingMethod){
var vertexBufferStructure = new VertexBufferStructure();
var BuildInfo = new PipelineBuildInfo(ShaderModules,vertexBufferStructure.getVertexInput(),new int[]{
MultiRenderTargetAttachments.POSITION_FORMAT, MultiRenderTargetAttachments.ALBEDO_FORMAT, MultiRenderTargetAttachments.NORMAL_FORMAT, MultiRenderTargetAttachments.PBR_FORMAT})
MultiRenderTargetAttachments.POSITION_FORMAT, MultiRenderTargetAttachments.ALBEDO_FORMAT,
MultiRenderTargetAttachments.NORMAL_FORMAT, MultiRenderTargetAttachments.PBR_FORMAT,
MultiRenderTargetAttachments.EMISSIVE_FORMAT, MultiRenderTargetAttachments.TRANSLUCECNY_FORMAT,
MultiRenderTargetAttachments.OPACITY_FORMAT})
.SetDepthFormat(MultiRenderTargetAttachments.DEPTH_FORMAT)
.SetDepthWrite(DepthWrite)
.SetPushConstantRanges(
@ -415,6 +419,9 @@ public class ForwardSceneRender implements SceneRenderer {//dynamic rendering
var VkMesh = VkMeshList.get(j);
String MaterialID = VkMesh.MaterialID();
int MaterialIndex = materialsCache.GetPosition(MaterialID);
if(MaterialIndex == -1) {
continue;
}
VulkanMaterial vulkanMaterial = materialsCache.GetMaterial(MaterialID);
if (vulkanMaterial == null) {
Logger.warn("Mesh [{}] in model [{}] does not have material", j, model.GetID());
@ -461,7 +468,12 @@ public class ForwardSceneRender implements SceneRenderer {//dynamic rendering
DescriptorSetLayout.LayoutInformation LayoutInfo = descriptorLayoutFragStorage.GetLayoutInfo();
var Buffer = materialsCache.GetMaterialsBuffer();
descriptorSet.SetBuffer(device,Buffer,Buffer.GetRequestedSize(),LayoutInfo.Binding(),LayoutInfo.DescriptorType());
List<ImageView> imageViews = textureCache.GetTextureList().stream().map(ITexture::GetImageView).toList();
List<ImageView> imageViews = new ArrayList<>(textureCache.GetAll2DTextures().stream().map(ITexture::GetImageView).toList());
ImageView fallback = textureCache.GetTexture("resources/EngineResources/Texture/NoTexture.png").GetImageView();
while (imageViews.size() < TextureCache.MAX_TEXTURES) {
imageViews.add(fallback);
}
descriptorSet = VkCtx.GetDescriptorAllocator().AddDescriptorSet(device,DESCRIPTOR_ID_TEXT,descriptorLayoutTexture);
descriptorSet.SetImageArray(device,imageViews,textureSampler,0);
DescriptorSet descSetSkyBox = descriptorAllocator.AddDescriptorSet(device, DESCRIPTOR_ID_SKYBOX_CUBEMAP, descriptorLayoutSkyboxTexture);

View file

@ -18,6 +18,7 @@ import java.util.Arrays;
import static net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Util.VulkanUtils.vkCheck;
import static org.lwjgl.vulkan.KHRSurface.VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
import static org.lwjgl.vulkan.KHRSurface.VK_ERROR_SURFACE_LOST_KHR;
import static org.lwjgl.vulkan.VK13.*;
public class SwapChain {
@ -102,6 +103,19 @@ public class SwapChain {
return ReturnResult;
}
private static String VkResultName(int result) {
return switch (result) {
case VK_SUCCESS -> "VK_SUCCESS";
case KHRSwapchain.VK_SUBOPTIMAL_KHR -> "VK_SUBOPTIMAL_KHR";
case KHRSwapchain.VK_ERROR_OUT_OF_DATE_KHR -> "VK_ERROR_OUT_OF_DATE_KHR";
case VK_ERROR_DEVICE_LOST -> "VK_ERROR_DEVICE_LOST";
case VK_ERROR_OUT_OF_HOST_MEMORY -> "VK_ERROR_OUT_OF_HOST_MEMORY";
case VK_ERROR_OUT_OF_DEVICE_MEMORY -> "VK_ERROR_OUT_OF_DEVICE_MEMORY";
case VK_ERROR_SURFACE_LOST_KHR -> "VK_ERROR_SURFACE_LOST_KHR";
default -> "Unknown Vulkan error";
};
}
public int FetchNextImage(Device device, Semaphore ImageFetchSemaphore){
int ImageIndex;
try(var MemStack = MemoryStack.stackPush()){
@ -112,8 +126,10 @@ public class SwapChain {
}
else if (Error == KHRSwapchain.VK_SUBOPTIMAL_KHR){
//Logger.warn("Suboptimal surface properties match, not fatal");
} else if (Error == VK_ERROR_DEVICE_LOST) {
throw new RuntimeException("Vulkan device was lost while acquiring the next swapchain image. This usually means an earlier GPU operation was invalid. Result: " + VkResultName(Error) + " (" + Error + ")");
} else if (Error != VK_SUCCESS){
throw new RuntimeException("Failed to fetch next image in the swapchain: " + Error);
throw new RuntimeException("Failed to fetch next image in the swapchain: " + VkResultName(Error) + " (" + Error + ")");
}
ImageIndex = IntPointer.get(0);
}
@ -136,8 +152,8 @@ public class SwapChain {
} else if (Error == KHRSwapchain.VK_SUBOPTIMAL_KHR){
//Logger.warn("Suboptimal surface properties match, not fatal");
} else if (Error != VK_SUCCESS){
Logger.debug("Failure in Present Image");
throw new RuntimeException("failed to present KHR: " + Error);
Logger.debug("Failure in Present Image: " + VkResultName(Error) + " (" + Error + ")");
throw new RuntimeException("failed to present KHR: " + VkResultName(Error) + " (" + Error + ")");
}
}
return resize;

View file

@ -80,7 +80,7 @@ public class EngineThread implements IEngineThread{
Logger.debug("{} Thread Started",ThreadName);
EngineAccuracy = EngineConfig.getInstance().getAccuracy();
OriginalAccuracy = EngineAccuracy;
while (running && !PrimaryRuntime.CanClose && internalRunning && !Thread.currentThread().isInterrupted()){
while (running && internalRunning && !Thread.currentThread().isInterrupted()){
long now = System.nanoTime();
FrameTimes[0] = now - InitialTime;
FrameTimes[1] += FrameTimes[0];

View file

@ -108,7 +108,7 @@ public class VirtualEngineThread implements IEngineThread{
Logger.debug("{} Thread Started",ThreadName);
EngineAccuracy = EngineConfig.getInstance().getAccuracy();
OriginalAccuracy = EngineAccuracy;
while (EngineThread.running && !PrimaryRuntime.CanClose && internalRunning && !Thread.currentThread().isInterrupted()){
while (EngineThread.running && internalRunning && !Thread.currentThread().isInterrupted()){
long now = System.nanoTime();
FrameTimes[0] = now - InitialTime;
FrameTimes[1] += FrameTimes[0];

View file

@ -35,5 +35,5 @@ throttle_on_unfocus=false
user_display_name=TheSigma
vkValidated=true
vsync=false
z_near_plane=0.1f
z_far_plane=10000.0f
z_far_plane=0.1f
z_near_plane=16384.0f