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 { plugins {
id 'application' id 'application'
id 'java' 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.lwjglVersion = "3.4.1"
project.ext.jomlVersion = "1.10.8" project.ext.jomlVersion = "1.10.8"
project.ext.jomlprimitivesVersion = "1.10.0" 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 = 1) uniform sampler2D albedoSampler;
layout(set = 0, binding = 2) uniform sampler2D normalsSampler; layout(set = 0, binding = 2) uniform sampler2D normalsSampler;
layout(set = 0, binding = 3) uniform sampler2D pbrSampler; 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 { layout(scalar, set = 1, binding = 0) readonly buffer Lights {
Light lights[]; Light lights[];
@ -32,6 +35,7 @@ layout(scalar, set = 2, binding = 0) uniform SceneInfo {
float ambientLightIntensity; float ambientLightIntensity;
vec3 ambientLightColor; vec3 ambientLightColor;
uint numLights; uint numLights;
mat4 viewMatrix;
} sceneInfo; } sceneInfo;
float distributionGGX(vec3 N, vec3 H, float roughness) { float distributionGGX(vec3 N, vec3 H, float roughness) {
@ -126,6 +130,10 @@ void main() {
vec3 normal = texture(normalsSampler, inTextCoord).rgb; vec3 normal = texture(normalsSampler, inTextCoord).rgb;
vec3 worldPos = texture(posSampler, inTextCoord).rgb; vec3 worldPos = texture(posSampler, inTextCoord).rgb;
vec3 pbr = texture(pbrSampler, 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 roughness = pbr.g;
float metallic = pbr.b; float metallic = pbr.b;
@ -146,9 +154,9 @@ void main() {
} }
} }
vec3 ambient = sceneInfo.ambientLightColor * albedo * sceneInfo.ambientLightIntensity; 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) { if (length(normal) < 0.001) {
outFragColor = vec4(albedo,1.0f); outFragColor = vec4(albedo,1.0f);
return; 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 = 1) uniform sampler2D albedoSampler;
layout(set = 0, binding = 2) uniform sampler2D normalsSampler; layout(set = 0, binding = 2) uniform sampler2D normalsSampler;
layout(set = 0, binding = 3) uniform sampler2D pbrSampler; 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 { layout(scalar, set = 1, binding = 0) readonly buffer Lights {
Light lights[]; Light lights[];
@ -62,7 +66,7 @@ float chebyshevUpperBound(vec2 moments, float t) {
return p_max; return p_max;
} }
float calcVisibility(vec4 worldPosition, uint cascadeIndex) { float calcVisibility(vec4 worldPosition, uint cascadeIndex, float ShadowBias) {
vec4 shadowMapPosition = shadows.cascadeshadows[cascadeIndex].projViewMatrix * worldPosition; vec4 shadowMapPosition = shadows.cascadeshadows[cascadeIndex].projViewMatrix * worldPosition;
shadowMapPosition.xyz /= shadowMapPosition.w; shadowMapPosition.xyz /= shadowMapPosition.w;
@ -76,14 +80,25 @@ float calcVisibility(vec4 worldPosition, uint cascadeIndex) {
if (uv.x < 0.0 || uv.x > 1.0 || if (uv.x < 0.0 || uv.x > 1.0 ||
uv.y < 0.0 || uv.y > 1.0 || uv.y < 0.0 || uv.y > 1.0 ||
depth < 0.0 || depth > 1.0) { depth < ShadowBias || depth > 1.0) {
return 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); 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) { 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; 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 L = normalize(-light.position);
vec3 H = normalize(V + L); 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; kD *= 1.0 - metallic;
float NdotL = max(dot(N, L), 0.0); 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() { void main() {
@ -179,6 +196,20 @@ void main() {
vec4 worldPosW = texture(posSampler, inTextCoord); vec4 worldPosW = texture(posSampler, inTextCoord);
vec3 worldPos = worldPosW.xyz; vec3 worldPos = worldPosW.xyz;
vec3 pbr = texture(pbrSampler, inTextCoord).rgb; 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 roughness = pbr.g;
float metallic = pbr.b; float metallic = pbr.b;
@ -186,6 +217,8 @@ void main() {
vec3 N = normalize(normal); vec3 N = normalize(normal);
vec3 V = normalize(sceneInfo.camPos - worldPos); vec3 V = normalize(sceneInfo.camPos - worldPos);
vec3 F0 = vec3(0.04); vec3 F0 = vec3(0.04);
F0 = mix(F0, albedo, metallic); F0 = mix(F0, albedo, metallic);
@ -196,18 +229,19 @@ void main() {
cascadeIndex = i + 1; cascadeIndex = i + 1;
} }
} }
float shadow = calcVisibility(vec4(worldPos, 1), cascadeIndex); float shadow = calcVisibility(vec4(worldPos, 1), cascadeIndex,ShadowBias);
vec3 Lo = vec3(0.0); vec3 Lo = vec3(0.0);
for (uint i = 0; i < sceneInfo.numLights; i++) { for (uint i = 0; i < sceneInfo.numLights; i++) {
Light light = lights.lights[i]; Light light = lights.lights[i];
if (light.directional == 1) { 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 { } else {
Lo += calculatePointLight(light, worldPos, V, N, F0, albedo, metallic, roughness); Lo += calculatePointLight(light, worldPos, V, N, F0, albedo, metallic, roughness);
} }
} }
vec3 ambient = sceneInfo.ambientLightColor * albedo * sceneInfo.ambientLightIntensity; 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); outFragColor = vec4(Lo + ambient, 1.0f);
if (DEBUG_SHADOWS == 1) { if (DEBUG_SHADOWS == 1) {

View file

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

View file

@ -10,17 +10,25 @@ layout(location = 4) in vec2 inTextCoords;
layout(location = 0) out vec4 outAlbedo; layout(location = 0) out vec4 outAlbedo;
struct Material { struct Material {
vec4 diffuseColor; vec4 diffuseColor; //16
uint hasTexture; uint hasTexture; //20
uint textureIdx; uint textureIdx; //24
uint hasNormalMap; uint hasNormalMap; //28
uint normalMapIdx; uint normalMapIdx; //32
uint hasRoughMap; uint hasRoughMap; //36
uint roughMapIdx; uint roughMapIdx; //40
float roughnessFactor; float roughnessFactor; //44
float metallicFactor; 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{ layout(set = 2, binding = 0) readonly buffer MaterialUniform{
@ -36,13 +44,23 @@ layout(push_constant) uniform pc{
void main() void main()
{ {
Material material = matUniform.materials[push_constants.materialIdx]; Material material = matUniform.materials[push_constants.materialIdx];
if(material.hasTexture == 1){ if(material.hasTexture == 1){
vec4 texColor = texture(textSampler[material.textureIdx],inTextCoords); vec4 texColor = texture(textSampler[material.textureIdx],inTextCoords);
if(texColor.a < 0.4){discard;}
outAlbedo = texColor; outAlbedo = texColor;
} else{ } else{
outAlbedo = material.diffuseColor; 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 = 0) out vec4 outPos;
layout(location = 2) out vec4 outNormal; layout(location = 2) out vec4 outNormal;
layout(location = 3) out vec4 outPBR; layout(location = 3) out vec4 outPBR;
layout(location = 4) out vec4 outEmissive;
layout(location = 5) out vec4 outTranslucency;
layout(location = 6) out vec4 outOpacity;
struct Material { struct Material {
vec4 diffuseColor; vec4 diffuseColor; //16
uint hasTexture; uint hasTexture; //20
uint textureIdx; uint textureIdx; //24
uint hasNormalMap; uint hasNormalMap; //28
uint normalMapIdx; uint normalMapIdx; //32
uint hasRoughMap; uint hasRoughMap; //36
uint roughMapIdx; uint roughMapIdx; //40
float roughnessFactor; float roughnessFactor; //44
float metallicFactor; 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 { layout(set = 2, binding = 0) readonly buffer MaterialUniform {
Material materials[]; Material materials[];
@ -56,6 +68,17 @@ void main()
outAlbedo = material.diffuseColor; 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; if(outAlbedo.a < 0.5) discard;
@ -75,6 +98,18 @@ void main()
metallicFactor = material.metallicFactor; 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); 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; layout(location = 0) out vec4 outAlbedo;
struct Material { struct Material {
vec4 diffuseColor; vec4 diffuseColor; //16
uint hasTexture; uint hasTexture; //20
uint textureIdx; uint textureIdx; //24
uint hasNormalMap; uint hasNormalMap; //28
uint normalMapIdx; uint normalMapIdx; //32
uint hasRoughMap; uint hasRoughMap; //36
uint roughMapIdx; uint roughMapIdx; //40
float roughnessFactor; float roughnessFactor; //44
float metallicFactor; 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{ layout(set = 2, binding = 0) readonly buffer MaterialUniform{
@ -37,9 +46,18 @@ void main()
Material material = matUniform.materials[push_constants.materialIdx]; Material material = matUniform.materials[push_constants.materialIdx];
if(material.hasTexture == 1){ if(material.hasTexture == 1){
vec4 texColor = texture(textSampler[material.textureIdx],inTextCoords); vec4 texColor = texture(textSampler[material.textureIdx],inTextCoords);
if(texColor.a < 0.9){discard;}
outAlbedo = texColor; outAlbedo = texColor;
} else{ } else{
outAlbedo = material.diffuseColor; 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 = 0) out vec4 outPos;
layout(location = 2) out vec4 outNormal; layout(location = 2) out vec4 outNormal;
layout(location = 3) out vec4 outPBR; layout(location = 3) out vec4 outPBR;
layout(location = 4) out vec4 outEmissive;
layout(location = 5) out vec4 outTranslucency;
layout(location = 6) out vec4 outOpacity;
const float bayerMatrix[16] = float[]( const float bayerMatrix[16] = float[](
0.0 / 16.0, 8.0 / 16.0, 2.0 / 16.0, 10.0 / 16.0, 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 { struct Material {
vec4 diffuseColor; vec4 diffuseColor; //16
uint hasTexture; uint hasTexture; //20
uint textureIdx; uint textureIdx; //24
uint hasNormalMap; uint hasNormalMap; //28
uint normalMapIdx; uint normalMapIdx; //32
uint hasRoughMap; uint hasRoughMap; //36
uint roughMapIdx; uint roughMapIdx; //40
float roughnessFactor; float roughnessFactor; //44
float metallicFactor; 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 { layout(set = 2, binding = 0) readonly buffer MaterialUniform {
Material materials[]; Material materials[];
@ -67,6 +79,19 @@ void main()
int y = int(gl_FragCoord.y) % Intensity; int y = int(gl_FragCoord.y) % Intensity;
float threshold = bayerMatrix[y * Intensity + x]; float threshold = bayerMatrix[y * Intensity + x];
if(outAlbedo.a < threshold || outAlbedo.a < 0.05f) discard;*/ 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; if(outAlbedo.a < 0.75) discard;
@ -86,6 +111,18 @@ void main()
metallicFactor = material.metallicFactor; 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); outPBR = vec4(ao, roughnessFactor, metallicFactor, outAlbedo.a);
} }

View file

@ -11,17 +11,25 @@ layout(location = 4) in vec2 inTextCoords;
layout(location = 0) out vec4 outAlbedo; layout(location = 0) out vec4 outAlbedo;
struct Material { struct Material {
vec4 diffuseColor; vec4 diffuseColor; //16
uint hasTexture; uint hasTexture; //20
uint textureIdx; uint textureIdx; //24
uint hasNormalMap; uint hasNormalMap; //28
uint normalMapIdx; uint normalMapIdx; //32
uint hasRoughMap; uint hasRoughMap; //36
uint roughMapIdx; uint roughMapIdx; //40
float roughnessFactor; float roughnessFactor; //44
float metallicFactor; 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{ layout(set = 2, binding = 0) readonly buffer MaterialUniform{
Material materials[]; Material materials[];
} matUniform; } matUniform;
@ -37,9 +45,19 @@ void main()
Material material = matUniform.materials[push_constants.materialIdx]; Material material = matUniform.materials[push_constants.materialIdx];
if(material.hasTexture == 1){ if(material.hasTexture == 1){
vec4 texColor = texture(textSampler[material.textureIdx],inTextCoords); vec4 texColor = texture(textSampler[material.textureIdx],inTextCoords);
if(texColor.a >= 0.9){discard;}
outAlbedo = texColor; outAlbedo = texColor;
} else{ } else{
outAlbedo = material.diffuseColor; 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 = 0) out vec4 outPos;
layout(location = 2) out vec4 outNormal; layout(location = 2) out vec4 outNormal;
layout(location = 3) out vec4 outPBR; layout(location = 3) out vec4 outPBR;
layout(location = 4) out vec4 outEmissive;
layout(location = 5) out vec4 outTranslucency;
layout(location = 6) out vec4 outOpacity;
const float bayerMatrix[16] = float[]( const float bayerMatrix[16] = float[](
0.0 / 16.0, 8.0 / 16.0, 2.0 / 16.0, 10.0 / 16.0, 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 { struct Material {
vec4 diffuseColor; vec4 diffuseColor; //16
uint hasTexture; uint hasTexture; //20
uint textureIdx; uint textureIdx; //24
uint hasNormalMap; uint hasNormalMap; //28
uint normalMapIdx; uint normalMapIdx; //32
uint hasRoughMap; uint hasRoughMap; //36
uint roughMapIdx; uint roughMapIdx; //40
float roughnessFactor; float roughnessFactor; //44
float metallicFactor; 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 { layout(set = 2, binding = 0) readonly buffer MaterialUniform {
Material materials[]; Material materials[];
} matUniform; } matUniform;
@ -64,6 +77,17 @@ void main()
outAlbedo = material.diffuseColor; 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; if(outAlbedo.a >= 0.75 || outAlbedo.a < 0.05f) discard;
@ -83,6 +107,18 @@ void main()
metallicFactor = material.metallicFactor; 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); 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; layout(location = 0) out vec2 outFragColor;
struct Material { struct Material {
vec4 diffuseColor; vec4 diffuseColor; //16
uint hasTexture; uint hasTexture; //20
uint textureIdx; uint textureIdx; //24
uint hasNormalMap; uint hasNormalMap; //28
uint normalMapIdx; uint normalMapIdx; //32
uint hasRoughMap; uint hasRoughMap; //36
uint roughMapIdx; uint roughMapIdx; //40
float roughnessFactor; float roughnessFactor; //44
float metallicFactor; 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 = 1, binding = 0) uniform sampler2D textSampler[MAX_TEXTURES];
layout(set = 2, binding = 0) readonly buffer MaterialUniform { layout(set = 2, binding = 0) readonly buffer MaterialUniform {
Material materials[]; Material materials[];

View file

@ -7,5 +7,5 @@ layout(location = 1) out vec4 outColor;
layout(set = 2, binding = 0) uniform samplerCube skyboxSampler; layout(set = 2, binding = 0) uniform samplerCube skyboxSampler;
void main() { void main() {
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; outTexCoords = inPosition;
mat4 skyView = mat4(mat3(uboView.view)); mat4 skyView = mat4(mat3(uboView.view));
vec4 pos = uboProj.proj * skyView * vec4(inPosition, 1.0); vec4 pos = uboProj.proj * skyView * vec4(inPosition, 1.0);
gl_Position = vec4(pos.xy, 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 GLCapabilities glCapabilities = null;
private SceneRender sceneRenderer = null; private SceneRender sceneRenderer = null;
private OpenGLGuiRenderer GuiRenderer; private OpenGLGuiRenderer GuiRenderer;
private volatile boolean RebuildShadowsRequested = false;
@Override
public void RequestRebuildShadows() {
RebuildShadowsRequested = true;
}
public OpenGLGuiRenderer GetGuiRenderer(){return GuiRenderer;} public OpenGLGuiRenderer GetGuiRenderer(){return GuiRenderer;}
@ -108,6 +114,11 @@ public class OpenGLRenderer implements Renderer{
frameTimeNS = newFrameTimeNS; frameTimeNS = newFrameTimeNS;
} }
@Override
public void RebuildShadows() {
}
public void Resize(int width, int height) { public void Resize(int width, int height) {
GuiRenderer.Resize(width, height); GuiRenderer.Resize(width, height);
//sceneRenderer.Resize(width, height); //sceneRenderer.Resize(width, height);

View file

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

View file

@ -1,6 +1,7 @@
package net.halbear.Terrain4J.EngineCore.Logic; 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.DeferredSceneRender;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DisplayToScreen.ForwardSceneRender; import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DisplayToScreen.ForwardSceneRender;
import net.halbear.Terrain4J.EngineCore.ServerNetworking.ClientSideNetworkUtils; import net.halbear.Terrain4J.EngineCore.ServerNetworking.ClientSideNetworkUtils;
@ -92,6 +93,16 @@ public class EngineConfig {
public float SoundVolume = 0.0f; public float SoundVolume = 0.0f;
public float WeaponVolume = 0.0f; public float WeaponVolume = 0.0f;
public float AmbientVolume = 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; public float PlayerOnline = 1.0f;
@ -158,7 +169,12 @@ public class EngineConfig {
public String GetLoadingScreenImageLocation(){return LoadingScreenLocation;} public String GetLoadingScreenImageLocation(){return LoadingScreenLocation;}
public void SetLoadingScreenImageLocation(String location){this.LoadingScreenLocation = location;} public void SetLoadingScreenImageLocation(String location){this.LoadingScreenLocation = location;}
public int GetMaxVulkanCrashes(){return MaxVulkanCrashesAllowed;} 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 int GetShadowMapSize(){return ShadowMapSize;}
public void SetRenderer(Renderer renderer){this.renderer = renderer;} public void SetRenderer(Renderer renderer){this.renderer = renderer;}
public boolean DeferredRendering(){return renderer == Renderer.Deferred;} public boolean DeferredRendering(){return renderer == Renderer.Deferred;}
@ -320,9 +336,11 @@ public class EngineConfig {
FOV = (float)(DegToRad * Float.parseFloat(EngineConfigVar.getOrDefault("field_of_view", 60.0f).toString())); FOV = (float)(DegToRad * Float.parseFloat(EngineConfigVar.getOrDefault("field_of_view", 60.0f).toString()));
zNearPlane = (Float.parseFloat(EngineConfigVar.getOrDefault("z_near_plane", 1.0f).toString())); zNearPlane = (Float.parseFloat(EngineConfigVar.getOrDefault("z_near_plane", 1.0f).toString()));
zFarPlane = (Float.parseFloat(EngineConfigVar.getOrDefault("z_far_plane", 100.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())); AAValue = (Integer.parseInt(EngineConfigVar.getOrDefault("anti_alias_mode", 1).toString()));
renderer = Integer.parseInt(EngineConfigVar.getOrDefault("Renderer", 1).toString()) == 0 ? Renderer.Forward: Renderer.Deferred; renderer = Integer.parseInt(EngineConfigVar.getOrDefault("Renderer", 1).toString()) == 0 ? Renderer.Forward: Renderer.Deferred;
ShadowMapSize = Integer.parseInt(EngineConfigVar.getOrDefault("ShadowMapSize", 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()); MaxVulkanCrashesAllowed = Integer.parseInt(EngineConfigVar.getOrDefault("MaxAllowedVulkanCrashes", 10).toString());
ServerPort = Integer.parseInt(EngineConfigVar.getOrDefault("server_port", 25565).toString()); ServerPort = Integer.parseInt(EngineConfigVar.getOrDefault("server_port", 25565).toString());
CompatibilityMode = Boolean.parseBoolean(EngineConfigVar.getOrDefault("compatibility_mode", false).toString()); CompatibilityMode = Boolean.parseBoolean(EngineConfigVar.getOrDefault("compatibility_mode", false).toString());
@ -377,6 +395,7 @@ public class EngineConfig {
EngineConfigVar.setProperty("ShaderRecompiling","true"); EngineConfigVar.setProperty("ShaderRecompiling","true");
EngineConfigVar.setProperty("throttle_accuracy","100000"); EngineConfigVar.setProperty("throttle_accuracy","100000");
EngineConfigVar.setProperty("throttle_on_unfocus","true"); EngineConfigVar.setProperty("throttle_on_unfocus","true");
EngineConfigVar.setProperty("RenderShadows","true");
EngineConfigVar.setProperty("field_of_view","60"); EngineConfigVar.setProperty("field_of_view","60");
EngineConfigVar.setProperty("z_near_plane","1"); EngineConfigVar.setProperty("z_near_plane","1");
EngineConfigVar.setProperty("z_far_plane","100"); EngineConfigVar.setProperty("z_far_plane","100");
@ -384,6 +403,7 @@ public class EngineConfig {
EngineConfigVar.setProperty("DefaultTexturePath",DefaultTexturePath); EngineConfigVar.setProperty("DefaultTexturePath",DefaultTexturePath);
EngineConfigVar.setProperty("MaxDescriptors","1000"); EngineConfigVar.setProperty("MaxDescriptors","1000");
EngineConfigVar.setProperty("anti_alias_mode","1"); EngineConfigVar.setProperty("anti_alias_mode","1");
EngineConfigVar.setProperty("max_shadow_distance","16384");
EngineConfigVar.setProperty("server","false"); EngineConfigVar.setProperty("server","false");
EngineConfigVar.setProperty("ShadowMapSize","4096"); EngineConfigVar.setProperty("ShadowMapSize","4096");
EngineConfigVar.setProperty("LoadingScreenLocation",LoadingScreenLocation); 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 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) 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/*/ For a good explanation, visit this https://dyn4j.org/2010/01/sat/*/
public class SeparatingAxisTheoremTester { public class SeparatingAxisTheoremTester {

View file

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

View file

@ -32,8 +32,7 @@ import static org.lwjgl.assimp.Assimp.*;
public class ModelCompiler { public class ModelCompiler {
private static final Pattern EMBED_TEXT_ID = Pattern.compile("\\*([0-9)]+)"); private static final Pattern EMBED_TEXT_ID = Pattern.compile("\\*([0-9)]+)");
private static final int FLAGS = aiProcess_GenSmoothNormals | aiProcess_JoinIdenticalVertices private static final int FLAGS = aiProcess_GenSmoothNormals | aiProcess_JoinIdenticalVertices
| aiProcess_Triangulate | aiProcess_FixInfacingNormals | aiProcess_CalcTangentSpace | aiProcess_Triangulate | aiProcess_CalcTangentSpace | aiProcess_PreTransformVertices;
| aiProcess_PreTransformVertices;
@Parameter(names = "-model", description = "Model Path", required = true) @Parameter(names = "-model", description = "Model Path", required = true)
private String ModelPath; 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{ public static MaterialData ProcessMaterial(AIScene aiScene, AIMaterial aiMaterial, String ModelName, String BaseDirectory, int Position) throws IOException{
Vector4f diffuse = new Vector4f(); Vector4f diffuse = new Vector4f();
AIColor4D colour = AIColor4D.create(); AIColor4D colour = AIColor4D.create();
AIColor4D emissive_colour = AIColor4D.create();
int Result = aiGetMaterialColor(aiMaterial, AI_MATKEY_COLOR_DIFFUSE, aiTextureType_NONE, 0, colour); int Result = aiGetMaterialColor(aiMaterial, AI_MATKEY_COLOR_DIFFUSE, aiTextureType_NONE, 0, colour);
if(Result == aiReturn_SUCCESS){ if(Result == aiReturn_SUCCESS){
diffuse.set(colour.r(), colour.g(), colour.b(), colour.a()); 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 DiffuseTexture = ProcessTexture(aiScene,aiMaterial,BaseDirectory,aiTextureType_DIFFUSE);
String NormalTexture = ProcessTexture(aiScene,aiMaterial,BaseDirectory,aiTextureType_NORMALS); 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 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}; float[] MetallicArray = new float[]{0.0f};
int[] MaxPointer = new int[]{1}; int[] MaxPointer = new int[]{1};
@ -130,8 +138,26 @@ public class ModelCompiler {
RoughnessArray = new float[]{0.0f}; 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 { 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(); Scene scene = (Scene) engineInstance.scene();
List<ModelData> models = new ArrayList<>(); List<ModelData> models = new ArrayList<>();
List<MaterialData> materials = new ArrayList<>(); List<MaterialData> materials = new ArrayList<>();
// ModelData SponzaData = ModelLoader.LoadModel("resources/models/Cafe/exterior.json"); ModelData SponzaData = ModelLoader.LoadModel("resources/models/Cafe/exterior.json");
// List<MaterialData> SponzaMaterial = ModelLoader.LoadMaterials("resources/models/Cafe/exterior_mat.json"); List<MaterialData> SponzaMaterial = ModelLoader.LoadMaterials("resources/models/Cafe/exterior_mat.json");
// ModelData SponzaData1 = ModelLoader.LoadModel("resources/models/Cafe/interior.json"); ModelData SponzaData1 = ModelLoader.LoadModel("resources/models/Cafe/interior.json");
// List<MaterialData> SponzaMaterial1= ModelLoader.LoadMaterials("resources/models/Cafe/interior_mat.json"); List<MaterialData> SponzaMaterial1= ModelLoader.LoadMaterials("resources/models/Cafe/interior_mat.json");
// scene.AddActor(new Actor3D("Sponza1", SponzaData.ID(), new Vector3f(0,0f,-5f)).SetScale(0.1f)); scene.AddActor(new Actor3D("Sponza1", SponzaData.ID(), new Vector3f(0,0f,-5f)).SetScale(0.1f));
// scene.AddActor(new Actor3D("Sponza2", SponzaData1.ID(), new Vector3f(0,0f,-5f)).SetScale(0.1f)); scene.AddActor(new Actor3D("Sponza2", SponzaData1.ID(), new Vector3f(0,0f,-5f)).SetScale(0.1f));
// ModelData treeModel = ModelLoader.LoadModel("resources/models/tree/tree.json"); // ModelData treeModel = ModelLoader.LoadModel("resources/models/tree/tree.json");
// models.add(treeModel); // 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, 0.0f, 0.0f));
@ -113,7 +113,7 @@ public class GameCore implements GameLogic {
// materials.addAll(ModelLoader.LoadMaterials("resources/models/tree/tree_mat.json")); // materials.addAll(ModelLoader.LoadMaterials("resources/models/tree/tree_mat.json"));
// ModelData treeModel = ModelLoader.LoadModel("resources/models/Forest/forest.json"); // ModelData treeModel = ModelLoader.LoadModel("resources/models/Forest/forest.json");
// models.add(treeModel); // 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); // treeEntity.SetScale(10f);
// scene.AddActor(treeEntity); // scene.AddActor(treeEntity);
// materials.addAll(ModelLoader.LoadMaterials("resources/models/Forest/forest_mat.json")); // 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; boolean createOfflinePlayer = !PrimaryRuntime.IsServer && !ClientSideNetworkUtils.Connected;
// materials.addAll(SponzaMaterial); materials.addAll(SponzaMaterial);
// materials.addAll(SponzaMaterial1); materials.addAll(SponzaMaterial1);
// models.add(SponzaData); models.add(SponzaData);
// models.add(SponzaData1); models.add(SponzaData1);
materials.addAll(MelonaMat); materials.addAll(MelonaMat);
materials.addAll(CollisionVisualisationMat); materials.addAll(CollisionVisualisationMat);
materials.addAll(MelonaMaterial); materials.addAll(MelonaMaterial);
@ -191,49 +191,68 @@ public class GameCore implements GameLogic {
} }
scene.GetLightingManager().GetAmbientLightColour().set(1.0f, 0.9f, 0.75f); scene.GetLightingManager().GetAmbientLightColour().set(1.0f, 0.9f, 0.75f);
scene.GetLightingManager().SetAmbientLightIntensity(0.3f); scene.GetLightingManager().SetAmbientLightIntensity(0.15f);
// scene.GetLightingManager().GetAmbientLightColour().set(0.3f, 0.35f, 0.5f); scene.GetLightingManager().GetAmbientLightColour().set(0.3f, 0.35f, 0.5f);
// scene.GetLightingManager().SetAmbientLightIntensity(0.075f); 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, 2.00f); 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, 1.0f, 1.5f),new Vector3f(0.0f, -1.0f, 0.0f), true, 6.0f); 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); SkyLight.SetType(Light.LightType.Directional);
List<ILight> lights = new ArrayList<>(); List<ILight> lights = new ArrayList<>();
// lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-433, 445f, -424f).div(10.0f),false,3000.0f+ (float)(Math.random() * 100.0))); lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-433, 445f, -424f).div(10.0f),false,3000.0f+ (float)(Math.random() * 100.0)));
// lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-210, 445f, 460f).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f))); lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-210, 445f, 460f).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
// lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-966, 445f, 204f).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f))); lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-966, 445f, 204f).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
// lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-176, 445f, 1000f).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f))); lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-176, 445f, 1000f).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
// lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(777, 445f, 858).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f))); lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(777, 445f, 858).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
// lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(376, 445f, -2136).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f))); lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(376, 445f, -2136).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
// lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,2.0f),new Vector3f(2163, 445f, 1880).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f))); lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,2.0f),new Vector3f(2163, 445f, 1880).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
// lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(3334, 445f, 2405).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f))); lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(3334, 445f, 2405).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
// lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(3509, 445f, 1825).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f))); lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(3509, 445f, 1825).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
// lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(3877, 445f, 3378).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f))); lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(3877, 445f, 3378).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
// lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(4925, 445f, 3430).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f))); lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(4925, 445f, 3430).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
// lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-2083, 445f, -1826).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f))); lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-2083, 445f, -1826).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f)));
//
// lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(2076, 410, 1272).div(10.0f),false,100.0f));
// lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(2446, 465, 2303).div(10.0f),false,100.0f));
// lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-842, 410, -1141).div(10.0f),false,100.0f));
// lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-207, 410, -1830).div(10.0f),false,100.0f));
// lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(899, 460, -2015).div(10.0f),false,100.0f));
// lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(1775, 460, -3448).div(10.0f),false,100.0f));
// lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(1800, 460, -4154).div(10.0f),false,1000.0f));
// lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-1727, 410, -387).div(10.0f),false,100.0f));
// lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-1198, 410, -964).div(10.0f),false,100.0f));
// lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-1778, 410, -1502).div(10.0f),false,100.0f));
// lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-2692, 333, -2109).div(10.0f),false,100.0f));
// lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-2849, 333, -1724).div(10.0f),false,100.0f));
// lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-2019, 410, -729).div(10.0f),false,100.0f));
// lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-1727, 410, -389).div(10.0f),false,100.0f));
// lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-1337, 410, 122).div(10.0f),false,100.0f));
//
//
// lights.add(new Light(new Vector3f(0.75f,2.0f,0.75f),new Vector3f(1086, 425, -3375).div(10.0f),false,500.0f));
//lights.add(new Light(new Vector3f(3.0f,2.25f,0.0f),new Vector3f(350.0f, 1525.0f, -420.0f),false,4000.0f)); lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(2076, 410, 1272).div(10.0f),false,100.0f));
//lights.add(new Light(new Vector3f(3.0f,2.25f,0.0f),new Vector3f(400.0f, 1570.0f, -350.0f),false,1000.0f)); lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(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); lights.add(SkyLight);
ILight[] lightArr = new ILight[lights.size()]; ILight[] lightArr = new ILight[lights.size()];
@ -246,27 +265,29 @@ public class GameCore implements GameLogic {
} }
//if(PrimaryRuntime.IsServer) { //if(PrimaryRuntime.IsServer) {
permutation.GeneratePermutationArray(5783904701859L); permutation.GeneratePermutationArray(5783904701859L);
for(int x = -1; x < 2; x++){ // for(int x = -1; x < 2; x++){
for(int y = -1; y < 2; y++){ // for(int y = -1; y < 2; y++){
GenerateChunk(new Vector3i(x, 0, y), 16); // GenerateChunk(new Vector3i(x, 0, y), 16);
//
} // }
} // }
for(int i = 0; i < 20; i++){ // for(int i = 0; i < 20; i++){
SpawnNewActor(engineInstance, new Vector3f(-5 + (float)Math.random() * 10,10 + (float)Math.random() * 10, -5 + (float)Math.random() * 10), new Vector3f(0, 0, 0), new Vector3f(1, 1, 1)); // SpawnNewActor(engineInstance, new Vector3f(-5 + (float)Math.random() * 10,10 + (float)Math.random() * 10, -5 + (float)Math.random() * 10), new Vector3f(0, 0, 0), new Vector3f(1, 1, 1));
} // }
//} //}
Settings.textBuffer.set(ClientSideNetworkUtils.ServerIP); Settings.textBuffer.set(ClientSideNetworkUtils.ServerIP);
Settings.UsernameBuffer.set("Player"); Settings.UsernameBuffer.set("Player");
return new InitData(models,materials,guiTextures); return new InitData(models,materials,guiTextures);
} }
public static float lightAngle = 70; public static float lightAngle = 70;
public static float lightAnglex = 0;
private void updateDirLight() { 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 yValue = (float) Math.sin(Math.toRadians(lightAngle));
float xValue = (float) Math.sin(Math.toRadians(lightAnglex));
Vector3f lightDirection = SkyLight.GetPosition(); Vector3f lightDirection = SkyLight.GetPosition();
lightDirection.x = 0; lightDirection.x = xValue;
lightDirection.y = yValue; lightDirection.y = yValue;
lightDirection.z = zValue; lightDirection.z = zValue;
lightDirection.normalize(); lightDirection.normalize();
@ -502,6 +523,8 @@ public class GameCore implements GameLogic {
} }
} }
int GUI_MODE = 1;
@Override @Override
public void Input(EngineInstance engineInstance, long FrameDiffNanoSeconds) { public void Input(EngineInstance engineInstance, long FrameDiffNanoSeconds) {
if(PrimaryRuntime.IsServer || RenderThread.Headless) return; if(PrimaryRuntime.IsServer || RenderThread.Headless) return;
@ -510,7 +533,7 @@ public class GameCore implements GameLogic {
scene.GlobalInput(engineInstance,FrameDiffNanoSeconds, null, MOVEMENT_SPEED,this); scene.GlobalInput(engineInstance,FrameDiffNanoSeconds, null, MOVEMENT_SPEED,this);
KeyboardInput input = engineInstance.window().getKeyboardInput(); KeyboardInput input = engineInstance.window().getKeyboardInput();
if(input.keySinglePress(GLFW_KEY_F3)){ 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)){ if(input.keyPressed(GLFW_KEY_UP)){
lightAngle = (lightAngle + 0.5f) % 360; lightAngle = (lightAngle + 0.5f) % 360;
@ -520,6 +543,14 @@ public class GameCore implements GameLogic {
lightAngle = (lightAngle - 0.5f) % 360; lightAngle = (lightAngle - 0.5f) % 360;
updateDirLight(); 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)) { if (input.keySinglePress(GLFW_KEY_ESCAPE)) {
StartMenuActive = !StartMenuActive; StartMenuActive = !StartMenuActive;
StartMenu.GameStarted = StartMenuActive; StartMenu.GameStarted = StartMenuActive;
@ -587,7 +618,7 @@ public class GameCore implements GameLogic {
StartMenuActive = false; StartMenuActive = false;
} }
} else { } else {
engineInstance.scene().RenderGUIs(engineInstance, frameTimeNS, this); if(GUI_MODE == 1)engineInstance.scene().RenderGUIs(engineInstance, frameTimeNS, this);
if (ChangeGraphicsSettings) { if (ChangeGraphicsSettings) {
ImGuiViewport viewport = ImGui.getMainViewport(); ImGuiViewport viewport = ImGui.getMainViewport();
float CenterX = viewport.getWorkPosX() + viewport.getWorkSizeX() / 2.0f; float CenterX = viewport.getWorkPosX() + viewport.getWorkSizeX() / 2.0f;

View file

@ -6,6 +6,7 @@ import imgui.flag.ImGuiWindowFlags;
import imgui.type.ImFloat; import imgui.type.ImFloat;
import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig; import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig;
import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance; import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance;
import net.halbear.Terrain4J.EngineCore.Main.AudioInstance;
import net.halbear.Terrain4J.EngineCore.Main.GameCore; import net.halbear.Terrain4J.EngineCore.Main.GameCore;
import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime; import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime;
import net.halbear.Terrain4J.EngineCore.Main.Scene.GUIOverlay; import net.halbear.Terrain4J.EngineCore.Main.Scene.GUIOverlay;
@ -15,6 +16,14 @@ import org.tinylog.Logger;
public class PerformanceOverlay implements GUIOverlay { public class PerformanceOverlay implements GUIOverlay {
private final ImFloat GammaValue = new ImFloat(0.8545f); 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 @Override
public void RenderGUI(EngineInstance engineInstance, long frameTimeNS, GameCore parent) { public void RenderGUI(EngineInstance engineInstance, long frameTimeNS, GameCore parent) {
int windowFlags = ImGuiWindowFlags.NoDecoration int windowFlags = ImGuiWindowFlags.NoDecoration
@ -48,35 +57,111 @@ public class PerformanceOverlay implements GUIOverlay {
EngineConfig.getInstance().SetRenderingAPI(EngineConfig.RenderAPI.OpenGL); EngineConfig.getInstance().SetRenderingAPI(EngineConfig.RenderAPI.OpenGL);
} }
ImGui.text("Presets:"); ImGui.text("Presets:");
float ZFarPlane = Math.max(EngineConfig.getInstance().GetZFarPlane(), EngineConfig.getInstance().GetZNearPlane());
if(ImGui.button("Lowest")){ if(ImGui.button("Lowest")){
parent.ChangeGraphicsSettings = true; parent.ChangeGraphicsSettings = true;
parent.CoolDown = 2000; parent.CoolDown = 2000;
parent.NextAAMode = (0); parent.NextAAMode = (0);
ForwardSceneRender.SetDualPassRendering(false); ForwardSceneRender.SetDualPassRendering(false);
DeferredSceneRender.SetDualPassRendering(false); DeferredSceneRender.SetDualPassRendering(false);
EngineConfig.getInstance().SetRenderer(EngineConfig.Renderer.Forward);
EngineConfig.getInstance().RenderShadows(false);
EngineConfig.getInstance().SetAlphaToCoverage(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()); if(engineInstance.window().GetLinkedApi() == EngineConfig.RenderAPI.Vulkan)PrimaryRuntime.GetRenderThread().GetRenderer().GetSceneRender().RebuildPipelines(PrimaryRuntime.GetRenderThread().GetRenderer().GetVulkanContext());
} }
ImGui.sameLine(); ImGui.sameLine();
if(ImGui.button("Medium")){ if(ImGui.button("Medium")){
parent.ChangeGraphicsSettings = true; parent.ChangeGraphicsSettings = true;
parent.CoolDown = 2000; parent.CoolDown = 2000;
parent.NextAAMode = (1); parent.NextAAMode = (0);
ForwardSceneRender.SetDualPassRendering(true); ForwardSceneRender.SetDualPassRendering(true);
EngineConfig.getInstance().SetRenderer(EngineConfig.Renderer.Deferred);
DeferredSceneRender.SetDualPassRendering(true); DeferredSceneRender.SetDualPassRendering(true);
EngineConfig.getInstance().RenderShadows(true);
EngineConfig.getInstance().SetAlphaToCoverage(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()); if(engineInstance.window().GetLinkedApi() == EngineConfig.RenderAPI.Vulkan)PrimaryRuntime.GetRenderThread().GetRenderer().GetSceneRender().RebuildPipelines(PrimaryRuntime.GetRenderThread().GetRenderer().GetVulkanContext());
} }
ImGui.sameLine(); ImGui.sameLine();
if(ImGui.button("Highest")){ if(ImGui.button("High")){
parent.ChangeGraphicsSettings = true; parent.ChangeGraphicsSettings = true;
parent.CoolDown = 2000; parent.CoolDown = 2000;
parent.NextAAMode = (4); parent.NextAAMode = (0);
ForwardSceneRender.SetDualPassRendering(true); ForwardSceneRender.SetDualPassRendering(true);
EngineConfig.getInstance().SetRenderer(EngineConfig.Renderer.Deferred);
DeferredSceneRender.SetDualPassRendering(true); DeferredSceneRender.SetDualPassRendering(true);
EngineConfig.getInstance().SetAlphaToCoverage(false); 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()); 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(" ");
ImGui.text("anti aliasing:"); ImGui.text("anti aliasing:");
if(ImGui.button("No AA")){ if(ImGui.button("No AA")){

View file

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

View file

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

View file

@ -32,6 +32,22 @@ public class Project3D {
Resize(LastWidth,LastHeight); 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){ public void ChangeFOV(float newFOV){
FOV = newFOV; FOV = newFOV;
Resize(LastWidth,LastHeight); 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.Shader.*;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Shadows.CascadeData; 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.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.CommandBuffer;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DeviceLayers.Device; import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DeviceLayers.Device;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DisplayToScreen.ImageView; import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DisplayToScreen.ImageView;
@ -41,17 +42,22 @@ import static org.lwjgl.vulkan.VK13.*;
public class LightRenderer { public class LightRenderer {
private static final int COLOUR_FORMAT = VK_FORMAT_R32G32B32A32_SFLOAT; private static final int COLOUR_FORMAT = VK_FORMAT_R32G32B32A32_SFLOAT;
private static final String DESC_ID_ATT = "LIGHT_DESC_ID_ATT"; private static final String DESC_ID_ATT = "LIGHT_DESC_ID_ATT";
private static final String DESC_ID_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_SHADOW_MATRICES = "LIGHT_DESC_ID_SHADOW_MATRICES";
private static final String DESC_ID_LIGHTS = "LIGHT_DESC_ID_LIGHTS"; private static final String DESC_ID_LIGHTS = "LIGHT_DESC_ID_LIGHTS";
private static final String DESC_ID_SCENE = "LIGHT_DESC_ID_SCENE"; private static final String DESC_ID_SCENE = "LIGHT_DESC_ID_SCENE";
private static final String FRAGMENT_SHADER_FILE_GLSL = "resources/EngineResources/shaders/lighting_with_shadows_frag.glsl"; private static final String FRAGMENT_SHADER_FILE_GLSL = "resources/EngineResources/shaders/lighting_with_shadows_frag.glsl";
private static final String FRAGMENT_SHADER_FILE_SPV = FRAGMENT_SHADER_FILE_GLSL + ".spv"; private static final String FRAGMENT_SHADER_FILE_SPV = FRAGMENT_SHADER_FILE_GLSL + ".spv";
private static final String 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_GLSL = "resources/EngineResources/shaders/lighting_vertex.glsl";
private static final String VERTEX_SHADER_FILE_SPV = VERTEX_SHADER_FILE_GLSL + ".spv"; private static final String VERTEX_SHADER_FILE_SPV = VERTEX_SHADER_FILE_GLSL + ".spv";
private final DescriptorSetLayout AttachmentDescriptorSetLayout; private final DescriptorSetLayout AttachmentDescriptorSetLayout;
private final DescriptorSetLayout NoShadowsAttachmentDescriptorSetLayout;
private final VkClearValue ClearValueColour; private final VkClearValue ClearValueColour;
private final Pipeline pipeline; private final Pipeline pipeline;
private final Pipeline NoShadowsPipeline;
private final TextureSampler textureSampler; private final TextureSampler textureSampler;
private Attachment AttachmentColour; private Attachment AttachmentColour;
private VkRenderingAttachmentInfo.Buffer AttachmentInfoColour; private VkRenderingAttachmentInfo.Buffer AttachmentInfoColour;
@ -72,7 +78,7 @@ public class LightRenderer {
RenderInfo = CreateRenderInfo(AttachmentColour, AttachmentInfoColour); RenderInfo = CreateRenderInfo(AttachmentColour, AttachmentInfoColour);
lightSpecConsts = new LightSpecConsts(); lightSpecConsts = new LightSpecConsts();
ShaderModule[] shaderModules = CreateShaderModules(VkCtx, lightSpecConsts); ShaderModule[] shaderModules = CreateShaderModules(VkCtx, lightSpecConsts,true);
var textureSamplerInfo = new TextureSamplerInfo(VK_SAMPLER_ADDRESS_MODE_REPEAT, var textureSamplerInfo = new TextureSamplerInfo(VK_SAMPLER_ADDRESS_MODE_REPEAT,
VK_BORDER_COLOR_INT_OPAQUE_BLACK, 1, true); VK_BORDER_COLOR_INT_OPAQUE_BLACK, 1, true);
@ -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); descSetLayouts[i] = new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, i, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
} }
AttachmentDescriptorSetLayout = new DescriptorSetLayout(VkCtx, descSetLayouts); AttachmentDescriptorSetLayout = new DescriptorSetLayout(VkCtx, descSetLayouts);
CreateAttachmentDescriptorSet(VkCtx, AttachmentDescriptorSetLayout, attachments, textureSampler); CreateAttachmentDescriptorSet(VkCtx, AttachmentDescriptorSetLayout, attachments, textureSampler, true);
StorageDescriptorSetLayout = new DescriptorSetLayout(VkCtx, new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 0, 1, StorageDescriptorSetLayout = new DescriptorSetLayout(VkCtx, new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 0, 1,
VK_SHADER_STAGE_FRAGMENT_BIT)); VK_SHADER_STAGE_FRAGMENT_BIT));
@ -99,6 +105,19 @@ public class LightRenderer {
shadowMatrices = CreateShadowMatrixBuffers(VkCtx, StorageDescriptorSetLayout); shadowMatrices = CreateShadowMatrixBuffers(VkCtx, StorageDescriptorSetLayout);
pipeline = createPipeline(VkCtx, shaderModules, new DescriptorSetLayout[]{AttachmentDescriptorSetLayout, StorageDescriptorSetLayout, pipeline = createPipeline(VkCtx, shaderModules, new DescriptorSetLayout[]{AttachmentDescriptorSetLayout, StorageDescriptorSetLayout,
StorageDescriptorSetLayout, SceneDescriptorSetLayout}); 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()); Logger.debug("Light Renderer Pipeline -> [{}]",pipeline.GetVulkanPipeline());
Arrays.asList(shaderModules).forEach(s -> s.CleanUp(VkCtx)); 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, private static void CreateAttachmentDescriptorSet(VulkanContext VkCtx, DescriptorSetLayout descSetLayout, List<Attachment> attachments,
TextureSampler sampler) { TextureSampler sampler, boolean Shadows) {
DescriptorAllocator descAllocator = VkCtx.GetDescriptorAllocator(); DescriptorAllocator descAllocator = VkCtx.GetDescriptorAllocator();
Device device = VkCtx.GetDevice(); 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<>(); List<ImageView> imageViews = new ArrayList<>();
attachments.forEach(a -> imageViews.add(a.GetVkImageView())); attachments.forEach(a -> imageViews.add(a.GetVkImageView()));
descSet.SetImages(device, imageViews, sampler, 0); descSet.SetImages(device, imageViews, sampler, 0);
@ -176,14 +195,16 @@ public class LightRenderer {
return result; return result;
} }
private static ShaderModule[] CreateShaderModules(VulkanContext VkCtx, LightSpecConsts lightSpecConsts) { private static ShaderModule[] CreateShaderModules(VulkanContext VkCtx, LightSpecConsts lightSpecConsts, boolean shadowPipeline) {
if (EngineConfig.getInstance().RecompileShaders()) { if (EngineConfig.getInstance().RecompileShaders()) {
ShaderCompiler.CompileGLSLShaderOnChange(VERTEX_SHADER_FILE_GLSL, Shaderc.shaderc_glsl_vertex_shader); ShaderCompiler.CompileGLSLShaderOnChange(VERTEX_SHADER_FILE_GLSL, Shaderc.shaderc_glsl_vertex_shader);
ShaderCompiler.CompileGLSLShaderOnChange(FRAGMENT_SHADER_FILE_GLSL, Shaderc.shaderc_glsl_fragment_shader); //ShaderCompiler.CompileGLSLShaderOnChange( FRAGMENT_SHADER_FILE_GLSL, Shaderc.shaderc_glsl_fragment_shader);
ShaderCompiler.CompileGLSLShaderOnChange(shadowPipeline ? FRAGMENT_SHADER_FILE_GLSL : NO_SHADOWS_FRAGMENT_SHADER_FILE_GLSL, Shaderc.shaderc_glsl_fragment_shader);
} }
return new ShaderModule[]{ return new ShaderModule[]{
new ShaderModule(VkCtx, VK_SHADER_STAGE_VERTEX_BIT, VERTEX_SHADER_FILE_SPV, null), new ShaderModule(VkCtx, VK_SHADER_STAGE_VERTEX_BIT, VERTEX_SHADER_FILE_SPV, null),
new ShaderModule(VkCtx, VK_SHADER_STAGE_FRAGMENT_BIT, FRAGMENT_SHADER_FILE_SPV, 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(), VulkanUtils.ImageBarrier(stack, cmdHandle, mrtAttachments.GetDepthAttachment().GetVkImage().getVulkanImage(),
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT,
VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_2_SHADER_READ_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); VK_IMAGE_ASPECT_DEPTH_BIT);
VulkanUtils.ImageBarrier(stack, cmdHandle, shadowAttachment.GetVkImage().getVulkanImage(), 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) { private void UpdateCascadeShadowMatrices(VulkanContext vkCtx, CascadeShadows cascadeShadows, int currentFrame) {
VulkanBuffer buff = shadowMatrices[currentFrame]; VulkanBuffer buff = shadowMatrices[currentFrame];
long mappedMemory = buff.MapMemory(vkCtx); long mappedMemory = buff.MapMemory(vkCtx);
@ -324,6 +414,20 @@ public class LightRenderer {
buffer.UnMapMemory(VkCtx); 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) { public void resize(VulkanContext VkCtx, List<Attachment> attachments) {
RenderInfo.free(); RenderInfo.free();
AttachmentInfoColour.free(); AttachmentInfoColour.free();
@ -337,6 +441,13 @@ public class LightRenderer {
var imageViews = new ArrayList<ImageView>(); var imageViews = new ArrayList<ImageView>();
attachments.forEach(a -> imageViews.add(a.GetVkImageView())); attachments.forEach(a -> imageViews.add(a.GetVkImageView()));
descSet.SetImages(VkCtx.GetDevice(), imageViews, textureSampler, 0); 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) { public void cleanup(VulkanContext VkCtx) {
@ -346,7 +457,9 @@ public class LightRenderer {
SceneDescriptorSetLayout.CleanUp(VkCtx); SceneDescriptorSetLayout.CleanUp(VkCtx);
Arrays.asList(SceneBuffer).forEach(b -> b.cleanup(VkCtx)); Arrays.asList(SceneBuffer).forEach(b -> b.cleanup(VkCtx));
pipeline.CleanUp(VkCtx); pipeline.CleanUp(VkCtx);
NoShadowsPipeline.CleanUp(VkCtx);
AttachmentDescriptorSetLayout.CleanUp(VkCtx); AttachmentDescriptorSetLayout.CleanUp(VkCtx);
NoShadowsAttachmentDescriptorSetLayout.CleanUp(VkCtx);
textureSampler.CleanUp(VkCtx); textureSampler.CleanUp(VkCtx);
lightSpecConsts.cleanup(); lightSpecConsts.cleanup();
RenderInfo.free(); 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 DEPTH_FORMAT = VK_FORMAT_D32_SFLOAT;
public static final int NORMAL_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT; public static final int NORMAL_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT;
public static final int PBR_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT; public static final int PBR_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT;
public static final int 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; public static final int POSITION_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT;
private final List<Attachment> ColourAttachments; private final List<Attachment> ColourAttachments;
private final Attachment DepthAttachment; private final Attachment DepthAttachment;
@ -39,6 +42,15 @@ public class MultiRenderTargetAttachments {
//PBR //PBR
Attachment = new Attachment(VkCtx, Width, Height, PBR_FORMAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 1); Attachment = new Attachment(VkCtx, Width, Height, PBR_FORMAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 1);
ColourAttachments.add(Attachment); 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); 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) var RasterizationStateCreateInfo = VkPipelineRasterizationStateCreateInfo.calloc(MemStack)
.sType$Default() .sType$Default()
.polygonMode(VK_POLYGON_MODE_FILL) .polygonMode(VK_POLYGON_MODE_FILL)
.cullMode(VK_CULL_MODE_NONE) .cullMode(BuildInfo.CullMode())
.frontFace(VK_FRONT_FACE_CLOCKWISE) .frontFace(VK_FRONT_FACE_CLOCKWISE)
.depthClampEnable(BuildInfo.DepthClamp()) .depthClampEnable(BuildInfo.DepthClamp())
.lineWidth(1.0f); .lineWidth(1.0f);
@ -89,7 +89,7 @@ public class DefaultPipeline implements Pipeline {
.sType(VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO) .sType(VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO)
.depthTestEnable(BuildInfo.GetDepthTest()) .depthTestEnable(BuildInfo.GetDepthTest())
.depthWriteEnable(BuildInfo.performDepthWrite()) .depthWriteEnable(BuildInfo.performDepthWrite())
.depthCompareOp(VK_COMPARE_OP_LESS_OR_EQUAL) .depthCompareOp(BuildInfo.DepthBuffer())
.depthBoundsTestEnable(false) .depthBoundsTestEnable(false)
.stencilTestEnable(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 class TextureCache implements ITextureCache {
public static final int MAX_TEXTURES = 256; public static final int MAX_TEXTURES = 256;
private final IndexedLinkedHashMap<String, ITexture> TextureMap; private final IndexedLinkedHashMap<String, ITexture> TextureMap;
private final IndexedLinkedHashMap<String, ITexture> CubemapTextures;
private final List<String> ActualTextures; private final List<String> ActualTextures;
private final List<String> ActualCubemapTextures;
public TextureCache(){ public TextureCache(){
TextureMap = new IndexedLinkedHashMap<>(); TextureMap = new IndexedLinkedHashMap<>();
CubemapTextures = new IndexedLinkedHashMap<>();
ActualTextures = new ArrayList<>(); ActualTextures = new ArrayList<>();
ActualCubemapTextures = new ArrayList<>();
} }
public ITexture AddCubeMapTexture(VulkanContext VkCtx, String ID, String[] FacePaths, int Format) { 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 IndexedLinkedHashMap<String, ITexture> GetTextureCache(){return TextureMap;}
public List<ITexture> GetTextureList(){return new ArrayList<>(TextureMap.values());} 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){ public int GetPosition(String ID){
int result = -1; int result = 0;
if(ID != null){ if(ID != null){
result = TextureMap.GetIndexOf(ID); 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 net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Shader.ShaderModule;
import org.lwjgl.vulkan.VkPipelineVertexInputStateCreateInfo; import org.lwjgl.vulkan.VkPipelineVertexInputStateCreateInfo;
import static org.lwjgl.vulkan.VK10.VK_FORMAT_UNDEFINED; import static org.lwjgl.vulkan.VK10.*;
public class PipelineBuildInfo { public class PipelineBuildInfo {
private final ShaderModule[] ShaderModules; private final ShaderModule[] ShaderModules;
@ -20,6 +20,14 @@ public class PipelineBuildInfo {
private boolean alphaToCoverage = false; private boolean alphaToCoverage = false;
private final int[] ColourFormats; private final int[] ColourFormats;
private int BlendingMethod = 0; 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){ public PipelineBuildInfo(ShaderModule[] shaderModules, VkPipelineVertexInputStateCreateInfo VertexInput, int[] ColourFormat){
this.ColourFormats = ColourFormat; this.ColourFormats = ColourFormat;

View file

@ -31,6 +31,7 @@ import org.tinylog.Logger;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.LongBuffer; import java.nio.LongBuffer;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
@ -83,19 +84,68 @@ public class ShadowRenderer {
private final CascadeShadows[] cascadeShadows; private final CascadeShadows[] cascadeShadows;
private final VkClearValue ClearValueColour; private final VkClearValue ClearValueColour;
private final VkClearValue ClearValueDepth; private final VkClearValue ClearValueDepth;
private final Attachment colorAttachment; private Attachment colorAttachment;
private final VkRenderingAttachmentInfo.Buffer colorAttachmentInfo; private VkRenderingAttachmentInfo.Buffer colorAttachmentInfo;
private final Attachment depthAttachment; private Attachment depthAttachment;
private final VkRenderingAttachmentInfo depthAttachmentInfo; private VkRenderingAttachmentInfo depthAttachmentInfo;
private final DescriptorSetLayout descLayoutFrgStorage; private final DescriptorSetLayout descLayoutFrgStorage;
private final Pipeline pipeline; private Pipeline pipeline;
private final VulkanBuffer[] prjBuffers; private final VulkanBuffer[] prjBuffers;
private final ByteBuffer pushConstBuff; private final ByteBuffer pushConstBuff;
private final VkRenderingInfo renderingInfo; private VkRenderingInfo renderingInfo;
private final DescriptorSetLayout textDescriptorSetLayout; private final DescriptorSetLayout textDescriptorSetLayout;
private final TextureSampler textureSampler; private final TextureSampler textureSampler;
private final DescriptorSetLayout uniformGeomDescriptorSetLayout; 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) { public ShadowRenderer(VulkanContext VulkanContext) {
ClearValueColour = VkClearValue.calloc().color( ClearValueColour = VkClearValue.calloc().color(
c -> c.float32(0, 0.0f).float32(1, 0.0f).float32(2, 0.0f).float32(3, 0.0f)); c -> c.float32(0, 0.0f).float32(1, 0.0f).float32(2, 0.0f).float32(3, 0.0f));
@ -135,6 +185,7 @@ public class ShadowRenderer {
for (int i = 0; i < VulkanUtils.MAX_IN_FLIGHT; i++) { for (int i = 0; i < VulkanUtils.MAX_IN_FLIGHT; i++) {
cascadeShadows[i] = new CascadeShadows(); cascadeShadows[i] = new CascadeShadows();
} }
AllowShadowRendering(true);
} }
private static Attachment createColorAttachment(VulkanContext VulkanContext) { private static Attachment createColorAttachment(VulkanContext VulkanContext) {
@ -179,7 +230,9 @@ public class ShadowRenderer {
}) })
.SetDescriptorSetLayouts(DescriptorSetLayouts) .SetDescriptorSetLayouts(DescriptorSetLayouts)
.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); var pipeline = new DefaultPipeline(VulkanContext, buildInfo);
vtxBuffStruct.cleanup(); vtxBuffStruct.cleanup();
return pipeline; return pipeline;
@ -216,6 +269,7 @@ public class ShadowRenderer {
} }
public void cleanup(VulkanContext VulkanContext) { public void cleanup(VulkanContext VulkanContext) {
AllowShadowRendering(false);
pipeline.CleanUp(VulkanContext); pipeline.CleanUp(VulkanContext);
uniformGeomDescriptorSetLayout.CleanUp(VulkanContext); uniformGeomDescriptorSetLayout.CleanUp(VulkanContext);
descLayoutFrgStorage.CleanUp(VulkanContext); descLayoutFrgStorage.CleanUp(VulkanContext);
@ -248,7 +302,12 @@ public class ShadowRenderer {
var buffer = materialsCache.GetMaterialsBuffer(); var buffer = materialsCache.GetMaterialsBuffer();
descSet.SetBuffer(device, buffer, buffer.GetRequestedSize(), layoutInfo.Binding(), layoutInfo.DescriptorType()); descSet.SetBuffer(device, buffer, buffer.GetRequestedSize(), layoutInfo.Binding(), layoutInfo.DescriptorType());
List<ImageView> imageViews = textureCache.GetTextureList().stream().map(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 = VulkanContext.GetDescriptorAllocator().AddDescriptorSet(device, DESCRIPTOR_ID_TEXT, textDescriptorSetLayout);
descSet.SetImageArray(device, imageViews, textureSampler, 0); descSet.SetImageArray(device, imageViews, textureSampler, 0);
} }
@ -319,6 +378,9 @@ public class ShadowRenderer {
var vulkanMesh = vulkanMeshList.get(j); var vulkanMesh = vulkanMeshList.get(j);
String materialId = vulkanMesh.MaterialID(); String materialId = vulkanMesh.MaterialID();
int materialIdx = materialsCache.GetPosition(materialId); int materialIdx = materialsCache.GetPosition(materialId);
if(materialIdx == -1) {
continue;
}
VulkanMaterial vulkanMaterial = materialsCache.GetMaterial(materialId); VulkanMaterial vulkanMaterial = materialsCache.GetMaterial(materialId);
if (vulkanMaterial == null) { if (vulkanMaterial == null) {
Logger.warn("Mesh [{}] in model [{}] does not have material", j, model.GetID()); 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) { public static void updateCascadeShadows(CascadeShadows cascadeShadows, IScene scene) {
Camera camera = scene.GetCamera(); Camera camera = scene.GetCamera();
Matrix4f viewMatrix = camera.GetViewMatrix(); Matrix4f viewMatrix = camera.GetViewMatrix();
Project3D projection = scene.GetProjection(); Project3D projection = scene.GetProjection().GetNormalFarPlanes();
Matrix4f projMatrix = projection.GetProjectionMatrix(); Matrix4f projMatrix = projection.GetProjectionMatrix();
ILight[] lights = scene.GetLightingManager().GetLights(); ILight[] lights = scene.GetLightingManager().GetLights();
int numLights = lights.length; int numLights = lights.length;
@ -42,14 +42,10 @@ public class ShadowUtils {
float[] cascadeSplits = new float[SceneLightingManager.SHADOW_MAP_CASCADE_COUNT]; float[] cascadeSplits = new float[SceneLightingManager.SHADOW_MAP_CASCADE_COUNT];
float nearClip = projection.GetNearZ(); float nearClip = projection.GetNearZ();//projection.GetNearZ();
float farClip = projection.GetFarZ(); float farClip = EngineConfig.getInstance().MaxShadowDistance();//Math.min(projection.GetFarZ(), EngineConfig.getInstance().MaxShadowDistance());
float clipRange = farClip - nearClip; 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 minZ = nearClip;
float maxZ = nearClip + clipRange; float maxZ = nearClip + clipRange;

View file

@ -2,5 +2,5 @@ package net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.VkModel;
import org.joml.Vector4f; 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.Structure.DeviceLayers.Queues.Queue;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Util.VulkanBuffer; import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Util.VulkanBuffer;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Util.VulkanUtils; import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Util.VulkanUtils;
import org.joml.Vector4f;
import org.lwjgl.system.MemoryUtil; import org.lwjgl.system.MemoryUtil;
import org.tinylog.Logger; 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.*; import static org.lwjgl.vulkan.VK10.*;
public class MaterialsCache { 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 final IndexedLinkedHashMap<String, VulkanMaterial> MaterialsMap;
private VulkanBuffer MaterialsBuffer; private VulkanBuffer MaterialsBuffer;
@ -31,6 +33,7 @@ public class MaterialsCache {
//create staging buffer and GPU only accessibly buffer, add any located textures //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){ 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 MaterialCount = Materials.size();
int BufferSize = MATERIAL_SIZE * MaterialCount; int BufferSize = MATERIAL_SIZE * MaterialCount;
var SrcBuffer = new VulkanBuffer(VkCtx, BufferSize, var SrcBuffer = new VulkanBuffer(VkCtx, BufferSize,
@ -48,20 +51,28 @@ public class MaterialsCache {
int Offset = 0; int Offset = 0;
for(int i = 0; i < MaterialCount; i++){ for(int i = 0; i < MaterialCount; i++){
int materialBaseOffset = i * MATERIAL_SIZE;
Offset = materialBaseOffset;
var Material = Materials.get(i); var Material = Materials.get(i);
String TexturePath = Material.TexturePath(); String TexturePath = Material.TexturePath();
boolean ValidTexture = TexturePath != null && !TexturePath.isEmpty(); boolean hasDiffuseTexture = TexturePath != null && !TexturePath.isEmpty();
boolean TransparentTexture; boolean TransparentTexture;
Logger.debug("Material Texture Path -> [{}]",Material.TexturePath()); Logger.debug("Material Texture Path -> [{}]",Material.TexturePath());
if(ValidTexture){
if(hasDiffuseTexture){
ITexture newTexture = textureCache.AddTexture(VkCtx, TexturePath, TexturePath, VK_FORMAT_R8G8B8A8_SRGB); ITexture newTexture = textureCache.AddTexture(VkCtx, TexturePath, TexturePath, VK_FORMAT_R8G8B8A8_SRGB);
if(newTexture == null) { if(newTexture == null) {
TransparentTexture = false;
TexturePath = "resources/EngineResources/Texture/NoTexture.png"; 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{ } else{
TexturePath = "resources/EngineResources/Texture/NoTexture.png"; TexturePath = "resources/EngineResources/Texture/NoTexture.png";
textureCache.AddTexture(VkCtx, TexturePath, TexturePath, VK_FORMAT_R8G8B8A8_SRGB);
TransparentTexture = Material.DiffuseColour().w < 1.0f; TransparentTexture = Material.DiffuseColour().w < 1.0f;
} }
VulkanMaterial newMaterial = new VulkanMaterial(Material.ID(),TransparentTexture); VulkanMaterial newMaterial = new VulkanMaterial(Material.ID(),TransparentTexture);
@ -70,7 +81,7 @@ public class MaterialsCache {
Material.DiffuseColour().get(Offset,data); Material.DiffuseColour().get(Offset,data);
Offset += VulkanUtils.VEC4_SIZE; Offset += VulkanUtils.VEC4_SIZE;
data.putInt(Offset, ValidTexture ? 1 : 0); data.putInt(Offset, hasDiffuseTexture ? 1 : 0);
Offset += VulkanUtils.INT_SIZE; Offset += VulkanUtils.INT_SIZE;
data.putInt(Offset, textureCache.GetPosition(TexturePath)); data.putInt(Offset, textureCache.GetPosition(TexturePath));
Offset += VulkanUtils.INT_SIZE; Offset += VulkanUtils.INT_SIZE;
@ -79,17 +90,17 @@ public class MaterialsCache {
boolean hasNormalMap = NormalMap != null && !NormalMap.isEmpty(); boolean hasNormalMap = NormalMap != null && !NormalMap.isEmpty();
if(hasNormalMap){ if(hasNormalMap){
textureCache.AddTexture(VkCtx,NormalMap,NormalMap,VK_FORMAT_R8G8B8A8_UNORM); textureCache.AddTexture(VkCtx,NormalMap,NormalMap,VK_FORMAT_R8G8B8A8_UNORM);
} }else NormalMap = "resources/EngineResources/Texture/NoTexture.png";
data.putInt(Offset, hasNormalMap ? 1 : 0); data.putInt(Offset, hasNormalMap ? 1 : 0);
Offset += VulkanUtils.INT_SIZE; Offset += VulkanUtils.INT_SIZE;
data.putInt(Offset, textureCache.GetPosition(NormalMap)); data.putInt(Offset, textureCache.GetPosition(NormalMap));
Offset += VulkanUtils.INT_SIZE; Offset += VulkanUtils.INT_SIZE;
String RoughnessMap = Material.MetalRoughnessMap(); String RoughnessMap = Material.MetalRoughnessMap();
boolean hasRoughness = RoughnessMap != null && !RoughnessMap.isEmpty(); boolean hasRoughness = RoughnessMap != null && !RoughnessMap.equals("null") && !RoughnessMap.isEmpty();
if(hasRoughness){ if(hasRoughness){
textureCache.AddTexture(VkCtx,RoughnessMap,RoughnessMap,VK_FORMAT_R8G8B8A8_UNORM); textureCache.AddTexture(VkCtx,RoughnessMap,RoughnessMap,VK_FORMAT_R8G8B8A8_UNORM);
} }else RoughnessMap = "resources/EngineResources/Texture/NoTexture.png";
data.putInt(Offset, hasRoughness ? 1 : 0); data.putInt(Offset, hasRoughness ? 1 : 0);
Offset += VulkanUtils.INT_SIZE; Offset += VulkanUtils.INT_SIZE;
data.putInt(Offset, textureCache.GetPosition(RoughnessMap)); data.putInt(Offset, textureCache.GetPosition(RoughnessMap));
@ -99,6 +110,48 @@ public class MaterialsCache {
Offset += VulkanUtils.FLOAT_SIZE; Offset += VulkanUtils.FLOAT_SIZE;
data.putFloat(Offset, Material.Metallic()); data.putFloat(Offset, Material.Metallic());
Offset += VulkanUtils.FLOAT_SIZE; 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); // data.position(0);

View file

@ -205,7 +205,12 @@ public class SpriteRenderer {
public void LoadMaterials(VulkanContext VkCtx, MaterialsCache materialsCache, TextureCache textureCache){ public void LoadMaterials(VulkanContext VkCtx, MaterialsCache materialsCache, TextureCache textureCache){
DescriptorAllocator descriptorAllocator = VkCtx.GetDescriptorAllocator(); DescriptorAllocator descriptorAllocator = VkCtx.GetDescriptorAllocator();
Device device = VkCtx.GetDevice(); 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 descriptorSet = VkCtx.GetDescriptorAllocator().AddDescriptorSet(device,DESCRIPTOR_ID_TEXTURE,TextDescriptorSetLayout);
descriptorSet.SetImageArray(device,imageViews,TextureSampler,0); 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){ public DeferredSceneRender(VulkanContext vulkanContext, EngineInstance engineInstance){
ClearValueColour = VkClearValue.calloc().color( ClearValueColour = VkClearValue.calloc().color(
c -> c.float32(0, 0.0f).float32(1, 0.0f).float32(2, 0.0f).float32(3, 0.0f)); c -> c.float32(0, 0.0f).float32(1, 0.0f).float32(2, 0.0f).float32(3, 0.0f));
ClearValueDepth = VkClearValue.calloc().color(c -> c.float32(0, 1.0f)); ClearValueDepth = VkClearValue.calloc().color(c -> c.float32(0, 0.0f));
MRTAttachments = new MultiRenderTargetAttachments(vulkanContext); MRTAttachments = new MultiRenderTargetAttachments(vulkanContext);
AttachmentInfoColour = CreateColourAttachmentInfo(MRTAttachments, ClearValueColour); AttachmentInfoColour = CreateColourAttachmentInfo(MRTAttachments, ClearValueColour);
AttachmentInfoDepth = CreateDepthAttachmentInfo(MRTAttachments, ClearValueDepth); AttachmentInfoDepth = CreateDepthAttachmentInfo(MRTAttachments, ClearValueDepth);
@ -241,7 +241,10 @@ public class DeferredSceneRender implements SceneRenderer {//dynamic rendering
MultiRenderTargetAttachments.POSITION_FORMAT, MultiRenderTargetAttachments.POSITION_FORMAT,
MultiRenderTargetAttachments.ALBEDO_FORMAT, MultiRenderTargetAttachments.ALBEDO_FORMAT,
MultiRenderTargetAttachments.NORMAL_FORMAT, MultiRenderTargetAttachments.NORMAL_FORMAT,
MultiRenderTargetAttachments.PBR_FORMAT MultiRenderTargetAttachments.PBR_FORMAT,
MultiRenderTargetAttachments.EMISSIVE_FORMAT,
MultiRenderTargetAttachments.TRANSLUCECNY_FORMAT,
MultiRenderTargetAttachments.OPACITY_FORMAT
}; };
try (MemoryStack MemStack = MemoryStack.stackPush()) { 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){ private static Pipeline CreatePipeline(VulkanContext VkCtx, ShaderModule[] ShaderModules, DescriptorSetLayout[] DescriptorSetLayouts, boolean DepthWrite, boolean DualRender, boolean Blending, boolean AlphaToCoverage, int BlendingMethod){
var vertexBufferStructure = new VertexBufferStructure(); var vertexBufferStructure = new VertexBufferStructure();
var BuildInfo = new PipelineBuildInfo(ShaderModules,vertexBufferStructure.getVertexInput(),new int[]{ var BuildInfo = new PipelineBuildInfo(ShaderModules,vertexBufferStructure.getVertexInput(),new int[]{
MultiRenderTargetAttachments.POSITION_FORMAT, MultiRenderTargetAttachments.ALBEDO_FORMAT, MultiRenderTargetAttachments.NORMAL_FORMAT, MultiRenderTargetAttachments.PBR_FORMAT}) MultiRenderTargetAttachments.POSITION_FORMAT, MultiRenderTargetAttachments.ALBEDO_FORMAT,
MultiRenderTargetAttachments.NORMAL_FORMAT, MultiRenderTargetAttachments.PBR_FORMAT,
MultiRenderTargetAttachments.EMISSIVE_FORMAT, MultiRenderTargetAttachments.TRANSLUCECNY_FORMAT,
MultiRenderTargetAttachments.OPACITY_FORMAT})
.SetDepthFormat(MultiRenderTargetAttachments.DEPTH_FORMAT) .SetDepthFormat(MultiRenderTargetAttachments.DEPTH_FORMAT)
.SetDepthWrite(DepthWrite) .SetDepthWrite(DepthWrite)
.SetPushConstantRanges( .SetPushConstantRanges(
@ -318,10 +324,11 @@ public class DeferredSceneRender implements SceneRenderer {//dynamic rendering
VK_IMAGE_ASPECT_COLOR_BIT); VK_IMAGE_ASPECT_COLOR_BIT);
} }
VulkanUtils.ImageBarrier(MemStack, CommandHandle, MRTAttachments.GetDepthAttachment().GetVkImage().getVulkanImage(), 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_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT, VK_ACCESS_2_NONE,
VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_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_IMAGE_ASPECT_DEPTH_BIT); VK_IMAGE_ASPECT_DEPTH_BIT);
long InitialTime = System.nanoTime(); long InitialTime = System.nanoTime();
@ -427,13 +434,17 @@ public class DeferredSceneRender implements SceneRenderer {//dynamic rendering
var VkMesh = VkMeshList.get(j); var VkMesh = VkMeshList.get(j);
String MaterialID = VkMesh.MaterialID(); String MaterialID = VkMesh.MaterialID();
int MaterialIndex = materialsCache.GetPosition(MaterialID); int MaterialIndex = materialsCache.GetPosition(MaterialID);
if(MaterialIndex == -1) {
continue;
}
VulkanMaterial vulkanMaterial = materialsCache.GetMaterial(MaterialID); VulkanMaterial vulkanMaterial = materialsCache.GetMaterial(MaterialID);
if (vulkanMaterial == null) { if (vulkanMaterial == null) {
Logger.warn("Mesh [{}] in model [{}] does not have material", j, model.GetID()); Logger.warn("Mesh [{}] in model [{}] does not have material", j, model.GetID());
continue; continue;
} }
if (DualPassRendering || vulkanMaterial.HasTransparency() == Transparent) { 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()); vertexBuffer.put(0, VkMesh.VerticesBuffer().GetBuffer());
vkCmdBindVertexBuffers(CommandHandle, 0, vertexBuffer, offsets); vkCmdBindVertexBuffers(CommandHandle, 0, vertexBuffer, offsets);
vkCmdBindIndexBuffer(CommandHandle, VkMesh.IndicesBuffer().GetBuffer(), 0, VK_INDEX_TYPE_UINT32); 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){ private void SetPushConstants(VkCommandBuffer CmdHandle, Matrix4f ModelMatrix, int MaterialIndex){
ModelMatrix.get(0,PushConstBuffer); ModelMatrix.get(0,PushConstBuffer);
PushConstBuffer.putInt(VulkanUtils.MATRIX4X4_SIZE, MaterialIndex); PushConstBuffer.putInt(VulkanUtils.MATRIX4X4_SIZE, MaterialIndex);
@ -477,7 +497,12 @@ public class DeferredSceneRender implements SceneRenderer {//dynamic rendering
var buffer = materialsCache.GetMaterialsBuffer(); var buffer = materialsCache.GetMaterialsBuffer();
descSet.SetBuffer(device, buffer, buffer.GetRequestedSize(), layoutInfo.Binding(), layoutInfo.DescriptorType()); descSet.SetBuffer(device, buffer, buffer.GetRequestedSize(), layoutInfo.Binding(), layoutInfo.DescriptorType());
List<ImageView> imageViews = textureCache.GetTextureList().stream().map(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 = VkCtx.GetDescriptorAllocator().AddDescriptorSet(device, DESCRIPTOR_ID_TEXT, descriptorLayoutTexture);
descSet.SetImageArray(device, imageViews, textureSampler, 0); descSet.SetImageArray(device, imageViews, textureSampler, 0);

View file

@ -32,6 +32,7 @@ import org.tinylog.Logger;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.LongBuffer; import java.nio.LongBuffer;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
@ -117,7 +118,7 @@ public class ForwardSceneRender implements SceneRenderer {//dynamic rendering
public ForwardSceneRender(VulkanContext vulkanContext){ public ForwardSceneRender(VulkanContext vulkanContext){
ClearValueColour = VkClearValue.calloc().color( ClearValueColour = VkClearValue.calloc().color(
c -> c.float32(0, R).float32(1, G).float32(2, B).float32(3, 1.0f)); c -> c.float32(0, R).float32(1, G).float32(2, B).float32(3, 1.0f));
ClearValueDepth = VkClearValue.calloc().color(c -> c.float32(0, 1.0f)); ClearValueDepth = VkClearValue.calloc().color(c -> c.float32(0, 0.0f));
CreateRenderAttachments(vulkanContext); CreateRenderAttachments(vulkanContext);
PushConstBuffer = (MemoryUtil.memAlloc(PUSH_CONSTANTS_SIZE)); 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){ private static Pipeline CreateSkyboxPipeline(VulkanContext VkCtx, ShaderModule[] ShaderModules, DescriptorSetLayout[] DescriptorSetLayouts, boolean DepthWrite, boolean DualRender, boolean Blending, boolean AlphaToCoverage){
int[] skyboxFormats = new int[] { int[] skyboxFormats = new int[] {
MultiRenderTargetAttachments.POSITION_FORMAT, MultiRenderTargetAttachments.POSITION_FORMAT, MultiRenderTargetAttachments.ALBEDO_FORMAT,
MultiRenderTargetAttachments.ALBEDO_FORMAT, MultiRenderTargetAttachments.NORMAL_FORMAT, MultiRenderTargetAttachments.PBR_FORMAT,
MultiRenderTargetAttachments.NORMAL_FORMAT, MultiRenderTargetAttachments.EMISSIVE_FORMAT, MultiRenderTargetAttachments.TRANSLUCECNY_FORMAT,
MultiRenderTargetAttachments.PBR_FORMAT MultiRenderTargetAttachments.OPACITY_FORMAT
}; };
try (MemoryStack MemStack = MemoryStack.stackPush()) { 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){ private static Pipeline CreatePipeline(VulkanContext VkCtx, ShaderModule[] ShaderModules, DescriptorSetLayout[] DescriptorSetLayouts, boolean DepthWrite, boolean DualRender, boolean Blending, boolean AlphaToCoverage, int BlendingMethod){
var vertexBufferStructure = new VertexBufferStructure(); var vertexBufferStructure = new VertexBufferStructure();
var BuildInfo = new PipelineBuildInfo(ShaderModules,vertexBufferStructure.getVertexInput(),new int[]{ var BuildInfo = new PipelineBuildInfo(ShaderModules,vertexBufferStructure.getVertexInput(),new int[]{
MultiRenderTargetAttachments.POSITION_FORMAT, MultiRenderTargetAttachments.ALBEDO_FORMAT, MultiRenderTargetAttachments.NORMAL_FORMAT, MultiRenderTargetAttachments.PBR_FORMAT}) MultiRenderTargetAttachments.POSITION_FORMAT, MultiRenderTargetAttachments.ALBEDO_FORMAT,
MultiRenderTargetAttachments.NORMAL_FORMAT, MultiRenderTargetAttachments.PBR_FORMAT,
MultiRenderTargetAttachments.EMISSIVE_FORMAT, MultiRenderTargetAttachments.TRANSLUCECNY_FORMAT,
MultiRenderTargetAttachments.OPACITY_FORMAT})
.SetDepthFormat(MultiRenderTargetAttachments.DEPTH_FORMAT) .SetDepthFormat(MultiRenderTargetAttachments.DEPTH_FORMAT)
.SetDepthWrite(DepthWrite) .SetDepthWrite(DepthWrite)
.SetPushConstantRanges( .SetPushConstantRanges(
@ -415,6 +419,9 @@ public class ForwardSceneRender implements SceneRenderer {//dynamic rendering
var VkMesh = VkMeshList.get(j); var VkMesh = VkMeshList.get(j);
String MaterialID = VkMesh.MaterialID(); String MaterialID = VkMesh.MaterialID();
int MaterialIndex = materialsCache.GetPosition(MaterialID); int MaterialIndex = materialsCache.GetPosition(MaterialID);
if(MaterialIndex == -1) {
continue;
}
VulkanMaterial vulkanMaterial = materialsCache.GetMaterial(MaterialID); VulkanMaterial vulkanMaterial = materialsCache.GetMaterial(MaterialID);
if (vulkanMaterial == null) { if (vulkanMaterial == null) {
Logger.warn("Mesh [{}] in model [{}] does not have material", j, model.GetID()); 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(); DescriptorSetLayout.LayoutInformation LayoutInfo = descriptorLayoutFragStorage.GetLayoutInfo();
var Buffer = materialsCache.GetMaterialsBuffer(); var Buffer = materialsCache.GetMaterialsBuffer();
descriptorSet.SetBuffer(device,Buffer,Buffer.GetRequestedSize(),LayoutInfo.Binding(),LayoutInfo.DescriptorType()); descriptorSet.SetBuffer(device,Buffer,Buffer.GetRequestedSize(),LayoutInfo.Binding(),LayoutInfo.DescriptorType());
List<ImageView> imageViews = textureCache.GetTextureList().stream().map(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 = VkCtx.GetDescriptorAllocator().AddDescriptorSet(device,DESCRIPTOR_ID_TEXT,descriptorLayoutTexture);
descriptorSet.SetImageArray(device,imageViews,textureSampler,0); descriptorSet.SetImageArray(device,imageViews,textureSampler,0);
DescriptorSet descSetSkyBox = descriptorAllocator.AddDescriptorSet(device, DESCRIPTOR_ID_SKYBOX_CUBEMAP, descriptorLayoutSkyboxTexture); 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 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_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
import static org.lwjgl.vulkan.KHRSurface.VK_ERROR_SURFACE_LOST_KHR;
import static org.lwjgl.vulkan.VK13.*; import static org.lwjgl.vulkan.VK13.*;
public class SwapChain { public class SwapChain {
@ -102,6 +103,19 @@ public class SwapChain {
return ReturnResult; 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){ public int FetchNextImage(Device device, Semaphore ImageFetchSemaphore){
int ImageIndex; int ImageIndex;
try(var MemStack = MemoryStack.stackPush()){ try(var MemStack = MemoryStack.stackPush()){
@ -112,8 +126,10 @@ public class SwapChain {
} }
else if (Error == KHRSwapchain.VK_SUBOPTIMAL_KHR){ else if (Error == KHRSwapchain.VK_SUBOPTIMAL_KHR){
//Logger.warn("Suboptimal surface properties match, not fatal"); //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){ } 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); ImageIndex = IntPointer.get(0);
} }
@ -136,8 +152,8 @@ public class SwapChain {
} else if (Error == KHRSwapchain.VK_SUBOPTIMAL_KHR){ } else if (Error == KHRSwapchain.VK_SUBOPTIMAL_KHR){
//Logger.warn("Suboptimal surface properties match, not fatal"); //Logger.warn("Suboptimal surface properties match, not fatal");
} else if (Error != VK_SUCCESS){ } else if (Error != VK_SUCCESS){
Logger.debug("Failure in Present Image"); Logger.debug("Failure in Present Image: " + VkResultName(Error) + " (" + Error + ")");
throw new RuntimeException("failed to present KHR: " + Error); throw new RuntimeException("failed to present KHR: " + VkResultName(Error) + " (" + Error + ")");
} }
} }
return resize; return resize;

View file

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

View file

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

View file

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