From 7cf073f0791d7df459a97859004c0707783452f8 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 25 Jul 2025 22:28:28 +0300 Subject: [PATCH] fix: skybox is not visible behind translucent blocks --- res/preload.json | 1 + res/shaders/entity.glslf | 15 ++------- res/shaders/entity.glslv | 35 ++++--------------- res/shaders/lib/commons.glsl | 9 +---- res/shaders/lib/lighting.glsl | 5 +++ res/shaders/lib/sky.glsl | 14 ++++++++ res/shaders/lib/world_fragment_header.glsl | 17 ++++++++++ res/shaders/lib/world_uniforms.glsl | 15 +++++++++ res/shaders/lib/world_vertex_header.glsl | 17 ++++++++++ res/shaders/main.glslf | 19 ++--------- res/shaders/main.glslv | 37 +++++--------------- res/shaders/translucent.glslf | 38 +++++++++++++++++++++ res/shaders/translucent.glslv | 39 ++++++++++++++++++++++ src/graphics/render/WorldRenderer.cpp | 18 +++++++--- 14 files changed, 183 insertions(+), 96 deletions(-) create mode 100644 res/shaders/lib/sky.glsl create mode 100644 res/shaders/lib/world_fragment_header.glsl create mode 100644 res/shaders/lib/world_uniforms.glsl create mode 100644 res/shaders/lib/world_vertex_header.glsl create mode 100644 res/shaders/translucent.glslf create mode 100644 res/shaders/translucent.glslv diff --git a/res/preload.json b/res/preload.json index eb41f40d..887b0e26 100644 --- a/res/preload.json +++ b/res/preload.json @@ -5,6 +5,7 @@ "main", "lines", "entity", + "translucent", "background", "skybox_gen", "shadows" diff --git a/res/shaders/entity.glslf b/res/shaders/entity.glslf index 4d4fadba..f3293adb 100644 --- a/res/shaders/entity.glslf +++ b/res/shaders/entity.glslf @@ -3,27 +3,18 @@ layout (location = 1) out vec4 f_position; layout (location = 2) out vec4 f_normal; layout (location = 3) out vec4 f_emission; -in float a_distance; -in float a_fog; -in vec2 a_texCoord; -in vec3 a_dir; -in vec3 a_normal; -in vec3 a_position; -in vec3 a_realnormal; +#include + in vec4 a_color; -in vec4 a_modelpos; -in float a_emission; uniform sampler2D u_texture0; -uniform samplerCube u_skybox; + uniform vec3 u_fogColor; uniform float u_fogFactor; uniform float u_fogCurve; uniform bool u_alphaClip; uniform vec3 u_sunDir; -#include - void main() { vec4 texColor = texture(u_texture0, a_texCoord); float alpha = a_color.a * texColor.a; diff --git a/res/shaders/entity.glslv b/res/shaders/entity.glslv index d7b6d3e0..c337ddb2 100644 --- a/res/shaders/entity.glslv +++ b/res/shaders/entity.glslv @@ -6,44 +6,23 @@ layout (location = 2) in vec3 v_color; layout (location = 3) in vec4 v_light; layout (location = 4) in vec4 v_normal; -out float a_distance; -out float a_fog; -out vec2 a_texCoord; -out vec3 a_dir; -out vec3 a_normal; -out vec3 a_position; -out vec3 a_realnormal; -out vec4 a_color; -out vec4 a_modelpos; -out float a_emission; - -uniform mat4 u_model; -uniform mat4 u_proj; -uniform mat4 u_view; -uniform vec3 u_cameraPos; -uniform float u_gamma; -uniform float u_opacity; -uniform float u_timer; -uniform samplerCube u_skybox; - -uniform vec3 u_torchlightColor; -uniform float u_torchlightDistance; - +#include #include #include +#include + +out vec4 a_color; void main() { a_modelpos = u_model * vec4(v_position, 1.0); vec3 pos3d = a_modelpos.xyz - u_cameraPos; - a_modelpos.xyz = apply_planet_curvature(a_modelpos.xyz, pos3d); a_realnormal = v_normal.xyz * 2.0 - 1.0; a_normal = calc_screen_normal(a_realnormal); - vec3 light = v_light.rgb; - float torchlight = calc_torch_light(a_realnormal, a_modelpos.xyz); - light += torchlight * u_torchlightColor; - a_color = vec4(pow(light, vec3(u_gamma)), 1.0f); + a_color = vec4(calc_torch_light( + v_light.rgb, a_realnormal, a_modelpos.xyz, u_torchlightColor, u_gamma + ), 1.0); a_texCoord = v_texCoord; a_dir = a_modelpos.xyz - u_cameraPos; diff --git a/res/shaders/lib/commons.glsl b/res/shaders/lib/commons.glsl index 3701fcc3..e13b0ce1 100644 --- a/res/shaders/lib/commons.glsl +++ b/res/shaders/lib/commons.glsl @@ -1,14 +1,7 @@ #ifndef COMMONS_GLSL_ #define COMMONS_GLSL_ -#include -vec3 pick_sky_color(samplerCube cubemap) { - vec3 skyLightColor = texture(cubemap, vec3(0.4f, 0.0f, 0.4f)).rgb; - skyLightColor *= SKY_LIGHT_TINT; - skyLightColor = min(vec3(1.0f), skyLightColor * SKY_LIGHT_MUL); - skyLightColor = max(MIN_SKY_LIGHT, skyLightColor); - return skyLightColor; -} +#include vec3 apply_planet_curvature(vec3 modelPos, vec3 pos3d) { modelPos.y -= pow(length(pos3d.xz) * CURVATURE_FACTOR, 3.0f); diff --git a/res/shaders/lib/lighting.glsl b/res/shaders/lib/lighting.glsl index c9e14920..54e076ae 100644 --- a/res/shaders/lib/lighting.glsl +++ b/res/shaders/lib/lighting.glsl @@ -6,6 +6,11 @@ float calc_torch_light(vec3 normal, vec3 modelpos) { * max(0.0, -dot(normal, normalize(modelpos - u_cameraPos))); } +vec3 calc_torch_light(vec3 light, vec3 normal, vec3 modelpos, vec3 torchLightColor, float gamma) { + float torchlight = calc_torch_light(normal, modelpos); + return pow(light + torchlight * torchLightColor, vec3(gamma)); +} + vec3 calc_screen_normal(vec3 normal) { return transpose(inverse(mat3(u_view * u_model))) * normal; } diff --git a/res/shaders/lib/sky.glsl b/res/shaders/lib/sky.glsl new file mode 100644 index 00000000..771f37f2 --- /dev/null +++ b/res/shaders/lib/sky.glsl @@ -0,0 +1,14 @@ +#ifndef COMMONS_SKY_ +#define COMMONS_SKY_ + +#include + +vec3 pick_sky_color(samplerCube cubemap) { + vec3 skyLightColor = texture(cubemap, vec3(0.4f, 0.0f, 0.4f)).rgb; + skyLightColor *= SKY_LIGHT_TINT; + skyLightColor = min(vec3(1.0f), skyLightColor * SKY_LIGHT_MUL); + skyLightColor = max(MIN_SKY_LIGHT, skyLightColor); + return skyLightColor; +} + +#endif // COMMONS_SKY_ diff --git a/res/shaders/lib/world_fragment_header.glsl b/res/shaders/lib/world_fragment_header.glsl new file mode 100644 index 00000000..8e6e88bd --- /dev/null +++ b/res/shaders/lib/world_fragment_header.glsl @@ -0,0 +1,17 @@ +#ifndef GLSL_WORLD_FRAGMENT_HEADER_ +#define GLSL_WORLD_FRAGMENT_HEADER_ + +in float a_distance; +in float a_fog; +in vec2 a_texCoord; +in vec3 a_dir; +in vec3 a_normal; +in vec3 a_position; +in vec3 a_realnormal; +in vec3 a_skyLight; +in vec4 a_modelpos; +in float a_emission; + +#include + +#endif // GLSL_WORLD_FRAGMENT_HEADER_ diff --git a/res/shaders/lib/world_uniforms.glsl b/res/shaders/lib/world_uniforms.glsl new file mode 100644 index 00000000..20c8f529 --- /dev/null +++ b/res/shaders/lib/world_uniforms.glsl @@ -0,0 +1,15 @@ +#ifndef GLSL_WORLD_UNIFORMS_ +#define GLSL_WORLD_UNIFORMS_ + +uniform mat4 u_model; +uniform mat4 u_proj; +uniform mat4 u_view; +uniform vec3 u_cameraPos; +uniform float u_gamma; +uniform float u_opacity; +uniform float u_timer; +uniform samplerCube u_skybox; +uniform vec3 u_torchlightColor; +uniform float u_torchlightDistance; + +#endif // GLSL_WORLD_UNIFORMS_ diff --git a/res/shaders/lib/world_vertex_header.glsl b/res/shaders/lib/world_vertex_header.glsl new file mode 100644 index 00000000..9e755027 --- /dev/null +++ b/res/shaders/lib/world_vertex_header.glsl @@ -0,0 +1,17 @@ +#ifndef GLSL_WORLD_VERTEX_HEADER_ +#define GLSL_WORLD_VERTEX_HEADER_ + +out float a_distance; +out float a_fog; +out vec2 a_texCoord; +out vec3 a_dir; +out vec3 a_normal; +out vec3 a_position; +out vec3 a_realnormal; +out vec3 a_skyLight; +out vec4 a_modelpos; +out float a_emission; + +#include + +#endif // GLSL_WORLD_VERTEX_HEADER_ diff --git a/res/shaders/main.glslf b/res/shaders/main.glslf index f7336d9a..115cb927 100644 --- a/res/shaders/main.glslf +++ b/res/shaders/main.glslf @@ -3,20 +3,11 @@ layout (location = 1) out vec4 f_position; layout (location = 2) out vec4 f_normal; layout (location = 3) out vec4 f_emission; -in float a_distance; -in float a_fog; -in vec2 a_texCoord; -in vec3 a_dir; -in vec3 a_normal; -in vec3 a_position; -in vec3 a_realnormal; -in vec3 a_skyLight; -in vec4 a_modelpos; +#include + in vec4 a_torchLight; -in float a_emission; uniform sampler2D u_texture0; -uniform samplerCube u_skybox; uniform vec3 u_sunDir; // flags @@ -24,8 +15,6 @@ uniform bool u_alphaClip; uniform bool u_debugLights; uniform bool u_debugNormals; -#include - void main() { vec4 texColor = texture(u_texture0, a_texCoord); float alpha = texColor.a; @@ -39,9 +28,7 @@ void main() { } if (u_debugLights) texColor.rgb = u_debugNormals ? (a_normal * 0.5 + 0.5) : vec3(1.0); - else if (u_debugNormals) { - texColor.rgb *= a_normal * 0.5 + 0.5; - } + f_color = texColor; f_color.rgb *= min(vec3(1.0), a_torchLight.rgb + a_skyLight); diff --git a/res/shaders/main.glslv b/res/shaders/main.glslv index 4d50e5d9..3d722029 100644 --- a/res/shaders/main.glslv +++ b/res/shaders/main.glslv @@ -5,44 +5,23 @@ layout (location = 1) in vec2 v_texCoord; layout (location = 2) in vec4 v_light; layout (location = 3) in vec4 v_normal; -out float a_distance; -out float a_fog; -out vec2 a_texCoord; -out vec3 a_dir; -out vec3 a_normal; -out vec3 a_position; -out vec3 a_realnormal; -out vec4 a_torchLight; -out vec3 a_skyLight; -out vec4 a_modelpos; -out float a_emission; - -uniform mat4 u_model; -uniform mat4 u_proj; -uniform mat4 u_view; -uniform vec3 u_cameraPos; -uniform float u_gamma; -uniform float u_timer; -uniform samplerCube u_skybox; - -uniform vec3 u_torchlightColor; -uniform float u_torchlightDistance; - +#include #include #include +#include + +out vec4 a_torchLight; void main() { a_modelpos = u_model * vec4(v_position, 1.0f); vec3 pos3d = a_modelpos.xyz - u_cameraPos; - a_modelpos.xyz = apply_planet_curvature(a_modelpos.xyz, pos3d); a_realnormal = v_normal.xyz * 2.0 - 1.0; a_normal = calc_screen_normal(a_realnormal); - vec3 light = v_light.rgb; - float torchlight = calc_torch_light(a_realnormal, a_modelpos.xyz); - a_torchLight = vec4(pow(light + torchlight * u_torchlightColor, vec3(u_gamma)), 1.0f); - + a_torchLight = vec4(calc_torch_light( + v_light.rgb, a_realnormal, a_modelpos.xyz, u_torchlightColor, u_gamma + ), 1.0); a_texCoord = v_texCoord; a_dir = a_modelpos.xyz - u_cameraPos; @@ -51,9 +30,11 @@ void main() { mat4 viewmodel = u_view * u_model; a_distance = length(viewmodel * vec4(pos3d, 0.0)); + #ifndef ADVANCED_RENDER a_fog = calc_fog(length(viewmodel * vec4(pos3d * FOG_POS_SCALE, 0.0)) / 256.0); #endif + a_emission = v_normal.w; vec4 viewmodelpos = u_view * a_modelpos; diff --git a/res/shaders/translucent.glslf b/res/shaders/translucent.glslf new file mode 100644 index 00000000..e5a852ac --- /dev/null +++ b/res/shaders/translucent.glslf @@ -0,0 +1,38 @@ +layout (location = 0) out vec4 f_color; + +#include + +in vec4 a_torchLight; + +uniform sampler2D u_texture0; +uniform vec3 u_sunDir; + +// flags +uniform bool u_alphaClip; +uniform bool u_debugLights; +uniform bool u_debugNormals; + +#include + +void main() { + vec4 texColor = texture(u_texture0, a_texCoord); + float alpha = texColor.a; + if (u_alphaClip) { + if (alpha < 0.2f) + discard; + alpha = 1.0; + } else { + if (alpha < 0.002f) + discard; + } + if (u_debugLights) + texColor.rgb = u_debugNormals ? (a_normal * 0.5 + 0.5) : vec3(1.0); + + f_color = texColor; + f_color.rgb *= min(vec3(1.0), a_torchLight.rgb + a_skyLight + * calc_shadow(a_modelpos, a_realnormal, length(a_position))); + + vec3 fogColor = texture(u_skybox, a_dir).rgb; + f_color = mix(f_color, vec4(fogColor, 1.0), a_fog); + f_color.a = alpha; +} diff --git a/res/shaders/translucent.glslv b/res/shaders/translucent.glslv new file mode 100644 index 00000000..8c429e97 --- /dev/null +++ b/res/shaders/translucent.glslv @@ -0,0 +1,39 @@ +#include + +layout (location = 0) in vec3 v_position; +layout (location = 1) in vec2 v_texCoord; +layout (location = 2) in vec4 v_light; +layout (location = 3) in vec4 v_normal; + +#include +#include +#include +#include + +out vec4 a_torchLight; + +void main() { + a_modelpos = u_model * vec4(v_position, 1.0f); + vec3 pos3d = a_modelpos.xyz - u_cameraPos; + + a_realnormal = v_normal.xyz * 2.0 - 1.0; + a_normal = calc_screen_normal(a_realnormal); + + a_torchLight = vec4(calc_torch_light( + v_light.rgb, a_realnormal, a_modelpos.xyz, u_torchlightColor, u_gamma + ), 1.0); + a_texCoord = v_texCoord; + + a_dir = a_modelpos.xyz - u_cameraPos; + vec3 skyLightColor = pick_sky_color(u_skybox); + a_skyLight = skyLightColor.rgb*v_light.a; + + mat4 viewmodel = u_view * u_model; + a_distance = length(viewmodel * vec4(pos3d, 0.0)); + a_fog = calc_fog(length(viewmodel * vec4(pos3d * FOG_POS_SCALE, 0.0)) / 256.0); + a_emission = v_normal.w; + + vec4 viewmodelpos = u_view * a_modelpos; + a_position = viewmodelpos.xyz; + gl_Position = u_proj * viewmodelpos; +} diff --git a/src/graphics/render/WorldRenderer.cpp b/src/graphics/render/WorldRenderer.cpp index 30a25430..e8511fa5 100644 --- a/src/graphics/render/WorldRenderer.cpp +++ b/src/graphics/render/WorldRenderer.cpp @@ -220,8 +220,6 @@ void WorldRenderer::renderLevel( if (hudVisible) { renderLines(camera, linesShader, ctx); } - shader.use(); - chunks->drawSortedMeshes(camera, shader); if (!pause) { scripting::on_frontend_render(); @@ -431,6 +429,7 @@ void WorldRenderer::draw( auto& mainShader = assets.require("main"); auto& entityShader = assets.require("entity"); + auto& translucentShader = assets.require("translucent"); auto& deferredShader = assets.require("deferred_lighting").getShader(); const auto& settings = engine.getSettings(); @@ -463,6 +462,7 @@ void WorldRenderer::draw( mainShader.recompile(); entityShader.recompile(); deferredShader.recompile(); + translucentShader.recompile(); prevCTShaderSettings = currentSettings; } @@ -525,6 +525,7 @@ void WorldRenderer::draw( { DrawContext ctx = pctx.sub(); ctx.setDepthTest(true); + if (gbufferPipeline) { postProcessing.bindDepthBuffer(); } else { @@ -533,6 +534,16 @@ void WorldRenderer::draw( // Drawing background sky plane skybox->draw(ctx, camera, assets, worldInfo.daytime, clouds); + { + auto sctx = ctx.sub(); + sctx.setCullFace(true); + skybox->bind(); + translucentShader.use(); + setupWorldShader(translucentShader, camera, settings, fogFactor); + chunks->drawSortedMeshes(camera, translucentShader); + skybox->unbind(); + } + entityShader.use(); setupWorldShader(entityShader, camera, settings, fogFactor); @@ -552,8 +563,7 @@ void WorldRenderer::draw( glBindFramebuffer(GL_FRAMEBUFFER, 0); } postProcessing.render(pctx, assets, timer, camera); - - skybox->unbind(); + if (player.currentCamera == player.fpCamera) { DrawContext ctx = pctx.sub(); ctx.setDepthTest(true);