From 577836a03fd293071ee62a575bf66102e8b60c38 Mon Sep 17 00:00:00 2001 From: Halbear Date: Tue, 1 Sep 2026 03:33:26 +0100 Subject: [PATCH] SSAO, performance sucks and it flickers so tweaking is needed, also more material support --- .gitignore | 3 + .../SpriteShaders/sprite_fragment.glsl | 7 +- ...g_vertex.glsl => basic_screen_vertex.glsl} | 0 .../shaders/lighting_frag.glsl | 11 +- .../shaders/lighting_frag.glsl.spv | Bin 14796 -> 15800 bytes .../shaders/lighting_vertex.glsl.spv | Bin 1832 -> 0 bytes .../shaders/lighting_with_shadows_frag.glsl | 7 +- .../shaders/post_process_vtx.glsl | 9 - .../shaders/post_process_vtx.glsl.spv | Bin 1324 -> 0 bytes .../shaders/scene_fragment.glsl | 9 +- .../shaders/scene_fragment_deferred.glsl | 13 +- .../shaders/scene_fragment_deferred.glsl.spv | Bin 9924 -> 10228 bytes .../shaders/scene_opaque_fragment.glsl | 8 +- .../scene_opaque_fragment_deferred.glsl | 12 +- .../scene_opaque_fragment_deferred.glsl.spv | Bin 10328 -> 10632 bytes .../shaders/scene_translucent_fragment.glsl | 8 +- .../scene_translucent_fragment_deferred.glsl | 13 +- ...ene_translucent_fragment_deferred.glsl.spv | Bin 10496 -> 10800 bytes .../shaders/screen_space_fog.glsl | 104 +++++ .../EngineResources/shaders/shadow_frag.glsl | 7 +- .../shaders/ssao_blur_frag.glsl | 21 + .../EngineResources/shaders/ssao_frag.glsl | 95 ++++ .../EngineResources/shaders/swap_vtx.glsl | 8 - .../EngineResources/shaders/swap_vtx.glsl.spv | Bin 1324 -> 0 bytes .../EngineCore/Display/VulkanRenderer.java | 23 +- .../Logic/Rendering/ModelCompiler.java | 36 +- .../Universal/SSAO/SSAO_Utils.java | 52 +++ .../DeferredRendering/LightRenderer.java | 37 +- .../MultiRenderTargetAttachments.java | 4 +- .../Rendering/Pipeline/Images/Attachment.java | 8 + .../Rendering/Pipeline/Images/Texture.java | 1 + .../Pipeline/Images/TextureCache.java | 2 +- .../Rendering/PostProcessing/PostProcess.java | 2 +- .../ScreenSpace/AmbientOcclusionRenderer.java | 442 ++++++++++++++++++ .../Rendering/Shader/DescriptorSet.java | 11 + .../Rendering/VkModel/MaterialData.java | 2 +- .../SpriteRendering/SpriteRenderer.java | 4 +- .../Structure/SwapChain/SwapChainRender.java | 2 +- .../RenderingAPI/Vulkan/Util/VulkanUtils.java | 2 +- 39 files changed, 889 insertions(+), 74 deletions(-) rename resources/EngineResources/shaders/{lighting_vertex.glsl => basic_screen_vertex.glsl} (100%) delete mode 100644 resources/EngineResources/shaders/lighting_vertex.glsl.spv delete mode 100644 resources/EngineResources/shaders/post_process_vtx.glsl delete mode 100644 resources/EngineResources/shaders/post_process_vtx.glsl.spv create mode 100644 resources/EngineResources/shaders/screen_space_fog.glsl create mode 100644 resources/EngineResources/shaders/ssao_blur_frag.glsl create mode 100644 resources/EngineResources/shaders/ssao_frag.glsl delete mode 100644 resources/EngineResources/shaders/swap_vtx.glsl delete mode 100644 resources/EngineResources/shaders/swap_vtx.glsl.spv create mode 100644 src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Universal/SSAO/SSAO_Utils.java create mode 100644 src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Rendering/ScreenSpace/AmbientOcclusionRenderer.java diff --git a/.gitignore b/.gitignore index 966c12c..c725741 100644 --- a/.gitignore +++ b/.gitignore @@ -84,3 +84,6 @@ fabric.properties /.idea/ /.gradle/buildOutputCleanup/ /.gradle/ +/resources/models/bistrohd/ +/resources/models/Cafe/ +/resources/models/Forest/ diff --git a/resources/EngineResources/SpriteShaders/sprite_fragment.glsl b/resources/EngineResources/SpriteShaders/sprite_fragment.glsl index ea509ee..1cd34ea 100644 --- a/resources/EngineResources/SpriteShaders/sprite_fragment.glsl +++ b/resources/EngineResources/SpriteShaders/sprite_fragment.glsl @@ -1,6 +1,6 @@ #version 450 -const int MAX_TEXTURES = 128; +const int MAX_TEXTURES = 512; const float GAMMA_CONST = 0.4545; layout(location = 0) in vec2 inUV; @@ -16,9 +16,12 @@ vec4 gamma(vec4 color){ } void main() { + if (push_constants.textureIndex >= MAX_TEXTURES){ + outColor = vec4(0.0,0.0,1.0,1.0); + return; + } vec4 tex = texture(spriteTextures[push_constants.textureIndex], inUV); outColor = gamma(tex); - if (outColor.a <= 0.09) { discard; } diff --git a/resources/EngineResources/shaders/lighting_vertex.glsl b/resources/EngineResources/shaders/basic_screen_vertex.glsl similarity index 100% rename from resources/EngineResources/shaders/lighting_vertex.glsl rename to resources/EngineResources/shaders/basic_screen_vertex.glsl diff --git a/resources/EngineResources/shaders/lighting_frag.glsl b/resources/EngineResources/shaders/lighting_frag.glsl index 8108408..6fe8fc3 100644 --- a/resources/EngineResources/shaders/lighting_frag.glsl +++ b/resources/EngineResources/shaders/lighting_frag.glsl @@ -26,6 +26,7 @@ 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(scalar, set = 1, binding = 0) readonly buffer Lights { Light lights[]; @@ -134,6 +135,10 @@ void main() { 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; float roughness = pbr.g; float metallic = pbr.b; @@ -153,8 +158,10 @@ void main() { Lo += calculatePointLight(light, worldPos, V, N, F0, albedo, metallic, roughness); } } - vec3 ambient = sceneInfo.ambientLightColor * albedo * sceneInfo.ambientLightIntensity; - outFragColor = vec4(Lo + ambient + vec3(emissiveness), 1.0f); + 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); // outFragColor = vec4(color, 1.0f); if (length(normal) < 0.001) { diff --git a/resources/EngineResources/shaders/lighting_frag.glsl.spv b/resources/EngineResources/shaders/lighting_frag.glsl.spv index 067478a5ab94b93bef68c27dd6bf80a775b3c760..caffa84a5214bfa1b30a923ad69e73b96396e59e 100644 GIT binary patch delta 4663 zcmZ9OYj9m<6^3_`laMq`Z8$AyX_NLe;;ocYkz%Q>q_r2Ig;XgHKVuD$nI^%eozCEo z-A)I`AC4ol#~;oh2t~ju1}s9Uw-&jGf(_mfFKAU1FIb{N0Y!YCefFxG?3|Tvz3;kw zYp?He&J$yYKHkyP*n3)%G$idwM{?zj9hWvNz4xl8T31$*n;Md2Y;0gO;c4dY^95eB zeb*fE0Z42h=)r56q*YKvHYp&gC?iT*Wv&puutM0`*R?5+g?;*JL=UQn~ zas+)7$<@D$K9tX0Nsgg!H(h}z^eeF0C$fQQU2|pmBp)5xF}Q8#(CEm(_I&P%?8a$b zYqVO~w$bgQwxKzxBtMEgl3$o9& z_xCk5zS+_|1)nwr&j1e$e`IKIWG9(glBL;XdsoBOtZn*pYb*Jp)tG}NPBt))i?|5g zX9F){qe+l#Bv#$0w?5Rlth1xKIlQ#YM8exf$j#5WN}i#D-kjrlMzOP>ipxIMQ9a)! ztik$Nm)N?Z7TfGou4TenW^2)_T+2juyra70DJ(5m79zfz%V32Y$sbEHC&w&NR+~}X z?4rn6fqD(yC$JSk=XfcT_GskMz7?#$Gv@f<-Wlyp>sDgAju;#5vly(~ey~*FI|07N z9PD33-;LO+9-1|t9qp{9vJ2tvVbs$_FuT}x$!Y&uq1$A$ThN1W)1K~Kbv8);Fjy`m z_@i*^u!orMAvj{vyljc@LpWItnT7TwxQE29gvsTdRK1&yyAIlViZu|M=f{lZaV>li zv0aZB`B|YGyEsWJ$;~+b3cx2ZK^0G(>x*1T&H=c<_RfT2mq{)M}2%sK-2BK4t9X z6W9zh4z8QMyD?owdqzoiGvdY_R@wjo>1E0ntZ(3!DpiYr&%?t64g~cI5i7 zTf*(=pFli7<~8Pv=<@orL}^Y$z+D&&@PtLcm(b-6a1F)Ue3vhyUyn>DwfHOOeDX7) z%^25N-Z?yP2NBQUE%>c+s~UJ;VTimOW^j7%+VjCa87CuiD{5|-1)BF%I zPX0CWh#x_m&jQfXQ^7xltWVIAc%3|rc*VF*+MLAe<>!btH=#@OOu?b%#kseC0q1!% z)=r4^Go}XjOLX%%e;)J@;Ma&jURwrWc0Dk+MYvRQ7Bj4Jd3bD zk8W;X@K21{ee-5^yK5!>%=i~XXIuL>^aI)PdDT?(chDh3&lecQ;rSx^aA7;aDAwk- z{s+3-+Bh#aaoGNaep_Mlq7$#+_pI~1gnj`dWnP_^=1uCvPGBMfqJWpt-S2zpkHII= z)bF%7-ktah-Rd7@czrl(fm2 zAa0*W;oR}w$#22tW#Tc4B4@(M2ku0-b2p^L5}yvClLiy{6Jr))A}2P`w$3j2PZx1# zfQ^+8pDy&9h>5Fr4p=Vah9Y(@TxtRxY?VLZB`v_Oyfe{1MI!IoNInlv{xCjI!p}#S z^OxIQ6e-sYmiH_#VD#}U%l9C1b{#!EHQ7Q)C-V}B$!c)&G1($?IVZFIk;w5Sc8`1`I5OurZ$ykDJA+c0qyAZyP;d?H+ry}q&u*yv7TFNO2aHTVSgo`NISDenA&)3u+{c4J%)FkXM{{n#wj-@)1}M86Br1SnZMgedwj+$ttj%;xje(>PFT-5<5on_oExU+L6jV zdKaOWk5wO7E+mfC8aU&%N4wXeTd=n1><7@-ru_2>a-Ae%rNON)I9;RN8vrKIUwgUT z+G5=|qF+xkf9LrU7lX~c2GN!tD$enx0F9R*9*@n8K5j~Fn-DoSrFu+o8M-%F6ni;X p&L_D3f-Aq&mO8hbbpL;=4+2bJfDYxi()K#FTfpXnTNm!0`#(Ef6G;F7 delta 3670 zcmZ9OTWnNS6o&V7I;GPa&}k_MEu9uril8we1`H->1dL*e4<6(0_U z=%WcaFPcy&ikE^SP!)=zpdx~J!5er1MMUu~Dildj|8LLU^~lLA_WJ*I*=w(Tp*!wB z*i#uVY93`w%#@o-GktaC&9UmOcN{8>C(N2~aWXZdKW0p4dp^_Ak!>^j5+-goh`ZJ4 zPf5Ss>IpLtu1=}o4W4G$&SI$OsMFCKDAw3!W;}w zm!;;sE7leu7O&&N%QD@WP8W6JB7AZLhgIeC!+iOev1dl8LW<#VdHIrQrK&5_d1to0 zE3d>Qrdl|+JU_oXv-Ad6mE~K)85Ji-#|@ojDGS98g!3v3J0j9FODaYzW2;hA@nv~f zCRt0djb~>P7L#LrWonk+FFYG13$#S`DlMJQ<0k2T_5*fyTC3mxW*5bOnrpO-egjhZrc-fzp-YcPV4Q7<>qVAPV#h8}h(|V(CvN&G@_zhv^N=s^_?GtWL zUiQQL(E{{(^;CNjSYv|#O=pux^o~Xn!Lbl9P4^3V-{~Z#X=~;CiFEx8@s)DKx3J;G zW~>04O(V$%=D5cdZ4=-)SwyaS)f}I2n(!$_5wJ{wEn#13Q_wGs`e92o@@7Rb?^YD^ z#zZmijK}nkx5i`6+y0C2@d(y@4Tk&f11Ny|K7zx&HIo-7#r_y!!9PbZ)BF*^WZ{Vz z$s#-)#o?^lE2om>p9l+%sYTJK(!rtH-lAZh?l|VPa(_s|`JStO(dBj0;jdHk*JuQL z|Hq``&-wTMk4uNgpWcJ9G3^u5S4b+{*?m&Fet|ut7ztv7Ffa)h;8_WmVx1EBM4KJ& z@pHl}C94#}L|dfe1Mer>DqTN27k1`i^S8!=0$}I4O+M)h(&0RQQF^DtbY{DBR@mxR zvqL(ZmkOOXiWw58pP4BkCwcIt0P+t74sg`Cwiq~Ok4pa1y?90AIX9kFD|ZX;k?>)E z&Dj|#HZA^j>Exh`T=TsWy0~37@AIbPgDrC6?!P4=5W{&T0>3I@LJC0l!S6{gOi*ID z-iIVydA11~eq8qtB-j?at@+S#ag3{tXmQEu5Y!Damu!I=i z5n{mj5ySQzkxq<`yp7?2e=1DOPU*yekFfu~y3a%q#N$KjxN4sZ6GZC>0^^6BLcWmr zLVS0QI)0;k=D!#`JB{Jxlg0#`Y@EN>_=5yz+W3?7erMy60(;vp(s>hz z+^U^nji|QxFwuRaHiS@oi7sUVV z{OAxTtUp{|pSl`UB;Yb zfbJ(~md^J01xyi!<8$0?W~w8Z*gIb8IDGx8E)yUD{@A0d!gfKWQ$W+;yeYjC{ss9y Bywd;x diff --git a/resources/EngineResources/shaders/lighting_vertex.glsl.spv b/resources/EngineResources/shaders/lighting_vertex.glsl.spv deleted file mode 100644 index 60c1597608816200e59c62930d371d73e5b74af3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1832 zcmZ{l?Q0W35XMhy+8T|uzQ4O#t%+^Yq^JnKqY{Nm3yNPu$gTD8ybE`i&?pWofB#J4Szoq6Wjnc3MnI<<3Q#`AV~d%T+0@rpI??G)k(o0jHz-LV>1|pjAD16nAI_>tqSy?~Xv{}c!+6lofNz<0!w4~BJ6J_|X1B8Yah&)! zppWCg&#zH$n76g6(VFDwIOpp1&9L{}CYjxO9Qk(3+`MTz4YO!gm(3p@VGTtlkUSf4 z8kA)y&XxLP?ADgKY*t(C7p7@C+LnLI+}f76S@@Sqe>-QvCB?fM@3~8_+Fk2)*Vnsi z4|{{*u$N}rq3zM0o*yK3kOgB4Z+3zgM1yeTPZBC(OwLM0Ge-Q$ie-v3ozKwk*Dml= z@^fjM6up8!tv_(qL_>tm?Z!5dY|nZn16%XdEvh7W=?>qi6o%g3bS8-?L7 zUqutlY_qy~XNp;OHnYD+ayj=;<@w3+NVjq|;%7Om_}+@|!C{<%M-2``2iqk%sILh7 zoPM#}Fx-^{hxI9<|OY9`|9+>Dx7F_^?^@ z;=4LDt=)0aS-0fn%svTy{;E^h`%8>oe=D&AB~HKN@(u^3gS$9~q!Y)TIV>G)^2`z0 z;2Vm|TpX1U2mH1wXFkAOt@Mg@Pkj1#UINER$cukL0{%%H?29Evk3W{!r4pylE>>MS zv3P$Mt05iS#afaM#(R7yV=YSuC)S2C@(wKtIq>mTE)Q?TKQiWp8R3rD@ZBBh1M7!g H^19?FudD6Z diff --git a/resources/EngineResources/shaders/lighting_with_shadows_frag.glsl b/resources/EngineResources/shaders/lighting_with_shadows_frag.glsl index 81c739c..17d3d13 100644 --- a/resources/EngineResources/shaders/lighting_with_shadows_frag.glsl +++ b/resources/EngineResources/shaders/lighting_with_shadows_frag.glsl @@ -30,7 +30,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 sampler2DArray shadowSampler; +layout(set = 0, binding = 7) uniform sampler2D ssaoBlur; +layout(set = 0, binding = 8) uniform sampler2DArray shadowSampler; layout(scalar, set = 1, binding = 0) readonly buffer Lights { @@ -203,6 +204,7 @@ void main() { float emissiveness = emissive.r; float translucencyf = translucency.r; + float ssao = texture(ssaoBlur, inTextCoord).r; // outFragColor = vec4(emissive,1); // return; @@ -240,9 +242,10 @@ void main() { Lo += calculatePointLight(light, worldPos, V, N, F0, albedo, metallic, roughness); } } - vec3 ambient = sceneInfo.ambientLightColor * albedo * sceneInfo.ambientLightIntensity; + 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); if (DEBUG_SHADOWS == 1) { switch (cascadeIndex) { diff --git a/resources/EngineResources/shaders/post_process_vtx.glsl b/resources/EngineResources/shaders/post_process_vtx.glsl deleted file mode 100644 index bcc462a..0000000 --- a/resources/EngineResources/shaders/post_process_vtx.glsl +++ /dev/null @@ -1,9 +0,0 @@ -#version 450 - -layout(location = 0 ) out vec2 outTextCoord; - -void main() -{ - outTextCoord = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2); - gl_Position = vec4(outTextCoord.x * 2.0f - 1.0f, outTextCoord.y * -2.0f + 1.0f,0.0f,1.0f); -} \ No newline at end of file diff --git a/resources/EngineResources/shaders/post_process_vtx.glsl.spv b/resources/EngineResources/shaders/post_process_vtx.glsl.spv deleted file mode 100644 index 3f2126ad7f2979d3433d7b2e513383f021dd0d00..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1324 zcmZ9K+iMd+6voG-No#9w*0x@1-P(FJ^~6StH2;2>_lO1k}iGAur&Hc4G( zlb##cZs9&!bTbn=mvz%oZ&J{ZV)DF(`sB=fRJ^t0Vn5FZJwXFcAMexTogEZ*{3h$! zamimQ`HmfwDfCVK;91(!$%n3Rc_wz+^W4|-E-Mb*XLZV+GRGa2+fQBpr5hGUS=S!t zm=?KFnjYsGnhWz`#kvjsZ+cW>`ks^R%3^8hi!)y9R-s4otiY9T#%rE%>_JBlK}QV7 z3|CYY&6X7K#A}M0@{w#^Dt#axlZ%9TakTJ{D@^}ztHQJLk&Hgja~3f?dNB8c+pF{o z|KTNJ&g1-bdHSJW>Yta7WGwcBFUY93A$(CDJ=~@u<`rs?!{}>6o}S6m7r6XpPx=aP z63)3I4U7GeJo`C|JbqiI^*rEf9)5Wi@GXzckAQEN*wt$ zL@cwMmodj*V!?|Q$1HzW+;YV;&%EmKtYY|3XGJk}!k%-A;U@R23d46)mv>*2Q3w91 zy5s%fUML^QZ^_`87w0gWt1|fS(tvj=j+uR{xa$?q+(NAzimAnWhFUij!-rbCis6{= o*Q(Z@Vt8tG)HQRxBjXHm%s!mM?C;8Wf8Lxsfzkifm-R^Y50cendjJ3c diff --git a/resources/EngineResources/shaders/scene_fragment.glsl b/resources/EngineResources/shaders/scene_fragment.glsl index 87eb92c..5b3d90b 100644 --- a/resources/EngineResources/shaders/scene_fragment.glsl +++ b/resources/EngineResources/shaders/scene_fragment.glsl @@ -1,6 +1,6 @@ #version 450 -const int MAX_TEXTURES = 256; +const int MAX_TEXTURES = 512; layout(location = 0) in vec4 inPos; layout(location = 1) in vec3 inNormal; @@ -44,7 +44,12 @@ layout(push_constant) uniform pc{ void main() { - + Material material = matUniform.materials[inMaterialIdx]; + int textureIndex = int(material.textureIdx); + if (textureIndex >= MAX_TEXTURES){ + outAlbedo = vec4(0.0,0.0,1.0,1.0); + return; + } Material material = matUniform.materials[push_constants.materialIdx]; if(material.hasTexture == 1){ vec4 texColor = texture(textSampler[material.textureIdx],inTextCoords); diff --git a/resources/EngineResources/shaders/scene_fragment_deferred.glsl b/resources/EngineResources/shaders/scene_fragment_deferred.glsl index 2392663..32093e7 100644 --- a/resources/EngineResources/shaders/scene_fragment_deferred.glsl +++ b/resources/EngineResources/shaders/scene_fragment_deferred.glsl @@ -1,6 +1,7 @@ #version 450 -const int MAX_TEXTURES = 256; +const int MAX_TEXTURES = 512; + layout(location = 0) in vec4 inPos; layout(location = 1) in vec3 inNormal; @@ -62,6 +63,16 @@ void main() outPos = inPos; Material material = matUniform.materials[push_constants.materialIdx]; + int textureIndex = int(material.textureIdx); + if (textureIndex >= MAX_TEXTURES){ + outAlbedo = vec4(0.0,0.0,1.0,1.0); + outOpacity = vec4(0.0,0.0,1.0,1.0); + outNormal = vec4(0.0,0.0,1.0,1.0); + outEmissive = vec4(0.0,0.0,1.0,1.0); + outTranslucency = vec4(0.0,0.0,1.0,1.0); + outPBR = vec4(0.0,0.0,1.0,1.0); + return; + } if (material.hasTexture == 1) { outAlbedo = texture(textSampler[material.textureIdx], inTextCoords); } else { diff --git a/resources/EngineResources/shaders/scene_fragment_deferred.glsl.spv b/resources/EngineResources/shaders/scene_fragment_deferred.glsl.spv index 2e37b81814813a4579ef50a20dd7d390fa851c95..4240da6ac70470409b41275ba834cde763333c19 100644 GIT binary patch literal 10228 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 MAX_TEXTURES){ + outAlbedo = vec4(0.0,0.0,1.0,1.0); + return; + } if(material.hasTexture == 1){ vec4 texColor = texture(textSampler[material.textureIdx],inTextCoords); outAlbedo = texColor; diff --git a/resources/EngineResources/shaders/scene_opaque_fragment_deferred.glsl b/resources/EngineResources/shaders/scene_opaque_fragment_deferred.glsl index d91d780..01df0da 100644 --- a/resources/EngineResources/shaders/scene_opaque_fragment_deferred.glsl +++ b/resources/EngineResources/shaders/scene_opaque_fragment_deferred.glsl @@ -1,6 +1,6 @@ #version 450 -const int MAX_TEXTURES = 256; +const int MAX_TEXTURES = 512; layout(location = 0) in vec4 inPos; layout(location = 1) in vec3 inNormal; @@ -69,6 +69,16 @@ void main() outPos = inPos; Material material = matUniform.materials[push_constants.materialIdx]; + int textureIndex = int(material.textureIdx); + if (textureIndex >= MAX_TEXTURES){ + outAlbedo = vec4(0.0,0.0,1.0,1.0); + outOpacity = vec4(0.0,0.0,1.0,1.0); + outNormal = vec4(0.0,0.0,1.0,1.0); + outEmissive = vec4(0.0,0.0,1.0,1.0); + outTranslucency = vec4(0.0,0.0,1.0,1.0); + outPBR = vec4(0.0,0.0,1.0,1.0); + return; + } if (material.hasTexture == 1) { outAlbedo = texture(textSampler[material.textureIdx], inTextCoords); } else { diff --git a/resources/EngineResources/shaders/scene_opaque_fragment_deferred.glsl.spv b/resources/EngineResources/shaders/scene_opaque_fragment_deferred.glsl.spv index a4f90f28b012f975ca33528db9608d3fe4c1b1c3..34ff06d546c0400ff3f6e702c2322b337c112fb1 100644 GIT binary patch literal 10632 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 literal 10328 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 diff --git a/resources/EngineResources/shaders/scene_translucent_fragment.glsl b/resources/EngineResources/shaders/scene_translucent_fragment.glsl index 847195f..9af83fc 100644 --- a/resources/EngineResources/shaders/scene_translucent_fragment.glsl +++ b/resources/EngineResources/shaders/scene_translucent_fragment.glsl @@ -1,6 +1,6 @@ #version 450 -const int MAX_TEXTURES = 256; +const int MAX_TEXTURES = 512; layout(location = 0) in vec4 inPos; layout(location = 1) in vec3 inNormal; @@ -43,6 +43,11 @@ layout(push_constant) uniform pc{ void main() { Material material = matUniform.materials[push_constants.materialIdx]; + int textureIndex = int(material.textureIdx); + if (textureIndex >= MAX_TEXTURES){ + outAlbedo = vec4(0.0,0.0,1.0,1.0); + return; + } if(material.hasTexture == 1){ vec4 texColor = texture(textSampler[material.textureIdx],inTextCoords); outAlbedo = texColor; @@ -60,4 +65,5 @@ void main() if(opacityf >= 0.9){discard;} outAlbedo = vec4(outAlbedo.rgb, opacityf); + } \ No newline at end of file diff --git a/resources/EngineResources/shaders/scene_translucent_fragment_deferred.glsl b/resources/EngineResources/shaders/scene_translucent_fragment_deferred.glsl index 58d8529..ce01b25 100644 --- a/resources/EngineResources/shaders/scene_translucent_fragment_deferred.glsl +++ b/resources/EngineResources/shaders/scene_translucent_fragment_deferred.glsl @@ -1,6 +1,6 @@ #version 450 -const int MAX_TEXTURES = 256; +const int MAX_TEXTURES = 512; layout(location = 0) in vec4 inPos; layout(location = 1) in vec3 inNormal; @@ -69,8 +69,17 @@ layout(push_constant) uniform pc { void main() { outPos = inPos; - Material material = matUniform.materials[push_constants.materialIdx]; + int textureIndex = int(material.textureIdx); + if (textureIndex >= MAX_TEXTURES){ + outAlbedo = vec4(0.0,0.0,1.0,1.0); + outOpacity = vec4(0.0,0.0,1.0,1.0); + outNormal = vec4(0.0,0.0,1.0,1.0); + outEmissive = vec4(0.0,0.0,1.0,1.0); + outTranslucency = vec4(0.0,0.0,1.0,1.0); + outPBR = vec4(0.0,0.0,1.0,1.0); + return; + } if (material.hasTexture == 1) { outAlbedo = texture(textSampler[material.textureIdx], inTextCoords); } else { diff --git a/resources/EngineResources/shaders/scene_translucent_fragment_deferred.glsl.spv b/resources/EngineResources/shaders/scene_translucent_fragment_deferred.glsl.spv index 960f751111792b864973650e7bf939b86a086f2b..054991ce4ed7f9aeb79be323d7a99b4b214aa014 100644 GIT binary patch literal 10800 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 1.0 || + sampleUV.y < 0.0 || sampleUV.y > 1.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); + + occlusion += abs(fragPos.z)/200.0f; + validSamples += 1.0; + continue; + + 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.0; + } + + if (validSamples <= 0.0) { + outAO = 1.0; + return; + } + + occlusion = 1.0 - occlusion / validSamples; + outAO = clamp(occlusion, 0.0, 1.0); +} \ No newline at end of file diff --git a/resources/EngineResources/shaders/shadow_frag.glsl b/resources/EngineResources/shaders/shadow_frag.glsl index 0ba66bb..c65bc1a 100644 --- a/resources/EngineResources/shaders/shadow_frag.glsl +++ b/resources/EngineResources/shaders/shadow_frag.glsl @@ -1,7 +1,7 @@ #version 450 // Keep in sync manually with Java code -const int MAX_TEXTURES = 256; +const int MAX_TEXTURES = 512; layout (location = 0) in vec2 inTextCoords; layout (location = 1) in flat uint inMaterialIdx; @@ -36,6 +36,11 @@ layout(set = 2, binding = 0) readonly buffer MaterialUniform { void main() { Material material = matUniform.materials[inMaterialIdx]; + int textureIndex = int(material.textureIdx); + if (textureIndex >= MAX_TEXTURES){ + outFragColor = vec2(0.0,0.0); + return; + } vec4 albedo; if (material.hasTexture == 1) { albedo = texture(textSampler[material.textureIdx], inTextCoords); diff --git a/resources/EngineResources/shaders/ssao_blur_frag.glsl b/resources/EngineResources/shaders/ssao_blur_frag.glsl new file mode 100644 index 0000000..c16af41 --- /dev/null +++ b/resources/EngineResources/shaders/ssao_blur_frag.glsl @@ -0,0 +1,21 @@ +#version 450 + +layout(location = 0) in vec2 inTextCoord; +layout(location = 0) out float outAO; + +layout(set = 0, binding = 0) uniform sampler2D ssaoSampler; + +void main() { + + vec2 texelSize = 1.0 / vec2(textureSize(ssaoSampler, 0)); + float result = 0.0; + + 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; + } + } + + outAO = result / 25.0; +} \ No newline at end of file diff --git a/resources/EngineResources/shaders/ssao_frag.glsl b/resources/EngineResources/shaders/ssao_frag.glsl new file mode 100644 index 0000000..7c0e5f0 --- /dev/null +++ b/resources/EngineResources/shaders/ssao_frag.glsl @@ -0,0 +1,95 @@ +#version 450 + +layout(location = 0) in vec2 inTextCoord; +layout(location = 0) out float outAO; + +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[]; +} kernel; + +layout(set = 2, binding = 0) uniform SSAOInfo { + mat4 projection; //64 + mat4 view; //128 + vec2 screenSize; // 136 + float radius; //140 + float bias; //144 + int kernelSize; //160 +} ssao; + +void main() { + vec2 uv = inTextCoord; + + vec3 worldPos = texture(posSampler, uv).xyz; + vec3 worldNormal = normalize(texture(normalSampler, uv).xyz); + + vec2 noiseScale = ssao.screenSize / 4.0; + + if (length(worldNormal) < 0.001) { + outAO = 1.0; + return; + } + + vec3 fragPos = vec3(ssao.view * vec4(worldPos, 1.0)); + vec3 normal = normalize(mat3(ssao.view) * worldNormal); + + vec3 randomVec = normalize(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 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; + + vec4 offset = vec4(samplePos, 1.0); + offset = ssao.projection * offset; + 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) { + 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; + } + + if (validSamples <= 0.0) { + outAO = 1.0; + return; + } + + occlusion = 1.0 - occlusion / validSamples; + outAO = occlusion * pow(occlusion, 3.0); +} \ No newline at end of file diff --git a/resources/EngineResources/shaders/swap_vtx.glsl b/resources/EngineResources/shaders/swap_vtx.glsl deleted file mode 100644 index ebbaca0..0000000 --- a/resources/EngineResources/shaders/swap_vtx.glsl +++ /dev/null @@ -1,8 +0,0 @@ -#version 450 - -layout(location = 0) out vec2 outTextCoord; - -void main() { - outTextCoord = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2); - gl_Position = vec4(outTextCoord.x * 2.0f - 1.0f, outTextCoord.y * -2.0f + 1.0f,0.0f,1.0f); -} diff --git a/resources/EngineResources/shaders/swap_vtx.glsl.spv b/resources/EngineResources/shaders/swap_vtx.glsl.spv deleted file mode 100644 index 3f2126ad7f2979d3433d7b2e513383f021dd0d00..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1324 zcmZ9K+iMd+6voG-No#9w*0x@1-P(FJ^~6StH2;2>_lO1k}iGAur&Hc4G( zlb##cZs9&!bTbn=mvz%oZ&J{ZV)DF(`sB=fRJ^t0Vn5FZJwXFcAMexTogEZ*{3h$! zamimQ`HmfwDfCVK;91(!$%n3Rc_wz+^W4|-E-Mb*XLZV+GRGa2+fQBpr5hGUS=S!t zm=?KFnjYsGnhWz`#kvjsZ+cW>`ks^R%3^8hi!)y9R-s4otiY9T#%rE%>_JBlK}QV7 z3|CYY&6X7K#A}M0@{w#^Dt#axlZ%9TakTJ{D@^}ztHQJLk&Hgja~3f?dNB8c+pF{o z|KTNJ&g1-bdHSJW>Yta7WGwcBFUY93A$(CDJ=~@u<`rs?!{}>6o}S6m7r6XpPx=aP z63)3I4U7GeJo`C|JbqiI^*rEf9)5Wi@GXzckAQEN*wt$ zL@cwMmodj*V!?|Q$1HzW+;YV;&%EmKtYY|3XGJk}!k%-A;U@R23d46)mv>*2Q3w91 zy5s%fUML^QZ^_`87w0gWt1|fS(tvj=j+uR{xa$?q+(NAzimAnWhFUij!-rbCis6{= o*Q(Z@Vt8tG)HQRxBjXHm%s!mM?C;8Wf8Lxsfzkifm-R^Y50cendjJ3c 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 a1a9ebc..adac3c7 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Display/VulkanRenderer.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Display/VulkanRenderer.java @@ -12,6 +12,7 @@ import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.DeferredRe import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.Images.Attachment; import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.Images.TextureCache; import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.PostProcessing.PostProcess; +import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.ScreenSpace.AmbientOcclusionRenderer; 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; @@ -51,6 +52,7 @@ public class VulkanRenderer implements Renderer { private final Queue.PresentQueue PresentQueue; private final Semaphore[] RenderCompleteSemaphores; private final SceneRenderer sceneRender; + private final AmbientOcclusionRenderer ssaoRenderer; private final SpriteRenderer spriteRenderer; private final LightRenderer lightRenderer; private final PostProcess PostProcessor; @@ -110,13 +112,16 @@ public class VulkanRenderer implements Renderer { if(Deferred) { sceneRender = new DeferredSceneRender(RendererContext, engineInstance); shadowRender = new ShadowRenderer(RendererContext); + ssaoRenderer = new AmbientOcclusionRenderer(RendererContext,sceneRender.GetMRTAttachments().GetColourAttachments(), GraphicsQueue); List attachments = new ArrayList<>(sceneRender.GetMRTAttachments().GetColourAttachments()); + attachments.add(ssaoRenderer.getSSAOBlurAttachment()); attachments.add(shadowRender.getShadowAttachment()); lightRenderer = new LightRenderer(RendererContext, attachments); PostProcessor = new PostProcess(RendererContext, lightRenderer.getAttachment()); } else{ sceneRender = new ForwardSceneRender(RendererContext); + ssaoRenderer = null; PostProcessor = new PostProcess(RendererContext, sceneRender.GetAttachmentColour()); lightRenderer = null; shadowRender = null; @@ -189,6 +194,7 @@ public class VulkanRenderer implements Renderer { RendererContext.GetDevice().waitIdle(); Logger.debug("Waiting Vulkan Context"); sceneRender.cleanup(RendererContext); + if(ssaoRenderer != null)ssaoRenderer.cleanup(RendererContext); if(shadowRender != null)shadowRender.cleanup(RendererContext); if(lightRenderer != null)lightRenderer.cleanup(RendererContext); PostProcessor.CleanUp(RendererContext); @@ -231,16 +237,15 @@ public class VulkanRenderer implements Renderer { sceneRender.Render(engineInstance,RendererContext,CommandBuffer, modelsCache,materialsCache,CurrentFrame); boolean RenderShadows = ShadowRenderer.AllowShadowRendering() && EngineConfig.getInstance().RenderShadows(); - //lightRenderer.render(engineInstance, RendererContext, CommandBuffer, sceneRender.GetMRTAttachments(), shadowRender.getShadowAttachment(), CurrentFrame, shadowRender.getCascadeShadows(CurrentFrame)); + if(RenderShadows) {shadowRender.render(engineInstance, RendererContext, CommandBuffer, modelsCache, materialsCache, CurrentFrame); } + ssaoRenderer.Render(RendererContext,engineInstance, CommandBuffer, sceneRender.GetMRTAttachments(), CurrentFrame); if(RenderShadows) { - shadowRender.render(engineInstance, RendererContext, CommandBuffer, modelsCache, materialsCache, CurrentFrame); - lightRenderer.render(engineInstance, RendererContext, CommandBuffer, sceneRender.GetMRTAttachments(), shadowRender.getShadowAttachment(), CurrentFrame, shadowRender.getCascadeShadows(CurrentFrame)); - } else lightRenderer.render(engineInstance, RendererContext, CommandBuffer, sceneRender.GetMRTAttachments(),CurrentFrame); + 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()); spriteRenderer.Render(engineInstance,RendererContext,CommandBuffer,PostProcessor.GetAttachment(),modelsCache,CurrentFrame); GuiRender.Render(RendererContext,CommandBuffer,CurrentFrame,PostProcessor.GetAttachment()); - - swapChainRender.Render(RendererContext,CommandBuffer,PostProcessor.GetAttachment(),ImageIndex); RecordingStop(CommandBuffer); @@ -302,6 +307,7 @@ public class VulkanRenderer implements Renderer { shadowRender.RebuildPipelineAndRenderingAttachments(RendererContext); List attachments = new ArrayList<>(sceneRender.GetMRTAttachments().GetColourAttachments()); + attachments.add(ssaoRenderer.getSSAOBlurAttachment()); attachments.add(shadowRender.getShadowAttachment()); lightRenderer.updateAttachmentDescriptors(RendererContext, attachments); @@ -332,6 +338,11 @@ 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()); 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 4053f10..e542260 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 @@ -122,6 +122,7 @@ public class ModelCompiler { String NormalTexture = ProcessTexture(aiScene,aiMaterial,BaseDirectory,aiTextureType_NORMALS); String EmissiveTexture = ProcessTexture(aiScene,aiMaterial,BaseDirectory,aiTextureType_EMISSIVE); String TranslucencyTexture = ProcessTexture(aiScene,aiMaterial,BaseDirectory,aiTextureType_TRANSMISSION); + String SpecularTexture = ProcessTexture(aiScene,aiMaterial,BaseDirectory,aiTextureType_SPECULAR); String MetallicRoughTexture = ProcessTexture(aiScene, aiMaterial, BaseDirectory, AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLICROUGHNESS_TEXTURE); String OpacityTexture = ProcessTexture(aiScene,aiMaterial,BaseDirectory,aiTextureType_OPACITY); @@ -132,6 +133,18 @@ public class ModelCompiler { MetallicArray = new float[]{0.0f}; } + float[] SpecularArray = new float[]{0.0f}; + Result = aiGetMaterialFloatArray(aiMaterial,AI_MATKEY_SPECULAR_FACTOR,aiTextureType_NONE,0,SpecularArray,MaxPointer); + if(Result != aiReturn_SUCCESS){ + SpecularArray = new float[]{0.0f}; + } + + 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){ @@ -151,13 +164,32 @@ public class ModelCompiler { } float[] OpacityArray = new float[]{0.0f}; - Result = aiGetMaterialFloatArray(aiMaterial,AI_MATKEY_OPACITY,aiTextureType_NONE,0,OpacityArray,MaxPointer); if(Result != aiReturn_SUCCESS){ OpacityArray = new float[]{0.0f}; } - return new MaterialData(ModelName + "-mat-" + Position,DiffuseTexture,NormalTexture, MetallicRoughTexture,diffuse,RoughnessArray[0],MetallicArray[0], EmissiveTexture,emissiveColour, TranslucencyTexture, TranslucencyArray[0], OpacityTexture, OpacityArray[0]); + float[] RefractionArray = new float[]{0.0f}; + Result = aiGetMaterialFloatArray(aiMaterial,AI_MATKEY_REFRACTI,aiTextureType_NONE,0,RefractionArray,MaxPointer); + if(Result != aiReturn_SUCCESS){ + RefractionArray = new float[]{0.0f}; + } + + float[] ReflectionArray = new float[]{0.0f}; + Result = aiGetMaterialFloatArray(aiMaterial,AI_MATKEY_REFLECTIVITY,aiTextureType_NONE,0,ReflectionArray,MaxPointer); + if(Result != aiReturn_SUCCESS){ + 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]); } public static MeshData ProcessMesh(AIMesh aiMesh, List MaterialList, int MeshPosition, ModelBinaryData BinaryData) throws IOException { 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 new file mode 100644 index 0000000..1621056 --- /dev/null +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Universal/SSAO/SSAO_Utils.java @@ -0,0 +1,52 @@ +package net.halbear.Terrain4J.EngineCore.RenderingAPI.Universal.SSAO; + +import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Util.VulkanUtils; +import org.joml.Vector4f; +import org.lwjgl.BufferUtils; +import org.lwjgl.system.MemoryUtil; + +import java.nio.ByteBuffer; +import java.nio.FloatBuffer; +import java.util.Random; + +public class SSAO_Utils { + + public static FloatBuffer GenerateSampleKernel(int size, long MappedMemory) { + FloatBuffer kernel = MemoryUtil.memFloatBuffer(MappedMemory,size * 4); // vec4 alignment + Random rnd = new Random(); + + for (int i = 0; i < size; i++) { + + Vector4f sample = new Vector4f(rnd.nextFloat() * 2.0f - 1.0f,rnd.nextFloat() * 2.0f - 1.0f,rnd.nextFloat(),0); + sample = sample.normalize(); + + float scale = (float) i / (float) size; + scale = Lerp(0.1f, 1.0f, scale * scale); + sample.mul(scale); + kernel.put(sample.x); + kernel.put(sample.y); + kernel.put(sample.z); + kernel.put(0.0f); + } + return kernel; + } + + public static ByteBuffer GenerateNoiseTexture() { + ByteBuffer buffer = BufferUtils.createByteBuffer(16 * 4 * Float.BYTES); + Random rnd = new Random(); + for (int i = 0; i < 16; i++) { + float x = rnd.nextFloat() * 2.0f - 1.0f; + float y = rnd.nextFloat() * 2.0f - 1.0f; + buffer.putFloat(x); + buffer.putFloat(y); + buffer.putFloat(0.0f); + buffer.putFloat(0.0f); + } + buffer.flip(); + return buffer; + } + + private static float Lerp(float a, float b, float f) { + return a + f * (b - a); + } +} 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 0423e96..76c6e93 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 @@ -50,7 +50,7 @@ public class LightRenderer { private static final String FRAGMENT_SHADER_FILE_SPV = FRAGMENT_SHADER_FILE_GLSL + ".spv"; private static final String NO_SHADOWS_FRAGMENT_SHADER_FILE_GLSL = "resources/EngineResources/shaders/lighting_frag.glsl"; private static final String NO_SHADOWS_FRAGMENT_SHADER_FILE_SPV = NO_SHADOWS_FRAGMENT_SHADER_FILE_GLSL + ".spv"; - private static final String VERTEX_SHADER_FILE_GLSL = "resources/EngineResources/shaders/lighting_vertex.glsl"; + private static final String VERTEX_SHADER_FILE_GLSL = "resources/EngineResources/shaders/basic_screen_vertex.glsl"; private static final String VERTEX_SHADER_FILE_SPV = VERTEX_SHADER_FILE_GLSL + ".spv"; private final DescriptorSetLayout AttachmentDescriptorSetLayout; @@ -69,6 +69,8 @@ public class LightRenderer { private final DescriptorSetLayout StorageDescriptorSetLayout; private final VulkanBuffer[] shadowMatrices; + private int MinimumAttachments = 9; // shadow + ssaoBlur + public LightRenderer(VulkanContext VkCtx, List attachments){ ClearValueColour = VkClearValue.calloc().color( c -> c.float32(0, 0.0f).float32(1, 0.0f).float32(2, 0.0f).float32(3, 0.0f)); @@ -84,8 +86,9 @@ public class LightRenderer { VK_BORDER_COLOR_INT_OPAQUE_BLACK, 1, true); textureSampler = new TextureSampler(VkCtx, textureSamplerInfo); int numAttachments = attachments.size(); - DescriptorSetLayout.LayoutInformation[] descSetLayouts = new DescriptorSetLayout.LayoutInformation[numAttachments + 1]; - for (int i = 0; i < numAttachments + 1; i++) { + if(numAttachments < MinimumAttachments) numAttachments = MinimumAttachments; + 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); } AttachmentDescriptorSetLayout = new DescriptorSetLayout(VkCtx, descSetLayouts); @@ -209,7 +212,7 @@ public class LightRenderer { } - public void render(EngineInstance engineInstance, VulkanContext VkCtx, CommandBuffer cmdBuffer, MultiRenderTargetAttachments mrtAttachments,Attachment shadowAttachment, int CurrentFrame, CascadeShadows cascadeShadows) { + public void render(EngineInstance engineInstance, VulkanContext VkCtx, CommandBuffer cmdBuffer, MultiRenderTargetAttachments mrtAttachments,Attachment shadowAttachment, Attachment ssaoBlurAttachment, int CurrentFrame, CascadeShadows cascadeShadows) { try (var stack = MemoryStack.stackPush()) { VkCommandBuffer cmdHandle = cmdBuffer.GetVulkanCommandBuffer(); @@ -219,16 +222,6 @@ public class LightRenderer { VK_ACCESS_2_NONE, VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT, VK_IMAGE_ASPECT_COLOR_BIT); - List attachments = mrtAttachments.GetColourAttachments(); - int numAttachments = attachments.size(); - for (int i = 0; i < numAttachments; i++) { - Attachment attachment = attachments.get(i); - VulkanUtils.ImageBarrier(stack, cmdHandle, attachment.GetVkImage().getVulkanImage(), - VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, - VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT, - VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_2_SHADER_READ_BIT, - VK_IMAGE_ASPECT_COLOR_BIT); - } VulkanUtils.ImageBarrier(stack, cmdHandle, mrtAttachments.GetDepthAttachment().GetVkImage().getVulkanImage(), VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT, @@ -285,7 +278,7 @@ public class LightRenderer { } } - public void render(EngineInstance engineInstance, VulkanContext VkCtx, CommandBuffer cmdBuffer, MultiRenderTargetAttachments mrtAttachments, int CurrentFrame) { + public void render(EngineInstance engineInstance, VulkanContext VkCtx, CommandBuffer cmdBuffer, MultiRenderTargetAttachments mrtAttachments, Attachment SSAOattachment, int CurrentFrame) { try (var stack = MemoryStack.stackPush()) { VkCommandBuffer cmdHandle = cmdBuffer.GetVulkanCommandBuffer(); @@ -295,16 +288,6 @@ public class LightRenderer { VK_ACCESS_2_NONE, VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT, VK_IMAGE_ASPECT_COLOR_BIT); - List attachments = mrtAttachments.GetColourAttachments(); - int numAttachments = attachments.size(); - for (int i = 0; i < numAttachments; i++) { - Attachment attachment = attachments.get(i); - VulkanUtils.ImageBarrier(stack, cmdHandle, attachment.GetVkImage().getVulkanImage(), - VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, - VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT, - VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_2_SHADER_READ_BIT, - VK_IMAGE_ASPECT_COLOR_BIT); - } VulkanUtils.ImageBarrier(stack, cmdHandle, mrtAttachments.GetDepthAttachment().GetVkImage().getVulkanImage(), VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT, @@ -422,7 +405,7 @@ public class LightRenderer { DescriptorSet noShadowDescSet = VkCtx.GetDescriptorAllocator().GetDescriptorSet(DESC_ID_NOSHADOW_ATT); var noShadowImageViews = new ArrayList(); - for (int i = 0; i < attachments.size() - 1; i++) { + for (int i = 0; i < attachments.size(); i++) { noShadowImageViews.add(attachments.get(i).GetVkImageView()); } noShadowDescSet.SetImages(VkCtx.GetDevice(), noShadowImageViews, textureSampler, 0); @@ -444,7 +427,7 @@ public class LightRenderer { DescriptorSet noShadowDescSet = VkCtx.GetDescriptorAllocator().GetDescriptorSet(DESC_ID_NOSHADOW_ATT); var noShadowImageViews = new ArrayList(); - for (int i = 0; i < attachments.size() - 1; i++) { + for (int i = 0; i < attachments.size(); i++) { noShadowImageViews.add(attachments.get(i).GetVkImageView()); } noShadowDescSet.SetImages(VkCtx.GetDevice(), noShadowImageViews, textureSampler, 0); 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 f542079..107ecb5 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 @@ -18,7 +18,9 @@ public class MultiRenderTargetAttachments { public static final int EMISSIVE_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT; public static final int TRANSLUCECNY_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT; public static final int OPACITY_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT; - public static final int POSITION_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT; + public static final int POSITION_FORMAT = VK_FORMAT_R32G32B32A32_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; private final Attachment DepthAttachment; private final int Height; diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Rendering/Pipeline/Images/Attachment.java b/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Rendering/Pipeline/Images/Attachment.java index a90d0b7..72c7f68 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Rendering/Pipeline/Images/Attachment.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Rendering/Pipeline/Images/Attachment.java @@ -3,12 +3,20 @@ package net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline. import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig; import net.halbear.Terrain4J.EngineCore.Logic.Rendering.VulkanContext; import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DisplayToScreen.ImageView; +import org.w3c.dom.Text; import static org.lwjgl.vulkan.VK13.*; public class Attachment { private final Image VkImage; private final ImageView VkImageView; private boolean DepthAttachment; + + public Attachment(VulkanContext VkCtx, Texture ExistingImage){ + VkImageView = ExistingImage.GetImageView(); + VkImage = ExistingImage.GetImage(); + DepthAttachment = VkImageView.IsDepthImage(); + } + public Attachment(VulkanContext VkCtx, int Width, int Height, int Format, int Usage, boolean MultiSamples){ var ImageData = new Image.ImageData().Width(Width).Height(Height).Format(Format).SampleCount(EngineConfig.getInstance().GetRenderSampleCount()); diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Rendering/Pipeline/Images/Texture.java b/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Rendering/Pipeline/Images/Texture.java index fbc604d..a5e3657 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Rendering/Pipeline/Images/Texture.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Rendering/Pipeline/Images/Texture.java @@ -44,6 +44,7 @@ public class Texture implements ITexture { .AspectMask(VK_IMAGE_ASPECT_COLOR_BIT).MipLevels(MipMapLevels); imageView = new ImageView(VkCtx.GetDevice(), image.getVulkanImage(), ImageViewData, false); } + public Image GetImage(){return image;} public boolean HasTransparency(){return Transparent;} public void SetTransparency(ByteBuffer data){ int PixelCount = data.capacity()/4; diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Rendering/Pipeline/Images/TextureCache.java b/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Rendering/Pipeline/Images/TextureCache.java index 552777f..149e3d9 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Rendering/Pipeline/Images/TextureCache.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Rendering/Pipeline/Images/TextureCache.java @@ -18,7 +18,7 @@ import java.util.UUID; import static org.lwjgl.vulkan.VK10.VK_FORMAT_R8G8B8A8_SRGB; public class TextureCache implements ITextureCache { - public static final int MAX_TEXTURES = 256; + public static final int MAX_TEXTURES = 512; private final IndexedLinkedHashMap TextureMap; private final IndexedLinkedHashMap CubemapTextures; private final List ActualTextures; 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 7084d99..3cc77d3 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 @@ -35,7 +35,7 @@ public class PostProcess { private static final String MULTI_PASS_FRAGMENT_SHADER_FILE_SPV = MULTI_PASS_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/post_process_vtx.glsl"; + 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; 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 new file mode 100644 index 0000000..552ac70 --- /dev/null +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Rendering/ScreenSpace/AmbientOcclusionRenderer.java @@ -0,0 +1,442 @@ +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.Main.Scene.IScene; +import net.halbear.Terrain4J.EngineCore.RenderingAPI.Universal.SSAO.SSAO_Utils; +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.ImageSrc; +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.CommandPool; +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.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.FloatBuffer; +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.SSAO_BLUR_ATTACHMENT; +import static net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.DeferredRendering.MultiRenderTargetAttachments.SSAO_RAW_ATTACHMENT; +import static org.lwjgl.vulkan.VK10.*; +import static org.lwjgl.vulkan.VK10.VK_SHADER_STAGE_FRAGMENT_BIT; +import static org.lwjgl.vulkan.VK13.*; + +public class AmbientOcclusionRenderer { + + private static final long SSAO_INFO_BUFFER_SIZE = + VulkanUtils.MATRIX4X4_SIZE + // projection + 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 long SSAO_KERNEL_BUFFER_SIZE = SSAO_KERNEL_SIZE * 4L * VulkanUtils.FLOAT_SIZE; + + private static final String DESC_ID_SSAO_ATTACHMENTS = "SSAO_DESC_ID_ATTACHMENTS"; + private static final String DESC_ID_SSAO_KERNEL = "SSAO_DESC_ID_KERNEL"; + private static final String DESC_ID_SSAO_INFO = "SSAO_DESC_ID_INFO"; + private static final String DESC_ID_SSAO_BLUR_INPUT = "SSAO_DESC_ID_BLUR_INPUT"; + + private static final String BLUR_FRAGMENT_SHADER_FILE_GLSL = "resources/EngineResources/shaders/ssao_blur_frag.glsl"; + private static final String BLUR_FRAGMENT_SHADER_FILE_SPV = BLUR_FRAGMENT_SHADER_FILE_GLSL + ".spv"; + private static final String FRAGMENT_SHADER_FILE_GLSL = "resources/EngineResources/shaders/ssao_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 ssaoAttachment; + private VkRenderingAttachmentInfo.Buffer ssaoAttachmentInfo; + private Attachment ssaoBlurAttachment; + private VkRenderingAttachmentInfo.Buffer ssaoBlurAttachmentInfo; + private final Attachment[] SSAO_ATTACHMENTS = new Attachment[2]; + + private final Pipeline ssaoPipeline; + private final Pipeline blurPipeline; + private final TextureSampler textureSampler; + + private DescriptorSetLayout ssaoAttachmentDescriptorLayout; + private DescriptorSetLayout ssaoKernelDescriptorLayout; + private DescriptorSetLayout ssaoInfoDescriptorLayout; + private DescriptorSetLayout blurDescriptorLayout; + + private final VkClearValue clearColour; + private VulkanBuffer sampleKernelBuffer; + private VkRenderingInfo ssaoRenderInfo; + private VkRenderingInfo ssaoBlurRenderInfo; + + private VulkanBuffer[] ssaoInfoBuffers; + + private Texture NoiseTexture; + private Attachment NoiseImageAttachment; + + public AmbientOcclusionRenderer(VulkanContext VkCtx, List MRTAttachments, Queue queue) { + List attachments = new ArrayList<>(); + attachments.add(MRTAttachments.get(0)); // 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, + VK_BORDER_COLOR_INT_OPAQUE_BLACK, 1, true); + textureSampler = new TextureSampler(VkCtx, textureSamplerInfo); + + ByteBuffer NoiseTexturedata = SSAO_Utils.GenerateNoiseTexture(); + ImageSrc imageSrc = new ImageSrc(NoiseTexturedata, 4, 4,4); + NoiseTexture = new Texture(VkCtx,"SSAO_NOISE_SAMPLE", imageSrc,VK_FORMAT_R32G32B32A32_SFLOAT); + + var commandPool = new CommandPool(VkCtx, queue.GetQueueFamilyIndex(), false); + var commandBuffer = new CommandBuffer(VkCtx, commandPool, true, true); + commandBuffer.BeginRecording(); + NoiseTexture.RecordTextureTransition(commandBuffer); + commandBuffer.EndRecording(); + commandBuffer.SubmitAndWait(VkCtx, queue); + commandBuffer.cleanup(VkCtx,commandPool); + commandPool.cleanup(VkCtx); + + NoiseImageAttachment = new Attachment(VkCtx, NoiseTexture); + + attachments.add(NoiseImageAttachment); + + ssaoKernelDescriptorLayout = new DescriptorSetLayout(VkCtx, new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, + 0, 1, VK_SHADER_STAGE_FRAGMENT_BIT)); + sampleKernelBuffer = VulkanUtils.CreateHostVisibleBuffer(VkCtx, SSAO_KERNEL_BUFFER_SIZE, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, + DESC_ID_SSAO_KERNEL, ssaoKernelDescriptorLayout); + long MappedMemory = sampleKernelBuffer.MapMemory(VkCtx); + FloatBuffer KernelBuffer = SSAO_Utils.GenerateSampleKernel(SSAO_KERNEL_SIZE, MappedMemory); + sampleKernelBuffer.UnMapMemory(VkCtx); + + 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); + } + ssaoAttachmentDescriptorLayout = new DescriptorSetLayout(VkCtx, descSetLayouts); + CreateSSAOAttachmentDescriptorSet(VkCtx, attachments); + + 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 )); + + 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); + + ShaderModule[] shaderModules = CreateRawShaderModules(VkCtx); + ssaoPipeline = CreatePipeline(VkCtx, shaderModules, + new DescriptorSetLayout[]{ + ssaoAttachmentDescriptorLayout, + ssaoKernelDescriptorLayout, + ssaoInfoDescriptorLayout + },false); + Arrays.stream(shaderModules).toList().forEach(shaderModule -> shaderModule.CleanUp(VkCtx)); + + shaderModules = CreateBlurShaderModules(VkCtx); + blurPipeline = CreatePipeline( VkCtx, shaderModules, + 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}) + .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 ShaderModule[] CreateBlurShaderModules(VulkanContext VkCtx) { + if (EngineConfig.getInstance().RecompileShaders()) { + ShaderCompiler.CompileGLSLShaderOnChange(VERTEX_SHADER_FILE_GLSL, Shaderc.shaderc_glsl_vertex_shader); + ShaderCompiler.CompileGLSLShaderOnChange( BLUR_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, BLUR_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) { + 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()))) + .layerCount(1) + .pColorAttachments(attachmentInfo); + } + + private void CreateSSAOAttachmentDescriptorSet(VulkanContext vkCtx, List Attachments ) { + DescriptorSet descSet = vkCtx.GetDescriptorAllocator().AddDescriptorSet( + vkCtx.GetDevice(), DESC_ID_SSAO_ATTACHMENTS,ssaoAttachmentDescriptorLayout ); + + List imageViews = new ArrayList<>(); + Attachments.forEach(a -> imageViews.add(a.GetVkImageView())); + + descSet.SetImages(vkCtx.GetDevice(), imageViews, textureSampler, 0); + } + + + private void CreateBlurDescriptorSet(VulkanContext vkCtx) { + DescriptorSet descSet = vkCtx.GetDescriptorAllocator().AddDescriptorSet( + vkCtx.GetDevice(),DESC_ID_SSAO_BLUR_INPUT, blurDescriptorLayout); + + descSet.SetImage(vkCtx.GetDevice(), ssaoAttachment.GetVkImageView(), + textureSampler,0); + } + + private void CreateAttachments(VulkanContext VkCtx){ + SwapChain swapChain = VkCtx.GetSwapChain(); + VkExtent2D swapChainExtent = swapChain.GetSwapChainExtent(); + //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); + 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); + SSAO_ATTACHMENTS[1] = ssaoBlurAttachment; + } + + public void Render(VulkanContext VkCtx,EngineInstance engineInstance, CommandBuffer cmdBuffer, MultiRenderTargetAttachments MRT,int CurrentFrame) { + try (var stack = MemoryStack.stackPush()) { + + + VkCommandBuffer cmdHandle = cmdBuffer.GetVulkanCommandBuffer(); + + UpdateSSAOInfo(VkCtx, engineInstance, CurrentFrame); + + VulkanUtils.ImageBarrier(stack, cmdHandle, ssaoAttachment.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); + + + vkCmdBeginRendering(cmdHandle, ssaoRenderInfo); + + vkCmdBindPipeline(cmdHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, ssaoPipeline.GetVulkanPipeline()); + + SetViewportAndScissor(stack, cmdHandle, ssaoAttachment); + + DescriptorAllocator descAllocator = VkCtx.GetDescriptorAllocator(); + LongBuffer descriptorSets = stack.mallocLong(3) + .put(0, descAllocator.GetDescriptorSet(DESC_ID_SSAO_ATTACHMENTS).GetVkDescriptorSet()) + .put(1, descAllocator.GetDescriptorSet(DESC_ID_SSAO_KERNEL).GetVkDescriptorSet()) + .put(2, descAllocator.GetDescriptorSet(DESC_ID_SSAO_INFO, CurrentFrame).GetVkDescriptorSet()); + + vkCmdBindDescriptorSets(cmdHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, + ssaoPipeline.GetVulkanPipelineLayout(), 0, descriptorSets, null); + + vkCmdDraw(cmdHandle, 3, 1, 0, 0); + + vkCmdEndRendering(cmdHandle); + + //blur pass + VulkanUtils.ImageBarrier(stack, cmdHandle, ssaoAttachment.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, ssaoBlurAttachment.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); + + vkCmdBeginRendering(cmdHandle, ssaoBlurRenderInfo); + + vkCmdBindPipeline(cmdHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, blurPipeline.GetVulkanPipeline()); + + SetViewportAndScissor(stack, cmdHandle, ssaoBlurAttachment); + + LongBuffer blurDescriptorSets = stack.mallocLong(1) + .put(0, descAllocator.GetDescriptorSet(DESC_ID_SSAO_BLUR_INPUT).GetVkDescriptorSet()); + + vkCmdBindDescriptorSets(cmdHandle,VK_PIPELINE_BIND_POINT_GRAPHICS, + blurPipeline.GetVulkanPipelineLayout(),0, blurDescriptorSets,null ); + + vkCmdDraw(cmdHandle, 3, 1, 0, 0); + + vkCmdEndRendering(cmdHandle); + + VulkanUtils.ImageBarrier( stack, cmdHandle, ssaoBlurAttachment.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); + } + } + + private static void TransitionMRTtoReadOnly(MemoryStack stack,VkCommandBuffer cmdHandle, MultiRenderTargetAttachments MRT) { + List attachments = MRT.GetColourAttachments(); + + for (Attachment attachment : attachments) { + VulkanUtils.ImageBarrier( stack,cmdHandle, attachment.GetVkImage().getVulkanImage(), + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, + VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT, + VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT, + VK_ACCESS_2_SHADER_READ_BIT, + VK_IMAGE_ASPECT_COLOR_BIT + ); + } + } + + 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); + } + + private void UpdateSSAOInfo(VulkanContext vkCtx, EngineInstance engineInstance, int currentFrame) { + VulkanBuffer buffer = ssaoInfoBuffers[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().GetCamera().GetViewMatrix().get(offset, data); + offset += VulkanUtils.MATRIX4X4_SIZE; + + 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); + + buffer.UnMapMemory(vkCtx); + } + + public Attachment getSSAOBlurAttachment() { + return ssaoBlurAttachment; + } + + public void resize(VulkanContext VkCtx, List attachments) { + ssaoRenderInfo.free(); + ssaoBlurRenderInfo.free(); + ssaoAttachmentInfo.free(); + ssaoAttachment.CleanUp(VkCtx); + ssaoBlurAttachmentInfo.free(); + ssaoBlurAttachment.CleanUp(VkCtx); + + CreateAttachments(VkCtx); + + ssaoAttachmentInfo = CreateColourAttachmentInfo(ssaoAttachment, clearColour); + ssaoBlurAttachmentInfo = CreateColourAttachmentInfo(ssaoBlurAttachment, clearColour); + ssaoRenderInfo = CreateRenderInfo(ssaoAttachment, ssaoAttachmentInfo); + ssaoBlurRenderInfo = CreateRenderInfo(ssaoBlurAttachment, ssaoBlurAttachmentInfo); + + attachments.add(NoiseImageAttachment); + + CreateSSAOAttachmentDescriptorSet(VkCtx,attachments); + CreateBlurDescriptorSet(VkCtx); + } + + public void cleanup(VulkanContext VkCtx) { + ssaoRenderInfo.free(); + ssaoBlurRenderInfo.free(); + ssaoAttachmentInfo.free(); + ssaoAttachment.CleanUp(VkCtx); + ssaoBlurAttachmentInfo.free(); + ssaoBlurAttachment.CleanUp(VkCtx); + ssaoPipeline.CleanUp(VkCtx); + blurPipeline.CleanUp(VkCtx); + clearColour.free(); + Arrays.stream(ssaoInfoBuffers).toList().forEach(b -> b.cleanup(VkCtx)); + sampleKernelBuffer.cleanup(VkCtx); + ssaoAttachmentDescriptorLayout.CleanUp(VkCtx); + blurDescriptorLayout.CleanUp(VkCtx); + ssaoInfoDescriptorLayout.CleanUp(VkCtx); + ssaoKernelDescriptorLayout.CleanUp(VkCtx); + NoiseTexture.CleanUp(VkCtx); + textureSampler.CleanUp(VkCtx); + } +} diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Rendering/Shader/DescriptorSet.java b/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Rendering/Shader/DescriptorSet.java index fb5d281..41e990f 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Rendering/Shader/DescriptorSet.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Rendering/Shader/DescriptorSet.java @@ -1,5 +1,6 @@ package net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Shader; +import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.Images.TextureCache; import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DeviceLayers.Device; import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DisplayToScreen.ImageView; import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Util.VulkanBuffer; @@ -100,9 +101,19 @@ public class DescriptorSet { public void SetImageArray(Device device, List imageViews, TextureSampler textureSampler, int BaseBinding){ try(var MemStack = MemoryStack.stackPush()){ int ImageCount = imageViews.size(); + if (textureSampler == null || textureSampler.GetVkSampler() == 0) { + throw new NullPointerException("The provided TextureSampler is uninitialized or null!"); + } VkDescriptorImageInfo.Buffer imageInfos = VkDescriptorImageInfo.calloc(ImageCount,MemStack); for(int i = 0; i < ImageCount; i++){ + ImageView imageView = imageViews.get(i); + if (imageView == null || imageView.GetVulkanImageView() == 0) { + Logger.error("Texture or ImageView at index " + i + " is NULL! Check your material cache loading."); + imageView = imageViews.getFirst(); + if(imageView == null || imageView.GetVulkanImageView() == 0) throw new NullPointerException("The provided TextureSampler is uninitialized or null!"); + } + VkDescriptorImageInfo imageInfo = imageInfos.get(i); imageInfo.imageView(imageView.GetVulkanImageView()).sampler(textureSampler.GetVkSampler()); diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Rendering/VkModel/MaterialData.java b/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Rendering/VkModel/MaterialData.java index b9407bc..2a90378 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Rendering/VkModel/MaterialData.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Rendering/VkModel/MaterialData.java @@ -2,5 +2,5 @@ package net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.VkModel; import org.joml.Vector4f; -public record MaterialData(String ID, String TexturePath,String NormalTexturePath,String MetalRoughnessMap, Vector4f DiffuseColour,float Roughness, float Metallic, String EmissiveTexture,Vector4f EmissiveColour, String TranslucencyTexture, float Translucency, String OpacityTexture, float Opacity) { +public record MaterialData(String ID, String TexturePath,String NormalTexturePath,String MetalRoughnessMap, Vector4f DiffuseColour,float Roughness, float Metallic, String EmissiveTexture,Vector4f EmissiveColour, String TranslucencyTexture, float Translucency, String OpacityTexture, float Opacity, Vector4f ColorTransparency, float Refractiveness, float Reflectiveness) { } diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/SpriteRendering/SpriteRenderer.java b/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/SpriteRendering/SpriteRenderer.java index 2ffc790..f4553a5 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/SpriteRendering/SpriteRenderer.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/SpriteRendering/SpriteRenderer.java @@ -205,9 +205,11 @@ public class SpriteRenderer { public void LoadMaterials(VulkanContext VkCtx, MaterialsCache materialsCache, TextureCache textureCache){ DescriptorAllocator descriptorAllocator = VkCtx.GetDescriptorAllocator(); Device device = VkCtx.GetDevice(); - List imageViews = new ArrayList<>(textureCache.GetAll2DTextures().stream().map(ITexture::GetImageView).toList()); ImageView fallback = textureCache.GetTexture("resources/EngineResources/Texture/NoTexture.png").GetImageView(); + List imageViews = new ArrayList<>(); + imageViews.add(fallback); + imageViews.addAll(textureCache.GetAll2DTextures().stream().map(ITexture::GetImageView).toList()); while (imageViews.size() < TextureCache.MAX_TEXTURES) { imageViews.add(fallback); } diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Structure/SwapChain/SwapChainRender.java b/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Structure/SwapChain/SwapChainRender.java index 86d40a8..4a7a869 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Structure/SwapChain/SwapChainRender.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Structure/SwapChain/SwapChainRender.java @@ -29,7 +29,7 @@ public class SwapChainRender { private static final String DESCRIPTOR_ID_ATTACHMENT = "FWD_DESC_ID_ATT"; private static final String FRAGMENT_SHADER_FILE_GLSL = "resources/EngineResources/shaders/swap_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/swap_vtx.glsl"; + 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 VkClearValue ClearValueColour; 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 83f3e41..dbb6c87 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 @@ -160,7 +160,7 @@ public class VulkanUtils { descriptorAllocator.AddDescriptorSets(device, ID, BufferCount, layout); DescriptorSetLayout.LayoutInformation LayoutInfo = layout.GetLayoutInfo(); for(int i = 0; i < BufferCount; i++){ - Result[i] = new VulkanBuffer(VkCtx, BufferSize, Usage,VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE,VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); + Result[i] = new VulkanBuffer(VkCtx, BufferSize, Usage,VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE,VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); DescriptorSet descriptorSet = descriptorAllocator.GetDescriptorSet(ID, i); descriptorSet.SetBuffer(device, Result[i], Result[i].GetRequestedSize(), layout.GetLayoutInfo().Binding(),layout.GetLayoutInfo().DescriptorType());