diff --git a/.gitignore b/.gitignore index c725741..c80b3da 100644 --- a/.gitignore +++ b/.gitignore @@ -87,3 +87,5 @@ fabric.properties /resources/models/bistrohd/ /resources/models/Cafe/ /resources/models/Forest/ +/resources/models/tree/ +/resources/models/woman/ diff --git a/resources/EngineResources/Texture/test_cube.png b/resources/EngineResources/Texture/test_cube.png new file mode 100644 index 0000000..bc5571f Binary files /dev/null and b/resources/EngineResources/Texture/test_cube.png differ diff --git a/resources/EngineResources/shaders/bloom_pass_frag.glsl b/resources/EngineResources/shaders/bloom_pass_frag.glsl new file mode 100644 index 0000000..ee83d34 --- /dev/null +++ b/resources/EngineResources/shaders/bloom_pass_frag.glsl @@ -0,0 +1,61 @@ +#version 450 +layout(location = 0) out vec4 FragColor; + +layout(location = 0) in vec2 TexCoords; + +layout(set = 0, binding = 0) uniform sampler2D image; +layout(set = 0, binding = 1) uniform sampler2D bloomImage; +layout(set = 1 , binding = 0) uniform PassConfig{ + int ApplyToFinalImage; + int horizontal; + float GAMMA_CONST; + float Exposure; + float blur_radius; + vec3 padding; +} config; + + + +const float weight[5] = float[] (0.227027, 0.1945946, 0.1216216, 0.054054, 0.016216); + +vec3 safeBloomSample(vec2 uv) +{ + vec3 value = texture(bloomImage, uv).rgb; + return clamp(value, vec3(0.0), vec3(8.0)); +} + +void main() +{ + if(config.ApplyToFinalImage != 0){ + vec3 bloomColour = safeBloomSample(TexCoords); + vec3 hdrColour = texture(image, TexCoords).rgb; + hdrColour += bloomColour; + vec3 result = vec3(1.0) - exp(-hdrColour * config.Exposure); + result = pow(result, vec3(1.0 / config.GAMMA_CONST)); + FragColor = vec4(result, 1.0); + return; + } + + float blurRadius = config.blur_radius; + vec2 tex_offset = blurRadius / vec2(textureSize(bloomImage, 0)); + vec3 result = safeBloomSample(TexCoords) * weight[0]; + + if(config.horizontal != 0) + { + for(int i = 1; i < 5; ++i) + { + result += safeBloomSample(TexCoords + vec2(tex_offset.x * i, 0.0)) * weight[i]; + result += safeBloomSample(TexCoords - vec2(tex_offset.x * i, 0.0)) * weight[i]; + } + } + else + { + for(int i = 1; i < 5; ++i) + { + result += safeBloomSample(TexCoords + vec2(0.0, tex_offset.y * i)) * weight[i]; + result += safeBloomSample(TexCoords - vec2(0.0, tex_offset.y * i)) * weight[i]; + } + } + + FragColor = vec4(result, 1.0); +} \ No newline at end of file diff --git a/resources/EngineResources/shaders/lighting_frag.glsl b/resources/EngineResources/shaders/lighting_frag.glsl index 6fe8fc3..515758c 100644 --- a/resources/EngineResources/shaders/lighting_frag.glsl +++ b/resources/EngineResources/shaders/lighting_frag.glsl @@ -26,7 +26,8 @@ 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(set = 0, binding = 7) uniform sampler2D ssaoBlur; +layout(set = 0, binding = 7) uniform sampler2D ViewPos; +layout(set = 0, binding = 8) uniform sampler2D ssaoBlur; layout(scalar, set = 1, binding = 0) readonly buffer Lights { Light lights[]; @@ -128,17 +129,18 @@ vec3 calculateDirectionalLight(Light light, vec3 V, vec3 N, vec3 F0, vec3 albedo void main() { vec3 albedo = texture(albedoSampler, inTextCoord).rgb; - vec3 normal = texture(normalsSampler, inTextCoord).rgb; + vec4 normalW = texture(normalsSampler, inTextCoord); + vec3 normal = normalW.rgb; + vec3 viewPos = texture(ViewPos, inTextCoord).rgb; vec3 worldPos = texture(posSampler, inTextCoord).rgb; - vec3 pbr = texture(pbrSampler, inTextCoord).rgb; + vec4 pbr = texture(pbrSampler, inTextCoord); vec3 emissive = texture(emissiveSampler, inTextCoord).rgb; vec3 translucency = texture(TranslucencySampler, inTextCoord).rgb; float emissiveness = emissive.r; -// outFragColor = vec4(vec3(texture(ssaoBlur, inTextCoord).r), 1); -// return; - float ssao = texture(ssaoBlur, inTextCoord).r; + outFragColor = vec4(vec3(normalW.a/2.0,normalW.a/2.0,normalW.a/2.0), 1); + return; float roughness = pbr.g; float metallic = pbr.b; diff --git a/resources/EngineResources/shaders/lighting_frag.glsl.spv b/resources/EngineResources/shaders/lighting_frag.glsl.spv index caffa84..2fdb098 100644 Binary files a/resources/EngineResources/shaders/lighting_frag.glsl.spv and b/resources/EngineResources/shaders/lighting_frag.glsl.spv differ diff --git a/resources/EngineResources/shaders/lighting_with_shadows_frag.glsl b/resources/EngineResources/shaders/lighting_with_shadows_frag.glsl index 17d3d13..2065e0d 100644 --- a/resources/EngineResources/shaders/lighting_with_shadows_frag.glsl +++ b/resources/EngineResources/shaders/lighting_with_shadows_frag.glsl @@ -30,8 +30,9 @@ 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(set = 0, binding = 7) uniform sampler2D ssaoBlur; -layout(set = 0, binding = 8) uniform sampler2DArray shadowSampler; +layout(set = 0, binding = 7) uniform sampler2D viewPos; +layout(set = 0, binding = 8) uniform sampler2D ssaoBlur; +layout(set = 0, binding = 9) uniform sampler2DArray shadowSampler; layout(scalar, set = 1, binding = 0) readonly buffer Lights { @@ -62,12 +63,12 @@ float chebyshevUpperBound(vec2 moments, float t) { float p_max = variance / (variance + d * d); // Reduce light bleeding - p_max = smoothstep(0.2, 1.0, p_max); + p_max = smoothstep(0.5, 1.0, p_max); return p_max; } -float calcVisibility(vec4 worldPosition, uint cascadeIndex, float ShadowBias) { +float calcVisibility(vec4 worldPosition, uint cascadeIndex, float ShadowBias, vec2 texelSize) { vec4 shadowMapPosition = shadows.cascadeshadows[cascadeIndex].projViewMatrix * worldPosition; shadowMapPosition.xyz /= shadowMapPosition.w; @@ -87,19 +88,18 @@ float calcVisibility(vec4 worldPosition, uint cascadeIndex, float ShadowBias) { 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); - shadow += depth - ShadowBias > visibility ? 1.0 : 0.0; + shadow += visibility; } } shadow /= 9.0; - return 1 - shadow; + return shadow; } float distributionGGX(vec3 N, vec3 H, float roughness) { @@ -193,13 +193,17 @@ vec3 calculateDirectionalLight(Light light, vec3 V, vec3 N, vec3 F0, vec3 albedo void main() { vec3 albedo = texture(albedoSampler, inTextCoord).rgb; - vec3 normal = texture(normalsSampler, inTextCoord).rgb; + vec4 normalW = texture(normalsSampler, inTextCoord); + vec3 normal = normalW.rgb; vec4 worldPosW = texture(posSampler, inTextCoord); vec3 worldPos = worldPosW.xyz; - vec3 pbr = texture(pbrSampler, inTextCoord).rgb; + vec4 pbrW = texture(pbrSampler, inTextCoord); + vec3 pbr = pbrW.rgb; vec3 emissive = texture(emissiveSampler, inTextCoord).rgb; vec3 Opacity = texture(OpacitySampler, inTextCoord).rgb; vec3 translucency = texture(TranslucencySampler, inTextCoord).rgb; + float Reflectivity = pbrW.a; + float Refractivity = normalW.a; float emissiveness = emissive.r; float translucencyf = translucency.r; @@ -231,7 +235,10 @@ void main() { cascadeIndex = i + 1; } } - float shadow = calcVisibility(vec4(worldPos, 1), cascadeIndex,ShadowBias); + + vec2 texelSizeShadow = 1.0 / textureSize(shadowSampler, 0).rg; + + float shadow = calcVisibility(vec4(worldPos, 1), cascadeIndex,ShadowBias, texelSizeShadow); vec3 Lo = vec3(0.0); for (uint i = 0; i < sceneInfo.numLights; i++) { @@ -242,7 +249,7 @@ void main() { Lo += calculatePointLight(light, worldPos, V, N, F0, albedo, metallic, roughness); } } - vec3 ambient = sceneInfo.ambientLightColor * albedo * sceneInfo.ambientLightIntensity * vec3(ssao,ssao,ssao);; + vec3 ambient = sceneInfo.ambientLightColor * albedo * sceneInfo.ambientLightIntensity * vec3(ssao,ssao,ssao); if(emissive.x > 0 || emissive.y > 0 || emissive.z > 0) ambient = emissive; outFragColor = vec4(Lo + ambient, 1.0f); outFragColor = vec4(outFragColor.xyz/2 + (outFragColor.xyz/2) * vec3(ssao,ssao,ssao),1); diff --git a/resources/EngineResources/shaders/multi-sampled_post_process_frag.glsl b/resources/EngineResources/shaders/multi-sampled_post_process_frag.glsl index 0dd511b..f219f97 100644 --- a/resources/EngineResources/shaders/multi-sampled_post_process_frag.glsl +++ b/resources/EngineResources/shaders/multi-sampled_post_process_frag.glsl @@ -9,6 +9,7 @@ const float REDUCE_MUL = 1.0/32.0; layout(location = 0) in vec2 inTextCoord; layout(location = 0) out vec4 outFragColor; +layout(location = 1) out vec4 outBloomColour; layout(set = 0, binding = 0) uniform sampler2DMS inputTexture; @@ -19,7 +20,12 @@ layout(set = 1, binding = 0) uniform ScreenSize{ vec4 gamma(vec4 color){ return color = vec4(pow(color.rgb,vec3(GAMMA_CONST)),color.a); } - +vec3 HDR(float Gamma, float Exposure, sampler2D Texture, vec2 TexCoords){ + vec3 hdrColor = texture(Texture, TexCoords).rgb; + vec3 mapped = vec3(1.0) - exp(-hdrColor * Exposure); + mapped = pow(mapped, vec3(1.0 / Gamma)); + return mapped; +} vec4 msaa(int sampleCount, sampler2DMS textureIn,vec2 TextCoord){ ivec2 pixelCoords = ivec2(TextCoord * textureSize(textureIn)); vec4 colorSum = vec4(0.0); @@ -34,6 +40,8 @@ vec4 msaa(int sampleCount, sampler2DMS textureIn,vec2 TextCoord){ void main(){ ivec2 pixelCoords = ivec2(inTextCoord * textureSize(inputTexture)); + outFragColor = texelFetch(inputTexture, pixelCoords, 0); + if(USE_AA == 0){ outFragColor = texelFetch(inputTexture,pixelCoords,0); } @@ -49,5 +57,16 @@ void main(){ if(USE_AA == 4){ outFragColor = msaa(8,inputTexture,inTextCoord); } - outFragColor = gamma(outFragColor); + + vec3 color = outFragColor.rgb; + + float brightness = dot(color, vec3(0.2126, 0.7152, 0.0722)); + + float threshold = 1.0; + float softKnee = 0.5; + + float contribution = max(brightness - threshold, 0.0); + contribution = contribution / max(contribution + softKnee, 0.0001); + + outBloomColour = vec4(color * contribution, 1.0); } \ No newline at end of file diff --git a/resources/EngineResources/shaders/multi-sampled_post_process_frag.glsl.spv b/resources/EngineResources/shaders/multi-sampled_post_process_frag.glsl.spv index 2cf3d79..2b3bfbe 100644 Binary files a/resources/EngineResources/shaders/multi-sampled_post_process_frag.glsl.spv and b/resources/EngineResources/shaders/multi-sampled_post_process_frag.glsl.spv differ diff --git a/resources/EngineResources/shaders/post_process_frag.glsl b/resources/EngineResources/shaders/post_process_frag.glsl index b15b7d0..38ef3ac 100644 --- a/resources/EngineResources/shaders/post_process_frag.glsl +++ b/resources/EngineResources/shaders/post_process_frag.glsl @@ -2,13 +2,15 @@ layout(constant_id = 0) const int USE_AA = 0; -const float GAMMA_CONST = 0.8545; +const float GAMMA_CONST = 0.4545; +const float Exposure = 2.0; const float SPAN_MAX = 8.0; const float REDUCE_MIN = 1.0/128.0; const float REDUCE_MUL = 1.0/32.0; layout(location = 0) in vec2 inTextCoord; layout(location = 0) out vec4 outFragColor; +layout(location = 1) out vec4 outBloomColour; layout(set = 0, binding = 0) uniform sampler2D inputTexture; @@ -20,6 +22,13 @@ vec4 gamma(vec4 color){ return color = vec4(pow(color.rgb,vec3(GAMMA_CONST)),color.a); } +vec3 HDR(float Gamma, float Exposure, sampler2D Texture, vec2 TexCoords){ + vec3 hdrColor = texture(Texture, TexCoords).rgb; + vec3 mapped = vec3(1.0) - exp(-hdrColor * Exposure); + mapped = pow(mapped, vec3(1.0 / Gamma)); + return mapped; +} + // Sourced from: https://mini.gmshaders.com/p/gm-shaders-mini-fxaa vec4 fxaa(sampler2D tex, vec2 uv) { vec2 u_texel = 1.0 / screenSize.size; @@ -74,17 +83,32 @@ void main(){ if(USE_AA == 1){ outFragColor = fxaa(inputTexture, inTextCoord); - outFragColor = gamma(outFragColor); - return; } - if(USE_AA == 2){ + else if(USE_AA == 2){ + outFragColor = texture(inputTexture, inTextCoord); } - if(USE_AA == 3){ + else if(USE_AA == 3){ + outFragColor = texture(inputTexture, inTextCoord); } - if(USE_AA == 4){ + else if(USE_AA == 4){ + outFragColor = texture(inputTexture, inTextCoord); } - outFragColor = gamma(texture(inputTexture,inTextCoord)); + else { + outFragColor = texture(inputTexture, inTextCoord); + } + + vec3 color = outFragColor.rgb; + + float brightness = dot(color, vec3(0.2126, 0.7152, 0.0722)); + + float threshold = 1.0; + float softKnee = 0.5; + + float contribution = max(brightness - threshold, 0.0); + contribution = contribution / max(contribution + softKnee, 0.0001); + + outBloomColour = vec4(color * contribution, 1.0); } \ No newline at end of file diff --git a/resources/EngineResources/shaders/post_process_frag.glsl.spv b/resources/EngineResources/shaders/post_process_frag.glsl.spv index 055aba0..ad42b72 100644 Binary files a/resources/EngineResources/shaders/post_process_frag.glsl.spv and b/resources/EngineResources/shaders/post_process_frag.glsl.spv differ diff --git a/resources/EngineResources/shaders/scene_fragment.glsl b/resources/EngineResources/shaders/scene_fragment.glsl index 5b3d90b..88ffb95 100644 --- a/resources/EngineResources/shaders/scene_fragment.glsl +++ b/resources/EngineResources/shaders/scene_fragment.glsl @@ -7,8 +7,10 @@ layout(location = 1) in vec3 inNormal; layout(location = 2) in vec3 inTangent; layout(location = 3) in vec3 inBitangent; layout(location = 4) in vec2 inTextCoords; +layout(location = 5) in mat4 viewMatrix; layout(location = 0) out vec4 outAlbedo; +layout(location = 1) out vec4 outViewPos; struct Material { vec4 diffuseColor; //16 @@ -29,6 +31,10 @@ struct Material { uint hasOpacityMap; //88 uint OpacityMapIdx; //92 float OpacityFactor; //96 + float reflectiveness; //100 + float refractiveness; //104 + float Padding1; //108 + float Padding2; //112 }; layout(set = 2, binding = 0) readonly buffer MaterialUniform{ @@ -37,6 +43,7 @@ layout(set = 2, binding = 0) readonly buffer MaterialUniform{ layout(set = 3, binding = 0) uniform sampler2D textSampler[MAX_TEXTURES]; + layout(push_constant) uniform pc{ layout(offset = 64) uint materialIdx; } push_constants; @@ -44,13 +51,15 @@ layout(push_constant) uniform pc{ void main() { - Material material = matUniform.materials[inMaterialIdx]; + vec4 viewPos = vec4(viewMatrix * inPos); + outViewPos = viewPos; + + Material material = matUniform.materials[push_constants.materialIdx]; int textureIndex = int(material.textureIdx); if (textureIndex >= MAX_TEXTURES){ outAlbedo = vec4(0.0,0.0,1.0,1.0); return; } - Material material = matUniform.materials[push_constants.materialIdx]; if(material.hasTexture == 1){ vec4 texColor = texture(textSampler[material.textureIdx],inTextCoords); outAlbedo = texColor; diff --git a/resources/EngineResources/shaders/scene_fragment.glsl.spv b/resources/EngineResources/shaders/scene_fragment.glsl.spv index 9776783..a05b0b0 100644 Binary files a/resources/EngineResources/shaders/scene_fragment.glsl.spv and b/resources/EngineResources/shaders/scene_fragment.glsl.spv differ diff --git a/resources/EngineResources/shaders/scene_fragment_deferred.glsl b/resources/EngineResources/shaders/scene_fragment_deferred.glsl index 32093e7..2f768a7 100644 --- a/resources/EngineResources/shaders/scene_fragment_deferred.glsl +++ b/resources/EngineResources/shaders/scene_fragment_deferred.glsl @@ -8,6 +8,7 @@ layout(location = 1) in vec3 inNormal; layout(location = 2) in vec3 inTangent; layout(location = 3) in vec3 inBitangent; layout(location = 4) in vec2 inTextCoords; +layout(location = 5) in mat4 viewMatrix; layout(location = 1) out vec4 outAlbedo ; layout(location = 0) out vec4 outPos; @@ -16,6 +17,7 @@ layout(location = 3) out vec4 outPBR; layout(location = 4) out vec4 outEmissive; layout(location = 5) out vec4 outTranslucency; layout(location = 6) out vec4 outOpacity; +layout(location = 7) out vec4 outViewPos; struct Material { vec4 diffuseColor; //16 @@ -36,6 +38,10 @@ struct Material { uint hasOpacityMap; //88 uint OpacityMapIdx; //92 float OpacityFactor; //96 + float reflectiveness; //100 + float refractiveness; //104 + float Padding1; //108 + float Padding2; //112 }; layout(set = 2, binding = 0) readonly buffer MaterialUniform { Material materials[]; @@ -62,6 +68,9 @@ void main() { outPos = inPos; + vec4 viewPos = vec4(viewMatrix * vec4(inPos.xyz, 1.0)); + outViewPos = viewPos; + Material material = matUniform.materials[push_constants.materialIdx]; int textureIndex = int(material.textureIdx); if (textureIndex >= MAX_TEXTURES){ @@ -95,7 +104,7 @@ void main() mat3 TBN = mat3(inTangent, inBitangent, inNormal); vec3 newNormal = calcNormal(material, inNormal, inTextCoords, TBN); - outNormal = vec4(newNormal, 1.0f); + float ao = 0.5f; float roughnessFactor = 0.0f; @@ -121,6 +130,9 @@ void main() } outTranslucency = Translucency; - outPBR = vec4(ao, roughnessFactor, metallicFactor, 1.0f); + float Refractiveness = material.refractiveness; + float Reflectiveness = material.reflectiveness; + outNormal = vec4(newNormal, Refractiveness); + outPBR = vec4(ao, roughnessFactor, metallicFactor, Reflectiveness); } \ No newline at end of file diff --git a/resources/EngineResources/shaders/scene_fragment_deferred.glsl.spv b/resources/EngineResources/shaders/scene_fragment_deferred.glsl.spv index 4240da6..e660504 100644 Binary files a/resources/EngineResources/shaders/scene_fragment_deferred.glsl.spv and b/resources/EngineResources/shaders/scene_fragment_deferred.glsl.spv differ diff --git a/resources/EngineResources/shaders/scene_opaque_fragment.glsl b/resources/EngineResources/shaders/scene_opaque_fragment.glsl index e981d77..166e854 100644 --- a/resources/EngineResources/shaders/scene_opaque_fragment.glsl +++ b/resources/EngineResources/shaders/scene_opaque_fragment.glsl @@ -8,8 +8,10 @@ layout(location = 1) in vec3 inNormal; layout(location = 2) in vec3 inTangent; layout(location = 3) in vec3 inBitangent; layout(location = 4) in vec2 inTextCoords; +layout(location = 5) in mat4 viewMatrix; layout(location = 0) out vec4 outAlbedo; +layout(location = 1) out vec4 outViewPos; struct Material { vec4 diffuseColor; //16 @@ -30,6 +32,10 @@ struct Material { uint hasOpacityMap; //88 uint OpacityMapIdx; //92 float OpacityFactor; //96 + float reflectiveness; //100 + float refractiveness; //104 + float Padding1; //108 + float Padding2; //112 }; layout(set = 2, binding = 0) readonly buffer MaterialUniform{ @@ -44,6 +50,9 @@ layout(push_constant) uniform pc{ void main() { + vec4 viewPos = vec4(viewMatrix * inPos); + outViewPos = viewPos; + Material material = matUniform.materials[push_constants.materialIdx]; int textureIndex = int(material.textureIdx); if (textureIndex >= MAX_TEXTURES){ diff --git a/resources/EngineResources/shaders/scene_opaque_fragment.glsl.spv b/resources/EngineResources/shaders/scene_opaque_fragment.glsl.spv index 251492d..156f36f 100644 Binary files a/resources/EngineResources/shaders/scene_opaque_fragment.glsl.spv and b/resources/EngineResources/shaders/scene_opaque_fragment.glsl.spv differ diff --git a/resources/EngineResources/shaders/scene_opaque_fragment_deferred.glsl b/resources/EngineResources/shaders/scene_opaque_fragment_deferred.glsl index 01df0da..1ce2cf5 100644 --- a/resources/EngineResources/shaders/scene_opaque_fragment_deferred.glsl +++ b/resources/EngineResources/shaders/scene_opaque_fragment_deferred.glsl @@ -7,6 +7,7 @@ layout(location = 1) in vec3 inNormal; layout(location = 2) in vec3 inTangent; layout(location = 3) in vec3 inBitangent; layout(location = 4) in vec2 inTextCoords; +layout(location = 5) in mat4 viewMatrix; layout(location = 1) out vec4 outAlbedo ; layout(location = 0) out vec4 outPos; @@ -15,6 +16,7 @@ layout(location = 3) out vec4 outPBR; layout(location = 4) out vec4 outEmissive; layout(location = 5) out vec4 outTranslucency; layout(location = 6) out vec4 outOpacity; +layout(location = 7) out vec4 outViewPos; const float bayerMatrix[16] = float[]( 0.0 / 16.0, 8.0 / 16.0, 2.0 / 16.0, 10.0 / 16.0, @@ -42,6 +44,10 @@ struct Material { uint hasOpacityMap; //88 uint OpacityMapIdx; //92 float OpacityFactor; //96 + float reflectiveness; //100 + float refractiveness; //104 + float Padding1; //108 + float Padding2; //112 }; layout(set = 2, binding = 0) readonly buffer MaterialUniform { Material materials[]; @@ -68,6 +74,9 @@ void main() { outPos = inPos; + vec4 viewPos = vec4(viewMatrix * vec4(inPos.xyz, 1.0)); + outViewPos = viewPos; + Material material = matUniform.materials[push_constants.materialIdx]; int textureIndex = int(material.textureIdx); if (textureIndex >= MAX_TEXTURES){ @@ -84,11 +93,6 @@ void main() } else { outAlbedo = material.diffuseColor; } - /*int Intensity = 4; - int x = int(gl_FragCoord.x) % Intensity; - int y = int(gl_FragCoord.y) % Intensity; - float threshold = bayerMatrix[y * Intensity + x]; - if(outAlbedo.a < threshold || outAlbedo.a < 0.05f) discard;*/ vec4 Opacity = vec4(outAlbedo.a,outAlbedo.a,outAlbedo.a,1); if(material.OpacityFactor != 1) Opacity = vec4(material.OpacityFactor, material.OpacityFactor, material.OpacityFactor, 1); @@ -102,12 +106,11 @@ void main() outAlbedo = vec4(outAlbedo.rgb, opacityf); - if(outAlbedo.a < 0.75) discard; - + if(outAlbedo.a < 0.9) discard; mat3 TBN = mat3(inTangent, inBitangent, inNormal); vec3 newNormal = calcNormal(material, inNormal, inTextCoords, TBN); - outNormal = vec4(newNormal, outAlbedo.a); + float ao = 0.5f; float roughnessFactor = 0.0f; @@ -133,6 +136,9 @@ void main() } outTranslucency = Translucency; - outPBR = vec4(ao, roughnessFactor, metallicFactor, outAlbedo.a); + float Refractiveness = material.refractiveness; + float Reflectiveness = material.reflectiveness; + outNormal = vec4(newNormal, Refractiveness); + outPBR = vec4(ao, roughnessFactor, metallicFactor, Reflectiveness); } \ No newline at end of file diff --git a/resources/EngineResources/shaders/scene_opaque_fragment_deferred.glsl.spv b/resources/EngineResources/shaders/scene_opaque_fragment_deferred.glsl.spv deleted file mode 100644 index 34ff06d..0000000 Binary files a/resources/EngineResources/shaders/scene_opaque_fragment_deferred.glsl.spv and /dev/null differ diff --git a/resources/EngineResources/shaders/scene_translucent_fragment.glsl b/resources/EngineResources/shaders/scene_translucent_fragment.glsl index 9af83fc..242f6d9 100644 --- a/resources/EngineResources/shaders/scene_translucent_fragment.glsl +++ b/resources/EngineResources/shaders/scene_translucent_fragment.glsl @@ -7,8 +7,10 @@ layout(location = 1) in vec3 inNormal; layout(location = 2) in vec3 inTangent; layout(location = 3) in vec3 inBitangent; layout(location = 4) in vec2 inTextCoords; +layout(location = 5) in mat4 viewMatrix; layout(location = 0) out vec4 outAlbedo; +layout(location = 1) out vec4 outViewPos; struct Material { vec4 diffuseColor; //16 @@ -29,6 +31,10 @@ struct Material { uint hasOpacityMap; //88 uint OpacityMapIdx; //92 float OpacityFactor; //96 + float reflectiveness; //100 + float refractiveness; //104 + float Padding1; //108 + float Padding2; //112 }; layout(set = 2, binding = 0) readonly buffer MaterialUniform{ Material materials[]; @@ -42,6 +48,10 @@ layout(push_constant) uniform pc{ void main() { + + vec4 viewPos = vec4(viewMatrix * inPos); + outViewPos = viewPos; + Material material = matUniform.materials[push_constants.materialIdx]; int textureIndex = int(material.textureIdx); if (textureIndex >= MAX_TEXTURES){ diff --git a/resources/EngineResources/shaders/scene_translucent_fragment.glsl.spv b/resources/EngineResources/shaders/scene_translucent_fragment.glsl.spv index 53ea5ee..da41461 100644 Binary files a/resources/EngineResources/shaders/scene_translucent_fragment.glsl.spv and b/resources/EngineResources/shaders/scene_translucent_fragment.glsl.spv differ diff --git a/resources/EngineResources/shaders/scene_translucent_fragment_deferred.glsl b/resources/EngineResources/shaders/scene_translucent_fragment_deferred.glsl index ce01b25..b25de20 100644 --- a/resources/EngineResources/shaders/scene_translucent_fragment_deferred.glsl +++ b/resources/EngineResources/shaders/scene_translucent_fragment_deferred.glsl @@ -7,6 +7,7 @@ layout(location = 1) in vec3 inNormal; layout(location = 2) in vec3 inTangent; layout(location = 3) in vec3 inBitangent; layout(location = 4) in vec2 inTextCoords; +layout(location = 5) in mat4 viewMatrix; layout(location = 1) out vec4 outAlbedo ; layout(location = 0) out vec4 outPos; @@ -15,6 +16,7 @@ layout(location = 3) out vec4 outPBR; layout(location = 4) out vec4 outEmissive; layout(location = 5) out vec4 outTranslucency; layout(location = 6) out vec4 outOpacity; +layout(location = 7) out vec4 outViewPos; const float bayerMatrix[16] = float[]( 0.0 / 16.0, 8.0 / 16.0, 2.0 / 16.0, 10.0 / 16.0, @@ -43,6 +45,10 @@ struct Material { uint hasOpacityMap; //88 uint OpacityMapIdx; //92 float OpacityFactor; //96 + float reflectiveness; //100 + float refractiveness; //104 + float Padding1; //108 + float Padding2; //112 }; layout(set = 2, binding = 0) readonly buffer MaterialUniform { @@ -69,6 +75,10 @@ layout(push_constant) uniform pc { void main() { outPos = inPos; + + vec4 viewPos = vec4(viewMatrix * vec4(inPos.xyz, 1.0)); + outViewPos = viewPos; + Material material = matUniform.materials[push_constants.materialIdx]; int textureIndex = int(material.textureIdx); if (textureIndex >= MAX_TEXTURES){ @@ -98,11 +108,11 @@ void main() outAlbedo = vec4(outAlbedo.rgb, opacityf); - if(outAlbedo.a >= 0.75 || outAlbedo.a < 0.05f) discard; + if(outAlbedo.a >= 0.9 || outAlbedo.a <= 0.1) discard; mat3 TBN = mat3(inTangent, inBitangent, inNormal); vec3 newNormal = calcNormal(material, inNormal, inTextCoords, TBN); - outNormal = vec4(newNormal, outAlbedo.a); + float ao = 0.5f; float roughnessFactor = 0.0f; @@ -128,6 +138,9 @@ void main() } outTranslucency = Translucency; - outPBR = vec4(ao, roughnessFactor, metallicFactor, outAlbedo.a); + float Refractiveness = material.refractiveness; + float Reflectiveness = material.reflectiveness; + outNormal = vec4(newNormal, Refractiveness); + outPBR = vec4(ao, roughnessFactor, metallicFactor, Reflectiveness); } \ No newline at end of file diff --git a/resources/EngineResources/shaders/scene_translucent_fragment_deferred.glsl.spv b/resources/EngineResources/shaders/scene_translucent_fragment_deferred.glsl.spv deleted file mode 100644 index 054991c..0000000 Binary files a/resources/EngineResources/shaders/scene_translucent_fragment_deferred.glsl.spv and /dev/null differ diff --git a/resources/EngineResources/shaders/scene_vertex.glsl b/resources/EngineResources/shaders/scene_vertex.glsl index a3db2ae..996f253 100644 --- a/resources/EngineResources/shaders/scene_vertex.glsl +++ b/resources/EngineResources/shaders/scene_vertex.glsl @@ -11,7 +11,7 @@ layout(location = 1) out vec3 outNormal; layout(location = 2) out vec3 outTangent; layout(location = 3) out vec3 outBitangent; layout(location = 4) out vec2 outTextCoords; - +layout(location = 5) out mat4 viewMatrix; layout(set = 0, binding = 0) uniform ProjUniform{ mat4 matrix; @@ -27,6 +27,7 @@ layout(push_constant) uniform pc{ void main() { + viewMatrix = viewUniform.matrix; vec4 worldPos = push_constants.modelMatrix * vec4(inPos,1); gl_Position = projUniform.matrix * viewUniform.matrix * push_constants.modelMatrix * vec4(inPos,1); mat3 mNormal = transpose(inverse(mat3(push_constants.modelMatrix))); diff --git a/resources/EngineResources/shaders/scene_vertex.glsl.spv b/resources/EngineResources/shaders/scene_vertex.glsl.spv index 305b965..4a1d6a1 100644 Binary files a/resources/EngineResources/shaders/scene_vertex.glsl.spv and b/resources/EngineResources/shaders/scene_vertex.glsl.spv differ diff --git a/resources/EngineResources/shaders/screen_space_reflection_frag.glsl b/resources/EngineResources/shaders/screen_space_reflection_frag.glsl new file mode 100644 index 0000000..cdcc9af --- /dev/null +++ b/resources/EngineResources/shaders/screen_space_reflection_frag.glsl @@ -0,0 +1,128 @@ +#version 450 + +layout(location = 0) in vec2 fragTexCoord; +layout(location = 0) out vec4 outColor; + +layout(set = 0, binding = 0) uniform sampler2D albedoSampler; +layout(set = 0, binding = 1) uniform sampler2D worldPosSampler; +layout(set = 0, binding = 2) uniform sampler2D normalSampler; +layout(set = 0, binding = 3) uniform sampler2D pbrSampler; + +layout(set = 1, binding = 0) uniform CameraProperties { + mat4 projection; + mat4 invProjection; + mat4 view; + mat4 invView; + float ssrStepSize; + float ssrMaxDistance; + int maxSteps; + int padding; + vec4 cameraWorldPos; +} ubo; + +const float THICKNESS = 0.35; +const float MIN_REFLECTION = 0.01; + +float edgeFade(vec2 uv) { + vec2 fade = smoothstep(vec2(0.0), vec2(0.08), uv) * + smoothstep(vec2(0.0), vec2(0.08), vec2(1.0) - uv); + return fade.x * fade.y; +} + +void main() { + vec4 sceneColor = texture(albedoSampler, fragTexCoord); + vec4 posSample = texture(worldPosSampler, fragTexCoord); + vec4 normalSample = texture(normalSampler, fragTexCoord); + vec4 pbrSample = texture(pbrSampler, fragTexCoord); + + if (posSample.a == 0.0 || length(posSample.xyz) == 0.0 || length(normalSample.xyz) < 0.001) { + outColor = sceneColor; + return; + } + + vec3 worldPos = posSample.xyz; + vec3 worldNormal = normalize(normalSample.xyz); + + float roughness = clamp(pbrSample.g, 0.0, 1.0); + float metallic = clamp(pbrSample.b, 0.0, 1.0); + float reflectiveness = clamp(pbrSample.a, 0.0, 1.0); + float refractiveness = clamp(normalSample.a, 0.0, 2.0); + + vec3 viewDirToCamera = normalize(ubo.cameraWorldPos.xyz - worldPos); + float NoV = clamp(dot(worldNormal, viewDirToCamera), 0.0, 1.0); + float fresnel = pow(1.0 - NoV, 5.0); + + float materialReflection = reflectiveness + refractiveness - 1; + materialReflection *= mix(0.75, 1.0, metallic); + materialReflection *= smoothstep(0.7, 0.05, roughness); + materialReflection *= mix(0.45, 1.0, fresnel); + + if (materialReflection <= MIN_REFLECTION) { + outColor = sceneColor; + return; + } + + vec3 viewDir = normalize(worldPos - ubo.cameraWorldPos.xyz); + vec3 reflectDir = normalize(reflect(viewDir, worldNormal)); + + if (dot(reflectDir, worldNormal) <= 0.0) { + outColor = sceneColor; + return; + } + + int steps = clamp(ubo.maxSteps, 1, 128); + float stepSize = max(ubo.ssrStepSize, 0.01); + float maxDistance = max(ubo.ssrMaxDistance, stepSize); + + vec3 rayPos = worldPos; + vec2 hitUV = vec2(0.0); + bool hitFound = false; + + for (int i = 0; i < steps; i++) { + rayPos += reflectDir * stepSize; + + if (distance(rayPos, worldPos) > maxDistance) { + break; + } + + vec4 clip = ubo.projection * ubo.view * vec4(rayPos, 1.0); + if (clip.w <= 0.0) { + break; + } + + vec2 uv = clip.xy / clip.w; + uv = uv * 0.5 + 0.5; + uv.y = 1.0 - uv.y; + + if (uv.x <= 0.0 || uv.x >= 1.0 || uv.y <= 0.0 || uv.y >= 1.0) { + break; + } + + vec4 surfaceWorld = texture(worldPosSampler, uv); + if (surfaceWorld.a == 0.0 || length(surfaceWorld.xyz) == 0.0) { + continue; + } + + float rayViewZ = abs((ubo.view * vec4(rayPos, 1.0)).z); + float surfaceViewZ = abs((ubo.view * vec4(surfaceWorld.xyz, 1.0)).z); + + float depthDelta = rayViewZ - surfaceViewZ; + if (depthDelta >= 0.0 && depthDelta < THICKNESS) { + hitUV = uv; + hitFound = true; + break; + } + } + + if (!hitFound) { + outColor = sceneColor; + return; + } + + vec3 reflectedColor = texture(albedoSampler, hitUV).rgb; + + float fade = edgeFade(hitUV); + float weight = clamp(materialReflection * fade, 0.0, 0.85); + + outColor = vec4(mix(sceneColor.rgb, reflectedColor, weight), sceneColor.a); +} \ No newline at end of file diff --git a/resources/EngineResources/shaders/shadow_frag.glsl b/resources/EngineResources/shaders/shadow_frag.glsl index c65bc1a..9b381eb 100644 --- a/resources/EngineResources/shaders/shadow_frag.glsl +++ b/resources/EngineResources/shaders/shadow_frag.glsl @@ -27,6 +27,10 @@ struct Material { uint hasOpacityMap; //88 uint OpacityMapIdx; //92 float OpacityFactor; //96 + float reflectiveness; //100 + float refractiveness; //104 + float Padding1; //108 + float Padding2; //112 }; layout(set = 1, binding = 0) uniform sampler2D textSampler[MAX_TEXTURES]; layout(set = 2, binding = 0) readonly buffer MaterialUniform { @@ -35,7 +39,21 @@ layout(set = 2, binding = 0) readonly buffer MaterialUniform { void main() { + Material material = matUniform.materials[inMaterialIdx]; + + float Refractiveness = material.refractiveness; + float Reflectiveness = material.reflectiveness; + float Translucency = material.translucencyFactor; + float Opacity = material.OpacityFactor; + if(material.hasTranslucencyMap > 0){ + vec4 translucencyMap = texture(textSampler[material.translucencyMapIdx], inTextCoords); + Translucency = (translucencyMap.x + translucencyMap.y + translucencyMap.z)/3.0; + } + if(material.hasOpacityMap > 0){ + vec4 opacityMap = texture(textSampler[material.OpacityMapIdx], inTextCoords); + Opacity = (opacityMap.x + opacityMap.y + opacityMap.z)/3.0; + } int textureIndex = int(material.textureIdx); if (textureIndex >= MAX_TEXTURES){ outFragColor = vec2(0.0,0.0); @@ -47,7 +65,7 @@ void main() } else { albedo = material.diffuseColor; } - if (albedo.a < 0.5) { + if (albedo.a < 0.5 || Translucency > 0.5 || Opacity < 0.5) { discard; } @@ -55,7 +73,6 @@ void main() float moment1 = depth; float moment2 = depth * depth; - // Adjust moments to avoid light bleeding float dx = dFdx(depth); float dy = dFdy(depth); moment2 += 0.25 * (dx * dx + dy * dy); diff --git a/resources/EngineResources/shaders/skybox_fragment.glsl b/resources/EngineResources/shaders/skybox_fragment.glsl index 056c61d..2dfeedd 100644 --- a/resources/EngineResources/shaders/skybox_fragment.glsl +++ b/resources/EngineResources/shaders/skybox_fragment.glsl @@ -7,5 +7,5 @@ layout(location = 1) out vec4 outColor; layout(set = 2, binding = 0) uniform samplerCube skyboxSampler; void main() { - outColor = texture(skyboxSampler, outTexCoords) * vec4(0.0,0.05,0.1,1); + outColor = texture(skyboxSampler, outTexCoords);// * vec4(3,1.0,0.65,1); } \ No newline at end of file diff --git a/resources/EngineResources/shaders/skybox_fragment.glsl.spv b/resources/EngineResources/shaders/skybox_fragment.glsl.spv index 6842753..3f18f85 100644 Binary files a/resources/EngineResources/shaders/skybox_fragment.glsl.spv and b/resources/EngineResources/shaders/skybox_fragment.glsl.spv differ diff --git a/resources/EngineResources/shaders/ssao_blur_frag.glsl b/resources/EngineResources/shaders/ssao_blur_frag.glsl index c16af41..40b5edc 100644 --- a/resources/EngineResources/shaders/ssao_blur_frag.glsl +++ b/resources/EngineResources/shaders/ssao_blur_frag.glsl @@ -4,18 +4,42 @@ layout(location = 0) in vec2 inTextCoord; layout(location = 0) out float outAO; layout(set = 0, binding = 0) uniform sampler2D ssaoSampler; +layout(set = 0, binding = 1) uniform sampler2D viewPosSampler; void main() { + vec2 texelSize = 2.0 / vec2(textureSize(ssaoSampler, 0)); - vec2 texelSize = 1.0 / vec2(textureSize(ssaoSampler, 0)); - float result = 0.0; + float centerAO = texture(ssaoSampler, inTextCoord).r; + float centerDepth = texture(viewPosSampler, inTextCoord).z; - for (int x = -2; x <= 2; x++) { - for (int y = -2; y <= 2; y++) { - vec2 offset = vec2(float(x), float(y)) * texelSize; - result += texture(ssaoSampler, vec2(inTextCoord.x,inTextCoord.y) + offset).r; - } + float totalAO = centerAO; + float totalWeight = 1.0; + + float weights[4] = float[](0.227027, 0.1216216, 0.054054, 0.016216); + int offsets[4] = int[](-2, -1, 1, 2); + const float Sharpness = 20.0; + + for (int i = 0; i < 4; i++) { + vec2 offsetH = vec2(float(offsets[i]), 0.0) * texelSize; + vec2 uvH = inTextCoord + offsetH; + + float neighborAOH = texture(ssaoSampler, uvH).r; + float neighborDepthH = texture(viewPosSampler, uvH).z; + + float weightH = weights[i] * max(0.0, 1.0 - Sharpness * abs(centerDepth - neighborDepthH)); + totalAO += neighborAOH * weightH; + totalWeight += weightH; + + vec2 offsetV = vec2(0.0, float(offsets[i])) * texelSize; + vec2 uvV = inTextCoord + offsetV; + + float neighborAOV = texture(ssaoSampler, uvV).r; + float neighborDepthV = texture(viewPosSampler, uvV).z; + + float weightV = weights[i] * max(0.0, 1.0 - Sharpness * abs(centerDepth - neighborDepthV)); + totalAO += neighborAOV * weightV; + totalWeight += weightV; } - outAO = result / 25.0; + outAO = totalAO / totalWeight; } \ No newline at end of file diff --git a/resources/EngineResources/shaders/ssao_frag.glsl b/resources/EngineResources/shaders/ssao_frag.glsl index 7c0e5f0..467fab6 100644 --- a/resources/EngineResources/shaders/ssao_frag.glsl +++ b/resources/EngineResources/shaders/ssao_frag.glsl @@ -2,13 +2,14 @@ layout(location = 0) in vec2 inTextCoord; layout(location = 0) out float outAO; +layout(location = 1) out vec4 viewPos; layout(set = 0, binding = 0) uniform sampler2D posSampler; layout(set = 0, binding = 1) uniform sampler2D normalSampler; layout(set = 0, binding = 2) uniform sampler2D noiseSampler; -layout(set = 1, binding = 0) readonly buffer SSAOKernel { - vec4 samples[]; +layout(set = 1, binding = 0) uniform SSAOKernel { + vec4 samples[64]; } kernel; layout(set = 2, binding = 0) uniform SSAOInfo { @@ -17,79 +18,75 @@ layout(set = 2, binding = 0) uniform SSAOInfo { vec2 screenSize; // 136 float radius; //140 float bias; //144 - int kernelSize; //160 + int kernelSize; //148 + float ResolutionScale; //152; + vec2 Padding; //160; } ssao; void main() { - vec2 uv = inTextCoord; - vec3 worldPos = texture(posSampler, uv).xyz; - vec3 worldNormal = normalize(texture(normalSampler, uv).xyz); + vec2 ScreenSize = ssao.screenSize * ssao.ResolutionScale; - vec2 noiseScale = ssao.screenSize / 4.0; + int KERNEL_SIZE = ssao.kernelSize; + vec3 fragPos = texture(posSampler, inTextCoord).xyz; + vec3 worldNorm = normalize(texture(normalSampler, inTextCoord).xyz); - if (length(worldNormal) < 0.001) { + if (dot(worldNorm, worldNorm) < 0.001) { outAO = 1.0; return; } - vec3 fragPos = vec3(ssao.view * vec4(worldPos, 1.0)); - vec3 normal = normalize(mat3(ssao.view) * worldNormal); + vec3 normal = normalize(mat3(ssao.view) * worldNorm); - vec3 randomVec = normalize(texture(noiseSampler, inTextCoord * noiseScale).xyz); + viewPos = vec4(fragPos, 1); + vec2 noiseScale = ScreenSize / 4.0; + vec3 randomVec = texture(noiseSampler, inTextCoord * noiseScale).xyz; vec3 tangent = normalize(randomVec - normal * dot(randomVec, normal)); vec3 bitangent = cross(normal, tangent); mat3 TBN = mat3(tangent, bitangent, normal); + float fragDepth = -fragPos.z; + + float minOptimalDistance = 15; + float maxKernelSize = float(ssao.kernelSize); + + // Calculate a dynamic loop limit based on proximity + // If closer than 1.5 units, smoothly scale down the loop count + int dynamicKernelSize = int(KERNEL_SIZE); + if (fragDepth < minOptimalDistance) { + float proximityFactor = clamp(fragDepth / minOptimalDistance, 0.2, 1.0); + dynamicKernelSize = int(maxKernelSize * proximityFactor); + } + + // Force a hard minimum baseline of samples so SSAO doesn't completely disappear + dynamicKernelSize = max(dynamicKernelSize, 16); float occlusion = 0.0; - float validSamples = 0.0;; - for (int i = 0; i < ssao.kernelSize; i++) { - vec3 samplePos = TBN * kernel.samples[i].xyz; - samplePos = fragPos + samplePos * ssao.radius; + float Passes = 0.0f; - vec4 offset = vec4(samplePos, 1.0); - offset = ssao.projection * offset; + for (int i = 0; i < dynamicKernelSize; i++) { + vec3 samplePos = fragPos + (TBN * kernel.samples[i].xyz) * ssao.radius; + vec4 offset = ssao.projection * vec4(samplePos, 1.0); offset.xyz /= offset.w; offset.xyz = offset.xyz * 0.5 + 0.5; - - vec2 sampleUV = offset.xy; - sampleUV.y = 1 - sampleUV.y; - - if (sampleUV.x < 0.0 || sampleUV.x > 1.0 || - sampleUV.y < 0.0 || sampleUV.y > 1.0) { + vec2 sampleUV = clamp(vec2(offset.x, 1.0 - offset.y), 0.0, 1.0); + vec3 sampleViewPos = texture(posSampler, sampleUV).xyz; + float sampleDepth = -sampleViewPos.z; + float depthDelta = abs(fragDepth - sampleDepth); + if (depthDelta > ssao.radius * 2.0) { continue; } - - vec3 sampleWorldPos = texture(posSampler, sampleUV).xyz; - vec3 sampleWorldNormal = texture(normalSampler, sampleUV).xyz; - - if (length(sampleWorldNormal) < 0.001) { - continue; - } - - vec3 sampleViewPos = vec3(ssao.view * vec4(sampleWorldPos, 1.0)); - - float depthDelta = abs(fragPos.z - sampleViewPos.z); - if (depthDelta > ssao.radius) { - continue; - } - - float rangeCheck = 1.0 - depthDelta / ssao.radius; - rangeCheck = rangeCheck * rangeCheck * (3.0 - 2.0 * rangeCheck); - - if (sampleViewPos.z >= samplePos.z + ssao.bias) { - occlusion += rangeCheck; - } - validSamples += 1; + float rangeCheck = smoothstep(0.0, 1.0, ssao.radius / depthDelta); + float isOccluded = step(samplePos.z + ssao.bias, sampleViewPos.z); + occlusion += isOccluded * rangeCheck; + Passes += 1.0; } - if (validSamples <= 0.0) { - outAO = 1.0; - return; + float Subtraction = 0.0; + if(Passes > 0){ + Subtraction = (occlusion / Passes); } - - occlusion = 1.0 - occlusion / validSamples; - outAO = occlusion * pow(occlusion, 3.0); + occlusion = 1.0 - Subtraction; + outAO = clamp(pow(occlusion, 3), 0.0, 1.0); } \ No newline at end of file diff --git a/resources/models/cube/Cube_mat.json b/resources/models/cube/Cube_mat.json index bed79f1..bc42d48 100644 --- a/resources/models/cube/Cube_mat.json +++ b/resources/models/cube/Cube_mat.json @@ -11,7 +11,26 @@ "W": 1.0 }, "Roughness": 0.0, - "Metallic": 0.0 + "Metallic": 1.0, + "EmissiveTexture": "", + "EmissiveColour": { + "X": 0.0, + "Y": 0.0, + "Z": 0.0, + "W": 1.0 + }, + "TranslucencyTexture": "", + "Translucency": 0.0, + "OpacityTexture": "", + "Opacity": 1.0, + "ColorTransparency": { + "X": 0.0, + "Y": 0.0, + "Z": 0.0, + "W": 1.0 + }, + "Refractiveness": 1.0, + "Reflectiveness": 1.0 }, { "ID": "Cube-mat-1", @@ -25,7 +44,26 @@ "W": 1.0 }, "Roughness": 0.0, - "Metallic": 0.0 + "Metallic": 1.0, + "EmissiveTexture": "", + "EmissiveColour": { + "X": 0.0, + "Y": 0.0, + "Z": 0.0, + "W": 1.0 + }, + "TranslucencyTexture": "", + "Translucency": 0.0, + "OpacityTexture": "", + "Opacity": 1.0, + "ColorTransparency": { + "X": 0.0, + "Y": 0.0, + "Z": 0.0, + "W": 1.0 + }, + "Refractiveness": 1.0, + "Reflectiveness": 1.0 }, { "ID": "Cube-mat-2", @@ -39,6 +77,25 @@ "W": 1.0 }, "Roughness": 0.0, - "Metallic": 0.0 + "Metallic": 1.0, + "EmissiveTexture": "", + "EmissiveColour": { + "X": 0.0, + "Y": 0.0, + "Z": 0.0, + "W": 1.0 + }, + "TranslucencyTexture": "", + "Translucency": 0.0, + "OpacityTexture": "", + "Opacity": 1.0, + "ColorTransparency": { + "X": 0.0, + "Y": 0.0, + "Z": 0.0, + "W": 1.0 + }, + "Refractiveness": 1.0, + "Reflectiveness": 1.0 } ] \ No newline at end of file diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Display/VulkanRenderer.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Display/VulkanRenderer.java index adac3c7..bbdf370 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Display/VulkanRenderer.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Display/VulkanRenderer.java @@ -13,6 +13,7 @@ import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.I import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.Images.TextureCache; import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.PostProcessing.PostProcess; import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.ScreenSpace.AmbientOcclusionRenderer; +import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.ScreenSpace.ReflectionsRenderer; import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Shadows.ShadowRenderer; import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.VkModel.*; import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.SpriteRendering.SpriteRenderer; @@ -53,6 +54,7 @@ public class VulkanRenderer implements Renderer { private final Semaphore[] RenderCompleteSemaphores; private final SceneRenderer sceneRender; private final AmbientOcclusionRenderer ssaoRenderer; + private final ReflectionsRenderer ssrRender; private final SpriteRenderer spriteRenderer; private final LightRenderer lightRenderer; private final PostProcess PostProcessor; @@ -117,7 +119,8 @@ public class VulkanRenderer implements Renderer { attachments.add(ssaoRenderer.getSSAOBlurAttachment()); attachments.add(shadowRender.getShadowAttachment()); lightRenderer = new LightRenderer(RendererContext, attachments); - PostProcessor = new PostProcess(RendererContext, lightRenderer.getAttachment()); + ssrRender = new ReflectionsRenderer(RendererContext, sceneRender.GetMRTAttachments().GetColourAttachments(), lightRenderer.getAttachment()); + PostProcessor = new PostProcess(RendererContext, ssrRender.GetSSRAttachment()); } else{ sceneRender = new ForwardSceneRender(RendererContext); @@ -125,6 +128,7 @@ public class VulkanRenderer implements Renderer { PostProcessor = new PostProcess(RendererContext, sceneRender.GetAttachmentColour()); lightRenderer = null; shadowRender = null; + ssrRender = null; } spriteRenderer= new SpriteRenderer(engineInstance, RendererContext, PostProcessor.GetAttachment()); GuiRender = new GuiRenderer(engineInstance, RendererContext, GraphicsQueue, PostProcessor.GetAttachment()); @@ -195,6 +199,7 @@ public class VulkanRenderer implements Renderer { Logger.debug("Waiting Vulkan Context"); sceneRender.cleanup(RendererContext); if(ssaoRenderer != null)ssaoRenderer.cleanup(RendererContext); + if(ssrRender != null)ssrRender.cleanup(RendererContext); if(shadowRender != null)shadowRender.cleanup(RendererContext); if(lightRenderer != null)lightRenderer.cleanup(RendererContext); PostProcessor.CleanUp(RendererContext); @@ -219,6 +224,23 @@ public class VulkanRenderer implements Renderer { VulkanUtils.CleanUpRemaining(RendererContext.GetDevice()); RendererContext.cleanup(); } + + public enum DebugRenderMode{ + Albedo, + Normals, + Pos, + SSAO, + Depth, + NoPosProcess, + Emissive, + Translucency, + Opacity, + PBR + } + + public static volatile boolean Debug = false; + public static volatile DebugRenderMode debugMode = DebugRenderMode.Albedo; + public void DeferredRender(EngineInstance engineInstance){ SwapChain swapChain = RendererContext.GetSwapChain(); WaitForFence(CurrentFrame); @@ -227,12 +249,6 @@ public class VulkanRenderer implements Renderer { var CommandPool = CommandPools[CurrentFrame]; var CommandBuffer = CommandBuffers[CurrentFrame]; - int ImageIndex; - if (Resize || (ImageIndex = swapChain.FetchNextImage(RendererContext.GetDevice(), PresentCompleteSemaphores[imageAcquisitionIndex])) < 0){ - resize(engineInstance); - return; - } - RecordingStart(CommandPool, CommandBuffer); sceneRender.Render(engineInstance,RendererContext,CommandBuffer, modelsCache,materialsCache,CurrentFrame); @@ -243,9 +259,17 @@ public class VulkanRenderer implements Renderer { lightRenderer.render(engineInstance, RendererContext, CommandBuffer, sceneRender.GetMRTAttachments(), shadowRender.getShadowAttachment(), ssaoRenderer.getSSAOBlurAttachment(), CurrentFrame, shadowRender.getCascadeShadows(CurrentFrame)); } else lightRenderer.render(engineInstance, RendererContext, CommandBuffer, sceneRender.GetMRTAttachments(),ssaoRenderer.getSSAOBlurAttachment(),CurrentFrame); - PostProcessor.Render(RendererContext,CommandBuffer,lightRenderer.getAttachment()); + ssrRender.Render( RendererContext, engineInstance, CommandBuffer, CurrentFrame); + PostProcessor.Render(RendererContext,CommandBuffer,ssrRender.GetSSRAttachment()); spriteRenderer.Render(engineInstance,RendererContext,CommandBuffer,PostProcessor.GetAttachment(),modelsCache,CurrentFrame); GuiRender.Render(RendererContext,CommandBuffer,CurrentFrame,PostProcessor.GetAttachment()); + + int ImageIndex; + if (Resize || (ImageIndex = swapChain.FetchNextImage(RendererContext.GetDevice(), PresentCompleteSemaphores[imageAcquisitionIndex])) < 0){ + resize(engineInstance); + return; + } + swapChainRender.Render(RendererContext,CommandBuffer,PostProcessor.GetAttachment(),ImageIndex); RecordingStop(CommandBuffer); @@ -290,8 +314,8 @@ public class VulkanRenderer implements Renderer { RebuildShadowsRequested = false; RebuildShadows(); } - - if(Deferred) DeferredRender(engineInstance); + if (Deferred) DeferredRender(engineInstance); +// else if(Deferred)DebugDeferredRender(engineInstance, debugMode); else ForwardRender(engineInstance); } @@ -338,14 +362,21 @@ public class VulkanRenderer implements Renderer { sceneRender.Resize(engineInstance,RendererContext); if(Deferred) { List attachments = new ArrayList<>(sceneRender.GetMRTAttachments().GetColourAttachments()); - List ssaoAttachments = new ArrayList<>(); - ssaoAttachments.add(attachments.get(0)); - ssaoAttachments.add(attachments.get(2)); - ssaoRenderer.resize(RendererContext, ssaoAttachments); attachments.add(ssaoRenderer.getSSAOBlurAttachment()); attachments.add(shadowRender.getShadowAttachment()); lightRenderer.resize(RendererContext, attachments); - PostProcessor.Resize(RendererContext, lightRenderer.getAttachment()); + List ssaoAttachments = new ArrayList<>(); + ssaoAttachments.add(attachments.get(7)); + ssaoAttachments.add(attachments.get(2)); + ssaoRenderer.resize(RendererContext, ssaoAttachments); + ssaoAttachments.clear(); + ssaoAttachments.add(lightRenderer.getAttachment()); + ssaoAttachments.add(attachments.get(0)); + ssaoAttachments.add(attachments.get(2)); + ssaoAttachments.add(attachments.get(3)); + ssrRender.resize(RendererContext, ssaoAttachments); + + PostProcessor.Resize(RendererContext, ssrRender.GetSSRAttachment()); } else{ PostProcessor.Resize(RendererContext, sceneRender.GetAttachmentColour()); } diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Logic/Rendering/ModelCompiler.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Logic/Rendering/ModelCompiler.java index e542260..331ecad 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Logic/Rendering/ModelCompiler.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Logic/Rendering/ModelCompiler.java @@ -139,12 +139,20 @@ public class ModelCompiler { SpecularArray = new float[]{0.0f}; } + float[] GlossinessArray = new float[]{0.0f}; + Result = aiGetMaterialFloatArray(aiMaterial,AI_MATKEY_GLOSSINESS_FACTOR,aiTextureType_NONE,0,GlossinessArray,MaxPointer); + if(Result != aiReturn_SUCCESS){ + GlossinessArray = new float[]{0.0f}; + } + if(SpecularArray[0] == 0.0f && GlossinessArray[0] != 0.0f) + SpecularArray[0] = GlossinessArray[0]; if(MetallicArray[0] == 0.0f && SpecularArray[0] != 0.0f) MetallicArray[0] = SpecularArray[0]; if(MetallicRoughTexture.isEmpty()){ MetallicRoughTexture = SpecularTexture; } + float[] RoughnessArray = new float[]{0.0f}; Result = aiGetMaterialFloatArray(aiMaterial,AI_MATKEY_ROUGHNESS_FACTOR,aiTextureType_NONE,0,RoughnessArray,MaxPointer); if(Result != aiReturn_SUCCESS){ @@ -169,6 +177,13 @@ public class ModelCompiler { OpacityArray = new float[]{0.0f}; } + AIColor4D colour_transparency = AIColor4D.create(); + Vector4f ColorTransparency = new Vector4f(); + Result = aiGetMaterialColor(aiMaterial,AI_MATKEY_COLOR_TRANSPARENT,aiTextureType_NONE,0,colour_transparency); + if(Result != aiReturn_SUCCESS){ + ColorTransparency.set(colour_transparency.r(),colour_transparency.g(),colour_transparency.b(),colour_transparency.a()); + } + float[] RefractionArray = new float[]{0.0f}; Result = aiGetMaterialFloatArray(aiMaterial,AI_MATKEY_REFRACTI,aiTextureType_NONE,0,RefractionArray,MaxPointer); if(Result != aiReturn_SUCCESS){ @@ -181,14 +196,6 @@ public class ModelCompiler { ReflectionArray = new float[]{0.0f}; } - AIColor4D colour_transparency = AIColor4D.create(); - Vector4f ColorTransparency = new Vector4f(); - - Result = aiGetMaterialColor(aiMaterial,AI_MATKEY_COLOR_TRANSPARENT,aiTextureType_NONE,0,colour_transparency); - if(Result != aiReturn_SUCCESS){ - ColorTransparency.set(colour_transparency.r(),colour_transparency.g(),colour_transparency.b(),colour_transparency.a()); - } - return new MaterialData(ModelName + "-mat-" + Position,DiffuseTexture,NormalTexture, MetallicRoughTexture,diffuse,RoughnessArray[0],MetallicArray[0], EmissiveTexture,emissiveColour, TranslucencyTexture, TranslucencyArray[0], OpacityTexture, OpacityArray[0],ColorTransparency,RefractionArray[0], ReflectionArray[0]); } diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Main/GameCore.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Main/GameCore.java index 012c25d..c4936a5 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Main/GameCore.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Main/GameCore.java @@ -52,7 +52,7 @@ import static org.lwjgl.glfw.GLFW.*; public class GameCore implements GameLogic { private static final float MOUSE_SENSITIVITY = 0.1f; - private static final float MOVEMENT_SPEED = 0.1f; + private static final float MOVEMENT_SPEED = 0.01f; public static boolean LoadingLevel = false; private Vector2f LastMousePos = new Vector2f(0,0); @@ -100,11 +100,15 @@ public class GameCore implements GameLogic { List models = new ArrayList<>(); List materials = new ArrayList<>(); ModelData SponzaData = ModelLoader.LoadModel("resources/models/Cafe/exterior.json"); + models.add(SponzaData); List SponzaMaterial = ModelLoader.LoadMaterials("resources/models/Cafe/exterior_mat.json"); + materials.addAll(SponzaMaterial); ModelData SponzaData1 = ModelLoader.LoadModel("resources/models/Cafe/interior.json"); + models.add(SponzaData1); List SponzaMaterial1= ModelLoader.LoadMaterials("resources/models/Cafe/interior_mat.json"); - scene.AddActor(new Actor3D("Sponza1", SponzaData.ID(), new Vector3f(0,0f,-5f)).SetScale(0.1f)); - scene.AddActor(new Actor3D("Sponza2", SponzaData1.ID(), new Vector3f(0,0f,-5f)).SetScale(0.1f)); + materials.addAll(SponzaMaterial1); + scene.AddActor(new Actor3D("Sponza1", SponzaData.ID(), new Vector3f(0,0f,-5f)).SetScale(0.05f)); + scene.AddActor(new Actor3D("Sponza2", SponzaData1.ID(), new Vector3f(0,0f,-5f)).SetScale(0.05f)); // ModelData treeModel = ModelLoader.LoadModel("resources/models/tree/tree.json"); // models.add(treeModel); // Actor3D treeEntity = new Actor3D("treeEntity", treeModel.ID(), new Vector3f(0.0f, 0.0f, 0.0f)); @@ -113,8 +117,8 @@ public class GameCore implements GameLogic { // materials.addAll(ModelLoader.LoadMaterials("resources/models/tree/tree_mat.json")); // ModelData treeModel = ModelLoader.LoadModel("resources/models/Forest/forest.json"); // models.add(treeModel); -// Actor3D treeEntity = new Actor3D("treeEntity", treeModel.ID(), new Vector3f(0.0f, -100.0f, 0.0f)); -// treeEntity.SetScale(10f); +// Actor3D treeEntity = new Actor3D("treeEntity", treeModel.ID(), new Vector3f(0.0f, 00.0f, 0.0f)); +// treeEntity.SetScale(0.1f); // scene.AddActor(treeEntity); // materials.addAll(ModelLoader.LoadMaterials("resources/models/Forest/forest_mat.json")); MelonaData = ModelLoader.LoadModel("resources/models/cube/Cube.json"); @@ -158,10 +162,6 @@ public class GameCore implements GameLogic { } boolean createOfflinePlayer = !PrimaryRuntime.IsServer && !ClientSideNetworkUtils.Connected; - materials.addAll(SponzaMaterial); - materials.addAll(SponzaMaterial1); - models.add(SponzaData); - models.add(SponzaData1); materials.addAll(MelonaMat); materials.addAll(CollisionVisualisationMat); materials.addAll(MelonaMaterial); @@ -191,90 +191,105 @@ public class GameCore implements GameLogic { } scene.GetLightingManager().GetAmbientLightColour().set(1.0f, 0.9f, 0.75f); - scene.GetLightingManager().SetAmbientLightIntensity(0.15f); - scene.GetLightingManager().GetAmbientLightColour().set(0.3f, 0.35f, 0.5f); - scene.GetLightingManager().SetAmbientLightIntensity(0.05f); - - SkyLight = new Light(new Vector3f(1.5f, 1.20f, 1.0f),new Vector3f(0.0f, -1.0f, 0.3f), true, 4.00f); - SkyLight = new Light(new Vector3f(0.25f, 0.75f, 1.3f),new Vector3f(0.0f, -1.0f, 0.0f), true, 4.0f); - SkyLight.SetType(Light.LightType.Directional); + scene.GetLightingManager().SetAmbientLightIntensity(0.1f); +// scene.GetLightingManager().GetAmbientLightColour().set(0.6f, 0.5f, 0.4f); +// scene.GetLightingManager().SetAmbientLightIntensity(0.1f); List lights = new ArrayList<>(); - lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-433, 445f, -424f).div(10.0f),false,3000.0f+ (float)(Math.random() * 100.0))); - lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-210, 445f, 460f).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f))); - lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-966, 445f, 204f).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f))); - lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-176, 445f, 1000f).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f))); - lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(777, 445f, 858).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f))); - lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(376, 445f, -2136).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f))); - lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,2.0f),new Vector3f(2163, 445f, 1880).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f))); - lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(3334, 445f, 2405).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f))); - lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(3509, 445f, 1825).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f))); - lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(3877, 445f, 3378).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f))); - lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(4925, 445f, 3430).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f))); - lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-2083, 445f, -1826).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f))); - lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(2076, 410, 1272).div(10.0f),false,100.0f)); - lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(2446, 465, 2303).div(10.0f),false,100.0f)); - lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-842, 410, -1141).div(10.0f),false,100.0f)); - lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-207, 410, -1830).div(10.0f),false,100.0f)); - lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(899, 460, -2015).div(10.0f),false,100.0f)); - lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(1775, 460, -3448).div(10.0f),false,100.0f)); - lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(1800, 460, -4154).div(10.0f),false,1000.0f)); - lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-1727, 410, -387).div(10.0f),false,100.0f)); - lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-1198, 410, -964).div(10.0f),false,100.0f)); - lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-1778, 410, -1502).div(10.0f),false,100.0f)); - lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-2692, 333, -2109).div(10.0f),false,100.0f)); - lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-2849, 333, -1724).div(10.0f),false,100.0f)); - lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-2019, 410, -729).div(10.0f),false,100.0f)); - lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-1727, 410, -389).div(10.0f),false,100.0f)); - lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-1337, 410, 122).div(10.0f),false,100.0f)); + 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(2.75f, 1.75f, 0.3f),new Vector3f(0.0f, -1.0f, 0.0f), true, 6.0f); + //SkyLight = new Light(new Vector3f(1.5f, 1.20f, 1.0f),new Vector3f(0.0f, -1.0f, 0.3f), true, 5.00f); + SkyLight.SetType(Light.LightType.Directional); - 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(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-433, 445f, -424f).div(20.0f),false,3000.0f/10.0f+ (float)(Math.random() * 100.0/10.0f))); + lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-210, 445f, 460f).div(20.0f),false,700.0f/10.0f + (float)(Math.random() * 150.0f/10.0f))); + lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-966, 445f, 204f).div(20.0f),false,700.0f/10.0f + (float)(Math.random() * 150.0f/10.0f))); + lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-176, 445f, 1000f).div(20.0f),false,700.0f/10.0f + (float)(Math.random() * 150.0f/10.0f))); + lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(777, 445f, 858).div(20.0f),false,700.0f/10.0f + (float)(Math.random() * 150.0f/10.0f))); + lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(376, 445f, -2136).div(20.0f),false,700.0f/10.0f + (float)(Math.random() * 150.0f/10.0f))); + lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,2.0f),new Vector3f(2163, 445f, 1880).div(20.0f),false,700.0f/10.0f + (float)(Math.random() * 150.0f/10.0f))); + lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(3334, 445f, 2405).div(20.0f),false,700.0f/10.0f + (float)(Math.random() * 150.0f/10.0f))); + lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(3509, 445f, 1825).div(20.0f),false,700.0f/10.0f + (float)(Math.random() * 150.0f/10.0f))); + lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(3877, 445f, 3378).div(20.0f),false,700.0f/10.0f + (float)(Math.random() * 150.0f/10.0f))); + lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(4925, 445f, 3430).div(20.0f),false,700.0f/10.0f + (float)(Math.random() * 150.0f/10.0f))); + lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-2083, 445f, -1826).div(20.0f),false,700.0f/10.0f + (float)(Math.random() * 150.0f/10.0f))); + + lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(2076, 410, 1272).div(20.0f),false,100.0f/10.0f)); + lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(2446, 465, 2303).div(20.0f),false,100.0f/10.0f)); + lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-842, 410, -1141).div(20.0f),false,100.0f/10.0f)); + lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-207, 410, -1830).div(20.0f),false,100.0f/10.0f)); + lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(899, 460, -2015).div(20.0f),false,100.0f/10.0f)); + lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(1775, 460, -3448).div(20.0f),false,100.0f/10.0f)); + lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(1800, 460, -4154).div(20.0f),false,1000.0f/10.0f)); + lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-1727, 410, -387).div(20.0f),false,100.0f/10.0f)); + lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-1198, 410, -964).div(20.0f),false,100.0f/10.0f)); + lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-1778, 410, -1502).div(20.0f),false,100.0f/10.0f)); + lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-2692, 333, -2109).div(20.0f),false,100.0f/10.0f)); + lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-2849, 333, -1724).div(20.0f),false,100.0f/10.0f)); + lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-2019, 410, -729).div(20.0f),false,100.0f/10.0f)); + lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-1727, 410, -389).div(20.0f),false,100.0f/10.0f)); + lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-1337, 410, 122).div(20.0f),false,100.0f/10.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(20.0f),false,200.0f/10.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(20.0f),false,200.0f/10.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(20.0f),false,200.0f/10.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(20.0f),false,200.0f/10.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(20.0f),false,75.0f/10.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(20.0f),false,75.0f/10.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(20.0f),false,75.0f/10.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(20.0f),false,75.0f/10.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(20.0f),false,50.0f/10.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(20.0f),false,50.0f/10.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(20.0f),false,50.0f/10.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(20.0f),false,50.0f/10.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(20.0f),false,50.0f/10.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(20.0f),false,50.0f/10.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(20.0f),false,50.0f/10.0f)); + + + lights.add(new Light(new Vector3f(0.75f,2.0f,0.75f),new Vector3f(1086, 425, -3375).div(20.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)); + ILight[] lightArr = new ILight[lights.size()]; lightArr = lights.toArray(lightArr); scene.GetLightingManager().AddLights(lightArr); + Vector3f Position = new Vector3f(-40, 5, 10); + + SpawnPosition.set(Position); + rotationMatrix.set(new Matrix4f().rotateX((float)Math.random()).rotateY((float)Math.random()).rotateZ((float)Math.random())); + SpawnDirection.set(new Vector3f((float)Math.random())); + rotationMatrix.positiveZ(SpawnDirection).negate().mul(5); + SpawnPosition.add(SpawnDirection); + var Cube = new Actor3D("MelonaSpawned" + scene.GetActors().size(), CubeModelID, new Vector3f(SpawnPosition)); + + Cube.SetScale(5f); + ConvexMesh mesh = ConvexMesh.Box(0.5f,0.5f,0.5f); + Cube.CreatePhysicsController(mesh ,0); + Cube.SetPositionOffset(new Vector3f(0,0,0)); + + Cube.SetServerSynced(false); + + scene.AddActor(Cube); + InitiateAudio(engineInstance); - for(int i = 0; i < ActorEditorComponents.size(); i++){ - ActorEditorComponents.get(i).UpdateAll(); - } - //if(PrimaryRuntime.IsServer) { - permutation.GeneratePermutationArray(5783904701859L); -// for(int x = -1; x < 2; x++){ -// for(int y = -1; y < 2; y++){ -// GenerateChunk(new Vector3i(x, 0, y), 16); -// -// } +// permutation.GeneratePermutationArray(5783904701859L); +// for(int x = -1; x < 2; x++){ +// for(int y = -1; y < 2; y++){ +// GenerateChunk(new Vector3i(x, 0, y), 16); // } -// for(int i = 0; i < 20; i++){ -// SpawnNewActor(engineInstance, new Vector3f(-5 + (float)Math.random() * 10,10 + (float)Math.random() * 10, -5 + (float)Math.random() * 10), new Vector3f(0, 0, 0), new Vector3f(1, 1, 1)); -// } - //} +// } +// for(int i = 0; i < 20; i++){ +// SpawnNewActor(engineInstance, new Vector3f(-5 + (float)Math.random() * 10,10 + (float)Math.random() * 10, -5 + (float)Math.random() * 10), new Vector3f(0, 0, 0), new Vector3f(1, 1, 1)); +// } Settings.textBuffer.set(ClientSideNetworkUtils.ServerIP); Settings.UsernameBuffer.set("Player"); return new InitData(models,materials,guiTextures); @@ -348,7 +363,7 @@ public class GameCore implements GameLogic { RigidPhysicsController physicsController = (RigidPhysicsController) Melona.GetPhysicsController(); //RigidBody.RigidBodyRegister.get(physicsController.RigidBodyID).LinearVelocity.set(0,0,-20f -(40f * (float)Math.random())); - scene.AddActor(Melona); + //scene.AddActor(Melona); } public void SetPlayerActorID(String id) { this.PlayerActorID = id; diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Main/Scene/GUIs/PerformanceOverlay.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Main/Scene/GUIs/PerformanceOverlay.java index c71afb8..10e0f32 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Main/Scene/GUIs/PerformanceOverlay.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Main/Scene/GUIs/PerformanceOverlay.java @@ -4,20 +4,28 @@ import imgui.ImGui; import imgui.flag.ImGuiCond; import imgui.flag.ImGuiWindowFlags; import imgui.type.ImFloat; +import net.halbear.Terrain4J.EngineCore.Display.VulkanRenderer; import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig; import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance; import net.halbear.Terrain4J.EngineCore.Main.AudioInstance; import net.halbear.Terrain4J.EngineCore.Main.GameCore; import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime; import net.halbear.Terrain4J.EngineCore.Main.Scene.GUIOverlay; +import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.PostProcessing.PostProcess; +import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.ScreenSpace.AmbientOcclusionRenderer; 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.Util.VulkanBuffer; import org.tinylog.Logger; public class PerformanceOverlay implements GUIOverlay { private final ImFloat GammaValue = new ImFloat(0.8545f); public int[] ShadowSize = new int[]{4096}; public int[] ShadowDistance = new int[]{1000}; + public float[] Gamma = new float[]{1.75f}; + public float[] Exposure = new float[]{2.5f}; + public float[] BlurRadius = new float[]{2.5f}; + public float[] SSAOscale = new float[]{1.0f}; public PerformanceOverlay(){ ShadowSize[0] = EngineConfig.getInstance().GetShadowMapSize(); @@ -46,6 +54,64 @@ public class PerformanceOverlay implements GUIOverlay { ImGui.separator(); ImGui.text("GRAPHICS SETTINGS:"); ImGui.text(" "); +// ImGui.text("Debug Options"); +// ImGui.text(" "); +// if(ImGui.button("Debug On")){ +// Logger.debug("Debug On"); +// VulkanRenderer.Debug = true; +// } +// ImGui.sameLine(); +// if(ImGui.button("Debug Off")){ +// Logger.debug("Debug Off"); +// VulkanRenderer.Debug = false; +// } +// if(ImGui.button("Albedo")){ +// Logger.debug("Albedo"); +// VulkanRenderer.debugMode = VulkanRenderer.DebugRenderMode.Albedo; +// } +// ImGui.sameLine(); +// if(ImGui.button("Normals")){ +// Logger.debug("Normals"); +// VulkanRenderer.debugMode = VulkanRenderer.DebugRenderMode.Normals; +// } +// ImGui.sameLine(); +// if(ImGui.button("PBR")){ +// Logger.debug("PBR"); +// VulkanRenderer.debugMode = VulkanRenderer.DebugRenderMode.PBR; +// } +// ImGui.sameLine(); +// if(ImGui.button("SSAO")){ +// Logger.debug("SSAO"); +// VulkanRenderer.debugMode = VulkanRenderer.DebugRenderMode.SSAO; +// } +// if(ImGui.button("Position")){ +// Logger.debug("Position"); +// VulkanRenderer.debugMode = VulkanRenderer.DebugRenderMode.Pos; +// } +// ImGui.sameLine(); +// if(ImGui.button("Emissive")){ +// Logger.debug("Emissive"); +// VulkanRenderer.debugMode = VulkanRenderer.DebugRenderMode.Emissive; +// } +// ImGui.sameLine(); +// if(ImGui.button("Opacity")){ +// Logger.debug("Opacity"); +// VulkanRenderer.debugMode = VulkanRenderer.DebugRenderMode.Opacity; +// } +// ImGui.sameLine(); +// if(ImGui.button("Translucency")){ +// Logger.debug("Translucency"); +// VulkanRenderer.debugMode = VulkanRenderer.DebugRenderMode.Translucency; +// } +// if(ImGui.button("No PostFX")){ +// Logger.debug("No PostFX"); +// VulkanRenderer.debugMode = VulkanRenderer.DebugRenderMode.NoPosProcess; +// } +// ImGui.sameLine(); +// if(ImGui.button("Depth")){ +// Logger.debug("Depth"); +// VulkanRenderer.debugMode = VulkanRenderer.DebugRenderMode.Depth; +// } ImGui.text("Rendering API:"); if(ImGui.button("Vulkan")){ Logger.debug("Switch to Vulkan"); @@ -162,6 +228,18 @@ public class PerformanceOverlay implements GUIOverlay { parent.CoolDown = 2000; EngineConfig.getInstance().MaxShadowDistance(ShadowDistance[0]); } + if (ImGui.sliderFloat("Gamma", Gamma, 0,10f)) { + PostProcess.GAMMA = Gamma[0]; + } + if (ImGui.sliderFloat("Exposure", Exposure, 0,10f)) { + PostProcess.EXPOSURE = Exposure[0]; + } + if (ImGui.sliderFloat("Bloom Radius", BlurRadius, 0,10f)) { + PostProcess.BLOOM_RADIUS = BlurRadius[0]; + } + if (ImGui.sliderFloat("SSAO Resolution", SSAOscale, 0,2f)) { + AmbientOcclusionRenderer.SSAO_RESOLUTION_SCALE = SSAOscale[0]; + } ImGui.text(" "); ImGui.text("anti aliasing:"); if(ImGui.button("No AA")){ @@ -234,10 +312,6 @@ public class PerformanceOverlay implements GUIOverlay { EngineConfig.getInstance().SetAlphaToCoverage(true); if(engineInstance.window().GetLinkedApi() == EngineConfig.RenderAPI.Vulkan) PrimaryRuntime.GetRenderThread().GetRenderer().GetSceneRender().RebuildPipelines(PrimaryRuntime.GetRenderThread().GetRenderer().GetVulkanContext()); } - ImGui.inputFloat("Gamma", GammaValue, 0.0025f, 0.22725f, "%.4f"); - if (ImGui.isItemDeactivatedAfterEdit()) { - // EngineConfig.getInstance().Gamma = GammaValue.get(); - } ImGui.separator(); ImGui.text("Level Tools:"); if(ImGui.button("Spawn Melona")){ diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Universal/SSAO/SSAO_Utils.java b/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Universal/SSAO/SSAO_Utils.java index 1621056..baf1bbb 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Universal/SSAO/SSAO_Utils.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Universal/SSAO/SSAO_Utils.java @@ -32,9 +32,9 @@ public class SSAO_Utils { } public static ByteBuffer GenerateNoiseTexture() { - ByteBuffer buffer = BufferUtils.createByteBuffer(16 * 4 * Float.BYTES); + ByteBuffer buffer = BufferUtils.createByteBuffer(4 * 4 * 4 * Float.BYTES); Random rnd = new Random(); - for (int i = 0; i < 16; i++) { + for (int i = 0; i < 4 * 4; i++) { float x = rnd.nextFloat() * 2.0f - 1.0f; float y = rnd.nextFloat() * 2.0f - 1.0f; buffer.putFloat(x); diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Rendering/DeferredRendering/LightRenderer.java b/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Rendering/DeferredRendering/LightRenderer.java index 76c6e93..9dd364b 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Rendering/DeferredRendering/LightRenderer.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Rendering/DeferredRendering/LightRenderer.java @@ -82,7 +82,7 @@ public class LightRenderer { lightSpecConsts = new LightSpecConsts(); ShaderModule[] shaderModules = CreateShaderModules(VkCtx, lightSpecConsts,true); - var textureSamplerInfo = new TextureSamplerInfo(VK_SAMPLER_ADDRESS_MODE_REPEAT, + var textureSamplerInfo = new TextureSamplerInfo(VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, VK_BORDER_COLOR_INT_OPAQUE_BLACK, 1, true); textureSampler = new TextureSampler(VkCtx, textureSamplerInfo); int numAttachments = attachments.size(); @@ -155,7 +155,7 @@ public class LightRenderer { SwapChain swapChain = VkCtx.GetSwapChain(); VkExtent2D swapChainExtent = swapChain.GetSwapChainExtent(); return new Attachment(VkCtx, swapChainExtent.width(), swapChainExtent.height(), - COLOUR_FORMAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,1); + COLOUR_FORMAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,1); } private static VkRenderingAttachmentInfo.Buffer CreateColourAttachmentInfo(Attachment attachment, VkClearValue clearValue) { diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Rendering/DeferredRendering/MultiRenderTargetAttachments.java b/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Rendering/DeferredRendering/MultiRenderTargetAttachments.java index 107ecb5..6304de1 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Rendering/DeferredRendering/MultiRenderTargetAttachments.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Rendering/DeferredRendering/MultiRenderTargetAttachments.java @@ -12,13 +12,16 @@ import static org.lwjgl.vulkan.VK10.VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; public class MultiRenderTargetAttachments { public static final int ALBEDO_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT; + public static final int SSR_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT; public static final int DEPTH_FORMAT = VK_FORMAT_D32_SFLOAT; + public static final int REFLECT_REFRACT = VK_FORMAT_R16G16_SFLOAT; public static final int NORMAL_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT; public static final int PBR_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT; public static final int EMISSIVE_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT; public static final int TRANSLUCECNY_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT; public static final int OPACITY_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT; public static final int POSITION_FORMAT = VK_FORMAT_R32G32B32A32_SFLOAT; + public static final int VIEW_POS_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT; public static final int SSAO_RAW_ATTACHMENT = VK_FORMAT_R8_UNORM; public static final int SSAO_BLUR_ATTACHMENT = VK_FORMAT_R8_UNORM; private final List ColourAttachments; @@ -53,6 +56,10 @@ public class MultiRenderTargetAttachments { //Opacity Attachment = new Attachment(VkCtx, Width, Height, OPACITY_FORMAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 1); ColourAttachments.add(Attachment); + //ViewPos + Attachment = new Attachment(VkCtx, Width, Height, VIEW_POS_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); } diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Rendering/PostProcessing/PostProcess.java b/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Rendering/PostProcessing/PostProcess.java index 3cc77d3..e5ec33d 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Rendering/PostProcessing/PostProcess.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Rendering/PostProcessing/PostProcess.java @@ -11,6 +11,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.Structure.DeviceLayers.CommandBuffer; import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DeviceLayers.Device; +import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DisplayToScreen.ImageView; import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.SwapChain.SwapChain; import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Util.VulkanBuffer; import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Util.VulkanUtils; @@ -20,9 +21,12 @@ import org.lwjgl.util.shaderc.Shaderc; import org.lwjgl.vulkan.*; import org.tinylog.Logger; +import java.nio.ByteBuffer; import java.nio.FloatBuffer; import java.nio.LongBuffer; +import java.util.ArrayList; import java.util.Arrays; +import java.util.List; import static org.lwjgl.vulkan.VK10.*; import static org.lwjgl.vulkan.VK13.*; @@ -30,56 +34,124 @@ import static org.lwjgl.vulkan.VK13.*; public class PostProcess { public static final int COLOUR_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT; private static final String DESCRIPTOR_ID_ATTACHMENT = "POST_DESC_ID_ATT"; + private static final String DESCRIPTOR_ID_BLOOM_PROPERTIES_HORIZONTAL = "POST_DESC_ID_BLOOM_PROPERTIES_HORIZONTAL"; + private static final String DESCRIPTOR_ID_BLOOM_PROPERTIES_VERTICAL = "POST_DESC_ID_BLOOM_PROPERTIES_VERTICAL"; + private static final String DESCRIPTOR_ID_BLOOM_PROPERTIES_FINAL = "POST_DESC_ID_BLOOM_PROPERTIES_FINAL"; + private static final String DESCRIPTOR_ID_BLOOM_ATTACHMENT = "POST_DESC_ID_BLOOM_ATT"; + private static final String DESCRIPTOR_ID_BLOOM_PONG_ATTACHMENT = "POST_DESC_ID_BLOOM_PONG_ATT"; + private static final String DESCRIPTOR_ID_BLOOM_IMAGE_ATTACHMENT = "POST_DESC_ID_BLOOM_IMAGE_ATT"; private static final String DESCRIPTOR_ID_SCREEN_SIZE = "POST_DESC_ID_SCREEN_SIZE"; private static final String MULTI_PASS_FRAGMENT_SHADER_FILE_GLSL = "resources/EngineResources/shaders/multi-sampled_post_process_frag.glsl"; private static final String MULTI_PASS_FRAGMENT_SHADER_FILE_SPV = MULTI_PASS_FRAGMENT_SHADER_FILE_GLSL + ".spv"; + private static final String BLOOM_FRAGMENT_SHADER_FILE_GLSL = "resources/EngineResources/shaders/bloom_pass_frag.glsl"; + private static final String BLOOM_FRAGMENT_SHADER_FILE_SPV = BLOOM_FRAGMENT_SHADER_FILE_GLSL + ".spv"; private static final String SINGLE_PASS_FRAGMENT_SHADER_FILE_GLSL = "resources/EngineResources/shaders/post_process_frag.glsl"; private static final String SINGLE_PASS_FRAGMENT_SHADER_FILE_SPV = SINGLE_PASS_FRAGMENT_SHADER_FILE_GLSL + ".spv"; private static final String VERTEX_SHADER_FILE_GLSL = "resources/EngineResources/shaders/basic_screen_vertex.glsl"; private static final String VERTEX_SHADER_FILE_SPV = VERTEX_SHADER_FILE_GLSL + ".spv"; private final DescriptorSetLayout AttachmentDescriptorSetLayout; + private final DescriptorSetLayout[] MultiAttachmentDescriptorSetLayout = new DescriptorSetLayout[2]; private final VkClearValue ClearValueColour; private final DescriptorSetLayout FragmentUniformDescriptorSetLayout; private final Pipeline pipeline; + private final Pipeline bloomPipeline; private final VulkanBuffer ScreenSizeBuffer; + private final VulkanBuffer BloomPropertiesHorizontalBuffer; + private final VulkanBuffer BloomPropertiesVerticalBuffer; + private final VulkanBuffer BloomPropertiesFinalBuffer; private final SpecializationConstants specConstants; private final TextureSampler textureSampler; private Attachment ColourAttachment; private VkRenderingAttachmentInfo.Buffer ColourAttachmentInfo; + private VkRenderingAttachmentInfo.Buffer FinalOutputInfo; + private Attachment BloomPingAttachment; + private Attachment BloomPongAttachment; + private Attachment FinalAttachment; + private VkRenderingAttachmentInfo.Buffer BloomPingAttachmentInfo; + private VkRenderingAttachmentInfo.Buffer BloomPongAttachmentInfo; private VkRenderingInfo RenderingInfo; + private VkRenderingInfo SingleRenderingInfo; + private VkRenderingInfo BloomPingRenderingInfo; + private VkRenderingInfo BloomPongRenderingInfo; public PostProcess(VulkanContext VkCtx, Attachment SrcAttachment){ ClearValueColour = VkClearValue.calloc(); ClearValueColour.color(c->c.float32(0,0.0f).float32(1,0.0f).float32(2,0.0f).float32(3,0.0f)); ColourAttachment = CreateColourAttachment(VkCtx); - ColourAttachmentInfo = CreateColourAttachmentInfo(ColourAttachment,ClearValueColour); - RenderingInfo = CreateRenderInfo(ColourAttachment,ColourAttachmentInfo); + BloomPingAttachment = CreateColourAttachment(VkCtx); + BloomPongAttachment = CreateColourAttachment(VkCtx); + FinalAttachment = CreateColourAttachment(VkCtx); - var TextureSamplerInfo = new TextureSamplerInfo(VK_SAMPLER_ADDRESS_MODE_REPEAT,VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK,1,true); - textureSampler = new TextureSampler(VkCtx, TextureSamplerInfo); + List attachments = new ArrayList<>(); + attachments.add(ColourAttachment); + attachments.add(BloomPingAttachment); + ColourAttachmentInfo = CreateColourAttachmentInfos(attachments,ClearValueColour); + BloomPingAttachmentInfo = CreateColourAttachmentInfo(BloomPingAttachment,ClearValueColour); + BloomPongAttachmentInfo = CreateColourAttachmentInfo(BloomPongAttachment,ClearValueColour); + FinalOutputInfo = CreateColourAttachmentInfo(FinalAttachment,ClearValueColour); + RenderingInfo = CreateRenderInfo(ColourAttachment,ColourAttachmentInfo); + BloomPingRenderingInfo = CreateRenderInfo(BloomPingAttachment, BloomPingAttachmentInfo); + BloomPongRenderingInfo = CreateRenderInfo(BloomPongAttachment, BloomPongAttachmentInfo); + SingleRenderingInfo = CreateRenderInfo(FinalAttachment,FinalOutputInfo); + + var textureSamplerInfo = new TextureSamplerInfo(VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, + VK_BORDER_COLOR_INT_OPAQUE_BLACK, 1, true); + textureSampler = new TextureSampler(VkCtx, textureSamplerInfo); + + DescriptorSetLayout.LayoutInformation[] descSetLayouts = new DescriptorSetLayout.LayoutInformation[2]; + for (int i = 0; i < 2; i++) { + descSetLayouts[i] = new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, i, 1, VK_SHADER_STAGE_FRAGMENT_BIT); + } var LayoutInfo = new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,0,1,VK_SHADER_STAGE_FRAGMENT_BIT); AttachmentDescriptorSetLayout = new DescriptorSetLayout(VkCtx, LayoutInfo); - CreateAttachmentDescriptorSet(VkCtx, AttachmentDescriptorSetLayout, SrcAttachment,textureSampler); + MultiAttachmentDescriptorSetLayout[0] = new DescriptorSetLayout(VkCtx, descSetLayouts); + CreateAttachmentDescriptorSet(VkCtx, AttachmentDescriptorSetLayout, SrcAttachment,textureSampler, DESCRIPTOR_ID_ATTACHMENT); + CreateAttachmentDescriptorSets(VkCtx, MultiAttachmentDescriptorSetLayout[0], new Attachment[]{BloomPingAttachment, BloomPingAttachment},textureSampler, DESCRIPTOR_ID_BLOOM_ATTACHMENT); + CreateAttachmentDescriptorSets(VkCtx, MultiAttachmentDescriptorSetLayout[0], new Attachment[]{BloomPongAttachment, BloomPongAttachment},textureSampler, DESCRIPTOR_ID_BLOOM_PONG_ATTACHMENT); + CreateAttachmentDescriptorSets(VkCtx, MultiAttachmentDescriptorSetLayout[0], new Attachment[]{ColourAttachment, BloomPingAttachment},textureSampler, DESCRIPTOR_ID_BLOOM_IMAGE_ATTACHMENT); LayoutInfo = new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0,1,VK_SHADER_STAGE_FRAGMENT_BIT); FragmentUniformDescriptorSetLayout = new DescriptorSetLayout(VkCtx, LayoutInfo); ScreenSizeBuffer = VulkanUtils.CreateHostVisibleBuffer(VkCtx, VulkanUtils.VEC2_SIZE, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,DESCRIPTOR_ID_SCREEN_SIZE,FragmentUniformDescriptorSetLayout); + BloomPropertiesHorizontalBuffer = VulkanUtils.CreateHostVisibleBuffer(VkCtx, VulkanUtils.BOOLEAN_SIZE * 2 + VulkanUtils.FLOAT_SIZE * 2+ VulkanUtils.VEC4_SIZE, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,DESCRIPTOR_ID_BLOOM_PROPERTIES_HORIZONTAL,FragmentUniformDescriptorSetLayout); + BloomPropertiesVerticalBuffer = VulkanUtils.CreateHostVisibleBuffer(VkCtx, VulkanUtils.BOOLEAN_SIZE * 2 + VulkanUtils.FLOAT_SIZE * 2 + VulkanUtils.VEC4_SIZE, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,DESCRIPTOR_ID_BLOOM_PROPERTIES_VERTICAL,FragmentUniformDescriptorSetLayout); + BloomPropertiesFinalBuffer = VulkanUtils.CreateHostVisibleBuffer(VkCtx, VulkanUtils.BOOLEAN_SIZE * 2 + VulkanUtils.FLOAT_SIZE * 2+ VulkanUtils.VEC4_SIZE, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,DESCRIPTOR_ID_BLOOM_PROPERTIES_FINAL,FragmentUniformDescriptorSetLayout); SetScreenSizeBuffer(VkCtx); + SetBloomPropertiesBuffer(VkCtx, BloomPropertiesHorizontalBuffer, true, false); + SetBloomPropertiesBuffer(VkCtx, BloomPropertiesVerticalBuffer, false, false); + SetBloomPropertiesBuffer(VkCtx, BloomPropertiesFinalBuffer, false, true); specConstants = new SpecializationConstants(); ShaderModule[] shaderModules = CreateShaderModules(VkCtx, specConstants); pipeline = CreatePipeline(VkCtx, shaderModules, new DescriptorSetLayout[]{AttachmentDescriptorSetLayout, FragmentUniformDescriptorSetLayout}); Arrays.asList(shaderModules).forEach(shader->shader.CleanUp(VkCtx)); + shaderModules = CreateBloomShaderModules(VkCtx, specConstants); + bloomPipeline = CreateSingleOutputPipeline(VkCtx, shaderModules, new DescriptorSetLayout[]{MultiAttachmentDescriptorSetLayout[0], FragmentUniformDescriptorSetLayout}); Logger.debug("Post Process Renderer Pipeline -> [{}]",pipeline.GetVulkanPipeline()); } + private static VkRenderingAttachmentInfo.Buffer CreateColourAttachmentInfos(List attachments, VkClearValue ClearValue){ + int numAttachments = attachments.size(); + VkRenderingAttachmentInfo.Buffer result = VkRenderingAttachmentInfo.calloc(numAttachments); + for (int i = 0; i < numAttachments; ++i) { + result.get(i) + .sType$Default() + .imageView(attachments.get(i).GetVkImageView().GetVulkanImageView()) + .imageLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) + .loadOp(VK_ATTACHMENT_LOAD_OP_CLEAR) + .storeOp(VK_ATTACHMENT_STORE_OP_STORE) + .clearValue(ClearValue); + } + return result; + } + private static Attachment CreateColourAttachment(VulkanContext VkCtx){ SwapChain swapChain = VkCtx.GetSwapChain(); VkExtent2D SwapChainExtent = swapChain.GetSwapChainExtent(); - return new Attachment(VkCtx,SwapChainExtent.width(),SwapChainExtent.height(),COLOUR_FORMAT,VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT); + return new Attachment(VkCtx,SwapChainExtent.width(),SwapChainExtent.height(),COLOUR_FORMAT,VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT); } private static VkRenderingAttachmentInfo.Buffer CreateColourAttachmentInfo(Attachment SrcAttachment, VkClearValue ClearValue){ @@ -94,8 +166,20 @@ public class PostProcess { private static Pipeline CreatePipeline(VulkanContext VkCtx, ShaderModule[] shaderModules, DescriptorSetLayout[] descriptorSetLayouts){ var VertexBufferStruct = new EmptyVertexBufferStruct(); - var BuildInfo = new PipelineBuildInfo(shaderModules,VertexBufferStruct.GetVertexInput(),new int[]{COLOUR_FORMAT}).SetDescriptorSetLayouts(descriptorSetLayouts).BlendingIsUsed(true); - var PipeLine = new DefaultPipeline(VkCtx,BuildInfo); + var BuildInfo = new PipelineBuildInfo(shaderModules, VertexBufferStruct.GetVertexInput(), new int[]{COLOUR_FORMAT, COLOUR_FORMAT}) + .SetDescriptorSetLayouts(descriptorSetLayouts) + .BlendingIsUsed(true); + var PipeLine = new DefaultPipeline(VkCtx, BuildInfo); + VertexBufferStruct.CleanUp(); + return PipeLine; + } + + private static Pipeline CreateSingleOutputPipeline(VulkanContext VkCtx, ShaderModule[] shaderModules, DescriptorSetLayout[] descriptorSetLayouts){ + var VertexBufferStruct = new EmptyVertexBufferStruct(); + var BuildInfo = new PipelineBuildInfo(shaderModules, VertexBufferStruct.GetVertexInput(), new int[]{COLOUR_FORMAT}) + .SetDescriptorSetLayouts(descriptorSetLayouts) + .BlendingIsUsed(true); + var PipeLine = new DefaultPipeline(VkCtx, BuildInfo); VertexBufferStruct.CleanUp(); return PipeLine; } @@ -116,13 +200,37 @@ public class PostProcess { return renderingInfo; } - private static void CreateAttachmentDescriptorSet(VulkanContext VkCtx, DescriptorSetLayout descriptorSetLayout, Attachment attachment, TextureSampler textureSampler){ + private static void CreateAttachmentDescriptorSets(VulkanContext VkCtx, DescriptorSetLayout descriptorSetLayout, Attachment[] attachment, TextureSampler textureSampler, String descriptorID){ DescriptorAllocator descriptorAllocator = VkCtx.GetDescriptorAllocator(); Device device = VkCtx.GetDevice(); - DescriptorSet descriptorSet = descriptorAllocator.AddDescriptorSets(device,DESCRIPTOR_ID_ATTACHMENT,1 , descriptorSetLayout)[0]; + DescriptorSet descriptorSet = descriptorAllocator.AddDescriptorSets(device,descriptorID,1 , descriptorSetLayout)[0]; + List images = new ArrayList<>(); + for(int i = 0; i < attachment.length; i++) { + images.add(attachment[i].GetVkImageView()); + } + descriptorSet.SetImages(device,images,textureSampler,0); + } + + + private static void CreateAttachmentDescriptorSet(VulkanContext VkCtx, DescriptorSetLayout descriptorSetLayout, Attachment attachment, TextureSampler textureSampler, String descriptorID){ + DescriptorAllocator descriptorAllocator = VkCtx.GetDescriptorAllocator(); + Device device = VkCtx.GetDevice(); + DescriptorSet descriptorSet = descriptorAllocator.AddDescriptorSets(device,descriptorID,1 , descriptorSetLayout)[0]; descriptorSet.SetImage(device,attachment.GetVkImageView(),textureSampler,0); } + private static ShaderModule[] CreateBloomShaderModules(VulkanContext VkCtx, SpecializationConstants specConstants){ + if(EngineConfig.getInstance().RecompileShaders()){ + ShaderCompiler.CompileGLSLShaderOnChange(VERTEX_SHADER_FILE_GLSL, Shaderc.shaderc_glsl_vertex_shader); + ShaderCompiler.CompileGLSLShaderOnChange(BLOOM_FRAGMENT_SHADER_FILE_GLSL, Shaderc.shaderc_glsl_fragment_shader); + } + return new ShaderModule[]{ + new ShaderModule(VkCtx,VK_SHADER_STAGE_VERTEX_BIT,VERTEX_SHADER_FILE_SPV,null), + new ShaderModule(VkCtx,VK_SHADER_STAGE_FRAGMENT_BIT,BLOOM_FRAGMENT_SHADER_FILE_SPV,null) + }; + + } + private static ShaderModule[] CreateShaderModules(VulkanContext VkCtx, SpecializationConstants specConstants){ String ShaderPath = SINGLE_PASS_FRAGMENT_SHADER_FILE_GLSL; if(EngineConfig.getInstance().RecompileShaders()){ @@ -140,6 +248,9 @@ public class PostProcess { } public void Render(VulkanContext VkCtx, CommandBuffer commandBuffer, Attachment SrcAttachment){ + SetBloomPropertiesBuffer(VkCtx, BloomPropertiesHorizontalBuffer, true, false); + SetBloomPropertiesBuffer(VkCtx, BloomPropertiesVerticalBuffer, false, false); + SetBloomPropertiesBuffer(VkCtx, BloomPropertiesFinalBuffer, false, true); try(var MemStack = MemoryStack.stackPush()){ SwapChain swapChain = VkCtx.GetSwapChain(); VkCommandBuffer CommandHandle = commandBuffer.GetVulkanCommandBuffer(); @@ -150,6 +261,12 @@ public class PostProcess { VulkanUtils.ImageBarrier(MemStack,CommandHandle,ColourAttachment.GetVkImage().getVulkanImage(), VK_IMAGE_LAYOUT_UNDEFINED,VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT,VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_2_NONE,VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT,VK_IMAGE_ASPECT_COLOR_BIT); + VulkanUtils.ImageBarrier(MemStack,CommandHandle,BloomPingAttachment.GetVkImage().getVulkanImage(), + VK_IMAGE_LAYOUT_UNDEFINED,VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT,VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, + VK_ACCESS_2_NONE,VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT,VK_IMAGE_ASPECT_COLOR_BIT); + VulkanUtils.ImageBarrier(MemStack,CommandHandle,BloomPongAttachment.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); vkCmdBeginRendering(CommandHandle,RenderingInfo); vkCmdBindPipeline(CommandHandle,VK_PIPELINE_BIND_POINT_GRAPHICS,pipeline.GetVulkanPipeline()); @@ -177,9 +294,82 @@ public class PostProcess { vkCmdBindDescriptorSets(CommandHandle,VK_PIPELINE_BIND_POINT_GRAPHICS,pipeline.GetVulkanPipelineLayout(),0,DescriptorSets,null); vkCmdDraw(CommandHandle,3,1,0,0); vkCmdEndRendering(CommandHandle); + + VulkanUtils.ImageBarrier(MemStack,CommandHandle,ColourAttachment.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(MemStack,CommandHandle,BloomPingAttachment.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); + + int Passes = 10; + boolean bloomPongHasBeenWritten = false; + + for(int i = 0; i < Passes; i++){ + boolean writePong = i % 2 == 0; + + Attachment srcBloomAttachment = writePong ? BloomPingAttachment : BloomPongAttachment; + Attachment dstBloomAttachment = writePong ? BloomPongAttachment : BloomPingAttachment; + VkRenderingInfo dstRenderingInfo = writePong ? BloomPongRenderingInfo : BloomPingRenderingInfo; + String srcDescriptorId = writePong ? DESCRIPTOR_ID_BLOOM_ATTACHMENT : DESCRIPTOR_ID_BLOOM_PONG_ATTACHMENT; + String bloomPropertiesDescriptorId = writePong ? DESCRIPTOR_ID_BLOOM_PROPERTIES_HORIZONTAL : DESCRIPTOR_ID_BLOOM_PROPERTIES_VERTICAL; + + int dstOldLayout = writePong && !bloomPongHasBeenWritten + ? VK_IMAGE_LAYOUT_UNDEFINED + : VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + + VulkanUtils.ImageBarrier(MemStack,CommandHandle,dstBloomAttachment.GetVkImage().getVulkanImage(), + dstOldLayout,VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT,VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, + VK_ACCESS_2_SHADER_READ_BIT,VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT, + VK_IMAGE_ASPECT_COLOR_BIT); + + vkCmdBeginRendering(CommandHandle,dstRenderingInfo); + vkCmdBindPipeline(CommandHandle,VK_PIPELINE_BIND_POINT_GRAPHICS,bloomPipeline.GetVulkanPipeline()); + + vkCmdSetViewport(CommandHandle,0,Viewport); + vkCmdSetScissor(CommandHandle,0,Scissor); + + LongBuffer BloomDescriptorSets = MemStack.mallocLong(2) + .put(0,descriptorAllocator.GetDescriptorSet(srcDescriptorId).GetVkDescriptorSet()) + .put(1,descriptorAllocator.GetDescriptorSet(bloomPropertiesDescriptorId).GetVkDescriptorSet()); + vkCmdBindDescriptorSets(CommandHandle,VK_PIPELINE_BIND_POINT_GRAPHICS,bloomPipeline.GetVulkanPipelineLayout(),0,BloomDescriptorSets,null); + + vkCmdDraw(CommandHandle,3,1,0,0); + vkCmdEndRendering(CommandHandle); + + VulkanUtils.ImageBarrier(MemStack,CommandHandle,dstBloomAttachment.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); + + if(writePong){ + bloomPongHasBeenWritten = true; + } + } + + VulkanUtils.ImageBarrier(MemStack,CommandHandle,FinalAttachment.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); + + vkCmdBeginRendering(CommandHandle,SingleRenderingInfo); + vkCmdBindPipeline(CommandHandle,VK_PIPELINE_BIND_POINT_GRAPHICS,bloomPipeline.GetVulkanPipeline()); + + vkCmdSetViewport(CommandHandle,0,Viewport); + + vkCmdSetScissor(CommandHandle,0,Scissor); + LongBuffer BloomDescriptorSets = MemStack.mallocLong(2) + .put(0,descriptorAllocator.GetDescriptorSet(DESCRIPTOR_ID_BLOOM_IMAGE_ATTACHMENT).GetVkDescriptorSet()) + .put(1,descriptorAllocator.GetDescriptorSet(DESCRIPTOR_ID_BLOOM_PROPERTIES_FINAL).GetVkDescriptorSet()); + vkCmdBindDescriptorSets(CommandHandle,VK_PIPELINE_BIND_POINT_GRAPHICS,bloomPipeline.GetVulkanPipelineLayout(),0,BloomDescriptorSets,null); + vkCmdDraw(CommandHandle,3,1,0,0); + + vkCmdEndRendering(CommandHandle); } } - public void Resize(VulkanContext VkCtx, Attachment SrcAttachment){ RenderingInfo.free();; ColourAttachment.CleanUp(VkCtx); @@ -188,11 +378,14 @@ public class PostProcess { ColourAttachmentInfo = CreateColourAttachmentInfo(ColourAttachment,ClearValueColour); RenderingInfo = CreateRenderInfo(ColourAttachment,ColourAttachmentInfo); - DescriptorAllocator descriptorAllocator = VkCtx.GetDescriptorAllocator(); - DescriptorSet descriptorSet = descriptorAllocator.GetDescriptorSet(DESCRIPTOR_ID_ATTACHMENT); - descriptorSet.SetImage(VkCtx.GetDevice(),SrcAttachment.GetVkImageView(),textureSampler,0); - + CreateAttachmentDescriptorSet(VkCtx, AttachmentDescriptorSetLayout, SrcAttachment,textureSampler, DESCRIPTOR_ID_ATTACHMENT); + CreateAttachmentDescriptorSets(VkCtx, MultiAttachmentDescriptorSetLayout[0], new Attachment[]{BloomPingAttachment, BloomPingAttachment},textureSampler, DESCRIPTOR_ID_BLOOM_ATTACHMENT); + CreateAttachmentDescriptorSets(VkCtx, MultiAttachmentDescriptorSetLayout[0], new Attachment[]{BloomPongAttachment, BloomPongAttachment},textureSampler, DESCRIPTOR_ID_BLOOM_PONG_ATTACHMENT); + CreateAttachmentDescriptorSets(VkCtx, MultiAttachmentDescriptorSetLayout[0], new Attachment[]{ColourAttachment, BloomPingAttachment},textureSampler, DESCRIPTOR_ID_BLOOM_IMAGE_ATTACHMENT); SetScreenSizeBuffer(VkCtx); + SetBloomPropertiesBuffer(VkCtx, BloomPropertiesHorizontalBuffer, true, false); + SetBloomPropertiesBuffer(VkCtx, BloomPropertiesVerticalBuffer, false, false); + SetBloomPropertiesBuffer(VkCtx, BloomPropertiesFinalBuffer, false, true); } private void SetScreenSizeBuffer(VulkanContext VkCtx){ @@ -204,11 +397,35 @@ public class PostProcess { ScreenSizeBuffer.UnMapMemory(VkCtx); } - public Attachment GetAttachment(){return ColourAttachment;} + public static float GAMMA = 1.75f; + public static float EXPOSURE = 2.5f; + public static float BLOOM_RADIUS = 2.5f; + + private void SetBloomPropertiesBuffer(VulkanContext VkCtx, VulkanBuffer buffer, boolean horizontal, boolean Complete){ + long MappedMemory = buffer.MapMemory(VkCtx); + ByteBuffer dataBuffer = MemoryUtil.memByteBuffer(MappedMemory,(int)buffer.GetRequestedSize()); + int Offset = 0; + dataBuffer.putInt(Offset,Complete ? 1 : 0); + Offset += VulkanUtils.BOOLEAN_SIZE; + dataBuffer.putInt(Offset,horizontal ? 1 : 0); + Offset += VulkanUtils.BOOLEAN_SIZE; + dataBuffer.putFloat(Offset,GAMMA); + Offset += VulkanUtils.FLOAT_SIZE; + dataBuffer.putFloat(Offset,EXPOSURE); + Offset += VulkanUtils.FLOAT_SIZE; + dataBuffer.putFloat(Offset,BLOOM_RADIUS); + Offset += VulkanUtils.FLOAT_SIZE; + buffer.UnMapMemory(VkCtx); + } + + public Attachment GetAttachment(){return FinalAttachment;} public void CleanUp(VulkanContext VkCtx){ ClearValueColour.free(); ColourAttachment.CleanUp(VkCtx); + BloomPingAttachment.CleanUp(VkCtx); + BloomPongAttachment.CleanUp(VkCtx); + FinalAttachment.CleanUp(VkCtx); textureSampler.CleanUp(VkCtx); AttachmentDescriptorSetLayout.CleanUp(VkCtx); FragmentUniformDescriptorSetLayout.CleanUp(VkCtx); @@ -216,6 +433,9 @@ public class PostProcess { RenderingInfo.free(); ColourAttachmentInfo.free(); ScreenSizeBuffer.cleanup(VkCtx); + BloomPropertiesHorizontalBuffer.cleanup(VkCtx); + BloomPropertiesVerticalBuffer.cleanup(VkCtx); + BloomPropertiesFinalBuffer.cleanup(VkCtx); specConstants.CleanUp(); } } diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Rendering/ScreenSpace/AmbientOcclusionRenderer.java b/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Rendering/ScreenSpace/AmbientOcclusionRenderer.java index 552ac70..8909212 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Rendering/ScreenSpace/AmbientOcclusionRenderer.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Rendering/ScreenSpace/AmbientOcclusionRenderer.java @@ -34,8 +34,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import static net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.DeferredRendering.MultiRenderTargetAttachments.SSAO_BLUR_ATTACHMENT; -import static net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.DeferredRendering.MultiRenderTargetAttachments.SSAO_RAW_ATTACHMENT; +import static net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.DeferredRendering.MultiRenderTargetAttachments.*; import static org.lwjgl.vulkan.VK10.*; import static org.lwjgl.vulkan.VK10.VK_SHADER_STAGE_FRAGMENT_BIT; import static org.lwjgl.vulkan.VK13.*; @@ -47,9 +46,9 @@ public class AmbientOcclusionRenderer { VulkanUtils.MATRIX4X4_SIZE + // view VulkanUtils.VEC4_SIZE + // screenSize.xy, radius, bias VulkanUtils.VEC4_SIZE; // kernelSize + padding - private static final int SSAO_KERNEL_SIZE = 32; - private static final float SSAO_RADIUS = 5.0f; - private static final float SSAO_BIAS = 0.15f; + private static final int SSAO_KERNEL_SIZE = 64; + private static final float SSAO_RADIUS = 2.75f; + private static final float SSAO_BIAS = 0.25f; private static final long SSAO_KERNEL_BUFFER_SIZE = SSAO_KERNEL_SIZE * 4L * VulkanUtils.FLOAT_SIZE; private static final String DESC_ID_SSAO_ATTACHMENTS = "SSAO_DESC_ID_ATTACHMENTS"; @@ -67,7 +66,9 @@ public class AmbientOcclusionRenderer { private VkRenderingAttachmentInfo.Buffer ssaoAttachmentInfo; private Attachment ssaoBlurAttachment; private VkRenderingAttachmentInfo.Buffer ssaoBlurAttachmentInfo; - private final Attachment[] SSAO_ATTACHMENTS = new Attachment[2]; + private Attachment ssaoViewPosAttachment; + private VkRenderingAttachmentInfo.Buffer ssaoViewPosAttachmentInfo; + private final Attachment[] SSAO_ATTACHMENTS = new Attachment[3]; private final Pipeline ssaoPipeline; private final Pipeline blurPipeline; @@ -90,14 +91,15 @@ public class AmbientOcclusionRenderer { public AmbientOcclusionRenderer(VulkanContext VkCtx, List MRTAttachments, Queue queue) { List attachments = new ArrayList<>(); - attachments.add(MRTAttachments.get(0)); // position + attachments.add(MRTAttachments.get(7)); // position attachments.add(MRTAttachments.get(2)); // normal CreateAttachments(VkCtx); clearColour = VkClearValue.calloc().color( c -> c.float32(0, 0.0f).float32(1, 0.0f).float32(2, 0.0f).float32(3, 0.0f)); ssaoAttachmentInfo = CreateColourAttachmentInfo(ssaoAttachment, clearColour); ssaoBlurAttachmentInfo = CreateColourAttachmentInfo(ssaoBlurAttachment, clearColour); - var textureSamplerInfo = new TextureSamplerInfo(VK_SAMPLER_ADDRESS_MODE_REPEAT, + ssaoViewPosAttachmentInfo = CreateColourAttachmentInfo(ssaoViewPosAttachment, clearColour); + var textureSamplerInfo = new TextureSamplerInfo(VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, VK_BORDER_COLOR_INT_OPAQUE_BLACK, 1, true); textureSampler = new TextureSampler(VkCtx, textureSamplerInfo); @@ -118,9 +120,9 @@ public class AmbientOcclusionRenderer { attachments.add(NoiseImageAttachment); - ssaoKernelDescriptorLayout = new DescriptorSetLayout(VkCtx, new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, + ssaoKernelDescriptorLayout = new DescriptorSetLayout(VkCtx, new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0, 1, VK_SHADER_STAGE_FRAGMENT_BIT)); - sampleKernelBuffer = VulkanUtils.CreateHostVisibleBuffer(VkCtx, SSAO_KERNEL_BUFFER_SIZE, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, + sampleKernelBuffer = VulkanUtils.CreateHostVisibleBuffer(VkCtx, SSAO_KERNEL_BUFFER_SIZE, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, DESC_ID_SSAO_KERNEL, ssaoKernelDescriptorLayout); long MappedMemory = sampleKernelBuffer.MapMemory(VkCtx); FloatBuffer KernelBuffer = SSAO_Utils.GenerateSampleKernel(SSAO_KERNEL_SIZE, MappedMemory); @@ -137,16 +139,20 @@ public class AmbientOcclusionRenderer { ssaoInfoDescriptorLayout = new DescriptorSetLayout(VkCtx,new DescriptorSetLayout.LayoutInformation( VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0,1,VK_SHADER_STAGE_FRAGMENT_BIT )); - blurDescriptorLayout = new DescriptorSetLayout(VkCtx,new DescriptorSetLayout.LayoutInformation( VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - 0,1,VK_SHADER_STAGE_FRAGMENT_BIT )); + DescriptorSetLayout.LayoutInformation[] descriptorSetLayouts = new DescriptorSetLayout.LayoutInformation[]{ + new DescriptorSetLayout.LayoutInformation( VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + 0,1,VK_SHADER_STAGE_FRAGMENT_BIT ), + new DescriptorSetLayout.LayoutInformation( VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + 1,1,VK_SHADER_STAGE_FRAGMENT_BIT )}; + blurDescriptorLayout = new DescriptorSetLayout(VkCtx,descriptorSetLayouts); CreateBlurDescriptorSet(VkCtx); ssaoInfoBuffers = VulkanUtils.CreateHostVisibleBuffers(VkCtx,SSAO_INFO_BUFFER_SIZE, VulkanUtils.MAX_IN_FLIGHT, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, DESC_ID_SSAO_INFO,ssaoInfoDescriptorLayout); - ssaoRenderInfo = CreateRenderInfo(ssaoAttachment, ssaoAttachmentInfo); - ssaoBlurRenderInfo = CreateRenderInfo(ssaoBlurAttachment, ssaoBlurAttachmentInfo); + ssaoRenderInfo = CreateRenderInfo(ssaoAttachment, ssaoAttachmentInfo,true); + ssaoBlurRenderInfo = CreateRenderInfo(ssaoBlurAttachment, ssaoBlurAttachmentInfo,false); ShaderModule[] shaderModules = CreateRawShaderModules(VkCtx); ssaoPipeline = CreatePipeline(VkCtx, shaderModules, @@ -159,15 +165,20 @@ public class AmbientOcclusionRenderer { shaderModules = CreateBlurShaderModules(VkCtx); blurPipeline = CreatePipeline( VkCtx, shaderModules, - new DescriptorSetLayout[]{ blurDescriptorLayout }, - true ); + new DescriptorSetLayout[]{ blurDescriptorLayout },true ); Arrays.stream(shaderModules).toList().forEach(shaderModule -> shaderModule.CleanUp(VkCtx)); } private static Pipeline CreatePipeline(VulkanContext VkCtx, ShaderModule[] shaderModules, DescriptorSetLayout[] descSetLayouts, boolean blur) { var vtxBuffStruct = new EmptyVertexBufferStruct(); - var buildInfo = new PipelineBuildInfo(shaderModules, vtxBuffStruct.GetVertexInput(),new int[]{blur ? SSAO_BLUR_ATTACHMENT : SSAO_RAW_ATTACHMENT}) + int[] formats; + if(blur){ + formats = new int[]{SSAO_BLUR_ATTACHMENT, VIEW_POS_FORMAT}; + } else { + formats = new int[]{SSAO_RAW_ATTACHMENT, VIEW_POS_FORMAT}; + } + var buildInfo = new PipelineBuildInfo(shaderModules, vtxBuffStruct.GetVertexInput(),formats) .SetDescriptorSetLayouts(descSetLayouts) .BlendingIsUsed(false) .SetDepthWrite(false) @@ -209,14 +220,17 @@ public class AmbientOcclusionRenderer { .clearValue(clearValue); } - private static VkRenderingInfo CreateRenderInfo(Attachment attachment, VkRenderingAttachmentInfo.Buffer attachmentInfo) { + private static VkRenderingInfo CreateRenderInfo(Attachment attachment, VkRenderingAttachmentInfo.Buffer attachmentInfo, boolean Raw) { + + int Width = attachment.GetVkImage().GetWidth(); + int Height = attachment.GetVkImage().GetHeight(); return VkRenderingInfo.calloc() .sType$Default() .renderArea(area -> area .offset(offset -> offset.x(0).y(0)) .extent(extent -> extent - .width(attachment.GetVkImage().GetWidth()) - .height(attachment.GetVkImage().GetHeight()))) + .width(Width) + .height(Height))) .layerCount(1) .pColorAttachments(attachmentInfo); } @@ -236,19 +250,31 @@ public class AmbientOcclusionRenderer { DescriptorSet descSet = vkCtx.GetDescriptorAllocator().AddDescriptorSet( vkCtx.GetDevice(),DESC_ID_SSAO_BLUR_INPUT, blurDescriptorLayout); - descSet.SetImage(vkCtx.GetDevice(), ssaoAttachment.GetVkImageView(), - textureSampler,0); + List imageViews = new ArrayList<>(); + imageViews.add(ssaoAttachment.GetVkImageView()); + imageViews.add(ssaoViewPosAttachment.GetVkImageView()); + + descSet.SetImages(vkCtx.GetDevice(), imageViews,textureSampler,0); } private void CreateAttachments(VulkanContext VkCtx){ SwapChain swapChain = VkCtx.GetSwapChain(); VkExtent2D swapChainExtent = swapChain.GetSwapChainExtent(); + + float AspectRatio = (float)swapChainExtent.width()/(float)swapChainExtent.height(); + int Width = swapChainExtent.width(); + int Height = swapChainExtent.height(); + int RawWidth = (int)(Math.round(Math.min(swapChainExtent.width()/2.0f, 1920 * AspectRatio))); + int RawHeight = (int)(Math.round(Math.min(swapChainExtent.height()/2.0f, 1080))); //SSAO Raw - ssaoAttachment = new Attachment(VkCtx, swapChainExtent.width(), swapChainExtent.height(), SSAO_RAW_ATTACHMENT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, 1); + ssaoAttachment = new Attachment(VkCtx, Width, Height, SSAO_RAW_ATTACHMENT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, 1); SSAO_ATTACHMENTS[0] = ssaoAttachment; //SSAO Blur - ssaoBlurAttachment = new Attachment(VkCtx, swapChainExtent.width(), swapChainExtent.height(), SSAO_BLUR_ATTACHMENT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, 1); + ssaoBlurAttachment = new Attachment(VkCtx, Width, Height, SSAO_BLUR_ATTACHMENT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, 1); SSAO_ATTACHMENTS[1] = ssaoBlurAttachment; + + ssaoViewPosAttachment = new Attachment(VkCtx, Width, Height, VIEW_POS_FORMAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, 1); + SSAO_ATTACHMENTS[1] = ssaoViewPosAttachment; } public void Render(VulkanContext VkCtx,EngineInstance engineInstance, CommandBuffer cmdBuffer, MultiRenderTargetAttachments MRT,int CurrentFrame) { @@ -268,6 +294,15 @@ public class AmbientOcclusionRenderer { VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT, VK_IMAGE_ASPECT_COLOR_BIT); + VulkanUtils.ImageBarrier(stack, cmdHandle, ssaoViewPosAttachment.GetVkImage().getVulkanImage(), + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT, + VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, + VK_ACCESS_2_SHADER_READ_BIT, + VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT, + VK_IMAGE_ASPECT_COLOR_BIT); + TransitionMRTtoReadOnly(stack, cmdHandle, MRT); @@ -371,6 +406,8 @@ public class AmbientOcclusionRenderer { vkCmdSetScissor(cmdHandle, 0, scissor); } + public static float SSAO_RESOLUTION_SCALE = 0.5f; + private void UpdateSSAOInfo(VulkanContext vkCtx, EngineInstance engineInstance, int currentFrame) { VulkanBuffer buffer = ssaoInfoBuffers[currentFrame]; long mappedMemory = buffer.MapMemory(vkCtx); @@ -383,15 +420,16 @@ public class AmbientOcclusionRenderer { engineInstance.scene().GetCamera().GetViewMatrix().get(offset, data); offset += VulkanUtils.MATRIX4X4_SIZE; - + //SSAO Raw data.putFloat(offset, ssaoAttachment.GetVkImage().GetWidth()); data.putFloat(offset + VulkanUtils.FLOAT_SIZE, ssaoAttachment.GetVkImage().GetHeight()); data.putFloat(offset + VulkanUtils.FLOAT_SIZE * 2, SSAO_RADIUS); data.putFloat(offset + VulkanUtils.FLOAT_SIZE * 3, SSAO_BIAS); offset += VulkanUtils.VEC4_SIZE; - data.putInt(offset, SSAO_KERNEL_SIZE); - + offset +=VulkanUtils.INT_SIZE; + data.putFloat(offset, SSAO_RESOLUTION_SCALE); + offset += VulkanUtils.FLOAT_SIZE; buffer.UnMapMemory(vkCtx); } @@ -411,8 +449,8 @@ public class AmbientOcclusionRenderer { ssaoAttachmentInfo = CreateColourAttachmentInfo(ssaoAttachment, clearColour); ssaoBlurAttachmentInfo = CreateColourAttachmentInfo(ssaoBlurAttachment, clearColour); - ssaoRenderInfo = CreateRenderInfo(ssaoAttachment, ssaoAttachmentInfo); - ssaoBlurRenderInfo = CreateRenderInfo(ssaoBlurAttachment, ssaoBlurAttachmentInfo); + ssaoRenderInfo = CreateRenderInfo(ssaoAttachment, ssaoAttachmentInfo,true); + ssaoBlurRenderInfo = CreateRenderInfo(ssaoBlurAttachment, ssaoBlurAttachmentInfo,false); attachments.add(NoiseImageAttachment); diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Rendering/ScreenSpace/ReflectionsRenderer.java b/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Rendering/ScreenSpace/ReflectionsRenderer.java new file mode 100644 index 0000000..6ca7d51 --- /dev/null +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Rendering/ScreenSpace/ReflectionsRenderer.java @@ -0,0 +1,310 @@ +package net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.ScreenSpace; + +import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig; +import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance; +import net.halbear.Terrain4J.EngineCore.Logic.Rendering.VulkanContext; +import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.DeferredRendering.MultiRenderTargetAttachments; +import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.EmptyVertexBufferStruct; +import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.DefaultPipeline; +import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.Images.Attachment; +import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.Images.Image; +import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.Images.Texture; +import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.Pipeline; +import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.PipelineBuildInfo; +import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Shader.*; +import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DeviceLayers.CommandBuffer; +import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DeviceLayers.Queues.Queue; +import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DisplayToScreen.ImageView; +import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.SwapChain.SwapChain; +import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Util.VulkanBuffer; +import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Util.VulkanUtils; +import org.joml.Matrix4f; +import org.lwjgl.system.MemoryStack; +import org.lwjgl.system.MemoryUtil; +import org.lwjgl.util.shaderc.Shaderc; +import org.lwjgl.vulkan.*; + +import java.nio.ByteBuffer; +import java.nio.LongBuffer; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import static net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.DeferredRendering.MultiRenderTargetAttachments.*; +import static org.lwjgl.vulkan.VK10.*; +import static org.lwjgl.vulkan.VK13.*; + +public class ReflectionsRenderer { + + private static final long SSR_INFO_BUFFER_SIZE = + VulkanUtils.MATRIX4X4_SIZE + // projection + VulkanUtils.MATRIX4X4_SIZE + // projection inv + VulkanUtils.MATRIX4X4_SIZE + // view + VulkanUtils.MATRIX4X4_SIZE + // view inv + VulkanUtils.VEC4_SIZE + // steps, distance, max steps + VulkanUtils.VEC4_SIZE; //Camera + public static float STEP_SIZE = 0.25f; + public static float MAX_DIST = 200.0f; + public static int MAX_STEPS = 64; + private static final String DESC_ID_SSR_ATTACHMENTS = "SSR_DESC_ID_ATTACHMENTS"; + private static final String DESC_ID_SSR_INFO = "SSR_DESC_ID_INFO"; + + private static final String FRAGMENT_SHADER_FILE_GLSL = "resources/EngineResources/shaders/screen_space_reflection_frag.glsl"; + private static final String FRAGMENT_SHADER_FILE_SPV = FRAGMENT_SHADER_FILE_GLSL + ".spv"; + private static final String VERTEX_SHADER_FILE_GLSL = "resources/EngineResources/shaders/basic_screen_vertex.glsl"; + private static final String VERTEX_SHADER_FILE_SPV = VERTEX_SHADER_FILE_GLSL + ".spv"; + private Attachment ssrAttachment; + private Attachment renderedSceneAttachment; + private VkRenderingAttachmentInfo.Buffer ssrAttachmentInfo; + + private final Pipeline ssrPipeline; + private final TextureSampler textureSampler; + + private DescriptorSetLayout ssrAttachmentDescriptorLayout; + private DescriptorSetLayout ssrInfoDescriptorLayout; + + + private final VkClearValue clearColour; + private VkRenderingInfo ssrRenderInfo; + + private VulkanBuffer[] ssrInfoBuffers; + + public ReflectionsRenderer(VulkanContext VkCtx, List MRTAttachments, Attachment Rendered) { + this.renderedSceneAttachment = Rendered; + + List attachments = new ArrayList<>(); + attachments.add(Rendered); + attachments.add(MRTAttachments.get(0)); // position + attachments.add(MRTAttachments.get(2)); // normal + attachments.add(MRTAttachments.get(3)); // pbr + CreateAttachments(VkCtx); + clearColour = VkClearValue.calloc().color( + c -> c.float32(0, 0.0f).float32(1, 0.0f).float32(2, 0.0f).float32(3, 0.0f)); + ssrAttachmentInfo = CreateColourAttachmentInfo(ssrAttachment, clearColour); + var textureSamplerInfo = new TextureSamplerInfo(VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, + VK_BORDER_COLOR_INT_OPAQUE_BLACK, 1, true); + textureSampler = new TextureSampler(VkCtx, textureSamplerInfo); + + int numAttachments = attachments.size(); + DescriptorSetLayout.LayoutInformation[] descSetLayouts = new DescriptorSetLayout.LayoutInformation[numAttachments]; + for (int i = 0; i < numAttachments; i++) { + descSetLayouts[i] = new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, i, 1, VK_SHADER_STAGE_FRAGMENT_BIT); + } + ssrAttachmentDescriptorLayout = new DescriptorSetLayout(VkCtx, descSetLayouts); + CreateSSRAttachmentDescriptorSet(VkCtx, attachments); + + ssrInfoDescriptorLayout = new DescriptorSetLayout(VkCtx,new DescriptorSetLayout.LayoutInformation( VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + 0,1,VK_SHADER_STAGE_FRAGMENT_BIT )); + + ssrInfoBuffers = VulkanUtils.CreateHostVisibleBuffers(VkCtx,SSR_INFO_BUFFER_SIZE, VulkanUtils.MAX_IN_FLIGHT, + VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, DESC_ID_SSR_INFO,ssrInfoDescriptorLayout); + + ssrRenderInfo = CreateRenderInfo(ssrAttachment, ssrAttachmentInfo,true); + + ShaderModule[] shaderModules = CreateRawShaderModules(VkCtx); + ssrPipeline = CreatePipeline(VkCtx, shaderModules, + new DescriptorSetLayout[]{ + ssrAttachmentDescriptorLayout, + ssrInfoDescriptorLayout + }); + Arrays.stream(shaderModules).toList().forEach(shaderModule -> shaderModule.CleanUp(VkCtx)); + } + + + private static Pipeline CreatePipeline(VulkanContext VkCtx, ShaderModule[] shaderModules, DescriptorSetLayout[] descSetLayouts ) { + var vtxBuffStruct = new EmptyVertexBufferStruct(); + int[] formats = new int[]{SSR_FORMAT}; + + var buildInfo = new PipelineBuildInfo(shaderModules, vtxBuffStruct.GetVertexInput(), formats) + .SetDescriptorSetLayouts(descSetLayouts) + .BlendingIsUsed(false) + .SetDepthWrite(false) + .SetDepthTest(false); + + var pipeline = new DefaultPipeline(VkCtx, buildInfo); + vtxBuffStruct.CleanUp(); + return pipeline; + } + + + private static ShaderModule[] CreateRawShaderModules(VulkanContext VkCtx) { + if (EngineConfig.getInstance().RecompileShaders()) { + ShaderCompiler.CompileGLSLShaderOnChange(VERTEX_SHADER_FILE_GLSL, Shaderc.shaderc_glsl_vertex_shader); + ShaderCompiler.CompileGLSLShaderOnChange( FRAGMENT_SHADER_FILE_GLSL , Shaderc.shaderc_glsl_fragment_shader); + } + return new ShaderModule[]{ + new ShaderModule(VkCtx, VK_SHADER_STAGE_VERTEX_BIT, VERTEX_SHADER_FILE_SPV, null), + new ShaderModule(VkCtx, VK_SHADER_STAGE_FRAGMENT_BIT, FRAGMENT_SHADER_FILE_SPV, null), + }; + } + + + private static VkRenderingAttachmentInfo.Buffer CreateColourAttachmentInfo(Attachment attachment, VkClearValue clearValue) { + return VkRenderingAttachmentInfo.calloc(1) + .sType$Default() + .imageView(attachment.GetVkImageView().GetVulkanImageView()) + .imageLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) + .loadOp(VK_ATTACHMENT_LOAD_OP_CLEAR) + .storeOp(VK_ATTACHMENT_STORE_OP_STORE) + .clearValue(clearValue); + } + + private static VkRenderingInfo CreateRenderInfo(Attachment attachment, VkRenderingAttachmentInfo.Buffer attachmentInfo, boolean Raw) { + + int Width = attachment.GetVkImage().GetWidth(); + int Height = attachment.GetVkImage().GetHeight(); + return VkRenderingInfo.calloc() + .sType$Default() + .renderArea(area -> area + .offset(offset -> offset.x(0).y(0)) + .extent(extent -> extent + .width(Width) + .height(Height))) + .layerCount(1) + .pColorAttachments(attachmentInfo); + } + + private void CreateSSRAttachmentDescriptorSet(VulkanContext vkCtx, List Attachments ) { + DescriptorSet descSet = vkCtx.GetDescriptorAllocator().AddDescriptorSet( + vkCtx.GetDevice(), DESC_ID_SSR_ATTACHMENTS, ssrAttachmentDescriptorLayout); + + List imageViews = new ArrayList<>(); + Attachments.forEach(a -> imageViews.add(a.GetVkImageView())); + + descSet.SetImages(vkCtx.GetDevice(), imageViews, textureSampler, 0); + } + + + + + private void CreateAttachments(VulkanContext VkCtx){ + SwapChain swapChain = VkCtx.GetSwapChain(); + VkExtent2D swapChainExtent = swapChain.GetSwapChainExtent(); + + float AspectRatio = (float)swapChainExtent.width()/(float)swapChainExtent.height(); + int Width = swapChainExtent.width(); + int Height = swapChainExtent.height(); + int RawWidth = (int)(Math.round(Math.min(swapChainExtent.width()/2.0f, 1920 * AspectRatio))); + int RawHeight = (int)(Math.round(Math.min(swapChainExtent.height()/2.0f, 1080))); + //SSR Raw + ssrAttachment = new Attachment(VkCtx, Width, Height, SSR_FORMAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, 1); + } + + public void Render(VulkanContext VkCtx,EngineInstance engineInstance, CommandBuffer cmdBuffer, int CurrentFrame) { + try (var stack = MemoryStack.stackPush()) { + + VkCommandBuffer cmdHandle = cmdBuffer.GetVulkanCommandBuffer(); + + UpdateSSRInfo(VkCtx, engineInstance, CurrentFrame); + + VulkanUtils.ImageBarrier(stack, cmdHandle, renderedSceneAttachment.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, ssrAttachment.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); + + vkCmdBeginRendering(cmdHandle, ssrRenderInfo); + + vkCmdBindPipeline(cmdHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, ssrPipeline.GetVulkanPipeline()); + + SetViewportAndScissor(stack, cmdHandle, ssrAttachment); + + DescriptorAllocator descAllocator = VkCtx.GetDescriptorAllocator(); + LongBuffer descriptorSets = stack.mallocLong(2) + .put(0, descAllocator.GetDescriptorSet(DESC_ID_SSR_ATTACHMENTS).GetVkDescriptorSet()) + .put(1, descAllocator.GetDescriptorSet(DESC_ID_SSR_INFO, CurrentFrame).GetVkDescriptorSet()); + + vkCmdBindDescriptorSets(cmdHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, + ssrPipeline.GetVulkanPipelineLayout(), 0, descriptorSets, null); + + vkCmdDraw(cmdHandle, 3, 1, 0, 0); + + vkCmdEndRendering(cmdHandle); + } + } + + private void SetViewportAndScissor(MemoryStack stack, VkCommandBuffer cmdHandle, Attachment attachment){ + Image ColourImage = attachment.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); + } + + + public Attachment GetSSRAttachment() { + return ssrAttachment; + } + + private void UpdateSSRInfo(VulkanContext vkCtx, EngineInstance engineInstance, int currentFrame) { + VulkanBuffer buffer = ssrInfoBuffers[currentFrame]; + long mappedMemory = buffer.MapMemory(vkCtx); + ByteBuffer data = MemoryUtil.memByteBuffer(mappedMemory, (int) buffer.GetRequestedSize()); + + int offset = 0; + + engineInstance.scene().GetProjection().GetProjectionMatrix().get(offset, data); + offset += VulkanUtils.MATRIX4X4_SIZE; + engineInstance.scene().GetProjection().GetProjectionMatrix().invert(new Matrix4f()).get(offset, data); + offset += VulkanUtils.MATRIX4X4_SIZE; + engineInstance.scene().GetCamera().GetViewMatrix().get(offset, data); + offset += VulkanUtils.MATRIX4X4_SIZE; + engineInstance.scene().GetCamera().GetViewMatrix().invert(new Matrix4f()).get(offset, data); + offset += VulkanUtils.MATRIX4X4_SIZE; + + data.putFloat(offset, STEP_SIZE); + data.putFloat(offset + VulkanUtils.FLOAT_SIZE, MAX_DIST); + data.putInt(offset + VulkanUtils.FLOAT_SIZE * 2, MAX_STEPS); + data.putInt(offset + VulkanUtils.FLOAT_SIZE * 3, 0); + offset += VulkanUtils.VEC4_SIZE; + + engineInstance.scene().GetCamera().GetPosition().get(offset, data); + data.putFloat(offset + VulkanUtils.VEC3_SIZE, 1.0f); + offset += VulkanUtils.VEC4_SIZE; + + buffer.UnMapMemory(vkCtx); + } + + public void resize(VulkanContext VkCtx, List attachments) { + ssrRenderInfo.free(); + ssrAttachmentInfo.free(); + ssrAttachment.CleanUp(VkCtx); + + renderedSceneAttachment = attachments.get(0); + + CreateAttachments(VkCtx); + + ssrAttachmentInfo = CreateColourAttachmentInfo(ssrAttachment, clearColour); + ssrRenderInfo = CreateRenderInfo(ssrAttachment, ssrAttachmentInfo,true); + CreateSSRAttachmentDescriptorSet(VkCtx, attachments); + } + + public void cleanup(VulkanContext VkCtx) { + ssrRenderInfo.free(); + ssrAttachmentInfo.free(); + ssrAttachment.CleanUp(VkCtx); + ssrPipeline.CleanUp(VkCtx); + clearColour.free(); + Arrays.stream(ssrInfoBuffers).toList().forEach(b -> b.cleanup(VkCtx)); + ssrAttachmentDescriptorLayout.CleanUp(VkCtx); + ssrInfoDescriptorLayout.CleanUp(VkCtx); + textureSampler.CleanUp(VkCtx); + } +} diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Rendering/VkModel/MaterialsCache.java b/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Rendering/VkModel/MaterialsCache.java index 83ea1df..25f0070 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Rendering/VkModel/MaterialsCache.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Rendering/VkModel/MaterialsCache.java @@ -22,7 +22,7 @@ import static org.lwjgl.util.vma.Vma.VMA_MEMORY_USAGE_AUTO; import static org.lwjgl.vulkan.VK10.*; public class MaterialsCache { - private static final int MATERIAL_RAW_SIZE = VulkanUtils.VEC4_SIZE * 4 + (VulkanUtils.INT_SIZE * 2 + VulkanUtils.FLOAT_SIZE) * 2 + (VulkanUtils.INT_SIZE * 2); + private static final int MATERIAL_RAW_SIZE = VulkanUtils.VEC4_SIZE * 4 + (VulkanUtils.INT_SIZE * 2 + VulkanUtils.FLOAT_SIZE) * 2 + (VulkanUtils.INT_SIZE * 4) + VulkanUtils.FLOAT_SIZE * 2; private static final int MATERIAL_SIZE = 16 * (int)(Math.ceil(MATERIAL_RAW_SIZE/16.0)); private final IndexedLinkedHashMap MaterialsMap; private VulkanBuffer MaterialsBuffer; @@ -151,6 +151,12 @@ public class MaterialsCache { data.putFloat(Offset, Material.Opacity()); Offset += VulkanUtils.FLOAT_SIZE; + + data.putFloat(Offset, Material.Reflectiveness()); + Offset += VulkanUtils.FLOAT_SIZE; + data.putFloat(Offset, Material.Refractiveness()); + Offset += VulkanUtils.FLOAT_SIZE; + Offset = materialBaseOffset + MATERIAL_SIZE; } // data.position(0); diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Structure/DisplayToScreen/DeferredSceneRender.java b/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Structure/DisplayToScreen/DeferredSceneRender.java index 20ee739..bf8b739 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Structure/DisplayToScreen/DeferredSceneRender.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Structure/DisplayToScreen/DeferredSceneRender.java @@ -244,7 +244,8 @@ public class DeferredSceneRender implements SceneRenderer {//dynamic rendering MultiRenderTargetAttachments.PBR_FORMAT, MultiRenderTargetAttachments.EMISSIVE_FORMAT, MultiRenderTargetAttachments.TRANSLUCECNY_FORMAT, - MultiRenderTargetAttachments.OPACITY_FORMAT + MultiRenderTargetAttachments.OPACITY_FORMAT, + MultiRenderTargetAttachments.VIEW_POS_FORMAT }; try (MemoryStack MemStack = MemoryStack.stackPush()) { @@ -285,7 +286,7 @@ public class DeferredSceneRender implements SceneRenderer {//dynamic rendering MultiRenderTargetAttachments.POSITION_FORMAT, MultiRenderTargetAttachments.ALBEDO_FORMAT, MultiRenderTargetAttachments.NORMAL_FORMAT, MultiRenderTargetAttachments.PBR_FORMAT, MultiRenderTargetAttachments.EMISSIVE_FORMAT, MultiRenderTargetAttachments.TRANSLUCECNY_FORMAT, - MultiRenderTargetAttachments.OPACITY_FORMAT}) + MultiRenderTargetAttachments.OPACITY_FORMAT, MultiRenderTargetAttachments.VIEW_POS_FORMAT}) .SetDepthFormat(MultiRenderTargetAttachments.DEPTH_FORMAT) .SetDepthWrite(DepthWrite) .SetPushConstantRanges( diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Util/VulkanUtils.java b/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Util/VulkanUtils.java index dbb6c87..3ba0d8f 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Util/VulkanUtils.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Util/VulkanUtils.java @@ -38,6 +38,7 @@ public class VulkanUtils { public static final int VEC4_SIZE = 4 * FLOAT_SIZE; public static final int VEC2_SIZE = 2 * FLOAT_SIZE; public static final int SHORT_LENGTH = 2; + public static final int BOOLEAN_SIZE = 4; private static final List DeletionQueue = new ArrayList<>();