From 04befce27d553d93c21261f5c2366fc174f3cf97 Mon Sep 17 00:00:00 2001 From: Halbear Date: Fri, 4 Sep 2026 00:23:48 +0100 Subject: [PATCH] HDR, Bloom and SSR --- .gitignore | 2 + .../EngineResources/Texture/test_cube.png | Bin 0 -> 1567 bytes .../shaders/bloom_pass_frag.glsl | 61 ++++ .../shaders/lighting_frag.glsl | 14 +- .../shaders/lighting_frag.glsl.spv | Bin 15800 -> 13336 bytes .../shaders/lighting_with_shadows_frag.glsl | 29 +- .../multi-sampled_post_process_frag.glsl | 23 +- .../multi-sampled_post_process_frag.glsl.spv | Bin 3704 -> 3704 bytes .../shaders/post_process_frag.glsl | 38 ++- .../shaders/post_process_frag.glsl.spv | Bin 6248 -> 6860 bytes .../shaders/scene_fragment.glsl | 13 +- .../shaders/scene_fragment.glsl.spv | Bin 6084 -> 6344 bytes .../shaders/scene_fragment_deferred.glsl | 16 +- .../shaders/scene_fragment_deferred.glsl.spv | Bin 10228 -> 11428 bytes .../shaders/scene_opaque_fragment.glsl | 9 + .../shaders/scene_opaque_fragment.glsl.spv | Bin 6084 -> 6344 bytes .../scene_opaque_fragment_deferred.glsl | 24 +- .../scene_opaque_fragment_deferred.glsl.spv | Bin 10632 -> 0 bytes .../shaders/scene_translucent_fragment.glsl | 10 + .../scene_translucent_fragment.glsl.spv | Bin 6084 -> 6344 bytes .../scene_translucent_fragment_deferred.glsl | 19 +- ...ene_translucent_fragment_deferred.glsl.spv | Bin 10800 -> 0 bytes .../EngineResources/shaders/scene_vertex.glsl | 3 +- .../shaders/scene_vertex.glsl.spv | Bin 3104 -> 3264 bytes .../shaders/screen_space_reflection_frag.glsl | 128 ++++++++ .../EngineResources/shaders/shadow_frag.glsl | 21 +- .../shaders/skybox_fragment.glsl | 2 +- .../shaders/skybox_fragment.glsl.spv | Bin 756 -> 644 bytes .../shaders/ssao_blur_frag.glsl | 40 ++- .../EngineResources/shaders/ssao_frag.glsl | 99 +++--- resources/models/cube/Cube_mat.json | 63 +++- .../EngineCore/Display/VulkanRenderer.java | 61 +++- .../Logic/Rendering/ModelCompiler.java | 23 +- .../Terrain4J/EngineCore/Main/GameCore.java | 179 +++++----- .../Main/Scene/GUIs/PerformanceOverlay.java | 82 ++++- .../Universal/SSAO/SSAO_Utils.java | 4 +- .../DeferredRendering/LightRenderer.java | 4 +- .../MultiRenderTargetAttachments.java | 7 + .../Rendering/PostProcessing/PostProcess.java | 252 +++++++++++++- .../ScreenSpace/AmbientOcclusionRenderer.java | 96 ++++-- .../ScreenSpace/ReflectionsRenderer.java | 310 ++++++++++++++++++ .../Rendering/VkModel/MaterialsCache.java | 8 +- .../DisplayToScreen/DeferredSceneRender.java | 5 +- .../RenderingAPI/Vulkan/Util/VulkanUtils.java | 1 + 44 files changed, 1377 insertions(+), 269 deletions(-) create mode 100644 resources/EngineResources/Texture/test_cube.png create mode 100644 resources/EngineResources/shaders/bloom_pass_frag.glsl delete mode 100644 resources/EngineResources/shaders/scene_opaque_fragment_deferred.glsl.spv delete mode 100644 resources/EngineResources/shaders/scene_translucent_fragment_deferred.glsl.spv create mode 100644 resources/EngineResources/shaders/screen_space_reflection_frag.glsl create mode 100644 src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Rendering/ScreenSpace/ReflectionsRenderer.java 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 0000000000000000000000000000000000000000..bc5571f8c18b96acf0ebebba3a2b30597e34956d GIT binary patch literal 1567 zcmV+)2H^RLP)Px)*-1n}R9J}7`4(eq0TU?k40m%D7{adg8 zo@g?Gs_Ou>9S0%btv>)@YUT_8qBBsNP6|RmUj91*`MN56zY{K=BR}~5WpV@(Cu{aDGJ8OFwKU8ZW{9N zDGE-lPRnWHpF2OX*h3*1*SNK`%eAYM+*;Zt7Bg8{%@T{599CU6?ibOGA-X;2p|G-= z<=WLrY<&i&R!7xToO%OQQ|Wd(sJf1-sWcl7omPuRwMM(umLx)U6rZBtfBWqpE#6++ zCl)jLZo5h**TOJVdMI>zuyMbLVW^}p*xX**$1qfehgG^g_|Mt_zrFr0rF?;Exk9a6 zp;9d2QxsH9Mb&l8QHvo%$FxSMl@DoDYc#4gOlt()H1Kznp~XnVkbrZk5V^d=&h8=U z3pR&Um$_7kmDMbfh(X*o`R0B>>fZRp>xAqmm0}6kb#Yynw$qelQ8iWeglUb?ZnaVT zewq!3X2U_bapgL5sSw}XFA%p)Qq}?hH?CY~Wi=~}e>tB7AQ{()L<~~a0&}SlK1CsrvKAOi#vwb;IycGgw`3nIoOuU;N5(3V#ynY;vBE)?AAG{^ z-ufdfBNt1n*#eN|P<6epG-CPe{r7(aG)@+WWTGKkIp&c$s_eJFUk}c9gS|*!#BDR(f7XgP%+x;e;)n0J4(@iF{xC zK-c{jx9@B+7Sh=(Ir2>4@r#**I^!`D!`0cVIGme4O}?;0I5a_Se}|vF{x=^d5G7yO zc?t^bl^ik$bqOxcf?U3^a}vB~3E0sI0LDUkA1J{2QxU|kB|%OQeNjY|d|?MWIw2zz zfZnLbW9E?r1^E*Z0Jyug+4s;JHBYi5B0qmBBClVBC?ZM`u>kZ&4RCJybf4i~$$24V zP`oJ>fP$1Aosel3V1lHV@JS@#O{oC>^5LT=>c^mVbOJFgfYf`*A6JwwA3kC%q;vjM zq)#F0F2Ds5J38^qyC;!=*V(!0(=2`QHF%;N3q1wDyR|77llXITQc>`XQ@*gnc+8X$ zj>k+{p1WI{eWU0d*%J{EDHbHoO`m43S3Z6IDVj+2#)KP2s*aYb7`2IySm~wFz{qiEl@&6=f9yC0T RLj(W-002ovPDHLkV1gdC@1g(z literal 0 HcmV?d00001 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 caffa84a5214bfa1b30a923ad69e73b96396e59e..2fdb0982c56546233dc72a0ea79219483f3f7f14 100644 GIT binary patch delta 3575 zcmZ9OTWnNS6o&V7F3c3BiJc;-SUOZ6h+=&45)DQm0>%q%jA(pvC?iZVmu6-Fwdw)! zf+zwWK?FhSU5g^(g=#RtghZ=8sWC<|@xg?EXm~O{kobRR&K`EphRs?3|F6B)I{U0W zn&C?hsR|Hj7nxJQS$OU|C%DP`EQRz!@7_+niD%XZ*9BIqx5_K>=d% z>QK1hLcLJYYH%WgQxTkw;LZr17QtPUv1fWF6XwDQo*BUxNARo&?v3ES2%a+u=MrYF zh(cvWsaS35jZ>!L&zrWy;~3?&2NKN^?E`p@YzCO)g03^!#;(3O)U7|*)whK@Ux|2N zNB4sBlb1-h;lO!v9L%0DKr+<9uFjdsOG}43*wr~dz0w#<)RlC0hwP==go&8HFxwp* z39+VMbDEX>3%YWb<4ol!vjQa%1fW<73WE5f+1xdF!s6Md$*XW!^0FBgQ<_bG+Fy{( zO{cf@cT)D#WcN^P_MR}tU*b}-`vM#fx*eaT%17rjW@=KI#ni;$^*IOV)PtQ5l=GPS z2qV4QR8%PrBxFJ5@bRv(4zEw*8hO+o80Y27D#s5Y&u@hzy z4K*d`19pHwJoB13QOvh`vXHJ|H^6iQ9QybEV0X^@QB3F0{qwI>3?lp_3}>h1e-n3$ zbUTS~LY&PC{!^IfdCeYKCxv?zmmacyw$e+rDe5CH5PJn^6dH>_f9pvgI7$c8D7N&o zp-o`+X`g)mm94*q^;gLeUy`BoTp^;?z3~R?Ulu+YpL)JiD*oQwbxC?^#Q!BX+vC!v zY6{?Bb4go_*H#Ckb1_>TyxYMU;r$WJ#cTc1k50y(Ipz=qJRZT^t2O{Scc6>82QB7P zaTi+5aXb~lTt`+<>&pc9(Ro7KImtmkcM;5eWc_&~?jsj-A6ZNRTt^o30$fLJyix@B zQJWCvK5{Ylk&C&HET(|I2U1n-Kl+kb`INP~u?idI5CS*7SUmBfxKzP5zW@H~G^oCj)O2Y?2Mn zWbm*F=vs7};91$5L(I!Pr|HJu64Qsq3Be|KUiOx7MiX!h&~1Y4viT9UFYtnFH-RsV z4?Mfav4OMece1@ZLV^lk(sTpt65bi|w!oK#;hE6_Ifv*r!7H-)6}JWMmF>p&_KCm= z!6tZBHas($fP;;`K>b0Ny(XKaqnae)*XDKE@VxPUJ;Ao1w`6l`gavu#Z2`BUcZ6|* zA5;1Svh1DGqKxEjr9uGNa%Y7blbo_uqas5<}}=>6eo)$*D8M8B86VP^vAx zidOYjDO#$usHr*`N)1(|ik7zMfU2fy*5dwt``hoyI{UfLeV)6Yv!3<;|KE4L>s@QF zwe~tEX&5|qNR|!C*2~tQEt4npY(oM($a*ytTWht94m#Pitq#+_}e&KWW9D(=96|PtPjkxgI`;Q^X^v56N+b z8OpM*&fb-)I%?hBxi&1@lzL^Yv%S{Sb?V}lRc);;Cm51YMl(iZwlVeL%R76H&Uq!< zgnD3{;n^s({y6QeJ*)b&ip=Wyj5Jmrry<*dx*oG3+Y&rK*DKjp)C1!W&9*~Z(N*j2 zsI?VonxnCeTgkS?-qP8FfmHBvgqK^3- z4~}`>865Ml3%J_0thT( zF`FAaw>M;m!8e7!fB;%CHpRQwTC^>Tg|tP+RbR`zEHart*g4cbzR$r>`t`951xay zF}n+#j_IBfzjpv{$nJ;xUTpio09#}BP>DZW;*SjA4cTMxITT|(Il$JKJvD$=vZvu4 zz3sKGYEQAhE7@~s`TK0`$W_O?7Oi`A%{}jOKxxQcr#@kE9lt3)xZdacVBdet`9_1* z&Hv`$nEz4W@*Ivqi#cotr*k;A#K#Tb4cT~j%;C-hY>nB35}#P&yA9wC*>i!zlx7 zjoH)zypm0am*;RMT6qo^pq1zFNVJ&4CE{WZj{~op!^W%~zV1wD%1-R(i>vLc+iLYa zTFJldtsP5hr}P}u+1a%`UjwJ%+tJz8&QT9<%0AZ5yZamaj{DFDp1GB54I1B&#IGSc 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 bf%Q|@$9LTdHuspbkAn46_irb1?*RV;L6$Z) 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 2cf3d79a272ff9ca6409715b5f6f718e50d76bde..2b3bfbeb89e7d5c33eca5c975313d14c42990fc1 100644 GIT binary patch delta 17 Ycmew%^FwBX0}D$)ue$wa7ZwvP06lF5od5s; delta 17 Ycmew%^FwBX0}G4gmKS!LU06)G07DlBZ2$lO 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 055aba0b967ca55e2d8a06a68d5527b2733b473b..ad42b726b2c30f8f7394e230ccd37af6145095d7 100644 GIT binary patch literal 6860 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 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 97767830fdd9a9334933c5275a19e4f82cb5f560..a05b0b0cd262a19b3b890926e90f499dabf6294f 100644 GIT binary patch literal 6344 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 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 4240da6ac70470409b41275ba834cde763333c19..e660504efa8a40bc208079731319f6df21c46b3c 100644 GIT binary patch literal 11428 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 MAX_TEXTURES){ diff --git a/resources/EngineResources/shaders/scene_opaque_fragment.glsl.spv b/resources/EngineResources/shaders/scene_opaque_fragment.glsl.spv index 251492d28d193ff36f9dd72d5b7b1cf38efb645d..156f36fa33551b58fba98d0bb88517c7e1a400a6 100644 GIT binary patch literal 6344 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 literal 6084 zcma);`IlT(5y#(TmJA>PWD^N-hNz%mj2afjkO?7~L?=v0LV`w_Ji2=(PkXw@UN8|C zZ~+weUE=~SD9AxviHg7YKY3h^p5y29-m96HIo%vzPUTj8tG;#X-dp$fjBePvF-b;} zi;|0zzb3_ZS+W5n0h`Fj*|{Tg+q%8_wjH-@H)2yVng<$l2~lH=%5s{ubY$wtIpojC zUyzrPOW_&EglMD8k|cj4$yjn>GCQ|0J3l`=w|Akova-k(0dpKodyP((Hc?s8#vD_xXN!ydZevfo+3pm+iQMP9 zPNm(Wjnln;hj}OXXCCYA72tvT>9t($2J!c_JIiVFV7h|2I*;|V!jZGq@{Jd~!|ndk zDQPj!1bC+er9{o{TaLFH-R{1$)}!q3P2yW_^wMTCtCg-*pS3rZvu>ANbg_L_8@vng zQTyJ~omU^eiz+-E<(en+y?9l@JK9NG-DbbmXw}Y?+`@k`{@(e{^Z1+A`PbKcNs)hk zC9P$>BK2y`m*QJ<6q_0~U$*9plyt#3U21=>^?{gcSl=6BeuH{L-=N+QAJiM-!+JyC zu-?!&s5it1^@jMc-q1I!H}nnb4SmCUL*KC8(5HBR&Od%@pUi!))EjbNsWkWOw zdPCpf-k8Yei$1uol`V2zskOkNt@ce9-M(=SdMQFdMw83IR%*rFR`-j3vqQ(pcO}?L zzk6z-)^2rsX{$#<^PK?aU0HpH#L@!m9Z8p0nvG7*&%m;l&(fZDyHmHEobOxP?)P># zA8gdyIX0H~pp|zdk2z~hahVoT!N&6UIcptio5(qRtFu<|j1@8C`PXmW6 z_*y}5p z_d)E&3g$f!ySakd|6%9?*9FEBW8^pF;e$(0!i0G2(+nt}-Y_JUHr8ormv_?o#muGc zyCtUos#1^mYp|Wiy7XVi=$e(7YYN@D^-nX#o`m0fYmTsQK=(|;elxmf81`GxeFwtc zj_y8&{SI{JaK0U-UiIGwX8jTWE_Bxy_D*!qGVB?2?|;~P&|PoX`_Mg$un(Yn7Gck! zdq!c;qkBGKA4d0#w5{tH;(lGht{i8)hU&cku0g!|g?%kM_CXxRMV@V%DVJ{r)53BAoxF zLS3y_+xN*e>i<)zo5%HN`(Eh}+xMz!zg*h4(yi8M5BpieKSAtax%Qg<6?^3!IcbL>InXd4%tz36g$cY`yFE@vMiN830#?)82|&L%{Td;K0n&H+S@wsA4fd(q|i ze#blq(dEn`akQ5O& z#^0AkL|l7`@k2<49EW2cei$)E+%=sjG2`{O5HWqrrTs5zvu;+j13sOgg>{t_{s>8B7eb9knYGWvO@`W`{V+%NUW{b}^|xjzFY9x!=(cIIFpGU0GyXE>P8NYytKVPo@izW6X zqwD`Nqo3>7_a#Kk^{Yqjub`XTI~cjYiZ1?Qnfq(#Vh-Z+4pLH1X4Mfa3)T54Xp|7vw+hF3x)EU2nq=>k+dbhrdh-)t~eh;bMt?y$SBObja z<~pJdN9WkV_yffLb05uV|NjsXkC-2!8*>bam>;8yKS~}sPa*QegZC43c~2w3`zgA3 z@P3B=6e4cDXBovJ{^#goPn7fg0$uDGB;v&){+H;+pCjILdJYkL7V&(ZXY})Y^!*AE z^L*6*!(T7zV&>e)_-n-bKTjvV!1!W`iTjNp8<42sH|W+7@A_}i<@g2mJ9II*f&IS3 Z%oTU&59soZ*KcmuZ9V$_ONQH#{{djeSl|Ev 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 34ff06d546c0400ff3f6e702c2322b337c112fb1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10632 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 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 53ea5ee287daf2761f52216b85d629f0666e7ac2..da41461012ce83fd19c3f31ddd0ddd74e737260b 100644 GIT binary patch literal 6344 zcma);iFaL96^Cz|fe6x4MiE*Qih@#WRVGDfN@-IxC8aHb7R`Hoc}btV+!x*et)iwl z0M4^G&sq@yML`#eh!yY;aycwr%kR7Q?&LP>h2`zqJ$wK5{_V5RIs2TKfwh}YOOiFo z8OfQ+-;(^>kgNqsz=pGNV)DS`)=qb3>y=k+Gh$sbkOdmEo~S`aWxm=-bySdJ$Vub{ z^O1)MpyAv%OAzXRFz2=f2_0 z=emwmI|u7WyS+B^4)f1E*4xd&n`e$L=W;iQzopfluQvBq7ciIRv7R&>8EZM;P|n-m z>dhUI7V`{)w+m28)a<@xcv|mtc2{d%$`0QMzWI8$+H5vzg=@)Y?e+Oar^7C~*dD75 z-s$+LeOKYmst?~8B_57q%_G@fyfWttH^lq(hWKi|p>MU`(6?G|=v%Ef^sUw#`V{ZasmE{aBbo2zdPDBZ^@je{ zdPCo8y`isvZwzPiMIYRjHfFi5)SBbaminfHZr?Zuy%eD!1IamH3$^@itNTU2*`Y(^ zI}dE3*Eup>Yo(oTHSLm6{5J4-SJIg}FH1g8g|XG^?r0va&$J5cE=FRP-Yo06JIA^Q zs`CrYdOOSM``bu;!gjV=?HNl4A50b*i@Sq8l$^kB<(F(0HH$gP*hu%aBpKry-bnN3 z4K>4j)5%{==jv&5UDRmZ5uybl?3p=R*>h_ejjW49q(uc5Vq9D6m(RFz=0V z7nd;ai`Zxh^R9?pTEe_1VwaaN?}yly66U=S+g8H74`Smb%zGeqQwej;VtY!MJufy{ z!t8UgeI?A^7CTtN+#|6&N|?PYb|*5yxtibgRx*1a>*)dXJ@}l*FZM8O`F<1huXE@( zm--mu7xpFSo{zEix4P%1?q{xX#P|y1Cd5zM{w(LyHlOwBw^xn#T(wUYHbZ9HfBNki z{q~-AUe93mw}rO(&H)u4!_rniAI-fPMJ|AE4`@5zdHnDBk0O4X=swTh81a50SLqic z9vt;i^4mAYn%DgHM?Y?v_y6YK$l5%6b8bTSY_*-&UUL0n*A=#BE9ScGp;2TFaz$aE zjqYbI&(@mE<(;&CF>`7Ao{8x{ztAK8LTu-;F8v!BU9%E%jiNiZ{xQbblki^(W{$8g zL-$O>egnE^81@^{eFwtchVDLw{Z@46aK0-Gz3jgR%=#n#?dYyA?Ca4z%dp4Mz5ikF zM0dSm??(45!oC^Zvj}?<-7^Y%3f=Pwdp~-9MuXXVVC~xBe=oWlbT0oLLUmo!jP8-K zo|AS3iG6duRm9Ic+J`f1ar+in@@j}Niay0y_ht@RgIvhYG#TYgn6)o3`iWb+wr_=>{%)>j9PjbH*v?P7%zu>8xy9vc`?iS1{KwJV3-jGy z=;jFj!{~ltKZb68ZR4Iql4N{5?5D71XJ@xt&ok)8ME<{^J9nIgwr`u5^Z&Kbi2X0uKD9Sv?t|$5oe{S8(Z40i_F~EQew--m9c1-> zUx0Y$eIu@C4*S914DlVT+&lkj#2z+ApK;!aix7RclFK>$?H2PhzxDWrTeI97Sdq4I za-8cmh#dD%&KTn*h@4SGj<#{Z*^Dm7y$a52(dGEQ$k8?~IIlyOdle$bH&KqZalyG7U5@)6oNLkLT!YBbHcpPY--gKX&6MMrUWdr>EtR8f zT&(9E=yL4WSkDdUa(r*)Xd4%t?dWoh3C@nf9%q!JZCr3}M3-YP2InSpbL>RqXd4%t zUFdRr!-F${E@w9)N830#?)4r-&N@Vnd;LyCj_0;Ur@jXAVZ_|(k-Lq)a_t>3abvoSJ>+gg-1+Aj??J@1 z?`8ZTatyg0j`!q4h%w@>@2&zfUjKcFSgc+9U({yZ)@ZHHzmf4Hh&7plK29(?UG z-#qf~XZ#paL5?Hx?ct9j;t}%+^a@gr`6RY@#5{mrLCP@?VvFx%Rj%tH#N2ZA9Y(Bi zkx`$yyf2?ZT$4Q+HGR6kpC-mW`V1mw4$t&+jDDV}zRx0J?w5Mx{yh51++P3_kC-p^ ziTM(kc*K0UPs~@q#ACf*MK`xxedYD)^Gu>fM{|!cehslk@4o9FVf;EG{%EoOZxqo(pw ztm6lae%4{k_YpDcP>(u(h`zFpAAyM*c`6VJxJa~_zFCvd2!FvK- zJb1rCmn&|)Cm6*d{@3VY4;J(M23_n)B;v&){PWD^N-hNz%mj2afjkO?7~L?=v0LV`w_G~GRur#;As%<1O%aw@m#TlKA5_ujg`be<&`R6Qg+|(K*0c11 zrg4*%xU^kw^&8cIaU!a9j3?vCdCYOJmNmO+t%b^pHs+XmBVAnV_nLb;txmV_P2@h; zb*k1o+B}{0yUaVmKl4~`R)7Z@r`K}18^qt$=`Pn=2Wu;stMgb-I~+M{E#G*-JKX6n zost&wOn`SwP)gM7zU6qk+3W4A)icTt-z2`}W>#yp(t7Dy^;vs!Iqmh>MHky=wZS_d zAGPl--FfxlyP(3uQLcG1--}ljyrbP(yVvU1o9+6Ul3VyM#Gjq(Jcqw&oqv7J7Zv&E zS8DY%D^jo4d@;T?N3p3<^CfG(NJ$rr)1~(3S|5nHhV{K6<~OJ}^bP6_@j<;IKCCzN z4eJekgL*@JP;ZD2>kWOwdPCo^-q1I!H}nnb4SkCD=iKAB_Q~A$O1&ZXm3l+}u-?!& ztT*%x?v06jzUYH{+UX+Km0AlN+G^kQ(Cr)NpqC;PWHh-HY^7e@ZFRrsH#>Bke3yf* z^n0fk>Ya8ktF_}~SrPb`_{1hy0`z-D0bh-`8$@#vuoqo2v zb$_$b$+5A-2d%s#dCXa3ip#W!3O1I%&uRNm$3)KQTb;IxXRL@B&);t5thJY#?W~OR zEl=Bbq%0vv_rrC6{k9fE5}5Zz%smUtyCQa31sg4~*Hkd?hjE)LnD;_#s)BhZ#9m*) zybog6S1|8^*o_s;{ukR`!R&jnnF?mVi``klT(j8z3TAJM%~de_S?o{+vxmiwRxtNS z?A{7y&x(BjndQvP?|M(>_GsR_qv-qbIgelLVc7EhX6aMs&~GmFX~Zw=YtcO)W9?&g z&rRLWTr-IA_Gp!_E#G?d+pk*?&r#bx)%MeViLq+if7&CZ-@hBQi+aZLzag~Ee<`T= zG?upd6=?3w6mli`?E!7)znuR)|0%?83*G108zVkQ`C~&x8?}@I&{x8>^Gx(hGD-2-FG1D z?da}f*zZ7h4(HoZ>Q(SrKXA$-s zx@Q#jJi6x-_F;6-NZY!OA@0{@?8Uubq~d{ua7t=sD=uUM{hyuUFc} zXQdwJ*P_OPEd{1e0;mTRxsU$Ix-p%d$D zf6v2jPoFLA-DL4jUWs^5z1KU*X&?E{i|=OT-qY72_MI{MjI)ogM)ciHF6Y=>VhnJ{ z^E>UkYmIVmX9e2E$#JgNA?9)Ya;6!tMdVB&a3L5{X@!FeOP z9QQCd*Q3k14w0j6TyWlmF30^3&JE~td|Tvb8yB1#(dBqX!P$l`$M;8$wsFCEE4m!} zEI4mNm*X2HN830##=RYpRfZHZC|fqswvMgL5mooLdk%+Q!K-_d5|e z=OJ?JvD*+izJGGGjf?fX8(oh58SA+nUCvHKj<#{Z*@Z60nBeR#?HNWn+QtRv4s<#8 zVsP$6H^&}Cj<#{Z*^4g6cQ-h*=yLWUaXG|?baQ(TBX=EL+?WPq6R9EM z#`ycPh=^-1F@6Y1k>hae!w)0Ih`Xi}C1$+-HX^2PxwQX9ZPsm#*6RHB?+Rj#zDdFV zNQnnuyUI6@{EV@WIETMO^6ila5b=olDEj)C(_rEeb7nxy$H2r7u`1W~am3tm^*xAK zW0z5%x$MVJAg;+XkD5MN;x7{8nLdPwnZq-EgwfA4)%P$W=6Z`6-pJx&^I+}Z$@e7DGdbeEvB;ywm@#o6*f2qVC zV|4vrVf1tT`o4^axqkJ?{Z({xdj});*U-gZD06=uUF<%@8Y7S6-#JP5{~L(&Shw-c zVIALM^s^3QzKMughkDfUZS?hZd!IgjNeD9ck2h(#)wC6 ziMfub!_hf*F#Zs+|J+A&+W$X7#3Sa%=*ApFBIYOP;*XF=&f|zY@!fA4kNk_bj7W#6N{D_GmfJ&(X!6Mj~D;;(vi|{9lRpoSsF*o z#5^DM|M1s~x|lgPGX4tj{?F5i&ojPIV&Z-y$Oa^8_%*sU#Jm0*bUA*3{T5wJZeYJF ZF>}Qo`aQaQ= 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 054991ce4ed7f9aeb79be323d7a99b4b214aa014..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10800 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 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 68427531b749db0f606a462d536402d6a51a9564..3f18f856e0c908a4713cec4136dc9dfde1bef76b 100644 GIT binary patch delta 47 ycmeyu+QQ1q%%sfDz`)4B&A`hbvXNJqX>tuyfQTIfGXp0B1A{OS{{_lg05JfbxCO`n delta 157 zcmZo+{ld!2%%sfDz`)4B&A`hbwUJktDN>t(g@KKMfk6a_K>)@V1+vec@v(*R#lZYC zaK1Q5F++pB4g)(7GB8L0F~|&%K9E}R$+Aqr8m$bhU|C6^h%gX?RM{~wGjIZFkl0_K ITP%PW0MFVE4*&oF 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<>();