From 5b231d6920c7027b8bf079a16c3bf4992482c49a Mon Sep 17 00:00:00 2001 From: Halbear Date: Mon, 31 Aug 2026 14:13:59 +0100 Subject: [PATCH] OpenGL works again, Vulkan can be switched to, fixed most of the vulkan validation errors, better shadows, soft shadows, emissive lighting, and multiple different opacity rendering methods --- build.gradle | 10 ++ .../shaders/lighting_frag.glsl | 12 +- .../shaders/lighting_frag.glsl.spv | Bin 14120 -> 14796 bytes .../shaders/lighting_with_shadows_frag.glsl | 54 ++++-- .../multi-sampled_post_process_frag.glsl.spv | Bin 3704 -> 3704 bytes .../shaders/post_process_frag.glsl | 2 +- .../shaders/post_process_frag.glsl.spv | Bin 6248 -> 6248 bytes .../shaders/scene_fragment.glsl | 40 +++-- .../shaders/scene_fragment.glsl.spv | Bin 3424 -> 6084 bytes .../shaders/scene_fragment_deferred.glsl | 53 +++++- .../shaders/scene_fragment_deferred.glsl.spv | Bin 6024 -> 9924 bytes .../shaders/scene_opaque_fragment.glsl | 38 +++-- .../shaders/scene_opaque_fragment.glsl.spv | Bin 3424 -> 6084 bytes .../scene_opaque_fragment_deferred.glsl | 55 +++++- .../scene_opaque_fragment_deferred.glsl.spv | Bin 6428 -> 10328 bytes .../shaders/scene_translucent_fragment.glsl | 42 +++-- .../scene_translucent_fragment.glsl.spv | Bin 3592 -> 6084 bytes .../scene_translucent_fragment_deferred.glsl | 54 +++++- ...ene_translucent_fragment_deferred.glsl.spv | Bin 6596 -> 10496 bytes .../EngineResources/shaders/shadow_frag.glsl | 28 ++-- .../shaders/shadow_geometry.glsl | 20 +-- .../shaders/skybox_fragment.glsl | 2 +- .../shaders/skybox_fragment.glsl.spv | Bin 644 -> 756 bytes .../shaders/skybox_vertex.glsl | 2 +- .../shaders/skybox_vertex.glsl.spv | Bin 2488 -> 2452 bytes .../EngineCore/Display/OpenGLRenderer.java | 11 ++ .../EngineCore/Display/Renderer.java | 4 + .../EngineCore/Display/VulkanRenderer.java | 73 ++++++-- .../EngineCore/Logic/EngineConfig.java | 24 ++- .../SeparatingAxisTheoremTester.java | 1 - .../Logic/Physics/WorldPhysicsManager.java | 19 +-- .../Logic/Rendering/ModelCompiler.java | 32 +++- .../Terrain4J/EngineCore/Main/GameCore.java | 157 +++++++++++------- .../Main/Scene/GUIs/PerformanceOverlay.java | 91 +++++++++- .../Main/Scene/GUIs/SettingsMenu.java | 85 +++++++++- .../EngineCore/Main/Scene/Scene.java | 4 +- .../Universal/Projection/Project3D.java | 16 ++ .../DeferredRendering/LightRenderer.java | 133 +++++++++++++-- .../MultiRenderTargetAttachments.java | 12 ++ .../Rendering/Pipeline/DefaultPipeline.java | 4 +- .../Pipeline/Images/TextureCache.java | 15 +- .../Rendering/Pipeline/PipelineBuildInfo.java | 10 +- .../Rendering/Shadows/ShadowRenderer.java | 78 ++++++++- .../Vulkan/Rendering/Shadows/ShadowUtils.java | 10 +- .../Rendering/VkModel/MaterialData.java | 2 +- .../Rendering/VkModel/MaterialsCache.java | 71 +++++++- .../SpriteRendering/SpriteRenderer.java | 7 +- .../DisplayToScreen/DeferredSceneRender.java | 41 ++++- .../DisplayToScreen/ForwardSceneRender.java | 26 ++- .../Vulkan/Structure/SwapChain/SwapChain.java | 22 ++- .../EngineCore/Threads/EngineThread.java | 2 +- .../EngineCore/Threads/RenderThread.java | 2 +- .../Threads/VirtualEngineThread.java | 2 +- terrain4j.properties | 4 +- 54 files changed, 1102 insertions(+), 268 deletions(-) diff --git a/build.gradle b/build.gradle index a154d98..d043272 100644 --- a/build.gradle +++ b/build.gradle @@ -9,7 +9,17 @@ buildscript { plugins { id 'application' id 'java' + id 'com.gradleup.shadow' version '9.2.0' } + +jar { + manifest { + attributes( + 'Main-Class': 'net.halbear.Executable.Launcher' + ) + } +} + project.ext.lwjglVersion = "3.4.1" project.ext.jomlVersion = "1.10.8" project.ext.jomlprimitivesVersion = "1.10.0" diff --git a/resources/EngineResources/shaders/lighting_frag.glsl b/resources/EngineResources/shaders/lighting_frag.glsl index a7fada2..8108408 100644 --- a/resources/EngineResources/shaders/lighting_frag.glsl +++ b/resources/EngineResources/shaders/lighting_frag.glsl @@ -23,6 +23,9 @@ layout(set = 0, binding = 0) uniform sampler2D posSampler; layout(set = 0, binding = 1) uniform sampler2D albedoSampler; layout(set = 0, binding = 2) uniform sampler2D normalsSampler; layout(set = 0, binding = 3) uniform sampler2D pbrSampler; +layout(set = 0, binding = 4) uniform sampler2D emissiveSampler; +layout(set = 0, binding = 5) uniform sampler2D TranslucencySampler; +layout(set = 0, binding = 6) uniform sampler2D OpacitySampler; layout(scalar, set = 1, binding = 0) readonly buffer Lights { Light lights[]; @@ -32,6 +35,7 @@ layout(scalar, set = 2, binding = 0) uniform SceneInfo { float ambientLightIntensity; vec3 ambientLightColor; uint numLights; + mat4 viewMatrix; } sceneInfo; float distributionGGX(vec3 N, vec3 H, float roughness) { @@ -126,6 +130,10 @@ void main() { vec3 normal = texture(normalsSampler, inTextCoord).rgb; vec3 worldPos = texture(posSampler, inTextCoord).rgb; vec3 pbr = texture(pbrSampler, inTextCoord).rgb; + vec3 emissive = texture(emissiveSampler, inTextCoord).rgb; + vec3 translucency = texture(TranslucencySampler, inTextCoord).rgb; + float emissiveness = emissive.r; + float roughness = pbr.g; float metallic = pbr.b; @@ -146,9 +154,9 @@ void main() { } } vec3 ambient = sceneInfo.ambientLightColor * albedo * sceneInfo.ambientLightIntensity; - vec3 color = ambient + Lo; + outFragColor = vec4(Lo + ambient + vec3(emissiveness), 1.0f); - outFragColor = vec4(color, 1.0f); + // outFragColor = vec4(color, 1.0f); if (length(normal) < 0.001) { outFragColor = vec4(albedo,1.0f); return; diff --git a/resources/EngineResources/shaders/lighting_frag.glsl.spv b/resources/EngineResources/shaders/lighting_frag.glsl.spv index 8cd6ee9301b02a7a4b8e12b94c9627eff6261667..067478a5ab94b93bef68c27dd6bf80a775b3c760 100644 GIT binary patch delta 4347 zcmZ9PYj9j;8OPu4X49liv`LWONN5tpQG{{Eah&Ra12YN?BJH3ue$iRt3OkczLpG(t zms4fLFN)$p#S2ie3Pn`fq96)V@mec_7pmf|UdAilDwF~hf4`IS)I-kfv+wi&KezXG zo=t9<-QOLoFPmJRQZ21agX!dJ2G6Yx?|SoF`?A(dyW4GF)=E5$)SKQ{ODVVunlp3L zt@(ogApF97bGAFZWvVqhb@`(I@|45Bp~6>VuB+slZFRegF^%*I`1#J3i!YgNy`^9q zl-LeA(^_awPq(KQ9qVZa-0O>p)zi)BZz}Xg+KGMv(`cPD`}Pi8FY$6dQ_Y!89ZL14 z{9g?NO4dfIr`>R`eW~_( zx*Pp$T>GJ?S#VksEFyFhPlO2McYtA=k%1n5}tGyV@`E$*w_QK`m zrODs5^4hGYxPs%%*E2ecZ?EJ8x{uf^r@c|Z|F_qR^CfpW8;`gZlVG3VNRi|QDx5Ks z8DFa^q(`CS2?f`4?DAMVk~vY{t!Kr_8Mgs((q1kn?GxBZ$3)|jyxbrklgCYwi%tS*2^uIK zrs$YP98|Y;fR?imLc&C2#bv)$Dw^2JVxSu`Owhn%#-ol#>!I>8})rgqdXm_E%qE@+7Fhx zu}=F2d>=;VlZ+q4QQyT=?@2=dPuz_%pO|xdSwY6SPlW6YU-`;N_#*J1h>BD4U{lKX z4PBJ=p}dz|ZjWZMKLmmM!8Z9Swz*gF_6j!Mo*s6weZ7k9xFtTbC}`Ua2lw698`u}a z_FKgVE4VKo9eH);H2+#*#gA67Sq@dO)3Q-UR4-`*Q*iVA90uQ{m2&NLS9~v_XCJN^5?Tprn;u&wfQ)Bn5T38 z9;5cie=T}mV)K6pA%AwPz=t7p(hvncf-bN4I79*Oh4wR;pzHe>xJON9TY(B<{_;)%7nJD*0s0vRaZ_s^j7 zDc);s#_Y&YG+5*|#?K)(k{fZ1M4vDDz+V7wL#`yoLbs#qBOk?fq4Ozch5a~HZ?$Uu1~z6{4Fom%EJkG@eyJ%9)ijIEH+(V%h2pP-wFPZ4AjI)E7TFyi)!^)trf`6;?Fz8!I4e+D+@Za8Da`o-ja zj-DB03pdEwJpwk!tusihqjo3q3nV5IyYtJEzZD<1_E(79^~hmz{D#rTUDoz%Y`a-R;)A@_#env;30HzB!3)z8)Blz7{y_G0^QeF+hIm=*q%i9M^4)jMse7l z_JZ#&jZZN?T`~R_J@)S?y4XN>%!{-gY|>{K#bH~99=qwUig+WP#~rDopTg+kT*Tpw zFK1(#!#pavpXufd@_u_jGcpFC~&Xz++#+##2 z&II?Oo8Uf1FSs4JADg|ywnqc zExNow zcE>)l0bQGaLE1+q7=7#`+Qtz%k5E1GPojG~E}(6J=R-*P#HwCUauyEmq>|G$R`o)F a@%n2oR>fpol(wTx-3d(W*)_U#?f(Gzju5W^ delta 3637 zcmZ9OTWnNS7=`zA+R`a4Qidv6s0@uSYK{70z(9ftf{_^1VB&+Cf)$#yGuW1p@N!BB z`T__Xk%|h`DVr4LdVzu>uJ6qLo8ug3v)5YxW$*p(i#^b` zC0m&+svG89!VPzoZtR-M>k_3qZ@Im!sx`N0{(@{{TbpyPME|W0r=`;M_a&UWK2nly zz3|Q6+9`a~yvA(fwb?s!(n=N487@tw6P@9@RGt3aow^{vD=BMsQOm5R`3u@D_Xg>0 zvFH+cbxFJCGR982t-`aE7Q9`!DH^rd?G|n(k>|bmd0whH!1)&D+M3#%a$&AKH5Lu| zj;7Yec@nb?&GM9QxTgHP04p<`mut?osxNWH?qz8NG@Of2QoPQ*~u%We~ zMSj>174T0Bcwe4hG!$^Sz~M*%KN=2{=cXMmPzMV5pm;;e+@{8Cdo+ziQG97yb~rFR z9geG5TbFcfj?8YRJi&Z*`7W=8Rh8*m%?ry&HS?xuXyepoXu%tlAtTIZe4?<8U|SO( zp_dV=vEUUSp*QTWOxM38OQ|dq)MjX#*a*g*={HHxjfuE6Da?#WU(U9mFavM~7k$Q= zk>rS%YS7y5BhHkm ztPhOp2p+ErQdexXzNT>UyrP~w)R~3BsiG}xPhvry5KN6W%6Xr#evSlZ1aQu8TCpn; zVZ#VG>~J2bIPWUp zJS}FYuskouIe|Peo(Iv9BL`ieOW z`SXxe?BK^@oRqu@@gaB>jN?C8z!TlmtM5q!({%9(UnTS1YMlNlepl`lMxUy^VhiBr zzg8H3Zio4Y!sz(3MR06PW1a94wF>Pw{C;8mg6NQAB#3>)z#v?phtxKxZBl?Gdf4m6 zH;Q+tEmI7MHwoi|Zi8(W)-M_hJ7aN1HYb8S;ec=(E$L&zXvQBGZtMLn8R^}^gX7z9!3Cc)&OPECZMM2!xx7CQ* zr$!7MKVsOP{ldiP6^UXv;O~eN(<@92d_VhdvwK$pLA*P2d}0Zo*QPj^KV_G?FkdHZ)E?Wu#(Mj(95e zz3}evu9})eN4Qe|t`E1?)Qq=U{3z>B-ka>d2zQ13HR;=6zlz!7j|szVfxijc;*Sf% z&Gx&nEq*{4K1nYRIsXu@cVX?g^8>;#+fx4&jxY5uaWq0~sc7+~vSj#9^(>v9d>IXO zLU_Ache`)ODU9Z?NDvtjNno$a4snh$Z|x~HUJ34pP4cwYjsGo9jh6fU`9~NZbn={0 z|F0T(7??N?&spvnhE+aLb8rNoRb#b->d|bVB4IS+N%45KipB9kC!RlX(ae9CFq%CG zWq}AHpNT22F}7*tUc+^^_HeO`!$r!}@W(z|HU{O77;H9Zh42#j^M4&yT`5lPtJMOG zyR`ZqDdz}djhRFy*(&rp3|tOdIVr1~#p_$W4wM@wHW* ZD?$PS 1.0 || uv.y < 0.0 || uv.y > 1.0 || - depth < 0.0 || depth > 1.0) { + depth < ShadowBias || depth > 1.0) { return 1.0; } - vec2 moments = texture(shadowSampler, vec3(uv, cascadeIndex)).rg; + float shadow = 0.0; - float visibility = chebyshevUpperBound(moments, depth); - return visibility; + 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 /= 9.0; + + return 1 - shadow; } float distributionGGX(vec3 N, vec3 H, float roughness) { @@ -150,7 +165,7 @@ vec3 calculatePointLight(Light light, vec3 worldPos, vec3 V, vec3 N, vec3 F0, ve return (kD * albedo / PI + specular) * radiance * NdotL; } -vec3 calculateDirectionalLight(Light light, vec3 V, vec3 N, vec3 F0, vec3 albedo, float metallic, float roughness) { +vec3 calculateDirectionalLight(Light light, vec3 V, vec3 N, vec3 F0, vec3 albedo, float metallic, float roughness, float translucency) { vec3 L = normalize(-light.position); vec3 H = normalize(V + L); @@ -170,7 +185,9 @@ vec3 calculateDirectionalLight(Light light, vec3 V, vec3 N, vec3 F0, vec3 albedo kD *= 1.0 - metallic; float NdotL = max(dot(N, L), 0.0); - return (kD * albedo / PI + specular) * radiance * NdotL; + vec3 shadowValue = (kD * albedo / PI + specular) * radiance * NdotL; + vec3 lightValue = (kD * albedo / PI + specular) * radiance; + return (shadowValue * (1 - translucency)) + (lightValue * translucency); } void main() { @@ -179,6 +196,20 @@ void main() { vec4 worldPosW = texture(posSampler, inTextCoord); vec3 worldPos = worldPosW.xyz; vec3 pbr = texture(pbrSampler, inTextCoord).rgb; + vec3 emissive = texture(emissiveSampler, inTextCoord).rgb; + vec3 Opacity = texture(OpacitySampler, inTextCoord).rgb; + vec3 translucency = texture(TranslucencySampler, inTextCoord).rgb; + + float emissiveness = emissive.r; + float translucencyf = translucency.r; + +// outFragColor = vec4(emissive,1); +// return; + + float ShadowBias = 0.05f; + + float opacityf = Opacity.x + Opacity.y + Opacity.z; + opacityf = opacityf/3.0; float roughness = pbr.g; float metallic = pbr.b; @@ -186,6 +217,8 @@ void main() { vec3 N = normalize(normal); vec3 V = normalize(sceneInfo.camPos - worldPos); + + vec3 F0 = vec3(0.04); F0 = mix(F0, albedo, metallic); @@ -196,18 +229,19 @@ void main() { cascadeIndex = i + 1; } } - float shadow = calcVisibility(vec4(worldPos, 1), cascadeIndex); + float shadow = calcVisibility(vec4(worldPos, 1), cascadeIndex,ShadowBias); vec3 Lo = vec3(0.0); for (uint i = 0; i < sceneInfo.numLights; i++) { Light light = lights.lights[i]; if (light.directional == 1) { - Lo += calculateDirectionalLight(light, V, N, F0, albedo, metallic, roughness) * shadow; + Lo += calculateDirectionalLight(light, V, N, F0, albedo, metallic, roughness,translucencyf) * shadow; } else { Lo += calculatePointLight(light, worldPos, V, N, F0, albedo, metallic, roughness); } } vec3 ambient = sceneInfo.ambientLightColor * albedo * sceneInfo.ambientLightIntensity; + if(emissive.x > 0 || emissive.y > 0 || emissive.z > 0) ambient = emissive; outFragColor = vec4(Lo + ambient, 1.0f); if (DEBUG_SHADOWS == 1) { 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 1cce2dd893b88a6ffb0ea1f049ac8a4e735226ca..2cf3d79a272ff9ca6409715b5f6f718e50d76bde 100644 GIT binary patch delta 17 Ycmew%^FwBX0}G4gmKS!LU06)G07DlBZ2$lO delta 17 Ycmew%^FwBX0}D&@fhhaUE-WTo075keHUIzs diff --git a/resources/EngineResources/shaders/post_process_frag.glsl b/resources/EngineResources/shaders/post_process_frag.glsl index e4c4353..b15b7d0 100644 --- a/resources/EngineResources/shaders/post_process_frag.glsl +++ b/resources/EngineResources/shaders/post_process_frag.glsl @@ -2,7 +2,7 @@ layout(constant_id = 0) const int USE_AA = 0; -const float GAMMA_CONST = 0.4545; +const float GAMMA_CONST = 0.8545; const float SPAN_MAX = 8.0; const float REDUCE_MIN = 1.0/128.0; const float REDUCE_MUL = 1.0/32.0; diff --git a/resources/EngineResources/shaders/post_process_frag.glsl.spv b/resources/EngineResources/shaders/post_process_frag.glsl.spv index a4a924fa32132fb8c0adf718156b2defa031fc8a..055aba0b967ca55e2d8a06a68d5527b2733b473b 100644 GIT binary patch delta 17 YcmaE1@WNn21q(~_fhhaUH7sw00Y`=hZvX%Q delta 17 ZcmaE1@WNn21q+MimKS!LYgpb00{}>92c`f3 diff --git a/resources/EngineResources/shaders/scene_fragment.glsl b/resources/EngineResources/shaders/scene_fragment.glsl index 759800e..87eb92c 100644 --- a/resources/EngineResources/shaders/scene_fragment.glsl +++ b/resources/EngineResources/shaders/scene_fragment.glsl @@ -10,17 +10,25 @@ layout(location = 4) in vec2 inTextCoords; layout(location = 0) out vec4 outAlbedo; - struct Material { - vec4 diffuseColor; - uint hasTexture; - uint textureIdx; - uint hasNormalMap; - uint normalMapIdx; - uint hasRoughMap; - uint roughMapIdx; - float roughnessFactor; - float metallicFactor; + vec4 diffuseColor; //16 + uint hasTexture; //20 + uint textureIdx; //24 + uint hasNormalMap; //28 + uint normalMapIdx; //32 + uint hasRoughMap; //36 + uint roughMapIdx; //40 + float roughnessFactor; //44 + float metallicFactor; //48 + vec4 emissiveColour; //64 + uint hasEmissiveMap; //68 + uint emissiveMapIdx; //72 + uint hasTranslucencyMap; //76 + uint translucencyMapIdx; //80 + float translucencyFactor; //84 + uint hasOpacityMap; //88 + uint OpacityMapIdx; //92 + float OpacityFactor; //96 }; layout(set = 2, binding = 0) readonly buffer MaterialUniform{ @@ -36,13 +44,23 @@ layout(push_constant) uniform pc{ void main() { + Material material = matUniform.materials[push_constants.materialIdx]; if(material.hasTexture == 1){ vec4 texColor = texture(textSampler[material.textureIdx],inTextCoords); - if(texColor.a < 0.4){discard;} outAlbedo = texColor; } else{ outAlbedo = material.diffuseColor; } + vec4 Opacity = vec4(outAlbedo.a,outAlbedo.a,outAlbedo.a,1); + if(material.OpacityFactor != 1) Opacity = vec4(material.OpacityFactor, material.OpacityFactor, material.OpacityFactor, 1); + if(material.hasOpacityMap > 0 && material.OpacityMapIdx < MAX_TEXTURES){ + Opacity = texture(textSampler[material.OpacityMapIdx], inTextCoords); + } + float opacityf = Opacity.x + Opacity.y + Opacity.z; + opacityf = opacityf/3; + if(opacityf < 0.4){discard;} + + outAlbedo = vec4(outAlbedo.rgb, opacityf); } \ No newline at end of file diff --git a/resources/EngineResources/shaders/scene_fragment.glsl.spv b/resources/EngineResources/shaders/scene_fragment.glsl.spv index 0cf93b536360bc7c1a3df0cade1162fd9808da74..97767830fdd9a9334933c5275a19e4f82cb5f560 100644 GIT binary patch literal 6084 zcma);`IlT(5y#(TmJA>PWD^N-hNz%mj2afjBojh1iB6c1gai#TX}WtRPkXw@UN8~a zTv6OXK?4ddD9Axv35&n@GyXXqm!s$S`MmdP=4DPd$Cp#NRo|*_-MaVIy*uYi zD)JigI&wZd+R;?-r9+kTdAte`_IMSJ=1vxf88qo>YC5X z^Up3-s%bY*y;K-=N;mH>fxCDc+wmkKfwIGvAx_hTJ#n4gG_9 zL*Jm@(AU2=#9EWblyl^p9HtSl}y>g|l5f~8HLrJb!-yJk5V-?z5a z>+WdWU9Yt=Y$WkPEAB`ZbIO?fGR>ocjb!h0+T7nVk#qW1r_KBs%VS2fx0^XD&4qfi zTg3U6r_GyFmXM));JUwl8}lIv%=;qdo(1Mz5xb~_4HwwkN|^Vdm%Pa!n_k= z?<`^72eGS5nD;>J+7f2}i)}7p_Py9t3A5kDZYg1|S!_=Uv$w@&N|^mDw!ehg!(xX@ zn0q94M+viM#qLC=IWzOS-eZ|Pob~Q7`W}4F;}?4vwtT;7`qVk}n@fEX@eBJ(bkE0F z`&iv`Q};916k@zRTIOrZw;uiW>juPg)V5Ex{j^UrmTmh_d#LdHcY}6b&q($+gtqxF z1Qnme(pJ9&&ApjGE+xM`pzZt@^S|dmf%t8p`#gJN#QTX{rC*GAaMUNrZ{HYeUh~@@ z{kUb`|C|2`*5=upa|60(tL?n@lIs_{sjxj;G1qMmO&~+aHHH0FbU$->w$@}W@1*sM znM>PuOHBVIg&y&jVLOj?>A!-}H7haK1iEwUpJa?Z3BUK&9ARID?wN-DUUbhe?DwJj z4uriK-F*!EL+H-od|L{=?7sob`Xl}$=&mp9t>~U**i-1<|FCzWyWX&Oqk9%%??v}4 z!k$6*jKZEp_k6-WfbJP-Ti0R4{kn)dQ#g!^Ja-vLzQiF?k+7%PaM{#veP9PiQsw)1;V`j0aXA>#72(*o1qK=%wi2mRWM1s3&n z3fuT@p~pEn-isv3gWDtik<4CM-!s_JH^x7k`KP9g*M1K9+Z%6ev;G&+#jHuc`~7Fc zML7S4hw(pZ`)c;DMo5%HN`(Eh}+xMz$zh2na)2-HN5BpieKSAtax%Qg<6?^3! zI=agC_dNXe^r^z$K^E`irHJ>`d%cyM_L1+r_zqU?J$*Z3-x;INIQ#f=MBi=Xa*p){ z#sGITyVJhA)+l!yE6_Ghj&r>OF^}t)Gs$=*B4+}TqitMpHloXMZ-VnKbUD5Wag7Y49IqrXOu0faM+agEXxZqriF2^$p&L(s@zCUubjSJ5E z(dF1@!TA8X9N#E8+Q!K-?t_RN_g#)>dmSRjcTA49alyGBU5@)6oEy>Q+T{gb0@T&(A#=yL4OSkE?eIa?7q+QtQEJGvZWg0rKrrx@jE8yB3L z(dF2S!MO$996J#?+QtQE7rGqZ-QY~4%h`>{(Kb$wd%XvdvksBtUVjXcvlo%0ZCuRr zadbJp-!acVbU8DK9Bt!*b1S+W?^Ajc;e{r=5u(Dwz+NAA1P&Fwvm+*NdOV`_|b zq=JYWtMl8xONcf4 zCI$bq1s;6uGT%J%yNo@=Is6@xZ;#xAh)2xl&{xNt027axlYL@74<^2!Rk^M&Am)~< z?_R_j+l>0mWk24BxF*j$YP!F`Una&geE<`%7Tr z5%c9fF<$`_kC?CaiTN6sc&ztfbaTtqS6;6^&m?MeH1{Oq*AZ*M@ac@{TSOA z@#rlv*AaC%I>#2qClUM4eKe>2{}dt~F+V{!<}ea5KSdXRh&*zhM&yYH?`P=po2Uvr2DYEuc7DvcFHywD2;YiycWZR%gFR;^X5CMJ1cp*UL$B`Lk;^LfAHcjcO-eha%=Z@ISqwA1WLNttT! zKAD@LmjA3*?$nzNKg>>qwc8s@{-(XnciJ0Ozq?-R$PFttgM2FMw1QKqFJ8qY)SgjI zV@?FyBQN@VFE4P2!Vd{?%bDV!kg%LC;2iRqZkW>n+_7<{hQ};#Sx)_|i3Ok1bMcIE zgS?vyM%{EUDJ;5U()J8%gE#ISXCkdj1%cw@DtT6R!nmd!yv}+SN=m`OCbM|EVZM2c+F}wSZ6doLIEy3w!ykA9l{${i#U%% z(TKN#HLu{52HW0|*lJn-p1guHLPnSpW>tvQo)OUBDThaxwHlA}Q!UKNa{efvSW&ny z{L%u8!ROIz|FBq8ZBc$j;EOE&lE7o2lf%PZ7SQ1={hGkOS9FJ+ED7YG7u7*Y7LA%G zWp4;2fj3c&ez>b;5dt6W7`No3@lcGhBFkY6Vz&h}#=!rp?ct-*7>(Q$N&-#rpzz 0 && material.OpacityMapIdx < MAX_TEXTURES){ + Opacity = texture(textSampler[material.OpacityMapIdx], inTextCoords); + } + outOpacity = Opacity; + + float opacityf = Opacity.x + Opacity.y + Opacity.z; + opacityf = opacityf/3; + + outAlbedo = vec4(outAlbedo.rgb, opacityf); if(outAlbedo.a < 0.5) discard; @@ -75,6 +98,18 @@ void main() metallicFactor = material.metallicFactor; } + vec4 emissive = material.emissiveColour; + if (material.hasEmissiveMap > 0 && material.emissiveMapIdx < MAX_TEXTURES) { + emissive = texture(textSampler[material.emissiveMapIdx], inTextCoords); + } + outEmissive = emissive; + + vec4 Translucency = vec4(material.translucencyFactor,material.translucencyFactor,material.translucencyFactor,1); + if(material.hasTranslucencyMap > 0 && material.translucencyMapIdx < MAX_TEXTURES){ + Translucency = texture(textSampler[material.translucencyMapIdx], inTextCoords); + } + outTranslucency = Translucency; + outPBR = vec4(ao, roughnessFactor, metallicFactor, 1.0f); } \ 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 16cea282a80297563aa43372632c3a058e813655..2e37b81814813a4579ef50a20dd7d390fa851c95 100644 GIT binary patch literal 9924 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 diff --git a/resources/EngineResources/shaders/scene_opaque_fragment.glsl b/resources/EngineResources/shaders/scene_opaque_fragment.glsl index dea4039..f8290eb 100644 --- a/resources/EngineResources/shaders/scene_opaque_fragment.glsl +++ b/resources/EngineResources/shaders/scene_opaque_fragment.glsl @@ -11,15 +11,24 @@ layout(location = 4) in vec2 inTextCoords; layout(location = 0) out vec4 outAlbedo; struct Material { - vec4 diffuseColor; - uint hasTexture; - uint textureIdx; - uint hasNormalMap; - uint normalMapIdx; - uint hasRoughMap; - uint roughMapIdx; - float roughnessFactor; - float metallicFactor; + vec4 diffuseColor; //16 + uint hasTexture; //20 + uint textureIdx; //24 + uint hasNormalMap; //28 + uint normalMapIdx; //32 + uint hasRoughMap; //36 + uint roughMapIdx; //40 + float roughnessFactor; //44 + float metallicFactor; //48 + vec4 emissiveColour; //64 + uint hasEmissiveMap; //68 + uint emissiveMapIdx; //72 + uint hasTranslucencyMap; //76 + uint translucencyMapIdx; //80 + float translucencyFactor; //84 + uint hasOpacityMap; //88 + uint OpacityMapIdx; //92 + float OpacityFactor; //96 }; layout(set = 2, binding = 0) readonly buffer MaterialUniform{ @@ -37,9 +46,18 @@ void main() Material material = matUniform.materials[push_constants.materialIdx]; if(material.hasTexture == 1){ vec4 texColor = texture(textSampler[material.textureIdx],inTextCoords); - if(texColor.a < 0.9){discard;} outAlbedo = texColor; } else{ outAlbedo = material.diffuseColor; } + vec4 Opacity = vec4(outAlbedo.a,outAlbedo.a,outAlbedo.a,1); + if(material.OpacityFactor != 1) Opacity = vec4(material.OpacityFactor, material.OpacityFactor, material.OpacityFactor, 1); + if(material.hasOpacityMap > 0 && material.OpacityMapIdx < MAX_TEXTURES){ + Opacity = texture(textSampler[material.OpacityMapIdx], inTextCoords); + } + float opacityf = Opacity.x + Opacity.y + Opacity.z; + opacityf = opacityf/3; + if(opacityf < 0.9){discard;} + + outAlbedo = vec4(outAlbedo.rgb, opacityf); } \ No newline at end of file diff --git a/resources/EngineResources/shaders/scene_opaque_fragment.glsl.spv b/resources/EngineResources/shaders/scene_opaque_fragment.glsl.spv index 5a5dfb1f9f2e49cb2895e16471aa8c1c939cbeb7..251492d28d193ff36f9dd72d5b7b1cf38efb645d 100644 GIT binary patch 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 delta 1146 zcmYk4+iFu$5Qf*zsoBI0wW)+kmBtDpUg(8_H8uyUO+Cfhs#AHh#?UpoxcPZ!# z=za+mypY^jyb^s7FMJ0NDENQr+K?4~X8wO>&7PT+ZzsPW^y0DEF=HH)F`jw)+N&O@ z8Ds7Vb)hM=1pi}u+Zp_bO*(Iqua1|c^ja?#f=%jp8nA)o0+IUT?q8)s^G%yQpy>Ss+X{G2YuGsX?` zZY~^m)8VwRwTZx_6zav@R6{ichNKdD$uBno9UCGuyu)RuN99EixB`9bsDh zqAYQ=8SzW99Q1s{&tS@mB;M1DzZm?y7(eXX!Tt_PwS%>||LW2fe5c%CczGJT1E- zlm*^IHTuI{t%?x%WXHHIAB~4%j5S#fV-UL|pfLviUu_Q`jmBu?zEBouf(M2FRt_s6 imo-$(V$vLvvmvnC2_Y)*(CSeE_-FwN{nLlf3jYDLb93$h diff --git a/resources/EngineResources/shaders/scene_opaque_fragment_deferred.glsl b/resources/EngineResources/shaders/scene_opaque_fragment_deferred.glsl index b230395..d91d780 100644 --- a/resources/EngineResources/shaders/scene_opaque_fragment_deferred.glsl +++ b/resources/EngineResources/shaders/scene_opaque_fragment_deferred.glsl @@ -12,6 +12,9 @@ layout(location = 1) out vec4 outAlbedo ; layout(location = 0) out vec4 outPos; layout(location = 2) out vec4 outNormal; layout(location = 3) out vec4 outPBR; +layout(location = 4) out vec4 outEmissive; +layout(location = 5) out vec4 outTranslucency; +layout(location = 6) out vec4 outOpacity; const float bayerMatrix[16] = float[]( 0.0 / 16.0, 8.0 / 16.0, 2.0 / 16.0, 10.0 / 16.0, @@ -21,15 +24,24 @@ const float bayerMatrix[16] = float[]( ); struct Material { - vec4 diffuseColor; - uint hasTexture; - uint textureIdx; - uint hasNormalMap; - uint normalMapIdx; - uint hasRoughMap; - uint roughMapIdx; - float roughnessFactor; - float metallicFactor; + vec4 diffuseColor; //16 + uint hasTexture; //20 + uint textureIdx; //24 + uint hasNormalMap; //28 + uint normalMapIdx; //32 + uint hasRoughMap; //36 + uint roughMapIdx; //40 + float roughnessFactor; //44 + float metallicFactor; //48 + vec4 emissiveColour; //64 + uint hasEmissiveMap; //68 + uint emissiveMapIdx; //72 + uint hasTranslucencyMap; //76 + uint translucencyMapIdx; //80 + float translucencyFactor; //84 + uint hasOpacityMap; //88 + uint OpacityMapIdx; //92 + float OpacityFactor; //96 }; layout(set = 2, binding = 0) readonly buffer MaterialUniform { Material materials[]; @@ -67,6 +79,19 @@ void main() int y = int(gl_FragCoord.y) % Intensity; float threshold = bayerMatrix[y * Intensity + x]; if(outAlbedo.a < threshold || outAlbedo.a < 0.05f) discard;*/ + + vec4 Opacity = vec4(outAlbedo.a,outAlbedo.a,outAlbedo.a,1); + if(material.OpacityFactor != 1) Opacity = vec4(material.OpacityFactor, material.OpacityFactor, material.OpacityFactor, 1); + if(material.hasOpacityMap > 0 && material.OpacityMapIdx < MAX_TEXTURES){ + Opacity = texture(textSampler[material.OpacityMapIdx], inTextCoords); + } + outOpacity = Opacity; + + float opacityf = Opacity.x + Opacity.y + Opacity.z; + opacityf = opacityf/3; + + outAlbedo = vec4(outAlbedo.rgb, opacityf); + if(outAlbedo.a < 0.75) discard; @@ -86,6 +111,18 @@ void main() metallicFactor = material.metallicFactor; } + vec4 emissive = material.emissiveColour; + if (material.hasEmissiveMap > 0 && material.emissiveMapIdx < MAX_TEXTURES) { + emissive = texture(textSampler[material.emissiveMapIdx], inTextCoords); + } + outEmissive = emissive; + + vec4 Translucency = vec4(material.translucencyFactor,material.translucencyFactor,material.translucencyFactor,1); + if(material.hasTranslucencyMap > 0 && material.translucencyMapIdx < MAX_TEXTURES){ + Translucency = texture(textSampler[material.translucencyMapIdx], inTextCoords); + } + outTranslucency = Translucency; + outPBR = vec4(ao, roughnessFactor, metallicFactor, outAlbedo.a); } \ 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 index c06da7ba4d24b246220006f3168dd3f0da26db4e..a4f90f28b012f975ca33528db9608d3fe4c1b1c3 100644 GIT binary patch literal 10328 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 literal 6428 zcmZ{miJz5a6~|wggd zwy!`$B(^JAQITak?fXjG-_Y`@K7GIMeb41(8ejc!&iS3?+0OIaX&5`<7i>77tXr7B9bki4m724QZe;6R{eRqNh-*=x77$!9H*wI07C5 z4};U-JeWica~K@0ff1ABDGD|wW0UqR9qrq9D#ebjQh%|t zTH04MZgeiLROu`acI5+_h{(^WDQQZ^FviwGwb)-Olu=pTsFYLhDs^`c4iwk*mV5ha zzUI{D8uu0kb{F?o2m2Yfng6Wge5*C`mahF5Yq>MTZ|m*vDU`Ps`Y`L`IG;*5(yWX1 znreAFdk6RIH7&+zhVRcvQ)15UTgq380|OfiomHkCzR~!4iq%57TVu(R44JJPzZdwJ{N(xLx%FKz8!x^(5f?q%S*l|9|dmaU|Y`+2$Jl^;Oo0D7c#rkinl)7m>>eqN&_5ET?(>>f=<02HUA=wJo*IDaRb-&nW z`>~07+u`~K2ljS!_ErX}g-SI&qo(x!b7pJHcNM#Oi80pqpj7cXMMuatB!}UnCwwo6 zDOC0pE7dfwDSbamm9`S)Q`SE5JtGpBj_naD9dTLQh(&F*z~BJ~_lb zb&1`SzFDlJK9KYM95DqJ<(i&AA9^fFYIg3?K$l>J56jKZarUmHCfwq0BU8~oa_Ncb=)o*|1^G|1X z#GlV>eJEOixzMN_1r&g$DhW(?p+J;o6WEF7^E@s!@=BIJ%43uvF2EN zT;_A^7VPnvUta%&%)jS;!VJ0$iKf zGtr}#y%y`z@7k^gepA`07UY$z-d=Nk*2#Zi&!pl!9L7bR=NL%9Eb2ZNRll5ToR9RA zUzynpQs&}37h-!J#5Z z&$~VI4R_XZjxVlalubzEXQO*>v>oGxNY7NxIcRUrIOpuyYyp1eZbe$#+-*qvN6uXB z?HQ+kN2W*oE^Nng9{TSw54vj%`<3X{v;N(gp7&Sa zoR9HJ|JZZ9*njVQ^xbPRpFOT$+czNQXZ`~q;tytejHf&Vl4MPK-fu-S*Lz?+?IRf% z_CrH#-;fy3dXE6VnD1$H$9FyY9|wFl$NHYeaQ`CyJbJ`?wm$<75b;09^j>-&eu1>6 zT-5(1I^XKBf0ddo>3GKeI<*hf{l7`=JL~@6ruMnI|97dqrf&Z}wU^Z6|B%`TR>gRK zOzlZ^|Ao}}JdQ}=x=awD)WwcX#tIotQ}Sk5;7c+S>;B4_({p3K?S zJC(ETd;dO(@wELLC2ya}+1|smnZ1hn8Mgtf2di04TV}6iMc(OKf%kk1Fy4E>pDZcA zmX7hB?*^NJG5U;aN8SeX-AXOTxjo|$ynjvUoA4rZ_sd+z*EY@^$9gfa4sDy}%tF2t znB)6lj<#`;^D=aEJSWF7=M}&l-xzbWjfk`ZCvE^pqt~qM@}!gIliUlXd4&v=tI}Gv;o zPG1$=54=a}QTrZrYkOuq63asW6Fd(@iNcs)1(B40b7ZyoawBHsWU;{jlPGxCi<{z+n5kZ%HV zhk$$Z7Nnnhr0>l@&bg`on;W4nXU%cQ2f>k?{Wf%eW5WM-bbn*wyx)Otj$d%^M3)

F0gW_eJn+;2ltp+FwSu_8t(mzk)7rOe^xM zU;&UfW*+h!kk|GMzXm+Rcr%_tKL_Mp>sh3nHSb1#9mw?qYcwOj0pyK$KeQwMo9M$9XWG6guHALI-pKzB`bOYe9{JxzmyhwZBmR5n##cbZe;-{w#?#J^=eQC3 z19Z>r}Lrm%m6?wlRZH}A(_Xg~fW<9EhExNTAf~dU+UEUb`buqAC<&Cjlp9kc% z?bjv1HAlZLMK?x%d-lFuhb}MtMu3qZ)~w%p?#D9VK0KK1{q-5Q92sxx4d^R!IGDxW z2xq+h@!SOK-2@zO1JEC1$~)#nb?No82PBX3O(xTkGk^qa_qS> P>aIq&?tk&C+hhL&2;Gu6 diff --git a/resources/EngineResources/shaders/scene_translucent_fragment.glsl b/resources/EngineResources/shaders/scene_translucent_fragment.glsl index f909b2e..847195f 100644 --- a/resources/EngineResources/shaders/scene_translucent_fragment.glsl +++ b/resources/EngineResources/shaders/scene_translucent_fragment.glsl @@ -10,18 +10,26 @@ layout(location = 4) in vec2 inTextCoords; layout(location = 0) out vec4 outAlbedo; -struct Material{ - vec4 diffuseColor; - uint hasTexture; - uint textureIdx; - uint hasNormalMap; - uint normalMapIdx; - uint hasRoughMap; - uint roughMapIdx; - float roughnessFactor; - float metallicFactor; +struct Material { + vec4 diffuseColor; //16 + uint hasTexture; //20 + uint textureIdx; //24 + uint hasNormalMap; //28 + uint normalMapIdx; //32 + uint hasRoughMap; //36 + uint roughMapIdx; //40 + float roughnessFactor; //44 + float metallicFactor; //48 + vec4 emissiveColour; //64 + uint hasEmissiveMap; //68 + uint emissiveMapIdx; //72 + uint hasTranslucencyMap; //76 + uint translucencyMapIdx; //80 + float translucencyFactor; //84 + uint hasOpacityMap; //88 + uint OpacityMapIdx; //92 + float OpacityFactor; //96 }; - layout(set = 2, binding = 0) readonly buffer MaterialUniform{ Material materials[]; } matUniform; @@ -37,9 +45,19 @@ void main() Material material = matUniform.materials[push_constants.materialIdx]; if(material.hasTexture == 1){ vec4 texColor = texture(textSampler[material.textureIdx],inTextCoords); - if(texColor.a >= 0.9){discard;} outAlbedo = texColor; } else{ outAlbedo = material.diffuseColor; } + vec4 Opacity = vec4(outAlbedo.a,outAlbedo.a,outAlbedo.a,1); + if(material.OpacityFactor != 1) Opacity = vec4(material.OpacityFactor, material.OpacityFactor, material.OpacityFactor, 1); + if(material.hasOpacityMap > 0 && material.OpacityMapIdx < MAX_TEXTURES){ + Opacity = texture(textSampler[material.OpacityMapIdx], inTextCoords); + } + + float opacityf = Opacity.x + Opacity.y + Opacity.z; + opacityf = opacityf/3; + if(opacityf >= 0.9){discard;} + + outAlbedo = vec4(outAlbedo.rgb, opacityf); } \ No newline at end of file diff --git a/resources/EngineResources/shaders/scene_translucent_fragment.glsl.spv b/resources/EngineResources/shaders/scene_translucent_fragment.glsl.spv index 382a9ada80251c876e57f21e2fa8137132f94aa8..53ea5ee287daf2761f52216b85d629f0666e7ac2 100644 GIT binary patch literal 6084 zcma);`IlT(5y#(TmJA>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`aQaQ0w85QfjqN1K=iYEub?D2)|FT%YM==HmkJ_+l>ynxf|_8d&~QpI*oSO?zAenZpN0A9!gkk=k(C$c*%tHJfob( zoOE`FpY^Dh7C79(4+}w$)5RenJ{U7m zCml^XqtS?y5@w@g(nbcg{!Vn&nuzG5j6m{nr93A)VWOt!ypB!v&Wja=<9Zg6Gs3oz z62BnJJ=&!BMOhAd#^bck;eKwqE(uBORfS zWC=y*t#H%@#td>Q%c<;4wLp~ZS+fgA}yD6a4)~YOrw$N7uG}^-V zi>=8o2wpL_)-7@Lk8Z7=F?U1|`9J(t0zVP 0 && material.OpacityMapIdx < MAX_TEXTURES){ + Opacity = texture(textSampler[material.OpacityMapIdx], inTextCoords); + } + outOpacity = Opacity; + + float opacityf = Opacity.x + Opacity.y + Opacity.z; + opacityf = opacityf/3; + + outAlbedo = vec4(outAlbedo.rgb, opacityf); if(outAlbedo.a >= 0.75 || outAlbedo.a < 0.05f) discard; @@ -83,6 +107,18 @@ void main() metallicFactor = material.metallicFactor; } + vec4 emissive = material.emissiveColour; + if (material.hasEmissiveMap > 0 && material.emissiveMapIdx < MAX_TEXTURES) { + emissive = texture(textSampler[material.emissiveMapIdx], inTextCoords); + } + outEmissive = emissive; + + vec4 Translucency = vec4(material.translucencyFactor,material.translucencyFactor,material.translucencyFactor,1); + if(material.hasTranslucencyMap > 0 && material.translucencyMapIdx < MAX_TEXTURES){ + Translucency = texture(textSampler[material.translucencyMapIdx], inTextCoords); + } + outTranslucency = Translucency; + outPBR = vec4(ao, roughnessFactor, metallicFactor, outAlbedo.a); } \ 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 index e6305d2c4dd4e8bbfcc529fbb434f61797381790..960f751111792b864973650e7bf939b86a086f2b 100644 GIT binary patch literal 10496 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 ITP%PW0MFVE4*&oF delta 47 ycmeyu+QQ1q%%sfDz`)4B&A`hbvXNJqX>tuyfQTIfGXp0B1A{OS{{_lg05JfbxCO`n diff --git a/resources/EngineResources/shaders/skybox_vertex.glsl b/resources/EngineResources/shaders/skybox_vertex.glsl index 1a980ef..e5f4f14 100644 --- a/resources/EngineResources/shaders/skybox_vertex.glsl +++ b/resources/EngineResources/shaders/skybox_vertex.glsl @@ -14,5 +14,5 @@ void main() { outTexCoords = inPosition; mat4 skyView = mat4(mat3(uboView.view)); vec4 pos = uboProj.proj * skyView * vec4(inPosition, 1.0); - gl_Position = vec4(pos.xy, pos.w, pos.w); + gl_Position = vec4(pos.xy, 0.0, pos.w); } diff --git a/resources/EngineResources/shaders/skybox_vertex.glsl.spv b/resources/EngineResources/shaders/skybox_vertex.glsl.spv index ad6646e9dd034c88aa0ea11f613161bac2e78398..bf0a2ce9176e5839dfbcdf450a2b80e38da27ee8 100644 GIT binary patch delta 138 zcmdlXJVlt7nMs+Qfq{{Mn}L@hXd|ybD`UXsSk}|bIe`qU3~USx48B0@0mL8x6Y~SI zL1K(R9KgU1)XKo%55yp~AUP!<_5or?pcw%`IuM9mfmjrX?HHKBe31ITKocy07yu1_ B48;Hd delta 160 zcmbOtyhE6mnMs+Qfq{{Mn}L@hWFxOXD`U{+Sk}|bx{eI23||Y|FsH zzy_rKfEXkm2vh^&`%gCH6b=XgvOIv85r_jA*ntLuQ~+hcd attachments = new ArrayList<>(sceneRender.GetMRTAttachments().GetColourAttachments()); + attachments.add(shadowRender.getShadowAttachment()); + lightRenderer.updateAttachmentDescriptors(RendererContext, attachments); + + RendererContext.GetDevice().waitIdle(); + ShadowRenderer.AllowShadowRendering(true); + } + private void resize(EngineInstance engineInstance){ Window window = engineInstance.window(); if(window.getWidth() == 0 && window.getHeight() == 0){ diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Logic/EngineConfig.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Logic/EngineConfig.java index f0dd0ff..19c2a68 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Logic/EngineConfig.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Logic/EngineConfig.java @@ -1,6 +1,7 @@ package net.halbear.Terrain4J.EngineCore.Logic; +import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime; import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DisplayToScreen.DeferredSceneRender; import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DisplayToScreen.ForwardSceneRender; import net.halbear.Terrain4J.EngineCore.ServerNetworking.ClientSideNetworkUtils; @@ -92,6 +93,16 @@ public class EngineConfig { public float SoundVolume = 0.0f; public float WeaponVolume = 0.0f; public float AmbientVolume = 0.0f; + public float MaxShadowDistance = 16384.0f; + + + public float MaxShadowDistance(){return MaxShadowDistance;} + public void MaxShadowDistance(float newDistance){ MaxShadowDistance = newDistance;} + + public boolean RenderShadows = true; + + public boolean RenderShadows() {return RenderShadows;} + public void RenderShadows(boolean renderShadows) {RenderShadows = renderShadows;} public float PlayerOnline = 1.0f; @@ -158,7 +169,12 @@ public class EngineConfig { public String GetLoadingScreenImageLocation(){return LoadingScreenLocation;} public void SetLoadingScreenImageLocation(String location){this.LoadingScreenLocation = location;} public int GetMaxVulkanCrashes(){return MaxVulkanCrashesAllowed;} - public void SetShadowMapSize(int ShadowSize){this.ShadowMapSize = ShadowSize;} + public void SetShadowMapSize(int ShadowSize){ + this.ShadowMapSize = ShadowSize; + if (PrimaryRuntime.GetRenderThread() != null && PrimaryRuntime.GetRenderThread().GetRenderer() != null) { + PrimaryRuntime.GetRenderThread().GetRenderer().RequestRebuildShadows(); + } + } public int GetShadowMapSize(){return ShadowMapSize;} public void SetRenderer(Renderer renderer){this.renderer = renderer;} public boolean DeferredRendering(){return renderer == Renderer.Deferred;} @@ -320,9 +336,11 @@ public class EngineConfig { FOV = (float)(DegToRad * Float.parseFloat(EngineConfigVar.getOrDefault("field_of_view", 60.0f).toString())); zNearPlane = (Float.parseFloat(EngineConfigVar.getOrDefault("z_near_plane", 1.0f).toString())); zFarPlane = (Float.parseFloat(EngineConfigVar.getOrDefault("z_far_plane", 100.0f).toString())); + MaxShadowDistance = (Float.parseFloat(EngineConfigVar.getOrDefault("max_shadow_distance", 16384.0f).toString())); AAValue = (Integer.parseInt(EngineConfigVar.getOrDefault("anti_alias_mode", 1).toString())); renderer = Integer.parseInt(EngineConfigVar.getOrDefault("Renderer", 1).toString()) == 0 ? Renderer.Forward: Renderer.Deferred; - ShadowMapSize = Integer.parseInt(EngineConfigVar.getOrDefault("ShadowMapSize", 4096).toString()); + ShadowMapSize = Integer.parseInt(EngineConfigVar.getOrDefault("ShadowMapSize", 2048).toString()); + RenderShadows = Boolean.parseBoolean(EngineConfigVar.getOrDefault("RenderShadows", true).toString()); MaxVulkanCrashesAllowed = Integer.parseInt(EngineConfigVar.getOrDefault("MaxAllowedVulkanCrashes", 10).toString()); ServerPort = Integer.parseInt(EngineConfigVar.getOrDefault("server_port", 25565).toString()); CompatibilityMode = Boolean.parseBoolean(EngineConfigVar.getOrDefault("compatibility_mode", false).toString()); @@ -377,6 +395,7 @@ public class EngineConfig { EngineConfigVar.setProperty("ShaderRecompiling","true"); EngineConfigVar.setProperty("throttle_accuracy","100000"); EngineConfigVar.setProperty("throttle_on_unfocus","true"); + EngineConfigVar.setProperty("RenderShadows","true"); EngineConfigVar.setProperty("field_of_view","60"); EngineConfigVar.setProperty("z_near_plane","1"); EngineConfigVar.setProperty("z_far_plane","100"); @@ -384,6 +403,7 @@ public class EngineConfig { EngineConfigVar.setProperty("DefaultTexturePath",DefaultTexturePath); EngineConfigVar.setProperty("MaxDescriptors","1000"); EngineConfigVar.setProperty("anti_alias_mode","1"); + EngineConfigVar.setProperty("max_shadow_distance","16384"); EngineConfigVar.setProperty("server","false"); EngineConfigVar.setProperty("ShadowMapSize","4096"); EngineConfigVar.setProperty("LoadingScreenLocation",LoadingScreenLocation); diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Logic/Physics/RigidBody/SeparatingAxisTheoremTester.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Logic/Physics/RigidBody/SeparatingAxisTheoremTester.java index 8df545d..539fdc3 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Logic/Physics/RigidBody/SeparatingAxisTheoremTester.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Logic/Physics/RigidBody/SeparatingAxisTheoremTester.java @@ -15,7 +15,6 @@ overlap (least "penetration" or intersection amount) is the collision normal, face contacts are "resolved into a full contact manifold"(whatever that means) by clipping the incident face against the side planes of the reference face, this is what gives stable multipoint contact (e.g. a box resting flat on a floor gets 4 contact points, not 1) -I'm not gonna lie, I asked Google AI Overview for help on this one, and it did NOT help, but it *did* provide some pretty useful information on how to do it For a good explanation, visit this https://dyn4j.org/2010/01/sat/*/ public class SeparatingAxisTheoremTester { diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Logic/Physics/WorldPhysicsManager.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Logic/Physics/WorldPhysicsManager.java index ef247a4..816cf20 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Logic/Physics/WorldPhysicsManager.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Logic/Physics/WorldPhysicsManager.java @@ -82,6 +82,7 @@ public class WorldPhysicsManager { SweepForTunneling(); ResetGroundedFlags(); ResolveAllCollisions(); + SyncRigidBodiesToActors(); Accumulator -= FixedTimeStep; stepsRun++; } @@ -117,23 +118,6 @@ public class WorldPhysicsManager { Set testedPairs = new HashSet<>(); -// SpatialHashGrid.Cells().forEach((key, bucket)->{ -// int size = bucket.size(); -// for (int i = 0; i < size; i++) { -// RigidBody a = RigidBody.RigidBodyRegister.get(bucket.get(i)); -// if (a == null) continue; -// for (int j = i + 1; j < size; j++) { -// RigidBody b = RigidBody.RigidBodyRegister.get(bucket.get(j)); -// if (b == null || a == b) continue; -// TryResolve(a, b, worldBounds, testedPairs); -// } -// StaticSpatialHashGrid.GetFromKey(key).forEach((id)->{ -// RigidBody b = RigidBody.RigidBodyRegister.get(id); -// if (b == null || a == b) return; -// TryResolve(a, b, worldBounds, testedPairs); -// }); -// } -// }); for (List bucket : SpatialHashGrid.Buckets()) { int size = bucket.size(); for (int i = 0; i < size; i++) { @@ -152,6 +136,7 @@ public class WorldPhysicsManager { TryResolve(dyn, stat, worldBounds, testedPairs); } } + } private static boolean IsClientRemoteNetworkBody(RigidBody body) { 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 4573150..4053f10 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 @@ -32,8 +32,7 @@ import static org.lwjgl.assimp.Assimp.*; public class ModelCompiler { private static final Pattern EMBED_TEXT_ID = Pattern.compile("\\*([0-9)]+)"); private static final int FLAGS = aiProcess_GenSmoothNormals | aiProcess_JoinIdenticalVertices - | aiProcess_Triangulate | aiProcess_FixInfacingNormals | aiProcess_CalcTangentSpace - | aiProcess_PreTransformVertices; + | aiProcess_Triangulate | aiProcess_CalcTangentSpace | aiProcess_PreTransformVertices; @Parameter(names = "-model", description = "Model Path", required = true) private String ModelPath; @@ -108,14 +107,23 @@ public class ModelCompiler { public static MaterialData ProcessMaterial(AIScene aiScene, AIMaterial aiMaterial, String ModelName, String BaseDirectory, int Position) throws IOException{ Vector4f diffuse = new Vector4f(); AIColor4D colour = AIColor4D.create(); + AIColor4D emissive_colour = AIColor4D.create(); int Result = aiGetMaterialColor(aiMaterial, AI_MATKEY_COLOR_DIFFUSE, aiTextureType_NONE, 0, colour); if(Result == aiReturn_SUCCESS){ diffuse.set(colour.r(), colour.g(), colour.b(), colour.a()); } + Vector4f emissiveColour = new Vector4f(1,1,1,0); + Result = aiGetMaterialColor(aiMaterial, AI_MATKEY_COLOR_EMISSIVE, aiTextureType_NONE, 0, emissive_colour); + if(Result == aiReturn_SUCCESS){ + emissiveColour.set(emissive_colour.r(), emissive_colour.g(), emissive_colour.b(), emissive_colour.a()); + } String DiffuseTexture = ProcessTexture(aiScene,aiMaterial,BaseDirectory,aiTextureType_DIFFUSE); String NormalTexture = ProcessTexture(aiScene,aiMaterial,BaseDirectory,aiTextureType_NORMALS); + String EmissiveTexture = ProcessTexture(aiScene,aiMaterial,BaseDirectory,aiTextureType_EMISSIVE); + String TranslucencyTexture = ProcessTexture(aiScene,aiMaterial,BaseDirectory,aiTextureType_TRANSMISSION); String MetallicRoughTexture = ProcessTexture(aiScene, aiMaterial, BaseDirectory, AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLICROUGHNESS_TEXTURE); + String OpacityTexture = ProcessTexture(aiScene,aiMaterial,BaseDirectory,aiTextureType_OPACITY); float[] MetallicArray = new float[]{0.0f}; int[] MaxPointer = new int[]{1}; @@ -130,8 +138,26 @@ public class ModelCompiler { RoughnessArray = new float[]{0.0f}; } + float[] EmissiveArray = new float[]{0.0f}; + Result = aiGetMaterialFloatArray(aiMaterial,AI_MATKEY_EMISSIVE_INTENSITY,aiTextureType_NONE,0,EmissiveArray,MaxPointer); + if(Result == aiReturn_SUCCESS){ + emissiveColour.set(emissiveColour.x,emissiveColour.y,emissiveColour.z,EmissiveArray[0]); + } - return new MaterialData(ModelName + "-mat-" + Position,DiffuseTexture,NormalTexture, MetallicRoughTexture,diffuse,RoughnessArray[0],MetallicArray[0]); + float[] TranslucencyArray = new float[]{0.0f}; + Result = aiGetMaterialFloatArray(aiMaterial,AI_MATKEY_TRANSMISSION_FACTOR,aiTextureType_NONE,0,TranslucencyArray,MaxPointer); + if(Result != aiReturn_SUCCESS){ + TranslucencyArray = new float[]{0.0f}; + } + + float[] OpacityArray = new float[]{0.0f}; + + Result = aiGetMaterialFloatArray(aiMaterial,AI_MATKEY_OPACITY,aiTextureType_NONE,0,OpacityArray,MaxPointer); + if(Result != aiReturn_SUCCESS){ + OpacityArray = new float[]{0.0f}; + } + + return new MaterialData(ModelName + "-mat-" + Position,DiffuseTexture,NormalTexture, MetallicRoughTexture,diffuse,RoughnessArray[0],MetallicArray[0], EmissiveTexture,emissiveColour, TranslucencyTexture, TranslucencyArray[0], OpacityTexture, OpacityArray[0]); } public static MeshData ProcessMesh(AIMesh aiMesh, List MaterialList, int MeshPosition, ModelBinaryData BinaryData) throws IOException { 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 ed6ca3a..012c25d 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Main/GameCore.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Main/GameCore.java @@ -99,12 +99,12 @@ public class GameCore implements GameLogic { Scene scene = (Scene) engineInstance.scene(); List models = new ArrayList<>(); List materials = new ArrayList<>(); -// ModelData SponzaData = ModelLoader.LoadModel("resources/models/Cafe/exterior.json"); -// List SponzaMaterial = ModelLoader.LoadMaterials("resources/models/Cafe/exterior_mat.json"); -// ModelData SponzaData1 = ModelLoader.LoadModel("resources/models/Cafe/interior.json"); -// 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)); + ModelData SponzaData = ModelLoader.LoadModel("resources/models/Cafe/exterior.json"); + List SponzaMaterial = ModelLoader.LoadMaterials("resources/models/Cafe/exterior_mat.json"); + ModelData SponzaData1 = ModelLoader.LoadModel("resources/models/Cafe/interior.json"); + 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)); // ModelData treeModel = ModelLoader.LoadModel("resources/models/tree/tree.json"); // models.add(treeModel); // Actor3D treeEntity = new Actor3D("treeEntity", treeModel.ID(), new Vector3f(0.0f, 0.0f, 0.0f)); @@ -113,7 +113,7 @@ public class GameCore implements GameLogic { // materials.addAll(ModelLoader.LoadMaterials("resources/models/tree/tree_mat.json")); // ModelData treeModel = ModelLoader.LoadModel("resources/models/Forest/forest.json"); // models.add(treeModel); -// Actor3D treeEntity = new Actor3D("treeEntity", treeModel.ID(), new Vector3f(0.0f, 0.0f, 0.0f)); +// Actor3D treeEntity = new Actor3D("treeEntity", treeModel.ID(), new Vector3f(0.0f, -100.0f, 0.0f)); // treeEntity.SetScale(10f); // scene.AddActor(treeEntity); // materials.addAll(ModelLoader.LoadMaterials("resources/models/Forest/forest_mat.json")); @@ -158,10 +158,10 @@ public class GameCore implements GameLogic { } boolean createOfflinePlayer = !PrimaryRuntime.IsServer && !ClientSideNetworkUtils.Connected; -// materials.addAll(SponzaMaterial); -// materials.addAll(SponzaMaterial1); -// models.add(SponzaData); -// models.add(SponzaData1); + materials.addAll(SponzaMaterial); + materials.addAll(SponzaMaterial1); + models.add(SponzaData); + models.add(SponzaData1); materials.addAll(MelonaMat); materials.addAll(CollisionVisualisationMat); materials.addAll(MelonaMaterial); @@ -191,49 +191,68 @@ public class GameCore implements GameLogic { } scene.GetLightingManager().GetAmbientLightColour().set(1.0f, 0.9f, 0.75f); - scene.GetLightingManager().SetAmbientLightIntensity(0.3f); -// scene.GetLightingManager().GetAmbientLightColour().set(0.3f, 0.35f, 0.5f); -// scene.GetLightingManager().SetAmbientLightIntensity(0.075f); -// - SkyLight = new Light(new Vector3f(1.5f, 1.20f, 1.0f),new Vector3f(0.0f, -1.0f, 0.3f), true, 2.00f); -// SkyLight = new Light(new Vector3f(0.25f, 1.0f, 1.5f),new Vector3f(0.0f, -1.0f, 0.0f), true, 6.0f); + scene.GetLightingManager().SetAmbientLightIntensity(0.15f); + scene.GetLightingManager().GetAmbientLightColour().set(0.3f, 0.35f, 0.5f); + scene.GetLightingManager().SetAmbientLightIntensity(0.05f); + + SkyLight = new Light(new Vector3f(1.5f, 1.20f, 1.0f),new Vector3f(0.0f, -1.0f, 0.3f), true, 4.00f); + SkyLight = new Light(new Vector3f(0.25f, 0.75f, 1.3f),new Vector3f(0.0f, -1.0f, 0.0f), true, 4.0f); SkyLight.SetType(Light.LightType.Directional); List lights = new ArrayList<>(); -// lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-433, 445f, -424f).div(10.0f),false,3000.0f+ (float)(Math.random() * 100.0))); -// lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-210, 445f, 460f).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f))); -// lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-966, 445f, 204f).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f))); -// lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-176, 445f, 1000f).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f))); -// lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(777, 445f, 858).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f))); -// lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(376, 445f, -2136).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f))); -// lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,2.0f),new Vector3f(2163, 445f, 1880).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f))); -// lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(3334, 445f, 2405).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f))); -// lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(3509, 445f, 1825).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f))); -// lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(3877, 445f, 3378).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f))); -// lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(4925, 445f, 3430).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f))); -// lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-2083, 445f, -1826).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f))); -// -// lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(2076, 410, 1272).div(10.0f),false,100.0f)); -// lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(2446, 465, 2303).div(10.0f),false,100.0f)); -// lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-842, 410, -1141).div(10.0f),false,100.0f)); -// lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-207, 410, -1830).div(10.0f),false,100.0f)); -// lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(899, 460, -2015).div(10.0f),false,100.0f)); -// lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(1775, 460, -3448).div(10.0f),false,100.0f)); -// lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(1800, 460, -4154).div(10.0f),false,1000.0f)); -// lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-1727, 410, -387).div(10.0f),false,100.0f)); -// lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-1198, 410, -964).div(10.0f),false,100.0f)); -// lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-1778, 410, -1502).div(10.0f),false,100.0f)); -// lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-2692, 333, -2109).div(10.0f),false,100.0f)); -// lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-2849, 333, -1724).div(10.0f),false,100.0f)); -// lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-2019, 410, -729).div(10.0f),false,100.0f)); -// lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-1727, 410, -389).div(10.0f),false,100.0f)); -// lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-1337, 410, 122).div(10.0f),false,100.0f)); -// -// -// lights.add(new Light(new Vector3f(0.75f,2.0f,0.75f),new Vector3f(1086, 425, -3375).div(10.0f),false,500.0f)); + lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-433, 445f, -424f).div(10.0f),false,3000.0f+ (float)(Math.random() * 100.0))); + lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-210, 445f, 460f).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f))); + lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-966, 445f, 204f).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f))); + lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-176, 445f, 1000f).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f))); + lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(777, 445f, 858).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f))); + lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(376, 445f, -2136).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f))); + lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,2.0f),new Vector3f(2163, 445f, 1880).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f))); + lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(3334, 445f, 2405).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f))); + lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(3509, 445f, 1825).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f))); + lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(3877, 445f, 3378).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f))); + lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(4925, 445f, 3430).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f))); + lights.add(new Light(new Vector3f(1.9f+ (float)Math.random(),1.5f,1.0f),new Vector3f(-2083, 445f, -1826).div(10.0f),false,700.0f + (float)(Math.random() * 150.0f))); - //lights.add(new Light(new Vector3f(3.0f,2.25f,0.0f),new Vector3f(350.0f, 1525.0f, -420.0f),false,4000.0f)); - //lights.add(new Light(new Vector3f(3.0f,2.25f,0.0f),new Vector3f(400.0f, 1570.0f, -350.0f),false,1000.0f)); + lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(2076, 410, 1272).div(10.0f),false,100.0f)); + lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(2446, 465, 2303).div(10.0f),false,100.0f)); + lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-842, 410, -1141).div(10.0f),false,100.0f)); + lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-207, 410, -1830).div(10.0f),false,100.0f)); + lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(899, 460, -2015).div(10.0f),false,100.0f)); + lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(1775, 460, -3448).div(10.0f),false,100.0f)); + lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(1800, 460, -4154).div(10.0f),false,1000.0f)); + lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-1727, 410, -387).div(10.0f),false,100.0f)); + lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-1198, 410, -964).div(10.0f),false,100.0f)); + lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-1778, 410, -1502).div(10.0f),false,100.0f)); + lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-2692, 333, -2109).div(10.0f),false,100.0f)); + lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-2849, 333, -1724).div(10.0f),false,100.0f)); + lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-2019, 410, -729).div(10.0f),false,100.0f)); + lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-1727, 410, -389).div(10.0f),false,100.0f)); + lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(-1337, 410, 122).div(10.0f),false,100.0f)); + + lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(615.8f, 305.5f, -904.1f).div(10.0f),false,200.0f)); + lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(425.4f, 305.5f, -541.0f).div(10.0f),false,200.0f)); + lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(501.4f, 305.5f, -102.7f).div(10.0f),false,200.0f)); + lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(803.0f, 305.5f, 50.2f).div(10.0f),false,200.0f)); + + lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(720.4f, 261.6f, -329.2f).div(10.0f),false,75.0f)); + lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(879.4f,261.6f,-246.3f).div(10.0f),false,75.0f)); + lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(1037.7f,261.6f,-155.0f).div(10.0f),false,75.0f)); + lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(663.4f,261.6f,-468.9f).div(10.0f),false,75.0f)); + + lights.add(new Light(new Vector3f(1.9f + (float)Math.random(),1.5f,1.0f),new Vector3f(772.3f,243.7f,-513.7f).div(10.0f),false,50.0f)); + + lights.add(new Light(new Vector3f(1.2f + (float)Math.random(),1.1f,1.0f),new Vector3f(193.1f,260.7f,-859.3f).div(10.0f),false,50.0f)); + lights.add(new Light(new Vector3f(1.2f + (float)Math.random(),1.1f,1.0f),new Vector3f(51.0f,260.7f,-603.0f).div(10.0f),false,50.0f)); + lights.add(new Light(new Vector3f(1.2f + (float)Math.random(),1.1f,1.0f),new Vector3f(-95.0f,260.7f,-334.2f).div(10.0f),false,50.0f)); + lights.add(new Light(new Vector3f(1.2f + (float)Math.random(),1.1f,1.0f),new Vector3f(41.5f,260.7f,5.7f).div(10.0f),false,50.0f)); + lights.add(new Light(new Vector3f(1.2f + (float)Math.random(),1.1f,1.0f),new Vector3f(335.8f,260.7f,144.6f).div(10.0f),false,50.0f)); + lights.add(new Light(new Vector3f(1.2f + (float)Math.random(),1.1f,1.0f),new Vector3f(616.9f,260.7f,255.4f).div(10.0f),false,50.0f)); + + + lights.add(new Light(new Vector3f(0.75f,2.0f,0.75f),new Vector3f(1086, 425, -3375).div(10.0f),false,500.0f)); + +// lights.add(new Light(new Vector3f(3.0f,2.25f,0.0f),new Vector3f(350.0f, 1500.0f, -420.0f),false,10000.0f)); +// lights.add(new Light(new Vector3f(3.0f,2.25f,0.0f),new Vector3f(400.0f, 1550.0f, -350.0f),false,10000.0f)); lights.add(SkyLight); ILight[] lightArr = new ILight[lights.size()]; @@ -246,27 +265,29 @@ public class GameCore implements GameLogic { } //if(PrimaryRuntime.IsServer) { permutation.GeneratePermutationArray(5783904701859L); - for(int x = -1; x < 2; x++){ - for(int y = -1; y < 2; y++){ - GenerateChunk(new Vector3i(x, 0, y), 16); - - } - } - for(int i = 0; i < 20; i++){ - SpawnNewActor(engineInstance, new Vector3f(-5 + (float)Math.random() * 10,10 + (float)Math.random() * 10, -5 + (float)Math.random() * 10), new Vector3f(0, 0, 0), new Vector3f(1, 1, 1)); - } +// for(int x = -1; x < 2; x++){ +// for(int y = -1; y < 2; y++){ +// GenerateChunk(new Vector3i(x, 0, y), 16); +// +// } +// } +// for(int i = 0; i < 20; i++){ +// SpawnNewActor(engineInstance, new Vector3f(-5 + (float)Math.random() * 10,10 + (float)Math.random() * 10, -5 + (float)Math.random() * 10), new Vector3f(0, 0, 0), new Vector3f(1, 1, 1)); +// } //} Settings.textBuffer.set(ClientSideNetworkUtils.ServerIP); Settings.UsernameBuffer.set("Player"); return new InitData(models,materials,guiTextures); } public static float lightAngle = 70; + public static float lightAnglex = 0; private void updateDirLight() { - float zValue = (float) Math.cos(Math.toRadians(lightAngle)); + float zValue = (float) Math.cos(Math.toRadians(lightAngle)) + (float) Math.cos(Math.toRadians(lightAnglex)); float yValue = (float) Math.sin(Math.toRadians(lightAngle)); + float xValue = (float) Math.sin(Math.toRadians(lightAnglex)); Vector3f lightDirection = SkyLight.GetPosition(); - lightDirection.x = 0; + lightDirection.x = xValue; lightDirection.y = yValue; lightDirection.z = zValue; lightDirection.normalize(); @@ -502,6 +523,8 @@ public class GameCore implements GameLogic { } } + int GUI_MODE = 1; + @Override public void Input(EngineInstance engineInstance, long FrameDiffNanoSeconds) { if(PrimaryRuntime.IsServer || RenderThread.Headless) return; @@ -510,7 +533,7 @@ public class GameCore implements GameLogic { scene.GlobalInput(engineInstance,FrameDiffNanoSeconds, null, MOVEMENT_SPEED,this); KeyboardInput input = engineInstance.window().getKeyboardInput(); if(input.keySinglePress(GLFW_KEY_F3)){ - Scene.GUI_MODE = (Scene.GUI_MODE + 1) % 2; + GUI_MODE = (GUI_MODE + 1) % 3; } if(input.keyPressed(GLFW_KEY_UP)){ lightAngle = (lightAngle + 0.5f) % 360; @@ -520,6 +543,14 @@ public class GameCore implements GameLogic { lightAngle = (lightAngle - 0.5f) % 360; updateDirLight(); } + if(input.keyPressed(GLFW_KEY_RIGHT)){ + lightAnglex = (lightAnglex + 0.5f) % 360; + updateDirLight(); + } + if(input.keyPressed(GLFW_KEY_LEFT)){ + lightAnglex = (lightAnglex - 0.5f) % 360; + updateDirLight(); + } if (input.keySinglePress(GLFW_KEY_ESCAPE)) { StartMenuActive = !StartMenuActive; StartMenu.GameStarted = StartMenuActive; @@ -587,7 +618,7 @@ public class GameCore implements GameLogic { StartMenuActive = false; } } else { - engineInstance.scene().RenderGUIs(engineInstance, frameTimeNS, this); + if(GUI_MODE == 1)engineInstance.scene().RenderGUIs(engineInstance, frameTimeNS, this); if (ChangeGraphicsSettings) { ImGuiViewport viewport = ImGui.getMainViewport(); float CenterX = viewport.getWorkPosX() + viewport.getWorkSizeX() / 2.0f; 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 17cf2f0..c71afb8 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 @@ -6,6 +6,7 @@ import imgui.flag.ImGuiWindowFlags; import imgui.type.ImFloat; import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig; import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance; +import net.halbear.Terrain4J.EngineCore.Main.AudioInstance; import net.halbear.Terrain4J.EngineCore.Main.GameCore; import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime; import net.halbear.Terrain4J.EngineCore.Main.Scene.GUIOverlay; @@ -15,6 +16,14 @@ import org.tinylog.Logger; public class PerformanceOverlay implements GUIOverlay { private final ImFloat GammaValue = new ImFloat(0.8545f); + public int[] ShadowSize = new int[]{4096}; + public int[] ShadowDistance = new int[]{1000}; + + public PerformanceOverlay(){ + ShadowSize[0] = EngineConfig.getInstance().GetShadowMapSize(); + ShadowDistance[0] = (int)EngineConfig.getInstance().MaxShadowDistance(); + } + @Override public void RenderGUI(EngineInstance engineInstance, long frameTimeNS, GameCore parent) { int windowFlags = ImGuiWindowFlags.NoDecoration @@ -48,35 +57,111 @@ public class PerformanceOverlay implements GUIOverlay { EngineConfig.getInstance().SetRenderingAPI(EngineConfig.RenderAPI.OpenGL); } ImGui.text("Presets:"); + float ZFarPlane = Math.max(EngineConfig.getInstance().GetZFarPlane(), EngineConfig.getInstance().GetZNearPlane()); if(ImGui.button("Lowest")){ parent.ChangeGraphicsSettings = true; parent.CoolDown = 2000; parent.NextAAMode = (0); ForwardSceneRender.SetDualPassRendering(false); DeferredSceneRender.SetDualPassRendering(false); + EngineConfig.getInstance().SetRenderer(EngineConfig.Renderer.Forward); + EngineConfig.getInstance().RenderShadows(false); EngineConfig.getInstance().SetAlphaToCoverage(false); + EngineConfig.getInstance().SetShadowMapSize(1); + EngineConfig.getInstance().MaxShadowDistance(64); + ShadowDistance[0] = (int)Math.clamp(EngineConfig.getInstance().MaxShadowDistance(), 64, (int)(ZFarPlane * 1.5)); + ShadowSize[0] = (int)Math.clamp((EngineConfig.getInstance().GetShadowMapSize() / 16) * 16, 16, 8192); + if(engineInstance.window().GetLinkedApi() == EngineConfig.RenderAPI.Vulkan)PrimaryRuntime.GetRenderThread().GetRenderer().GetSceneRender().RebuildPipelines(PrimaryRuntime.GetRenderThread().GetRenderer().GetVulkanContext()); + } + ImGui.sameLine(); + if(ImGui.button("Low")){ + parent.ChangeGraphicsSettings = true; + parent.CoolDown = 2000; + parent.NextAAMode = (0); + ForwardSceneRender.SetDualPassRendering(false); + DeferredSceneRender.SetDualPassRendering(false); + EngineConfig.getInstance().SetRenderer(EngineConfig.Renderer.Deferred); + EngineConfig.getInstance().RenderShadows(true); + EngineConfig.getInstance().SetAlphaToCoverage(false); + EngineConfig.getInstance().SetShadowMapSize(256); + EngineConfig.getInstance().MaxShadowDistance((int)(ZFarPlane/4)); + ShadowDistance[0] = (int)Math.clamp(EngineConfig.getInstance().MaxShadowDistance(), 64, (int)(ZFarPlane * 1.5)); + ShadowSize[0] = (int)Math.clamp((EngineConfig.getInstance().GetShadowMapSize() / 16) * 16, 16, 8192); if(engineInstance.window().GetLinkedApi() == EngineConfig.RenderAPI.Vulkan)PrimaryRuntime.GetRenderThread().GetRenderer().GetSceneRender().RebuildPipelines(PrimaryRuntime.GetRenderThread().GetRenderer().GetVulkanContext()); } ImGui.sameLine(); if(ImGui.button("Medium")){ parent.ChangeGraphicsSettings = true; parent.CoolDown = 2000; - parent.NextAAMode = (1); + parent.NextAAMode = (0); ForwardSceneRender.SetDualPassRendering(true); + EngineConfig.getInstance().SetRenderer(EngineConfig.Renderer.Deferred); DeferredSceneRender.SetDualPassRendering(true); + EngineConfig.getInstance().RenderShadows(true); EngineConfig.getInstance().SetAlphaToCoverage(true); + EngineConfig.getInstance().SetShadowMapSize(1024); + EngineConfig.getInstance().MaxShadowDistance((int)(ZFarPlane/2)); + ShadowDistance[0] = (int)Math.clamp(EngineConfig.getInstance().MaxShadowDistance(), 64, (int)(ZFarPlane * 1.5)); + ShadowSize[0] = (int)Math.clamp((EngineConfig.getInstance().GetShadowMapSize() / 16) * 16, 16, 8192); if(engineInstance.window().GetLinkedApi() == EngineConfig.RenderAPI.Vulkan)PrimaryRuntime.GetRenderThread().GetRenderer().GetSceneRender().RebuildPipelines(PrimaryRuntime.GetRenderThread().GetRenderer().GetVulkanContext()); } ImGui.sameLine(); - if(ImGui.button("Highest")){ + if(ImGui.button("High")){ parent.ChangeGraphicsSettings = true; parent.CoolDown = 2000; - parent.NextAAMode = (4); + parent.NextAAMode = (0); ForwardSceneRender.SetDualPassRendering(true); + EngineConfig.getInstance().SetRenderer(EngineConfig.Renderer.Deferred); DeferredSceneRender.SetDualPassRendering(true); EngineConfig.getInstance().SetAlphaToCoverage(false); + EngineConfig.getInstance().RenderShadows(true); + EngineConfig.getInstance().SetShadowMapSize(4096); + EngineConfig.getInstance().MaxShadowDistance((int)(ZFarPlane)); + ShadowDistance[0] = (int)Math.clamp(EngineConfig.getInstance().MaxShadowDistance(), 64, (int)(ZFarPlane * 1.5)); + ShadowSize[0] = (int)Math.clamp((EngineConfig.getInstance().GetShadowMapSize() / 16) * 16, 16, 8192); if(engineInstance.window().GetLinkedApi() == EngineConfig.RenderAPI.Vulkan)PrimaryRuntime.GetRenderThread().GetRenderer().GetSceneRender().RebuildPipelines(PrimaryRuntime.GetRenderThread().GetRenderer().GetVulkanContext()); } + ImGui.sameLine(); + if(ImGui.button("Ultra")){ + parent.ChangeGraphicsSettings = true; + parent.CoolDown = 2000; + parent.NextAAMode = (0); + ForwardSceneRender.SetDualPassRendering(true); + EngineConfig.getInstance().SetRenderer(EngineConfig.Renderer.Deferred); + DeferredSceneRender.SetDualPassRendering(true); + EngineConfig.getInstance().SetAlphaToCoverage(false); + EngineConfig.getInstance().RenderShadows(true); + EngineConfig.getInstance().SetShadowMapSize(8192); + EngineConfig.getInstance().MaxShadowDistance( (int)(ZFarPlane * 1.5)); + ShadowDistance[0] = (int)Math.clamp(EngineConfig.getInstance().MaxShadowDistance(), 64, (int)(ZFarPlane * 1.5)); + ShadowSize[0] = (int)Math.clamp((EngineConfig.getInstance().GetShadowMapSize() / 16) * 16, 16, 8192); + if(engineInstance.window().GetLinkedApi() == EngineConfig.RenderAPI.Vulkan)PrimaryRuntime.GetRenderThread().GetRenderer().GetSceneRender().RebuildPipelines(PrimaryRuntime.GetRenderThread().GetRenderer().GetVulkanContext()); + } + ImGui.text(" "); + ImGui.text("Shadows:"); + if(ImGui.button("No Shadows")){ + // parent.ChangeGraphicsSettings = true; + // parent.CoolDown = 2000; + EngineConfig.getInstance().RenderShadows(false); + } + ImGui.sameLine(); + if(ImGui.button("Cascading")){ + // parent.ChangeGraphicsSettings = true; + // parent.CoolDown = 2000; + EngineConfig.getInstance().RenderShadows(true); + } + if (ImGui.sliderInt("Shadow Map Size", ShadowSize, 16, 8192)) { + ShadowSize[0] = Math.clamp((ShadowSize[0] / 16) * 16, 16, 8192); + parent.ChangeGraphicsSettings = true; + parent.CoolDown = 2000; + EngineConfig.getInstance().SetShadowMapSize(ShadowSize[0]); + } + if (ImGui.sliderInt("Shadow Distance", ShadowDistance, 64, (int)(ZFarPlane * 1.5))) { + ShadowDistance[0] = Math.clamp((ShadowDistance[0] / 64) * 64, 64, (int)(ZFarPlane * 1.5)); + parent.ChangeGraphicsSettings = true; + parent.CoolDown = 2000; + EngineConfig.getInstance().MaxShadowDistance(ShadowDistance[0]); + } ImGui.text(" "); ImGui.text("anti aliasing:"); if(ImGui.button("No AA")){ diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Main/Scene/GUIs/SettingsMenu.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Main/Scene/GUIs/SettingsMenu.java index 0de0775..7edca8e 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Main/Scene/GUIs/SettingsMenu.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Main/Scene/GUIs/SettingsMenu.java @@ -22,6 +22,8 @@ public class SettingsMenu implements GUIOverlay { public int[] SFX = new int[]{100}; public int[] Weapons = new int[]{100}; public int[] Ambient = new int[]{100}; + public int[] ShadowSize = new int[]{4096}; + public int[] ShadowDistance = new int[]{1000}; public ImInt ServerPort = new ImInt(25565); public final ImString textBuffer = new ImString(100); public final ImString UsernameBuffer = new ImString(24); @@ -34,6 +36,8 @@ public class SettingsMenu implements GUIOverlay { SFX[0] = (int)(EngineConfig.getInstance().SoundVolume * 100); Weapons[0] = (int)(EngineConfig.getInstance().WeaponVolume * 100); Ambient[0] = (int)(EngineConfig.getInstance().AmbientVolume * 100); + ShadowSize[0] = EngineConfig.getInstance().GetShadowMapSize(); + ShadowDistance[0] = (int)EngineConfig.getInstance().MaxShadowDistance(); AudioInstance.ApplyUniversalVolume(); @@ -191,13 +195,36 @@ public class SettingsMenu implements GUIOverlay { EngineConfig.getInstance().SetRenderingAPI(EngineConfig.RenderAPI.OpenGL); } ImGui.text("Presets:"); + float ZFarPlane = Math.max(EngineConfig.getInstance().GetZFarPlane(), EngineConfig.getInstance().GetZNearPlane()); if(ImGui.button("Lowest")){ parent.ChangeGraphicsSettings = true; parent.CoolDown = 2000; parent.NextAAMode = (0); ForwardSceneRender.SetDualPassRendering(false); DeferredSceneRender.SetDualPassRendering(false); + EngineConfig.getInstance().SetRenderer(EngineConfig.Renderer.Forward); + EngineConfig.getInstance().RenderShadows(false); EngineConfig.getInstance().SetAlphaToCoverage(false); + EngineConfig.getInstance().SetShadowMapSize(1); + EngineConfig.getInstance().MaxShadowDistance(64); + ShadowDistance[0] = (int)Math.clamp(EngineConfig.getInstance().MaxShadowDistance(), 64, (int)(ZFarPlane * 1.5)); + ShadowSize[0] = (int)Math.clamp((EngineConfig.getInstance().GetShadowMapSize() / 16) * 16, 16, 8192); + if(engineInstance.window().GetLinkedApi() == EngineConfig.RenderAPI.Vulkan)PrimaryRuntime.GetRenderThread().GetRenderer().GetSceneRender().RebuildPipelines(PrimaryRuntime.GetRenderThread().GetRenderer().GetVulkanContext()); + } + ImGui.sameLine(); + if(ImGui.button("Low")){ + parent.ChangeGraphicsSettings = true; + parent.CoolDown = 2000; + parent.NextAAMode = (0); + ForwardSceneRender.SetDualPassRendering(false); + DeferredSceneRender.SetDualPassRendering(false); + EngineConfig.getInstance().SetRenderer(EngineConfig.Renderer.Deferred); + EngineConfig.getInstance().RenderShadows(true); + EngineConfig.getInstance().SetAlphaToCoverage(false); + EngineConfig.getInstance().SetShadowMapSize(256); + EngineConfig.getInstance().MaxShadowDistance((int)(ZFarPlane/4)); + ShadowDistance[0] = (int)Math.clamp(EngineConfig.getInstance().MaxShadowDistance(), 64, (int)(ZFarPlane * 1.5)); + ShadowSize[0] = (int)Math.clamp((EngineConfig.getInstance().GetShadowMapSize() / 16) * 16, 16, 8192); if(engineInstance.window().GetLinkedApi() == EngineConfig.RenderAPI.Vulkan)PrimaryRuntime.GetRenderThread().GetRenderer().GetSceneRender().RebuildPipelines(PrimaryRuntime.GetRenderThread().GetRenderer().GetVulkanContext()); } ImGui.sameLine(); @@ -206,20 +233,74 @@ public class SettingsMenu implements GUIOverlay { parent.CoolDown = 2000; parent.NextAAMode = (1); ForwardSceneRender.SetDualPassRendering(true); + EngineConfig.getInstance().SetRenderer(EngineConfig.Renderer.Deferred); DeferredSceneRender.SetDualPassRendering(true); + EngineConfig.getInstance().RenderShadows(true); EngineConfig.getInstance().SetAlphaToCoverage(true); + EngineConfig.getInstance().SetShadowMapSize(1024); + EngineConfig.getInstance().MaxShadowDistance((int)(ZFarPlane/2)); + ShadowDistance[0] = (int)Math.clamp(EngineConfig.getInstance().MaxShadowDistance(), 64, (int)(ZFarPlane * 1.5)); + ShadowSize[0] = (int)Math.clamp((EngineConfig.getInstance().GetShadowMapSize() / 16) * 16, 16, 8192); if(engineInstance.window().GetLinkedApi() == EngineConfig.RenderAPI.Vulkan)PrimaryRuntime.GetRenderThread().GetRenderer().GetSceneRender().RebuildPipelines(PrimaryRuntime.GetRenderThread().GetRenderer().GetVulkanContext()); } ImGui.sameLine(); - if(ImGui.button("Highest")){ + if(ImGui.button("High")){ parent.ChangeGraphicsSettings = true; parent.CoolDown = 2000; - parent.NextAAMode = (4); + parent.NextAAMode = (0); ForwardSceneRender.SetDualPassRendering(true); + EngineConfig.getInstance().SetRenderer(EngineConfig.Renderer.Deferred); DeferredSceneRender.SetDualPassRendering(true); EngineConfig.getInstance().SetAlphaToCoverage(false); + EngineConfig.getInstance().RenderShadows(true); + EngineConfig.getInstance().SetShadowMapSize(4096); + EngineConfig.getInstance().MaxShadowDistance((int)(ZFarPlane)); + ShadowDistance[0] = (int)Math.clamp(EngineConfig.getInstance().MaxShadowDistance(), 64, (int)(ZFarPlane * 1.5)); + ShadowSize[0] = (int)Math.clamp((EngineConfig.getInstance().GetShadowMapSize() / 16) * 16, 16, 8192); if(engineInstance.window().GetLinkedApi() == EngineConfig.RenderAPI.Vulkan)PrimaryRuntime.GetRenderThread().GetRenderer().GetSceneRender().RebuildPipelines(PrimaryRuntime.GetRenderThread().GetRenderer().GetVulkanContext()); } + ImGui.sameLine(); + if(ImGui.button("Ultra")){ + parent.ChangeGraphicsSettings = true; + parent.CoolDown = 2000; + parent.NextAAMode = (0); + ForwardSceneRender.SetDualPassRendering(true); + EngineConfig.getInstance().SetRenderer(EngineConfig.Renderer.Deferred); + DeferredSceneRender.SetDualPassRendering(true); + EngineConfig.getInstance().SetAlphaToCoverage(false); + EngineConfig.getInstance().RenderShadows(true); + EngineConfig.getInstance().SetShadowMapSize(8192); + EngineConfig.getInstance().MaxShadowDistance( (int)(ZFarPlane * 1.5)); + ShadowDistance[0] = (int)Math.clamp(EngineConfig.getInstance().MaxShadowDistance(), 64, (int)(ZFarPlane * 1.5)); + ShadowSize[0] = (int)Math.clamp((EngineConfig.getInstance().GetShadowMapSize() / 16) * 16, 16, 8192); + if(engineInstance.window().GetLinkedApi() == EngineConfig.RenderAPI.Vulkan)PrimaryRuntime.GetRenderThread().GetRenderer().GetSceneRender().RebuildPipelines(PrimaryRuntime.GetRenderThread().GetRenderer().GetVulkanContext()); + } + ImGui.text(" "); + ImGui.text("Shadows:"); + if(ImGui.button("No Shadows")){ + // parent.ChangeGraphicsSettings = true; + // parent.CoolDown = 2000; + EngineConfig.getInstance().RenderShadows(false); + } + ImGui.sameLine(); + if(ImGui.button("Cascading")){ + // parent.ChangeGraphicsSettings = true; + // parent.CoolDown = 2000; + EngineConfig.getInstance().RenderShadows(true); + } + if (ImGui.sliderInt("Shadow Map Size", ShadowSize, 16, 8192)) { + ShadowSize[0] = Math.clamp((ShadowSize[0] / 16) * 16, 16, 8192); + parent.ChangeGraphicsSettings = true; + parent.CoolDown = 2000; + EngineConfig.getInstance().SetShadowMapSize(ShadowSize[0]); + } + if (ImGui.sliderInt("Shadow Distance", ShadowDistance, 64, (int)(ZFarPlane * 1.5))) { + ShadowDistance[0] = Math.clamp((ShadowDistance[0] / 64) * 64, 64, (int)(ZFarPlane * 1.5)); + parent.ChangeGraphicsSettings = true; + parent.CoolDown = 2000; + EngineConfig.getInstance().MaxShadowDistance(ShadowDistance[0]); + } + ImGui.text(" "); ImGui.text("anti aliasing:"); ImGui.text("Selected AA: " + EngineConfig.getInstance().RenderAAType().name()); if(ImGui.button("No AA")){ diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Main/Scene/Scene.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Main/Scene/Scene.java index 470790e..885267d 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Main/Scene/Scene.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Main/Scene/Scene.java @@ -156,9 +156,9 @@ public class Scene implements IScene { if(!PrimaryRuntime.IsServer && !RenderThread.Headless) { GUIReg.put("PerformanceOverlay",new PerformanceOverlay()); - ActiveGUIs.add("PerformanceOverlay"); + ActiveGUIs.add("PerformanceOverlay"); GUIReg.put("ChatLog",new GameChat()); - ActiveGUIs.add("ChatLog"); + //ActiveGUIs.add("ChatLog"); } } diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Universal/Projection/Project3D.java b/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Universal/Projection/Project3D.java index be94eeb..0dd11ed 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Universal/Projection/Project3D.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Universal/Projection/Project3D.java @@ -32,6 +32,22 @@ public class Project3D { Resize(LastWidth,LastHeight); } + public Project3D GetReversedFarPlanes(){ + Project3D newProjection; + float zNear = Math.max(ZFarPlane, ZNearPlane); + float zFar = Math.min(ZFarPlane, ZNearPlane); + newProjection = new Project3D(FOV, zNear, zFar, LastWidth, LastHeight); + return newProjection; + } + + public Project3D GetNormalFarPlanes(){ + Project3D newProjection; + float zNear = Math.min(ZFarPlane, ZNearPlane); + float zFar = Math.max(ZFarPlane, ZNearPlane); + newProjection = new Project3D(FOV, zNear, zFar, LastWidth, LastHeight); + return newProjection; + } + public void ChangeFOV(float newFOV){ FOV = newFOV; Resize(LastWidth,LastHeight); 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 5b102d6..0423e96 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 @@ -15,6 +15,7 @@ import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.P import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Shader.*; import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Shadows.CascadeData; import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Shadows.CascadeShadows; +import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Shadows.ShadowRenderer; import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DeviceLayers.CommandBuffer; import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DeviceLayers.Device; import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DisplayToScreen.ImageView; @@ -41,17 +42,22 @@ import static org.lwjgl.vulkan.VK13.*; public class LightRenderer { private static final int COLOUR_FORMAT = VK_FORMAT_R32G32B32A32_SFLOAT; private static final String DESC_ID_ATT = "LIGHT_DESC_ID_ATT"; + private static final String DESC_ID_NOSHADOW_ATT = "LIGHT_DESC_ID_NOSHADOW_ATT"; private static final String DESC_ID_SHADOW_MATRICES = "LIGHT_DESC_ID_SHADOW_MATRICES"; private static final String DESC_ID_LIGHTS = "LIGHT_DESC_ID_LIGHTS"; - private static final String DESC_ID_SCENE = "LIGHT_DESC_ID_SCENE "; + private static final String DESC_ID_SCENE = "LIGHT_DESC_ID_SCENE"; private static final String FRAGMENT_SHADER_FILE_GLSL = "resources/EngineResources/shaders/lighting_with_shadows_frag.glsl"; private static final String FRAGMENT_SHADER_FILE_SPV = FRAGMENT_SHADER_FILE_GLSL + ".spv"; + private static final String NO_SHADOWS_FRAGMENT_SHADER_FILE_GLSL = "resources/EngineResources/shaders/lighting_frag.glsl"; + private static final String NO_SHADOWS_FRAGMENT_SHADER_FILE_SPV = NO_SHADOWS_FRAGMENT_SHADER_FILE_GLSL + ".spv"; private static final String VERTEX_SHADER_FILE_GLSL = "resources/EngineResources/shaders/lighting_vertex.glsl"; private static final String VERTEX_SHADER_FILE_SPV = VERTEX_SHADER_FILE_GLSL + ".spv"; private final DescriptorSetLayout AttachmentDescriptorSetLayout; + private final DescriptorSetLayout NoShadowsAttachmentDescriptorSetLayout; private final VkClearValue ClearValueColour; private final Pipeline pipeline; + private final Pipeline NoShadowsPipeline; private final TextureSampler textureSampler; private Attachment AttachmentColour; private VkRenderingAttachmentInfo.Buffer AttachmentInfoColour; @@ -72,7 +78,7 @@ public class LightRenderer { RenderInfo = CreateRenderInfo(AttachmentColour, AttachmentInfoColour); lightSpecConsts = new LightSpecConsts(); - ShaderModule[] shaderModules = CreateShaderModules(VkCtx, lightSpecConsts); + ShaderModule[] shaderModules = CreateShaderModules(VkCtx, lightSpecConsts,true); var textureSamplerInfo = new TextureSamplerInfo(VK_SAMPLER_ADDRESS_MODE_REPEAT, VK_BORDER_COLOR_INT_OPAQUE_BLACK, 1, true); @@ -83,7 +89,7 @@ public class LightRenderer { descSetLayouts[i] = new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, i, 1, VK_SHADER_STAGE_FRAGMENT_BIT); } AttachmentDescriptorSetLayout = new DescriptorSetLayout(VkCtx, descSetLayouts); - CreateAttachmentDescriptorSet(VkCtx, AttachmentDescriptorSetLayout, attachments, textureSampler); + CreateAttachmentDescriptorSet(VkCtx, AttachmentDescriptorSetLayout, attachments, textureSampler, true); StorageDescriptorSetLayout = new DescriptorSetLayout(VkCtx, new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 0, 1, VK_SHADER_STAGE_FRAGMENT_BIT)); @@ -99,6 +105,19 @@ public class LightRenderer { shadowMatrices = CreateShadowMatrixBuffers(VkCtx, StorageDescriptorSetLayout); pipeline = createPipeline(VkCtx, shaderModules, new DescriptorSetLayout[]{AttachmentDescriptorSetLayout, StorageDescriptorSetLayout, StorageDescriptorSetLayout, SceneDescriptorSetLayout}); + Arrays.asList(shaderModules).forEach(s -> s.CleanUp(VkCtx)); + + numAttachments = attachments.size(); + DescriptorSetLayout.LayoutInformation[] OldDescSetLayouds = new DescriptorSetLayout.LayoutInformation[numAttachments]; + for (int i = 0; i < numAttachments; i++) { + OldDescSetLayouds[i] = new DescriptorSetLayout.LayoutInformation(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, i, 1, VK_SHADER_STAGE_FRAGMENT_BIT); + } + NoShadowsAttachmentDescriptorSetLayout = new DescriptorSetLayout(VkCtx, OldDescSetLayouds); + CreateAttachmentDescriptorSet(VkCtx, NoShadowsAttachmentDescriptorSetLayout, attachments, textureSampler, false); + + shaderModules = CreateShaderModules(VkCtx, lightSpecConsts,false); + NoShadowsPipeline = createPipeline(VkCtx, shaderModules, new DescriptorSetLayout[]{NoShadowsAttachmentDescriptorSetLayout, + StorageDescriptorSetLayout, SceneDescriptorSetLayout}); Logger.debug("Light Renderer Pipeline -> [{}]",pipeline.GetVulkanPipeline()); Arrays.asList(shaderModules).forEach(s -> s.CleanUp(VkCtx)); } @@ -120,10 +139,10 @@ public class LightRenderer { } private static void CreateAttachmentDescriptorSet(VulkanContext VkCtx, DescriptorSetLayout descSetLayout, List attachments, - TextureSampler sampler) { + TextureSampler sampler, boolean Shadows) { DescriptorAllocator descAllocator = VkCtx.GetDescriptorAllocator(); Device device = VkCtx.GetDevice(); - DescriptorSet descSet = descAllocator.AddDescriptorSet(device, DESC_ID_ATT, descSetLayout); + DescriptorSet descSet = descAllocator.AddDescriptorSet(device, Shadows ? DESC_ID_ATT : DESC_ID_NOSHADOW_ATT, descSetLayout); List imageViews = new ArrayList<>(); attachments.forEach(a -> imageViews.add(a.GetVkImageView())); descSet.SetImages(device, imageViews, sampler, 0); @@ -176,14 +195,16 @@ public class LightRenderer { return result; } - private static ShaderModule[] CreateShaderModules(VulkanContext VkCtx, LightSpecConsts lightSpecConsts) { + private static ShaderModule[] CreateShaderModules(VulkanContext VkCtx, LightSpecConsts lightSpecConsts, boolean shadowPipeline) { if (EngineConfig.getInstance().RecompileShaders()) { ShaderCompiler.CompileGLSLShaderOnChange(VERTEX_SHADER_FILE_GLSL, Shaderc.shaderc_glsl_vertex_shader); - ShaderCompiler.CompileGLSLShaderOnChange(FRAGMENT_SHADER_FILE_GLSL, Shaderc.shaderc_glsl_fragment_shader); + //ShaderCompiler.CompileGLSLShaderOnChange( FRAGMENT_SHADER_FILE_GLSL, Shaderc.shaderc_glsl_fragment_shader); + ShaderCompiler.CompileGLSLShaderOnChange(shadowPipeline ? FRAGMENT_SHADER_FILE_GLSL : NO_SHADOWS_FRAGMENT_SHADER_FILE_GLSL, Shaderc.shaderc_glsl_fragment_shader); } return new ShaderModule[]{ new ShaderModule(VkCtx, VK_SHADER_STAGE_VERTEX_BIT, VERTEX_SHADER_FILE_SPV, null), - new ShaderModule(VkCtx, VK_SHADER_STAGE_FRAGMENT_BIT, FRAGMENT_SHADER_FILE_SPV, lightSpecConsts.getSpecInfo()), + //new ShaderModule(VkCtx, VK_SHADER_STAGE_FRAGMENT_BIT, FRAGMENT_SHADER_FILE_SPV, lightSpecConsts.getSpecInfo()), + new ShaderModule(VkCtx, VK_SHADER_STAGE_FRAGMENT_BIT, shadowPipeline ? FRAGMENT_SHADER_FILE_SPV : NO_SHADOWS_FRAGMENT_SHADER_FILE_SPV, shadowPipeline ? lightSpecConsts.getSpecInfo() : null), }; } @@ -210,8 +231,10 @@ public class LightRenderer { } VulkanUtils.ImageBarrier(stack, cmdHandle, mrtAttachments.GetDepthAttachment().GetVkImage().getVulkanImage(), VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, - VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT, - VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_2_SHADER_READ_BIT, + VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT, + VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT, + VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, + VK_ACCESS_2_SHADER_READ_BIT, VK_IMAGE_ASPECT_DEPTH_BIT); VulkanUtils.ImageBarrier(stack, cmdHandle, shadowAttachment.GetVkImage().getVulkanImage(), @@ -262,6 +285,73 @@ public class LightRenderer { } } + public void render(EngineInstance engineInstance, VulkanContext VkCtx, CommandBuffer cmdBuffer, MultiRenderTargetAttachments mrtAttachments, int CurrentFrame) { + try (var stack = MemoryStack.stackPush()) { + VkCommandBuffer cmdHandle = cmdBuffer.GetVulkanCommandBuffer(); + + VulkanUtils.ImageBarrier(stack, cmdHandle, AttachmentColour.GetVkImage().getVulkanImage(), + VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, + VK_ACCESS_2_NONE, VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT, + VK_IMAGE_ASPECT_COLOR_BIT); + + List attachments = mrtAttachments.GetColourAttachments(); + int numAttachments = attachments.size(); + for (int i = 0; i < numAttachments; i++) { + Attachment attachment = attachments.get(i); + VulkanUtils.ImageBarrier(stack, cmdHandle, attachment.GetVkImage().getVulkanImage(), + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT, + VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_2_SHADER_READ_BIT, + VK_IMAGE_ASPECT_COLOR_BIT); + } + VulkanUtils.ImageBarrier(stack, cmdHandle, mrtAttachments.GetDepthAttachment().GetVkImage().getVulkanImage(), + VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT, + VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT, + VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, + VK_ACCESS_2_SHADER_READ_BIT, + VK_IMAGE_ASPECT_DEPTH_BIT); + + vkCmdBeginRendering(cmdHandle, RenderInfo); + + vkCmdBindPipeline(cmdHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, NoShadowsPipeline.GetVulkanPipeline()); + + + Image ColourImage = AttachmentColour.GetVkImage(); + int width = ColourImage.GetWidth(); + int height = ColourImage.GetHeight(); + var viewport = VkViewport.calloc(1, stack) + .x(0) + .y(height) + .height(-height) + .width(width) + .minDepth(0.0f) + .maxDepth(1.0f); + vkCmdSetViewport(cmdHandle, 0, viewport); + + var scissor = VkRect2D.calloc(1, stack) + .extent(it -> it.width(width).height(height)) + .offset(it -> it.x(0).y(0)); + vkCmdSetScissor(cmdHandle, 0, scissor); + + DescriptorAllocator descAllocator = VkCtx.GetDescriptorAllocator(); + LongBuffer descriptorSets = stack.mallocLong(3) + .put(0, descAllocator.GetDescriptorSet(DESC_ID_NOSHADOW_ATT).GetVkDescriptorSet()) + .put(1, descAllocator.GetDescriptorSet(DESC_ID_LIGHTS, CurrentFrame).GetVkDescriptorSet()) + .put(2, descAllocator.GetDescriptorSet(DESC_ID_SCENE, CurrentFrame).GetVkDescriptorSet()); + IScene scene = engineInstance.scene(); + UpdateSceneInfo(VkCtx, scene, CurrentFrame); + UpdateLights(VkCtx, scene, CurrentFrame); + vkCmdBindDescriptorSets(cmdHandle, VK_PIPELINE_BIND_POINT_GRAPHICS, + NoShadowsPipeline.GetVulkanPipelineLayout(), 0, descriptorSets, null); + + vkCmdDraw(cmdHandle, 3, 1, 0, 0); + + vkCmdEndRendering(cmdHandle); + } + } + private void UpdateCascadeShadowMatrices(VulkanContext vkCtx, CascadeShadows cascadeShadows, int currentFrame) { VulkanBuffer buff = shadowMatrices[currentFrame]; long mappedMemory = buff.MapMemory(vkCtx); @@ -324,6 +414,20 @@ public class LightRenderer { buffer.UnMapMemory(VkCtx); } + public void updateAttachmentDescriptors(VulkanContext VkCtx, List attachments) { + DescriptorSet descSet = VkCtx.GetDescriptorAllocator().GetDescriptorSet(DESC_ID_ATT); + var imageViews = new ArrayList(); + attachments.forEach(a -> imageViews.add(a.GetVkImageView())); + descSet.SetImages(VkCtx.GetDevice(), imageViews, textureSampler, 0); + + DescriptorSet noShadowDescSet = VkCtx.GetDescriptorAllocator().GetDescriptorSet(DESC_ID_NOSHADOW_ATT); + var noShadowImageViews = new ArrayList(); + for (int i = 0; i < attachments.size() - 1; i++) { + noShadowImageViews.add(attachments.get(i).GetVkImageView()); + } + noShadowDescSet.SetImages(VkCtx.GetDevice(), noShadowImageViews, textureSampler, 0); + } + public void resize(VulkanContext VkCtx, List attachments) { RenderInfo.free(); AttachmentInfoColour.free(); @@ -337,6 +441,13 @@ public class LightRenderer { var imageViews = new ArrayList(); attachments.forEach(a -> imageViews.add(a.GetVkImageView())); descSet.SetImages(VkCtx.GetDevice(), imageViews, textureSampler, 0); + + DescriptorSet noShadowDescSet = VkCtx.GetDescriptorAllocator().GetDescriptorSet(DESC_ID_NOSHADOW_ATT); + var noShadowImageViews = new ArrayList(); + for (int i = 0; i < attachments.size() - 1; i++) { + noShadowImageViews.add(attachments.get(i).GetVkImageView()); + } + noShadowDescSet.SetImages(VkCtx.GetDevice(), noShadowImageViews, textureSampler, 0); } public void cleanup(VulkanContext VkCtx) { @@ -346,7 +457,9 @@ public class LightRenderer { SceneDescriptorSetLayout.CleanUp(VkCtx); Arrays.asList(SceneBuffer).forEach(b -> b.cleanup(VkCtx)); pipeline.CleanUp(VkCtx); + NoShadowsPipeline.CleanUp(VkCtx); AttachmentDescriptorSetLayout.CleanUp(VkCtx); + NoShadowsAttachmentDescriptorSetLayout.CleanUp(VkCtx); textureSampler.CleanUp(VkCtx); lightSpecConsts.cleanup(); RenderInfo.free(); 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 8931415..f542079 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 @@ -15,6 +15,9 @@ public class MultiRenderTargetAttachments { public static final int DEPTH_FORMAT = VK_FORMAT_D32_SFLOAT; public static final int NORMAL_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT; public static final int PBR_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT; + public static final int EMISSIVE_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT; + public static final int TRANSLUCECNY_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT; + public static final int OPACITY_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT; public static final int POSITION_FORMAT = VK_FORMAT_R16G16B16A16_SFLOAT; private final List ColourAttachments; private final Attachment DepthAttachment; @@ -39,6 +42,15 @@ public class MultiRenderTargetAttachments { //PBR Attachment = new Attachment(VkCtx, Width, Height, PBR_FORMAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 1); ColourAttachments.add(Attachment); + //Emissive + Attachment = new Attachment(VkCtx, Width, Height, EMISSIVE_FORMAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 1); + ColourAttachments.add(Attachment); + //Translucency + Attachment = new Attachment(VkCtx, Width, Height, TRANSLUCECNY_FORMAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 1); + ColourAttachments.add(Attachment); + //Opacity + Attachment = new Attachment(VkCtx, Width, Height, OPACITY_FORMAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 1); + ColourAttachments.add(Attachment); DepthAttachment = new Attachment(VkCtx, Width, Height, DEPTH_FORMAT, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, 1); } diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Rendering/Pipeline/DefaultPipeline.java b/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Rendering/Pipeline/DefaultPipeline.java index fb57993..916876b 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Rendering/Pipeline/DefaultPipeline.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Rendering/Pipeline/DefaultPipeline.java @@ -69,7 +69,7 @@ public class DefaultPipeline implements Pipeline { var RasterizationStateCreateInfo = VkPipelineRasterizationStateCreateInfo.calloc(MemStack) .sType$Default() .polygonMode(VK_POLYGON_MODE_FILL) - .cullMode(VK_CULL_MODE_NONE) + .cullMode(BuildInfo.CullMode()) .frontFace(VK_FRONT_FACE_CLOCKWISE) .depthClampEnable(BuildInfo.DepthClamp()) .lineWidth(1.0f); @@ -89,7 +89,7 @@ public class DefaultPipeline implements Pipeline { .sType(VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO) .depthTestEnable(BuildInfo.GetDepthTest()) .depthWriteEnable(BuildInfo.performDepthWrite()) - .depthCompareOp(VK_COMPARE_OP_LESS_OR_EQUAL) + .depthCompareOp(BuildInfo.DepthBuffer()) .depthBoundsTestEnable(false) .stencilTestEnable(false); } 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 d5a5122..552777f 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 @@ -20,11 +20,15 @@ import static org.lwjgl.vulkan.VK10.VK_FORMAT_R8G8B8A8_SRGB; public class TextureCache implements ITextureCache { public static final int MAX_TEXTURES = 256; private final IndexedLinkedHashMap TextureMap; + private final IndexedLinkedHashMap CubemapTextures; private final List ActualTextures; + private final List ActualCubemapTextures; public TextureCache(){ TextureMap = new IndexedLinkedHashMap<>(); + CubemapTextures = new IndexedLinkedHashMap<>(); ActualTextures = new ArrayList<>(); + ActualCubemapTextures = new ArrayList<>(); } public ITexture AddCubeMapTexture(VulkanContext VkCtx, String ID, String[] FacePaths, int Format) { @@ -109,8 +113,17 @@ public class TextureCache implements ITextureCache { } public IndexedLinkedHashMap GetTextureCache(){return TextureMap;} public List GetTextureList(){return new ArrayList<>(TextureMap.values());} + public List GetAll2DTextures(){ + List result = new ArrayList<>(); + TextureMap.forEach((key,value)->{ + if(!(value instanceof CubeMapTexture)){ + result.add(value); + } + }); + return result; + } public int GetPosition(String ID){ - int result = -1; + int result = 0; if(ID != null){ result = TextureMap.GetIndexOf(ID); } diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Rendering/Pipeline/PipelineBuildInfo.java b/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Rendering/Pipeline/PipelineBuildInfo.java index aae2347..483c55c 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Rendering/Pipeline/PipelineBuildInfo.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Rendering/Pipeline/PipelineBuildInfo.java @@ -4,7 +4,7 @@ import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Shader.Des import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Shader.ShaderModule; import org.lwjgl.vulkan.VkPipelineVertexInputStateCreateInfo; -import static org.lwjgl.vulkan.VK10.VK_FORMAT_UNDEFINED; +import static org.lwjgl.vulkan.VK10.*; public class PipelineBuildInfo { private final ShaderModule[] ShaderModules; @@ -20,6 +20,14 @@ public class PipelineBuildInfo { private boolean alphaToCoverage = false; private final int[] ColourFormats; private int BlendingMethod = 0; + private int CullMode = VK_CULL_MODE_NONE; + private int DepthBuffer = VK_COMPARE_OP_GREATER_OR_EQUAL; + + public int DepthBuffer(){return DepthBuffer;} + public PipelineBuildInfo DepthBuffer(int DepthBuffer){this.DepthBuffer = DepthBuffer;return this;} + + public int CullMode(){return CullMode;} + public PipelineBuildInfo CullMode(int CullMode){this.CullMode = CullMode; return this;} public PipelineBuildInfo(ShaderModule[] shaderModules, VkPipelineVertexInputStateCreateInfo VertexInput, int[] ColourFormat){ this.ColourFormats = ColourFormat; diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Rendering/Shadows/ShadowRenderer.java b/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Rendering/Shadows/ShadowRenderer.java index 889b9bc..baf61b3 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Rendering/Shadows/ShadowRenderer.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Rendering/Shadows/ShadowRenderer.java @@ -31,6 +31,7 @@ import org.tinylog.Logger; import java.nio.ByteBuffer; import java.nio.LongBuffer; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -83,19 +84,68 @@ public class ShadowRenderer { private final CascadeShadows[] cascadeShadows; private final VkClearValue ClearValueColour; private final VkClearValue ClearValueDepth; - private final Attachment colorAttachment; - private final VkRenderingAttachmentInfo.Buffer colorAttachmentInfo; - private final Attachment depthAttachment; - private final VkRenderingAttachmentInfo depthAttachmentInfo; + private Attachment colorAttachment; + private VkRenderingAttachmentInfo.Buffer colorAttachmentInfo; + private Attachment depthAttachment; + private VkRenderingAttachmentInfo depthAttachmentInfo; private final DescriptorSetLayout descLayoutFrgStorage; - private final Pipeline pipeline; + private Pipeline pipeline; private final VulkanBuffer[] prjBuffers; private final ByteBuffer pushConstBuff; - private final VkRenderingInfo renderingInfo; + private VkRenderingInfo renderingInfo; private final DescriptorSetLayout textDescriptorSetLayout; private final TextureSampler textureSampler; private final DescriptorSetLayout uniformGeomDescriptorSetLayout; + public static volatile boolean AllowShadowRendering = false; + public static synchronized boolean AllowShadowRendering(){ return AllowShadowRendering;} + public static synchronized void AllowShadowRendering(boolean AllowShadowRendering){ ShadowRenderer.AllowShadowRendering = AllowShadowRendering;} + + public void RebuildPipelineAndRenderingAttachments(VulkanContext VulkanContext){ + + VkRenderingInfo NewRenderInfo; + Attachment newColourAttachment; + Attachment newDepthAttachment; + VkRenderingAttachmentInfo newDepthAttachmentInfo; + VkRenderingAttachmentInfo.Buffer newColourAttachmentInfo; + Pipeline newPipeline; + + newDepthAttachment = createDepthAttachment(VulkanContext); + newDepthAttachmentInfo = createDepthAttachmentInfo(newDepthAttachment, ClearValueDepth); + + newColourAttachment = createColorAttachment(VulkanContext); + newColourAttachmentInfo = createColorAttachmentInfo(newColourAttachment, ClearValueColour); + + NewRenderInfo = createRenderInfo(newColourAttachmentInfo, newDepthAttachmentInfo); + + ShaderModule[] shaderModules = createShaderModules(VulkanContext); + newPipeline = createPipeline(VulkanContext, shaderModules, new DescriptorSetLayout[]{uniformGeomDescriptorSetLayout, textDescriptorSetLayout, + descLayoutFrgStorage}); + Arrays.asList(shaderModules).forEach(s -> s.CleanUp(VulkanContext)); + + VkRenderingInfo OldRenderInfo = renderingInfo; + Attachment OldColourAttachment = colorAttachment; + Attachment OldDepthAttachment = depthAttachment; + VkRenderingAttachmentInfo OldDepthAttachmentInfo = depthAttachmentInfo; + VkRenderingAttachmentInfo.Buffer OldColourAttachmentInfo = colorAttachmentInfo; + Pipeline OldPipeline = pipeline; + + renderingInfo = NewRenderInfo; + colorAttachment = newColourAttachment; + depthAttachment = newDepthAttachment; + depthAttachmentInfo = newDepthAttachmentInfo; + colorAttachmentInfo = newColourAttachmentInfo; + pipeline = newPipeline; + + OldRenderInfo.free(); + OldDepthAttachmentInfo.free(); + OldDepthAttachment.CleanUp(VulkanContext); + OldColourAttachmentInfo.free(); + OldColourAttachment.CleanUp(VulkanContext); + OldPipeline.CleanUp(VulkanContext); + + } + public ShadowRenderer(VulkanContext VulkanContext) { ClearValueColour = VkClearValue.calloc().color( c -> c.float32(0, 0.0f).float32(1, 0.0f).float32(2, 0.0f).float32(3, 0.0f)); @@ -135,6 +185,7 @@ public class ShadowRenderer { for (int i = 0; i < VulkanUtils.MAX_IN_FLIGHT; i++) { cascadeShadows[i] = new CascadeShadows(); } + AllowShadowRendering(true); } private static Attachment createColorAttachment(VulkanContext VulkanContext) { @@ -179,7 +230,9 @@ public class ShadowRenderer { }) .SetDescriptorSetLayouts(DescriptorSetLayouts) .SetDescriptorSetLayouts(DescriptorSetLayouts) - .SetDepthClamp(VulkanContext.GetDevice().getDepthClamp()); + .SetDepthClamp(VulkanContext.GetDevice().getDepthClamp()) + .CullMode(VK_CULL_MODE_FRONT_BIT) + .DepthBuffer(VK_COMPARE_OP_LESS_OR_EQUAL); var pipeline = new DefaultPipeline(VulkanContext, buildInfo); vtxBuffStruct.cleanup(); return pipeline; @@ -216,6 +269,7 @@ public class ShadowRenderer { } public void cleanup(VulkanContext VulkanContext) { + AllowShadowRendering(false); pipeline.CleanUp(VulkanContext); uniformGeomDescriptorSetLayout.CleanUp(VulkanContext); descLayoutFrgStorage.CleanUp(VulkanContext); @@ -248,7 +302,12 @@ public class ShadowRenderer { var buffer = materialsCache.GetMaterialsBuffer(); descSet.SetBuffer(device, buffer, buffer.GetRequestedSize(), layoutInfo.Binding(), layoutInfo.DescriptorType()); - List imageViews = textureCache.GetTextureList().stream().map(ITexture::GetImageView).toList(); + List imageViews = new ArrayList<>(textureCache.GetAll2DTextures().stream().map(ITexture::GetImageView).toList()); + + ImageView fallback = textureCache.GetTexture("resources/EngineResources/Texture/NoTexture.png").GetImageView(); + while (imageViews.size() < TextureCache.MAX_TEXTURES) { + imageViews.add(fallback); + } descSet = VulkanContext.GetDescriptorAllocator().AddDescriptorSet(device, DESCRIPTOR_ID_TEXT, textDescriptorSetLayout); descSet.SetImageArray(device, imageViews, textureSampler, 0); } @@ -319,6 +378,9 @@ public class ShadowRenderer { var vulkanMesh = vulkanMeshList.get(j); String materialId = vulkanMesh.MaterialID(); int materialIdx = materialsCache.GetPosition(materialId); + if(materialIdx == -1) { + continue; + } VulkanMaterial vulkanMaterial = materialsCache.GetMaterial(materialId); if (vulkanMaterial == null) { Logger.warn("Mesh [{}] in model [{}] does not have material", j, model.GetID()); diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Rendering/Shadows/ShadowUtils.java b/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Rendering/Shadows/ShadowUtils.java index ec83742..ef50d53 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Rendering/Shadows/ShadowUtils.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Rendering/Shadows/ShadowUtils.java @@ -24,7 +24,7 @@ public class ShadowUtils { public static void updateCascadeShadows(CascadeShadows cascadeShadows, IScene scene) { Camera camera = scene.GetCamera(); Matrix4f viewMatrix = camera.GetViewMatrix(); - Project3D projection = scene.GetProjection(); + Project3D projection = scene.GetProjection().GetNormalFarPlanes(); Matrix4f projMatrix = projection.GetProjectionMatrix(); ILight[] lights = scene.GetLightingManager().GetLights(); int numLights = lights.length; @@ -42,14 +42,10 @@ public class ShadowUtils { float[] cascadeSplits = new float[SceneLightingManager.SHADOW_MAP_CASCADE_COUNT]; - float nearClip = projection.GetNearZ(); - float farClip = projection.GetFarZ(); + float nearClip = projection.GetNearZ();//projection.GetNearZ(); + float farClip = EngineConfig.getInstance().MaxShadowDistance();//Math.min(projection.GetFarZ(), EngineConfig.getInstance().MaxShadowDistance()); float clipRange = farClip - nearClip; - if (nearClip <= 0.0f || farClip <= nearClip) { - //throw new IllegalStateException("Invalid projection near/far planes for shadow cascades: near=" + nearClip + ", far=" + farClip); - } - float minZ = nearClip; float maxZ = nearClip + clipRange; 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 5e2f2f7..b9407bc 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) { +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) { } 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 82e0597..83ea1df 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 @@ -10,6 +10,7 @@ import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DeviceLaye import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DeviceLayers.Queues.Queue; import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Util.VulkanBuffer; import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Util.VulkanUtils; +import org.joml.Vector4f; import org.lwjgl.system.MemoryUtil; import org.tinylog.Logger; @@ -21,7 +22,8 @@ import static org.lwjgl.util.vma.Vma.VMA_MEMORY_USAGE_AUTO; import static org.lwjgl.vulkan.VK10.*; public class MaterialsCache { - private static final int MATERIAL_SIZE = VulkanUtils.VEC4_SIZE * 3; + private static final int MATERIAL_RAW_SIZE = VulkanUtils.VEC4_SIZE * 4 + (VulkanUtils.INT_SIZE * 2 + VulkanUtils.FLOAT_SIZE) * 2 + (VulkanUtils.INT_SIZE * 2); + private static final int MATERIAL_SIZE = 16 * (int)(Math.ceil(MATERIAL_RAW_SIZE/16.0)); private final IndexedLinkedHashMap MaterialsMap; private VulkanBuffer MaterialsBuffer; @@ -31,6 +33,7 @@ public class MaterialsCache { //create staging buffer and GPU only accessibly buffer, add any located textures public void LoadMaterials(VulkanContext VkCtx, List Materials, TextureCache textureCache, CommandPool commandPool, Queue queue){ + Logger.debug("MATERIAL SIZE: [{}], Expected Size: 96, raw size [{}]", MATERIAL_SIZE,MATERIAL_RAW_SIZE); int MaterialCount = Materials.size(); int BufferSize = MATERIAL_SIZE * MaterialCount; var SrcBuffer = new VulkanBuffer(VkCtx, BufferSize, @@ -48,20 +51,28 @@ public class MaterialsCache { int Offset = 0; for(int i = 0; i < MaterialCount; i++){ + int materialBaseOffset = i * MATERIAL_SIZE; + Offset = materialBaseOffset; var Material = Materials.get(i); String TexturePath = Material.TexturePath(); - boolean ValidTexture = TexturePath != null && !TexturePath.isEmpty(); + boolean hasDiffuseTexture = TexturePath != null && !TexturePath.isEmpty(); boolean TransparentTexture; Logger.debug("Material Texture Path -> [{}]",Material.TexturePath()); - if(ValidTexture){ + + if(hasDiffuseTexture){ ITexture newTexture = textureCache.AddTexture(VkCtx, TexturePath, TexturePath, VK_FORMAT_R8G8B8A8_SRGB); if(newTexture == null) { - TransparentTexture = false; TexturePath = "resources/EngineResources/Texture/NoTexture.png"; + textureCache.AddTexture(VkCtx, TexturePath, TexturePath, VK_FORMAT_R8G8B8A8_SRGB); + hasDiffuseTexture = false; + TransparentTexture = false; + } + else { + TransparentTexture = newTexture.HasTransparency(); } - else TransparentTexture = newTexture.HasTransparency(); } else{ TexturePath = "resources/EngineResources/Texture/NoTexture.png"; + textureCache.AddTexture(VkCtx, TexturePath, TexturePath, VK_FORMAT_R8G8B8A8_SRGB); TransparentTexture = Material.DiffuseColour().w < 1.0f; } VulkanMaterial newMaterial = new VulkanMaterial(Material.ID(),TransparentTexture); @@ -70,7 +81,7 @@ public class MaterialsCache { Material.DiffuseColour().get(Offset,data); Offset += VulkanUtils.VEC4_SIZE; - data.putInt(Offset, ValidTexture ? 1 : 0); + data.putInt(Offset, hasDiffuseTexture ? 1 : 0); Offset += VulkanUtils.INT_SIZE; data.putInt(Offset, textureCache.GetPosition(TexturePath)); Offset += VulkanUtils.INT_SIZE; @@ -79,17 +90,17 @@ public class MaterialsCache { boolean hasNormalMap = NormalMap != null && !NormalMap.isEmpty(); if(hasNormalMap){ textureCache.AddTexture(VkCtx,NormalMap,NormalMap,VK_FORMAT_R8G8B8A8_UNORM); - } + }else NormalMap = "resources/EngineResources/Texture/NoTexture.png"; data.putInt(Offset, hasNormalMap ? 1 : 0); Offset += VulkanUtils.INT_SIZE; data.putInt(Offset, textureCache.GetPosition(NormalMap)); Offset += VulkanUtils.INT_SIZE; String RoughnessMap = Material.MetalRoughnessMap(); - boolean hasRoughness = RoughnessMap != null && !RoughnessMap.isEmpty(); + boolean hasRoughness = RoughnessMap != null && !RoughnessMap.equals("null") && !RoughnessMap.isEmpty(); if(hasRoughness){ textureCache.AddTexture(VkCtx,RoughnessMap,RoughnessMap,VK_FORMAT_R8G8B8A8_UNORM); - } + }else RoughnessMap = "resources/EngineResources/Texture/NoTexture.png"; data.putInt(Offset, hasRoughness ? 1 : 0); Offset += VulkanUtils.INT_SIZE; data.putInt(Offset, textureCache.GetPosition(RoughnessMap)); @@ -99,6 +110,48 @@ public class MaterialsCache { Offset += VulkanUtils.FLOAT_SIZE; data.putFloat(Offset, Material.Metallic()); Offset += VulkanUtils.FLOAT_SIZE; + + if(Material.EmissiveColour() != null) { + Material.EmissiveColour().get(Offset, data); + } + else new Vector4f(0,0,0,0).get(Offset,data); + Offset += VulkanUtils.VEC4_SIZE; + String EmissiveMap = Material.EmissiveTexture(); + boolean hasEmissiveMap = EmissiveMap != null && !EmissiveMap.equals("null") && !EmissiveMap.isEmpty(); + if(hasEmissiveMap){ + textureCache.AddTexture(VkCtx,EmissiveMap,EmissiveMap,VK_FORMAT_R8G8B8A8_UNORM); + } else EmissiveMap = "resources/EngineResources/Texture/NoTexture.png"; + data.putInt(Offset, hasEmissiveMap ? 1 : 0); + Offset += VulkanUtils.INT_SIZE; + data.putInt(Offset, textureCache.GetPosition(EmissiveMap)); + Offset += VulkanUtils.INT_SIZE; + + String TranslucencyMap = Material.TranslucencyTexture(); + boolean hasTranslucency = TranslucencyMap != null && !TranslucencyMap.equals("null") && !TranslucencyMap.isEmpty(); + if(hasTranslucency){ + textureCache.AddTexture(VkCtx,TranslucencyMap,TranslucencyMap,VK_FORMAT_R8G8B8A8_UNORM); + }else TranslucencyMap = "resources/EngineResources/Texture/NoTexture.png"; + data.putInt(Offset, hasTranslucency ? 1 : 0); + Offset += VulkanUtils.INT_SIZE; + data.putInt(Offset, textureCache.GetPosition(TranslucencyMap)); + Offset += VulkanUtils.INT_SIZE; + + data.putFloat(Offset, Material.Translucency()); + Offset += VulkanUtils.FLOAT_SIZE; + + String OpacityMap = Material.OpacityTexture(); + boolean hasOpacity = OpacityMap != null && !OpacityMap.equals("null") && !OpacityMap.isEmpty(); + if(hasOpacity){ + textureCache.AddTexture(VkCtx,OpacityMap,OpacityMap,VK_FORMAT_R8G8B8A8_UNORM); + }else OpacityMap = "resources/EngineResources/Texture/NoTexture.png"; + data.putInt(Offset, hasOpacity ? 1 : 0); + Offset += VulkanUtils.INT_SIZE; + data.putInt(Offset, textureCache.GetPosition(OpacityMap)); + Offset += VulkanUtils.INT_SIZE; + + data.putFloat(Offset, Material.Opacity()); + Offset += VulkanUtils.FLOAT_SIZE; + Offset = materialBaseOffset + MATERIAL_SIZE; } // data.position(0); 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 8b39f45..2ffc790 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,7 +205,12 @@ public class SpriteRenderer { public void LoadMaterials(VulkanContext VkCtx, MaterialsCache materialsCache, TextureCache textureCache){ DescriptorAllocator descriptorAllocator = VkCtx.GetDescriptorAllocator(); Device device = VkCtx.GetDevice(); - List imageViews = textureCache.GetTextureList().stream().map(ITexture::GetImageView).toList(); + List imageViews = new ArrayList<>(textureCache.GetAll2DTextures().stream().map(ITexture::GetImageView).toList()); + + ImageView fallback = textureCache.GetTexture("resources/EngineResources/Texture/NoTexture.png").GetImageView(); + while (imageViews.size() < TextureCache.MAX_TEXTURES) { + imageViews.add(fallback); + } DescriptorSet descriptorSet = VkCtx.GetDescriptorAllocator().AddDescriptorSet(device,DESCRIPTOR_ID_TEXTURE,TextDescriptorSetLayout); descriptorSet.SetImageArray(device,imageViews,TextureSampler,0); } 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 08261b5..20ee739 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 @@ -108,7 +108,7 @@ public class DeferredSceneRender implements SceneRenderer {//dynamic rendering public DeferredSceneRender(VulkanContext vulkanContext, EngineInstance engineInstance){ ClearValueColour = VkClearValue.calloc().color( c -> c.float32(0, 0.0f).float32(1, 0.0f).float32(2, 0.0f).float32(3, 0.0f)); - ClearValueDepth = VkClearValue.calloc().color(c -> c.float32(0, 1.0f)); + ClearValueDepth = VkClearValue.calloc().color(c -> c.float32(0, 0.0f)); MRTAttachments = new MultiRenderTargetAttachments(vulkanContext); AttachmentInfoColour = CreateColourAttachmentInfo(MRTAttachments, ClearValueColour); AttachmentInfoDepth = CreateDepthAttachmentInfo(MRTAttachments, ClearValueDepth); @@ -241,7 +241,10 @@ public class DeferredSceneRender implements SceneRenderer {//dynamic rendering MultiRenderTargetAttachments.POSITION_FORMAT, MultiRenderTargetAttachments.ALBEDO_FORMAT, MultiRenderTargetAttachments.NORMAL_FORMAT, - MultiRenderTargetAttachments.PBR_FORMAT + MultiRenderTargetAttachments.PBR_FORMAT, + MultiRenderTargetAttachments.EMISSIVE_FORMAT, + MultiRenderTargetAttachments.TRANSLUCECNY_FORMAT, + MultiRenderTargetAttachments.OPACITY_FORMAT }; try (MemoryStack MemStack = MemoryStack.stackPush()) { @@ -279,7 +282,10 @@ public class DeferredSceneRender implements SceneRenderer {//dynamic rendering private static Pipeline CreatePipeline(VulkanContext VkCtx, ShaderModule[] ShaderModules, DescriptorSetLayout[] DescriptorSetLayouts, boolean DepthWrite, boolean DualRender, boolean Blending, boolean AlphaToCoverage, int BlendingMethod){ var vertexBufferStructure = new VertexBufferStructure(); var BuildInfo = new PipelineBuildInfo(ShaderModules,vertexBufferStructure.getVertexInput(),new int[]{ - MultiRenderTargetAttachments.POSITION_FORMAT, MultiRenderTargetAttachments.ALBEDO_FORMAT, MultiRenderTargetAttachments.NORMAL_FORMAT, MultiRenderTargetAttachments.PBR_FORMAT}) + MultiRenderTargetAttachments.POSITION_FORMAT, MultiRenderTargetAttachments.ALBEDO_FORMAT, + MultiRenderTargetAttachments.NORMAL_FORMAT, MultiRenderTargetAttachments.PBR_FORMAT, + MultiRenderTargetAttachments.EMISSIVE_FORMAT, MultiRenderTargetAttachments.TRANSLUCECNY_FORMAT, + MultiRenderTargetAttachments.OPACITY_FORMAT}) .SetDepthFormat(MultiRenderTargetAttachments.DEPTH_FORMAT) .SetDepthWrite(DepthWrite) .SetPushConstantRanges( @@ -318,10 +324,11 @@ public class DeferredSceneRender implements SceneRenderer {//dynamic rendering VK_IMAGE_ASPECT_COLOR_BIT); } VulkanUtils.ImageBarrier(MemStack, CommandHandle, MRTAttachments.GetDepthAttachment().GetVkImage().getVulkanImage(), - VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL, + VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, + VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT, - VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT, - VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, + VK_ACCESS_2_NONE, + VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_IMAGE_ASPECT_DEPTH_BIT); long InitialTime = System.nanoTime(); @@ -427,13 +434,17 @@ public class DeferredSceneRender implements SceneRenderer {//dynamic rendering var VkMesh = VkMeshList.get(j); String MaterialID = VkMesh.MaterialID(); int MaterialIndex = materialsCache.GetPosition(MaterialID); + if(MaterialIndex == -1) { + continue; + } VulkanMaterial vulkanMaterial = materialsCache.GetMaterial(MaterialID); if (vulkanMaterial == null) { Logger.warn("Mesh [{}] in model [{}] does not have material", j, model.GetID()); continue; } if (DualPassRendering || vulkanMaterial.HasTransparency() == Transparent) { - SetPushConstants(CommandHandle, Actor.GetModelMatrix(), MaterialIndex); + if(DualPassRendering) SetDualPassPushConstants(CommandHandle, Actor.GetModelMatrix(), MaterialIndex, Transparent); + else SetPushConstants(CommandHandle, Actor.GetModelMatrix(), MaterialIndex); vertexBuffer.put(0, VkMesh.VerticesBuffer().GetBuffer()); vkCmdBindVertexBuffers(CommandHandle, 0, vertexBuffer, offsets); vkCmdBindIndexBuffer(CommandHandle, VkMesh.IndicesBuffer().GetBuffer(), 0, VK_INDEX_TYPE_UINT32); @@ -447,6 +458,15 @@ public class DeferredSceneRender implements SceneRenderer {//dynamic rendering } } + private void SetDualPassPushConstants(VkCommandBuffer CmdHandle, Matrix4f ModelMatrix, int MaterialIndex, boolean Transparent){ + ModelMatrix.get(0,PushConstBuffer); + PushConstBuffer.putInt(VulkanUtils.MATRIX4X4_SIZE, MaterialIndex); + vkCmdPushConstants(CmdHandle, Transparent? VkPipelineTranslucent.GetVulkanPipelineLayout() : VkPipelineOpaque.GetVulkanPipelineLayout(), VK_SHADER_STAGE_VERTEX_BIT, 0, + PushConstBuffer.slice(0,VulkanUtils.MATRIX4X4_SIZE)); + vkCmdPushConstants(CmdHandle, Transparent? VkPipelineTranslucent.GetVulkanPipelineLayout() : VkPipelineOpaque.GetVulkanPipelineLayout(), VK_SHADER_STAGE_FRAGMENT_BIT, VulkanUtils.MATRIX4X4_SIZE, + PushConstBuffer.slice(VulkanUtils.MATRIX4X4_SIZE, VulkanUtils.INT_SIZE)); + } + private void SetPushConstants(VkCommandBuffer CmdHandle, Matrix4f ModelMatrix, int MaterialIndex){ ModelMatrix.get(0,PushConstBuffer); PushConstBuffer.putInt(VulkanUtils.MATRIX4X4_SIZE, MaterialIndex); @@ -477,7 +497,12 @@ public class DeferredSceneRender implements SceneRenderer {//dynamic rendering var buffer = materialsCache.GetMaterialsBuffer(); descSet.SetBuffer(device, buffer, buffer.GetRequestedSize(), layoutInfo.Binding(), layoutInfo.DescriptorType()); - List imageViews = textureCache.GetTextureList().stream().map(ITexture::GetImageView).toList(); + List imageViews = new ArrayList<>(textureCache.GetAll2DTextures().stream().map(ITexture::GetImageView).toList()); + + ImageView fallback = textureCache.GetTexture("resources/EngineResources/Texture/NoTexture.png").GetImageView(); + while (imageViews.size() < TextureCache.MAX_TEXTURES) { + imageViews.add(fallback); + } descSet = VkCtx.GetDescriptorAllocator().AddDescriptorSet(device, DESCRIPTOR_ID_TEXT, descriptorLayoutTexture); descSet.SetImageArray(device, imageViews, textureSampler, 0); diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Structure/DisplayToScreen/ForwardSceneRender.java b/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Structure/DisplayToScreen/ForwardSceneRender.java index 82d7664..1460682 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Structure/DisplayToScreen/ForwardSceneRender.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Structure/DisplayToScreen/ForwardSceneRender.java @@ -32,6 +32,7 @@ import org.tinylog.Logger; import java.nio.ByteBuffer; import java.nio.LongBuffer; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -117,7 +118,7 @@ public class ForwardSceneRender implements SceneRenderer {//dynamic rendering public ForwardSceneRender(VulkanContext vulkanContext){ ClearValueColour = VkClearValue.calloc().color( c -> c.float32(0, R).float32(1, G).float32(2, B).float32(3, 1.0f)); - ClearValueDepth = VkClearValue.calloc().color(c -> c.float32(0, 1.0f)); + ClearValueDepth = VkClearValue.calloc().color(c -> c.float32(0, 0.0f)); CreateRenderAttachments(vulkanContext); PushConstBuffer = (MemoryUtil.memAlloc(PUSH_CONSTANTS_SIZE)); @@ -250,10 +251,10 @@ public class ForwardSceneRender implements SceneRenderer {//dynamic rendering private static Pipeline CreateSkyboxPipeline(VulkanContext VkCtx, ShaderModule[] ShaderModules, DescriptorSetLayout[] DescriptorSetLayouts, boolean DepthWrite, boolean DualRender, boolean Blending, boolean AlphaToCoverage){ int[] skyboxFormats = new int[] { - MultiRenderTargetAttachments.POSITION_FORMAT, - MultiRenderTargetAttachments.ALBEDO_FORMAT, - MultiRenderTargetAttachments.NORMAL_FORMAT, - MultiRenderTargetAttachments.PBR_FORMAT + MultiRenderTargetAttachments.POSITION_FORMAT, MultiRenderTargetAttachments.ALBEDO_FORMAT, + MultiRenderTargetAttachments.NORMAL_FORMAT, MultiRenderTargetAttachments.PBR_FORMAT, + MultiRenderTargetAttachments.EMISSIVE_FORMAT, MultiRenderTargetAttachments.TRANSLUCECNY_FORMAT, + MultiRenderTargetAttachments.OPACITY_FORMAT }; try (MemoryStack MemStack = MemoryStack.stackPush()) { @@ -292,7 +293,10 @@ public class ForwardSceneRender implements SceneRenderer {//dynamic rendering private static Pipeline CreatePipeline(VulkanContext VkCtx, ShaderModule[] ShaderModules, DescriptorSetLayout[] DescriptorSetLayouts, boolean DepthWrite, boolean DualRender, boolean Blending, boolean AlphaToCoverage, int BlendingMethod){ var vertexBufferStructure = new VertexBufferStructure(); var BuildInfo = new PipelineBuildInfo(ShaderModules,vertexBufferStructure.getVertexInput(),new int[]{ - MultiRenderTargetAttachments.POSITION_FORMAT, MultiRenderTargetAttachments.ALBEDO_FORMAT, MultiRenderTargetAttachments.NORMAL_FORMAT, MultiRenderTargetAttachments.PBR_FORMAT}) + MultiRenderTargetAttachments.POSITION_FORMAT, MultiRenderTargetAttachments.ALBEDO_FORMAT, + MultiRenderTargetAttachments.NORMAL_FORMAT, MultiRenderTargetAttachments.PBR_FORMAT, + MultiRenderTargetAttachments.EMISSIVE_FORMAT, MultiRenderTargetAttachments.TRANSLUCECNY_FORMAT, + MultiRenderTargetAttachments.OPACITY_FORMAT}) .SetDepthFormat(MultiRenderTargetAttachments.DEPTH_FORMAT) .SetDepthWrite(DepthWrite) .SetPushConstantRanges( @@ -415,6 +419,9 @@ public class ForwardSceneRender implements SceneRenderer {//dynamic rendering var VkMesh = VkMeshList.get(j); String MaterialID = VkMesh.MaterialID(); int MaterialIndex = materialsCache.GetPosition(MaterialID); + if(MaterialIndex == -1) { + continue; + } VulkanMaterial vulkanMaterial = materialsCache.GetMaterial(MaterialID); if (vulkanMaterial == null) { Logger.warn("Mesh [{}] in model [{}] does not have material", j, model.GetID()); @@ -461,7 +468,12 @@ public class ForwardSceneRender implements SceneRenderer {//dynamic rendering DescriptorSetLayout.LayoutInformation LayoutInfo = descriptorLayoutFragStorage.GetLayoutInfo(); var Buffer = materialsCache.GetMaterialsBuffer(); descriptorSet.SetBuffer(device,Buffer,Buffer.GetRequestedSize(),LayoutInfo.Binding(),LayoutInfo.DescriptorType()); - List imageViews = textureCache.GetTextureList().stream().map(ITexture::GetImageView).toList(); + List imageViews = new ArrayList<>(textureCache.GetAll2DTextures().stream().map(ITexture::GetImageView).toList()); + + ImageView fallback = textureCache.GetTexture("resources/EngineResources/Texture/NoTexture.png").GetImageView(); + while (imageViews.size() < TextureCache.MAX_TEXTURES) { + imageViews.add(fallback); + } descriptorSet = VkCtx.GetDescriptorAllocator().AddDescriptorSet(device,DESCRIPTOR_ID_TEXT,descriptorLayoutTexture); descriptorSet.SetImageArray(device,imageViews,textureSampler,0); DescriptorSet descSetSkyBox = descriptorAllocator.AddDescriptorSet(device, DESCRIPTOR_ID_SKYBOX_CUBEMAP, descriptorLayoutSkyboxTexture); diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Structure/SwapChain/SwapChain.java b/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Structure/SwapChain/SwapChain.java index 6e57047..561b8cb 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Structure/SwapChain/SwapChain.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/RenderingAPI/Vulkan/Structure/SwapChain/SwapChain.java @@ -18,6 +18,7 @@ import java.util.Arrays; import static net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Util.VulkanUtils.vkCheck; import static org.lwjgl.vulkan.KHRSurface.VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; +import static org.lwjgl.vulkan.KHRSurface.VK_ERROR_SURFACE_LOST_KHR; import static org.lwjgl.vulkan.VK13.*; public class SwapChain { @@ -102,6 +103,19 @@ public class SwapChain { return ReturnResult; } + private static String VkResultName(int result) { + return switch (result) { + case VK_SUCCESS -> "VK_SUCCESS"; + case KHRSwapchain.VK_SUBOPTIMAL_KHR -> "VK_SUBOPTIMAL_KHR"; + case KHRSwapchain.VK_ERROR_OUT_OF_DATE_KHR -> "VK_ERROR_OUT_OF_DATE_KHR"; + case VK_ERROR_DEVICE_LOST -> "VK_ERROR_DEVICE_LOST"; + case VK_ERROR_OUT_OF_HOST_MEMORY -> "VK_ERROR_OUT_OF_HOST_MEMORY"; + case VK_ERROR_OUT_OF_DEVICE_MEMORY -> "VK_ERROR_OUT_OF_DEVICE_MEMORY"; + case VK_ERROR_SURFACE_LOST_KHR -> "VK_ERROR_SURFACE_LOST_KHR"; + default -> "Unknown Vulkan error"; + }; + } + public int FetchNextImage(Device device, Semaphore ImageFetchSemaphore){ int ImageIndex; try(var MemStack = MemoryStack.stackPush()){ @@ -112,8 +126,10 @@ public class SwapChain { } else if (Error == KHRSwapchain.VK_SUBOPTIMAL_KHR){ //Logger.warn("Suboptimal surface properties match, not fatal"); + } else if (Error == VK_ERROR_DEVICE_LOST) { + throw new RuntimeException("Vulkan device was lost while acquiring the next swapchain image. This usually means an earlier GPU operation was invalid. Result: " + VkResultName(Error) + " (" + Error + ")"); } else if (Error != VK_SUCCESS){ - throw new RuntimeException("Failed to fetch next image in the swapchain: " + Error); + throw new RuntimeException("Failed to fetch next image in the swapchain: " + VkResultName(Error) + " (" + Error + ")"); } ImageIndex = IntPointer.get(0); } @@ -136,8 +152,8 @@ public class SwapChain { } else if (Error == KHRSwapchain.VK_SUBOPTIMAL_KHR){ //Logger.warn("Suboptimal surface properties match, not fatal"); } else if (Error != VK_SUCCESS){ - Logger.debug("Failure in Present Image"); - throw new RuntimeException("failed to present KHR: " + Error); + Logger.debug("Failure in Present Image: " + VkResultName(Error) + " (" + Error + ")"); + throw new RuntimeException("failed to present KHR: " + VkResultName(Error) + " (" + Error + ")"); } } return resize; diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Threads/EngineThread.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Threads/EngineThread.java index 1a5ad07..28eba78 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Threads/EngineThread.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Threads/EngineThread.java @@ -80,7 +80,7 @@ public class EngineThread implements IEngineThread{ Logger.debug("{} Thread Started",ThreadName); EngineAccuracy = EngineConfig.getInstance().getAccuracy(); OriginalAccuracy = EngineAccuracy; - while (running && !PrimaryRuntime.CanClose && internalRunning && !Thread.currentThread().isInterrupted()){ + while (running && internalRunning && !Thread.currentThread().isInterrupted()){ long now = System.nanoTime(); FrameTimes[0] = now - InitialTime; FrameTimes[1] += FrameTimes[0]; diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Threads/RenderThread.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Threads/RenderThread.java index dd7ff71..532e91b 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Threads/RenderThread.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Threads/RenderThread.java @@ -17,7 +17,7 @@ public class RenderThread extends EngineThread { private Renderer render; private final InitData initData; public static int VulkanCrashCount = 0; - public static boolean Headless = false; + public static boolean Headless = false; public RenderThread(EngineInstance engineInstance, InitData initData, GameLogic appLogic) { //this.window = window; diff --git a/src/main/java/net/halbear/Terrain4J/EngineCore/Threads/VirtualEngineThread.java b/src/main/java/net/halbear/Terrain4J/EngineCore/Threads/VirtualEngineThread.java index e90dd75..b9bce35 100644 --- a/src/main/java/net/halbear/Terrain4J/EngineCore/Threads/VirtualEngineThread.java +++ b/src/main/java/net/halbear/Terrain4J/EngineCore/Threads/VirtualEngineThread.java @@ -108,7 +108,7 @@ public class VirtualEngineThread implements IEngineThread{ Logger.debug("{} Thread Started",ThreadName); EngineAccuracy = EngineConfig.getInstance().getAccuracy(); OriginalAccuracy = EngineAccuracy; - while (EngineThread.running && !PrimaryRuntime.CanClose && internalRunning && !Thread.currentThread().isInterrupted()){ + while (EngineThread.running && internalRunning && !Thread.currentThread().isInterrupted()){ long now = System.nanoTime(); FrameTimes[0] = now - InitialTime; FrameTimes[1] += FrameTimes[0]; diff --git a/terrain4j.properties b/terrain4j.properties index a6e6515..28ff3f5 100644 --- a/terrain4j.properties +++ b/terrain4j.properties @@ -35,5 +35,5 @@ throttle_on_unfocus=false user_display_name=TheSigma vkValidated=true vsync=false -z_near_plane=0.1f -z_far_plane=10000.0f +z_far_plane=0.1f +z_near_plane=16384.0f