From e158b384fa7374ef0ca58e42d8aba67a430f834f Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 10 May 2025 14:12:52 +0300 Subject: [PATCH] feat: shadows in fast pipeline & improve lights mix --- res/scripts/hud.lua | 2 +- res/shaders/lib/shadows.glsl | 17 ++++++++-------- res/shaders/main.glslf | 9 +++++---- res/shaders/main.glslv | 10 +++++---- src/graphics/core/PostProcessing.cpp | 1 + src/graphics/render/ChunksRenderer.cpp | 28 ++++++++++++++++++++++++++ src/graphics/render/ChunksRenderer.hpp | 3 +++ src/graphics/render/WorldRenderer.cpp | 14 ++++++------- src/graphics/render/WorldRenderer.hpp | 3 ++- 9 files changed, 62 insertions(+), 25 deletions(-) diff --git a/res/scripts/hud.lua b/res/scripts/hud.lua index 79fe0e42..f415cf39 100644 --- a/res/scripts/hud.lua +++ b/res/scripts/hud.lua @@ -58,5 +58,5 @@ function on_hud_open() local slot = gfx.posteffects.index("core:default") gfx.posteffects.set_effect(slot, "ssao") - gfx.posteffects.set_intensity(slot, 1.0) + --gfx.posteffects.set_intensity(slot, 1.0) end diff --git a/res/shaders/lib/shadows.glsl b/res/shaders/lib/shadows.glsl index db94e9dc..9e96d3ea 100644 --- a/res/shaders/lib/shadows.glsl +++ b/res/shaders/lib/shadows.glsl @@ -12,15 +12,16 @@ float calc_shadow() { shadow = 0.0; if (dot(a_realnormal, u_sunDir) < 0.0) { - for (int x = -1; x <= 1; x++) { - for (int y = -1; y <= 1; y++) { - shadow += texture(u_shadows, projCoords.xyz + vec3( - x * (1.0 / u_shadowsRes), - y * (1.0 / u_shadowsRes), 0.0 - )); - } + const vec3 offsets[4] = vec3[4]( + vec3(0.5, 0.5, 0.0), + vec3(-0.5, 0.5, 0.0), + vec3(0.5, -0.5, 0.0), + vec3(-0.5, -0.5, 0.0) + ); + for (int i = 0; i < 4; i++) { + shadow += texture(u_shadows, projCoords.xyz + offsets[i] / u_shadowsRes); } - shadow /= 9; + shadow /= 4; shadow = shadow * 0.5 + 0.5; } else { shadow = 0.5; diff --git a/res/shaders/main.glslf b/res/shaders/main.glslf index 89e83bbf..cbb29de6 100644 --- a/res/shaders/main.glslf +++ b/res/shaders/main.glslf @@ -2,7 +2,8 @@ layout (location = 0) out vec4 f_color; layout (location = 1) out vec4 f_position; layout (location = 2) out vec4 f_normal; -in vec4 a_color; +in vec4 a_torchLight; +in vec3 a_skyLight; in vec2 a_texCoord; in float a_fog; in vec3 a_position; @@ -31,7 +32,7 @@ void main() { float shadow = calc_shadow(); vec3 fogColor = texture(u_skybox, a_dir).rgb; vec4 texColor = texture(u_texture0, a_texCoord); - float alpha = a_color.a * texColor.a; + float alpha = texColor.a; if (u_alphaClip) { if (alpha < 0.2f) discard; @@ -45,8 +46,8 @@ void main() { else if (u_debugNormals) { texColor.rgb *= a_normal * 0.5 + 0.5; } - f_color = a_color * texColor; - f_color.rgb *= shadow; + f_color = texColor; + f_color.rgb *= min(vec3(1.0), a_torchLight.rgb + a_skyLight * shadow); f_color = mix(f_color, vec4(fogColor, 1.0), a_fog); f_color.a = alpha; f_position = vec4(a_position, 1.0); diff --git a/res/shaders/main.glslv b/res/shaders/main.glslv index 032a6d8e..d7e5b4fc 100644 --- a/res/shaders/main.glslv +++ b/res/shaders/main.glslv @@ -12,7 +12,8 @@ out vec3 a_dir; out vec3 a_normal; out vec3 a_position; out vec3 a_realnormal; -out vec4 a_color; +out vec4 a_torchLight; +out vec3 a_skyLight; out vec4 a_modelpos; uniform mat4 u_model; @@ -38,13 +39,14 @@ void main() { vec3 light = v_light.rgb; float torchlight = calc_torch_light(a_modelpos.xyz); - light += torchlight * u_torchlightColor; - a_color = vec4(pow(light, vec3(u_gamma)),1.0f); + a_torchLight = vec4(pow(light + torchlight * u_torchlightColor, vec3(u_gamma)), 1.0f); + a_texCoord = v_texCoord; a_dir = a_modelpos.xyz - u_cameraPos; vec3 skyLightColor = pick_sky_color(u_skybox); - a_color.rgb = max(a_color.rgb, skyLightColor.rgb*v_light.a); + a_skyLight = skyLightColor.rgb*v_light.a; + //a_color.rgb = max(a_color.rgb, skyLightColor.rgb*v_light.a); a_distance = length(u_view * u_model * vec4(pos3d * FOG_POS_SCALE, 0.0)); a_fog = calc_fog(a_distance / 256.0); diff --git a/src/graphics/core/PostProcessing.cpp b/src/graphics/core/PostProcessing.cpp index ceab2c1d..498782d4 100644 --- a/src/graphics/core/PostProcessing.cpp +++ b/src/graphics/core/PostProcessing.cpp @@ -72,6 +72,7 @@ void PostProcessing::use(DrawContext& context, bool gbufferPipeline) { } context.setFramebuffer(gbuffer.get()); } else { + gbuffer.reset(); refreshFbos(vp.x, vp.y); context.setFramebuffer(fbo.get()); } diff --git a/src/graphics/render/ChunksRenderer.cpp b/src/graphics/render/ChunksRenderer.cpp index 5cc7e81c..8c88931b 100644 --- a/src/graphics/render/ChunksRenderer.cpp +++ b/src/graphics/render/ChunksRenderer.cpp @@ -182,6 +182,34 @@ const Mesh* ChunksRenderer::retrieveChunk( return mesh; } +void ChunksRenderer::drawChunksShadowsPass( + const Camera& camera, Shader& shader +) { + const auto& atlas = assets.require("blocks"); + + atlas.getTexture()->bind(); + + for (int i = indices.size()-1; i >= 0; i--) { + auto& chunk = chunks.getChunks()[indices[i].index]; + if (chunk == nullptr) { + continue; + } + const auto& found = meshes.find({chunk->x, chunk->z}); + if (found == meshes.end()) { + continue; + } + auto mesh = found->second.mesh.get(); + if (mesh) { + glm::vec3 coord( + chunk->x * CHUNK_W + 0.5f, 0.5f, chunk->z * CHUNK_D + 0.5f + ); + glm::mat4 model = glm::translate(glm::mat4(1.0f), coord); + shader.uniformMatrix("u_model", model); + mesh->draw(); + } + } +} + void ChunksRenderer::drawChunks( const Camera& camera, Shader& shader ) { diff --git a/src/graphics/render/ChunksRenderer.hpp b/src/graphics/render/ChunksRenderer.hpp index 4efb9792..fcc8b07d 100644 --- a/src/graphics/render/ChunksRenderer.hpp +++ b/src/graphics/render/ChunksRenderer.hpp @@ -72,6 +72,9 @@ public: const Mesh* getOrRender( const std::shared_ptr& chunk, bool important ); + + void drawChunksShadowsPass(const Camera& camera, Shader& shader); + void drawChunks(const Camera& camera, Shader& shader); void drawSortedMeshes(const Camera& camera, Shader& shader); diff --git a/src/graphics/render/WorldRenderer.cpp b/src/graphics/render/WorldRenderer.cpp index b886c300..71f14a48 100644 --- a/src/graphics/render/WorldRenderer.cpp +++ b/src/graphics/render/WorldRenderer.cpp @@ -103,7 +103,7 @@ WorldRenderer::WorldRenderer( assets->require("skybox_gen") ); - shadowMap = std::make_unique(1024 * 4); + shadowMap = std::make_unique(1024 * 8); shadowCamera = std::make_unique(); } @@ -133,9 +133,9 @@ void WorldRenderer::setupWorldShader( shader.uniform2f("u_lightDir", skybox->getLightDir()); shader.uniform3f("u_cameraPos", camera.position); shader.uniform1i("u_skybox", 1); - shader.uniform1i("u_enableShadows", gbufferPipeline); + shader.uniform1i("u_enableShadows", shadows); - if (gbufferPipeline) { + if (shadows) { shader.uniformMatrix("u_shadowsMatrix", shadowCamera->getProjView()); shader.uniform3f("u_sunDir", shadowCamera->front); shader.uniform1i("u_shadowsRes", shadowMap->getResolution()); @@ -374,7 +374,7 @@ void WorldRenderer::draw( auto& linesShader = assets.require("lines"); auto& shadowsShader = assets.require("shadows"); - if (gbufferPipeline) { + if (shadows) { int resolution = shadowMap->getResolution(); float shadowMapScale = 0.05f; float shadowMapSize = resolution * shadowMapScale; @@ -384,7 +384,7 @@ void WorldRenderer::draw( shadowCamera->perspective = false; shadowCamera->setAspectRatio(1.0f); shadowCamera->rotate( - glm::radians(90.0f - worldInfo.daytime * 360.0f), + glm::radians(fmod(90.0f - worldInfo.daytime * 360.0f, 180.0f)), glm::radians(-40.0f), glm::radians(-0.0f) ); @@ -402,7 +402,7 @@ void WorldRenderer::draw( sctx.setViewport({resolution, resolution}); shadowMap->bind(); setupWorldShader(shadowsShader, *shadowCamera, settings, 0.0f); - chunks->drawChunks(*shadowCamera, shadowsShader); + chunks->drawChunksShadowsPass(*shadowCamera, shadowsShader); shadowMap->unbind(); } } @@ -444,7 +444,7 @@ void WorldRenderer::draw( assets, timer, camera, - gbufferPipeline ? shadowMap->getDepthMap() : 0 + shadows ? shadowMap->getDepthMap() : 0 ); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, 0); diff --git a/src/graphics/render/WorldRenderer.hpp b/src/graphics/render/WorldRenderer.hpp index 2832fca2..8e9d4d01 100644 --- a/src/graphics/render/WorldRenderer.hpp +++ b/src/graphics/render/WorldRenderer.hpp @@ -54,7 +54,8 @@ class WorldRenderer { float timer = 0.0f; bool debug = false; bool lightsDebug = false; - bool gbufferPipeline = true; + bool gbufferPipeline = false; + bool shadows = true; /// @brief Render block selection lines void renderBlockSelection();