From 0bd901d1a604c816b0f5488c80b41e9961abdc6d Mon Sep 17 00:00:00 2001 From: MihailRis Date: Tue, 8 Jul 2025 23:56:22 +0300 Subject: [PATCH] feat: deferred shading (day 2) --- res/shaders/background.glslf | 7 +- res/shaders/background.glslv | 4 +- res/shaders/effect.glslf | 6 +- res/shaders/effects/deferred_lighting.glsl | 21 +++-- res/shaders/entity.glslf | 2 +- res/shaders/entity.glslv | 1 + res/shaders/lib/fog.glsl | 19 +++++ res/shaders/lib/lighting.glsl | 15 ---- res/shaders/lib/shadows.glsl | 10 +-- res/shaders/main.glslf | 7 +- res/shaders/main.glslv | 1 + src/graphics/core/GBuffer.cpp | 18 ++++- src/graphics/core/GBuffer.hpp | 2 + src/graphics/core/PostEffect.cpp | 4 + src/graphics/core/PostEffect.hpp | 2 + src/graphics/core/PostProcessing.cpp | 89 ++++++++++++++++++---- src/graphics/core/PostProcessing.hpp | 13 +++- src/graphics/core/Shader.cpp | 6 ++ src/graphics/core/Shader.hpp | 1 + src/graphics/core/commons.hpp | 10 +++ src/graphics/render/Skybox.cpp | 41 +++++----- src/graphics/render/WorldRenderer.cpp | 47 ++++++++---- src/window/Camera.hpp | 2 +- 23 files changed, 236 insertions(+), 92 deletions(-) create mode 100644 res/shaders/lib/fog.glsl diff --git a/res/shaders/background.glslf b/res/shaders/background.glslf index d485650a..ea4079ba 100644 --- a/res/shaders/background.glslf +++ b/res/shaders/background.glslf @@ -3,11 +3,12 @@ layout (location = 0) out vec4 f_color; layout (location = 1) out vec4 f_position; layout (location = 2) out vec4 f_normal; +uniform mat4 u_view; uniform samplerCube u_skybox; void main(){ - vec3 dir = normalize(v_coord); - f_position = vec4(0.0, 0.0, -1e9, 1.0); - f_normal = vec4(0.0); + vec3 dir = normalize(v_coord) * 1e6; + f_position = u_view * vec4(dir, 1.0); + f_normal = vec4(0.0, 0.0, 1.0, 1.0); f_color = texture(u_skybox, dir); } diff --git a/res/shaders/background.glslv b/res/shaders/background.glslv index 4de0d5b8..a3dfa198 100644 --- a/res/shaders/background.glslv +++ b/res/shaders/background.glslv @@ -7,6 +7,6 @@ uniform float u_ar; uniform float u_zoom; void main(){ - v_coord = (vec4(v_position*vec2(u_ar, 1.0f)*u_zoom, -1.0, 1.0) * u_view).xyz; - gl_Position = vec4(v_position, 0.0, 1.0); + v_coord = (vec4(v_position * vec2(u_ar, 1.0f) * u_zoom, -1.0, 1.0) * u_view).xyz; + gl_Position = vec4(v_position, 1.0 - 1e-6, 1.0); } diff --git a/res/shaders/effect.glslf b/res/shaders/effect.glslf index 792b6c2b..be50d779 100644 --- a/res/shaders/effect.glslf +++ b/res/shaders/effect.glslf @@ -6,13 +6,17 @@ uniform sampler2D u_position; uniform sampler2D u_normal; uniform sampler2D u_noise; uniform sampler2D u_ssao; -uniform sampler2D u_shadows; +uniform samplerCube u_skybox; uniform ivec2 u_screenSize; uniform float u_intensity; uniform float u_timer; uniform bool u_enableShadows; uniform mat4 u_projection; +uniform mat4 u_view; +uniform mat4 u_inverseView; +uniform vec3 u_sunDir; +uniform vec3 u_cameraPos; #include <__effect__> diff --git a/res/shaders/effects/deferred_lighting.glsl b/res/shaders/effects/deferred_lighting.glsl index 79c01435..f21b1b4a 100644 --- a/res/shaders/effects/deferred_lighting.glsl +++ b/res/shaders/effects/deferred_lighting.glsl @@ -1,15 +1,24 @@ +#include +#include + vec4 effect() { float ssao = 0.0; - float z = texture(u_position, v_uv).z; + vec4 pos = texture(u_position, v_uv); + float z = pos.z; for (int y = -2; y <= 2; y++) { for (int x = -2; x <= 2; x++) { vec2 offset = vec2(x, y) / u_screenSize; - if (abs(z - texture(u_position, v_uv + offset * 2.0).z) > 0.05) - ssao += 1.0; - else - ssao += texture(u_ssao, v_uv + offset * 2.0).r; + ssao += texture(u_ssao, v_uv + offset * 2.0).r; } } ssao /= 24.0; - return vec4(texture(u_screen, v_uv).rgb * mix(1.0, ssao, 1.0), 1.0); + vec4 modelpos = u_inverseView * pos; + vec3 normal = transpose(mat3(u_view)) * texture(u_normal, v_uv).xyz; + vec3 dir = modelpos.xyz - u_cameraPos; +#ifdef ENABLE_SHADOWS + ssao *= calc_shadow(modelpos, normal, length(pos)); +#endif + vec3 fogColor = texture(u_skybox, dir).rgb; + float fog = calc_fog(length(u_view * vec4((modelpos.xyz - u_cameraPos) * FOG_POS_SCALE, 0.0)) / 256.0); + return vec4(mix(texture(u_screen, v_uv).rgb * mix(1.0, ssao, 1.0), fogColor, fog), 1.0); } diff --git a/res/shaders/entity.glslf b/res/shaders/entity.glslf index cda2c92c..8cc2f75a 100644 --- a/res/shaders/entity.glslf +++ b/res/shaders/entity.glslf @@ -23,7 +23,7 @@ uniform vec3 u_sunDir; #include void main() { - float shadow = calc_shadow(); + float shadow = calc_shadow(a_modelpos, a_realnormal, a_distance); vec3 fogColor = texture(u_skybox, a_dir).rgb; vec4 tex_color = texture(u_texture0, a_texCoord); float alpha = a_color.a * tex_color.a; diff --git a/res/shaders/entity.glslv b/res/shaders/entity.glslv index df11f062..24a8a714 100644 --- a/res/shaders/entity.glslv +++ b/res/shaders/entity.glslv @@ -29,6 +29,7 @@ uniform vec3 u_torchlightColor; uniform float u_torchlightDistance; #include +#include void main() { a_modelpos = u_model * vec4(v_position, 1.0); diff --git a/res/shaders/lib/fog.glsl b/res/shaders/lib/fog.glsl new file mode 100644 index 00000000..e5ff18bb --- /dev/null +++ b/res/shaders/lib/fog.glsl @@ -0,0 +1,19 @@ +#ifndef FOG_GLSL_ +#define FOG_GLSL_ + +uniform float u_fogFactor; +uniform float u_fogCurve; +uniform float u_weatherFogOpacity; +uniform float u_weatherFogDencity; +uniform float u_weatherFogCurve; + +float calc_fog(float depth) { + return min( + 1.0, + max(pow(depth * u_fogFactor, u_fogCurve), + min(pow(depth * u_weatherFogDencity, u_weatherFogCurve), + u_weatherFogOpacity)) + ); +} + +#endif // FOG_GLSL_ diff --git a/res/shaders/lib/lighting.glsl b/res/shaders/lib/lighting.glsl index a18a85a2..c9e14920 100644 --- a/res/shaders/lib/lighting.glsl +++ b/res/shaders/lib/lighting.glsl @@ -1,12 +1,6 @@ #ifndef LIGHTING_GLSL_ #define LIGHTING_GLSL_ -uniform float u_fogFactor; -uniform float u_fogCurve; -uniform float u_weatherFogOpacity; -uniform float u_weatherFogDencity; -uniform float u_weatherFogCurve; - float calc_torch_light(vec3 normal, vec3 modelpos) { return max(0.0, 1.0 - distance(u_cameraPos, modelpos) / u_torchlightDistance) * max(0.0, -dot(normal, normalize(modelpos - u_cameraPos))); @@ -16,13 +10,4 @@ vec3 calc_screen_normal(vec3 normal) { return transpose(inverse(mat3(u_view * u_model))) * normal; } -float calc_fog(float depth) { - return min( - 1.0, - max(pow(depth * u_fogFactor, u_fogCurve), - min(pow(depth * u_weatherFogDencity, u_weatherFogCurve), - u_weatherFogOpacity)) - ); -} - #endif // LIGHTING_GLSL_ diff --git a/res/shaders/lib/shadows.glsl b/res/shaders/lib/shadows.glsl index b66f8a4b..db37cdaa 100644 --- a/res/shaders/lib/shadows.glsl +++ b/res/shaders/lib/shadows.glsl @@ -10,14 +10,14 @@ uniform int u_shadowsRes; uniform float u_shadowsOpacity; uniform float u_shadowsSoftness; -float calc_shadow() { +float calc_shadow(vec4 modelPos, vec3 realnormal, float distance) { #ifdef ENABLE_SHADOWS float step = 1.0 / float(u_shadowsRes); float s = pow(abs(cos(u_dayTime * PI2)), 0.25) * u_shadowsOpacity; - vec3 normalOffset = a_realnormal * (a_distance > 64.0 ? 0.2 : 0.04); - int shadowIdx = a_distance > 80.0 ? 1 : 0; + vec3 normalOffset = realnormal * (distance > 64.0 ? 0.2 : 0.04); + int shadowIdx = distance > 80.0 ? 1 : 0; - vec4 mpos = u_shadowsMatrix[shadowIdx] * vec4(a_modelpos.xyz + normalOffset, 1.0); + vec4 mpos = u_shadowsMatrix[shadowIdx] * vec4(modelPos.xyz + normalOffset, 1.0); vec3 projCoords = mpos.xyz / mpos.w; projCoords = projCoords * 0.5 + 0.5; projCoords.z -= 0.00001 / u_shadowsRes; @@ -26,7 +26,7 @@ float calc_shadow() { } float shadow = 0.0; - if (dot(a_realnormal, u_sunDir) < 0.0) { + if (dot(realnormal, u_sunDir) < 0.0) { // 3x3 kernel for (int y = -1; y <= 1; y++) { for (int x = -1; x <= 1; x++) { diff --git a/res/shaders/main.glslf b/res/shaders/main.glslf index 51f0b9c6..2767390b 100644 --- a/res/shaders/main.glslf +++ b/res/shaders/main.glslf @@ -25,8 +25,7 @@ uniform bool u_debugNormals; #include void main() { - float shadow = calc_shadow(); - vec3 fogColor = texture(u_skybox, a_dir).rgb; + //vec3 fogColor = texture(u_skybox, a_dir).rgb; vec4 texColor = texture(u_texture0, a_texCoord); float alpha = texColor.a; if (u_alphaClip) { @@ -43,8 +42,8 @@ void main() { texColor.rgb *= a_normal * 0.5 + 0.5; } 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.rgb *= min(vec3(1.0), a_torchLight.rgb + a_skyLight); + //f_color = mix(f_color, vec4(fogColor, 1.0), a_fog * 0.0); f_color.a = alpha; f_position = vec4(a_position, 1.0); f_normal = vec4(a_normal, 1.0); diff --git a/res/shaders/main.glslv b/res/shaders/main.glslv index 2f0f084a..927b8519 100644 --- a/res/shaders/main.glslv +++ b/res/shaders/main.glslv @@ -28,6 +28,7 @@ uniform vec3 u_torchlightColor; uniform float u_torchlightDistance; #include +#include void main() { a_modelpos = u_model * vec4(v_position, 1.0f); diff --git a/src/graphics/core/GBuffer.cpp b/src/graphics/core/GBuffer.cpp index 08180d75..acb491e4 100644 --- a/src/graphics/core/GBuffer.cpp +++ b/src/graphics/core/GBuffer.cpp @@ -4,6 +4,8 @@ #include "debug/Logger.hpp" +using namespace advanced_pipeline; + static debug::Logger logger("gl-gbuffer"); void GBuffer::createColorBuffer() { @@ -162,20 +164,30 @@ void GBuffer::unbind() { } void GBuffer::bindBuffers() const { - glActiveTexture(GL_TEXTURE2); + glActiveTexture(GL_TEXTURE0 + TARGET_NORMALS); glBindTexture(GL_TEXTURE_2D, normalsBuffer); - glActiveTexture(GL_TEXTURE1); + glActiveTexture(GL_TEXTURE0 + TARGET_POSITIONS); glBindTexture(GL_TEXTURE_2D, positionsBuffer); - glActiveTexture(GL_TEXTURE0); + glActiveTexture(GL_TEXTURE0 + TARGET_COLOR); glBindTexture(GL_TEXTURE_2D, colorBuffer); + + if (TARGET_COLOR != 0) + glActiveTexture(GL_TEXTURE0); } void GBuffer::bindSSAOBuffer() const { glBindTexture(GL_TEXTURE_2D, ssaoBuffer); } +void GBuffer::bindDepthBuffer() { + glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, + GL_DEPTH_BUFFER_BIT, GL_NEAREST); +} + void GBuffer::resize(uint width, uint height) { if (this->width == width && this->height == height) { return; diff --git a/src/graphics/core/GBuffer.hpp b/src/graphics/core/GBuffer.hpp index 7fa66e1a..8885db7d 100644 --- a/src/graphics/core/GBuffer.hpp +++ b/src/graphics/core/GBuffer.hpp @@ -16,6 +16,8 @@ public: void bindBuffers() const; void bindSSAOBuffer() const; + void bindDepthBuffer(); + void resize(uint width, uint height); uint getWidth() const; diff --git a/src/graphics/core/PostEffect.cpp b/src/graphics/core/PostEffect.cpp index 317f215a..b0c34571 100644 --- a/src/graphics/core/PostEffect.cpp +++ b/src/graphics/core/PostEffect.cpp @@ -100,6 +100,10 @@ Shader& PostEffect::use() { return *shader; } +Shader& PostEffect::getShader() { + return *shader; +} + float PostEffect::getIntensity() const { return intensity; } diff --git a/src/graphics/core/PostEffect.hpp b/src/graphics/core/PostEffect.hpp index 6dac6748..a29fd404 100644 --- a/src/graphics/core/PostEffect.hpp +++ b/src/graphics/core/PostEffect.hpp @@ -48,6 +48,8 @@ public: Shader& use(); + Shader& getShader(); + float getIntensity() const; void setIntensity(float value); diff --git a/src/graphics/core/PostProcessing.cpp b/src/graphics/core/PostProcessing.cpp index 4a2608f3..652b3b36 100644 --- a/src/graphics/core/PostProcessing.cpp +++ b/src/graphics/core/PostProcessing.cpp @@ -12,6 +12,8 @@ #include #include +using namespace advanced_pipeline; + PostProcessing::PostProcessing(size_t effectSlotsCount) : effectSlots(effectSlotsCount) { // Fullscreen quad mesh bulding @@ -74,28 +76,46 @@ void PostProcessing::refreshFbos(uint width, uint height) { } } +void PostProcessing::bindDepthBuffer() { + gbuffer->bindDepthBuffer(); +} + void PostProcessing::configureEffect( const DrawContext& context, PostEffect& effect, Shader& shader, float timer, const Camera& camera, - uint shadowMap + uint shadowMap, + uint shadowMap2, + const glm::mat4& shadowMatrix, + const glm::mat4& shadowMatrix2, + uint shadowMapResolution ) { const auto& viewport = context.getViewport(); - shader.uniform1i("u_screen", 0); + shader.uniform1i("u_screen", TARGET_COLOR); + shader.uniform1i("u_skybox", TARGET_SKYBOX); if (gbuffer) { - shader.uniform1i("u_position", 1); - shader.uniform1i("u_normal", 2); + shader.uniform1i("u_position", TARGET_POSITIONS); + shader.uniform1i("u_normal", TARGET_NORMALS); } - shader.uniform1i("u_noise", 3); // used in SSAO pass - shader.uniform1i("u_ssao", 3); + shader.uniform1i("u_noise", TARGET_SSAO); // used in SSAO pass + shader.uniform1i("u_ssao", TARGET_SSAO); - shader.uniform1i("u_shadows", 4); + shader.uniform1i("u_shadows[0]", TARGET_SHADOWS0); + shader.uniform1i("u_shadows[1]", TARGET_SHADOWS1); + shader.uniformMatrix("u_shadowsMatrix[0]", shadowMatrix); + shader.uniformMatrix("u_shadowsMatrix[1]", shadowMatrix2); + shader.uniform1f("u_shadowsOpacity", 1.0f); + shader.uniform1f("u_shadowsSoftness", 1.0f); + shader.uniform1i("u_shadowsRes", shadowMapResolution); shader.uniform2i("u_screenSize", viewport); + shader.uniform3f("u_cameraPos", camera.position); shader.uniform1f("u_timer", timer); shader.uniform1i("u_enableShadows", shadowMap != 0); shader.uniformMatrix("u_projection", camera.getProjection()); + shader.uniformMatrix("u_view", camera.getView()); + shader.uniformMatrix("u_inverseView", glm::inverse(camera.getView())); } void PostProcessing::render( @@ -103,7 +123,11 @@ void PostProcessing::render( const Assets& assets, float timer, const Camera& camera, - uint shadowMap + uint shadowMap, + uint shadowMap2, + const glm::mat4& shadowMatrix, + const glm::mat4& shadowMatrix2, + uint shadowMapResolution ) { if (fbo == nullptr && gbuffer == nullptr) { throw std::runtime_error("'use(...)' was never called"); @@ -118,25 +142,40 @@ void PostProcessing::render( const auto& vp = context.getViewport(); refreshFbos(vp.x, vp.y); - glActiveTexture(GL_TEXTURE4); + glActiveTexture(GL_TEXTURE0 + TARGET_SHADOWS0); glBindTexture(GL_TEXTURE_2D, shadowMap); + glActiveTexture(GL_TEXTURE0 + TARGET_SHADOWS1); + glBindTexture(GL_TEXTURE_2D, shadowMap2); + + // Generating ssao if (gbuffer) { gbuffer->bindBuffers(); - glActiveTexture(GL_TEXTURE3); + glActiveTexture(GL_TEXTURE0 + TARGET_SSAO); glBindTexture(GL_TEXTURE_2D, noiseTexture); glActiveTexture(GL_TEXTURE0); auto& ssaoEffect = assets.require("ssao"); auto& shader = ssaoEffect.use(); - configureEffect(context, ssaoEffect, shader, timer, camera, shadowMap); + configureEffect( + context, + ssaoEffect, + shader, + timer, + camera, + shadowMap, + shadowMap2, + shadowMatrix, + shadowMatrix2, + shadowMapResolution + ); gbuffer->bindSSAO(); quadMesh->draw(); gbuffer->unbind(); - glActiveTexture(GL_TEXTURE3); + glActiveTexture(GL_TEXTURE0 + TARGET_SSAO); gbuffer->bindSSAOBuffer(); } else { glActiveTexture(GL_TEXTURE0); @@ -148,7 +187,18 @@ void PostProcessing::render( gbuffer ? "deferred_lighting" : "default" ); auto& shader = effect.use(); - configureEffect(context, effect, shader, timer, camera, shadowMap); + configureEffect( + context, + effect, + shader, + timer, + camera, + shadowMap, + shadowMap2, + shadowMatrix, + shadowMatrix2, + shadowMapResolution + ); quadMesh->draw(); return; } @@ -162,7 +212,18 @@ void PostProcessing::render( continue; } auto& shader = effect->use(); - configureEffect(context, *effect, shader, timer, camera, shadowMap); + configureEffect( + context, + *effect, + shader, + timer, + camera, + shadowMap, + shadowMap2, + shadowMatrix, + shadowMatrix2, + shadowMapResolution + ); if (currentPass > 1) { fbo->getTexture()->bind(); diff --git a/src/graphics/core/PostProcessing.hpp b/src/graphics/core/PostProcessing.hpp index dc0779ed..fc49c950 100644 --- a/src/graphics/core/PostProcessing.hpp +++ b/src/graphics/core/PostProcessing.hpp @@ -44,7 +44,11 @@ public: const Assets& assets, float timer, const Camera& camera, - uint shadowMap + uint shadowMap, + uint shadowMap2, + const glm::mat4& shadowMatrix, + const glm::mat4& shadowMatrix2, + uint shadowMapResolution ); void setEffect(size_t slot, std::shared_ptr effect); @@ -55,6 +59,7 @@ public: std::unique_ptr toImage(); Framebuffer* getFramebuffer() const; + void bindDepthBuffer(); private: void configureEffect( const DrawContext& context, @@ -62,7 +67,11 @@ private: Shader& shader, float timer, const Camera& camera, - uint shadowMap + uint shadowMap, + uint shadowMap2, + const glm::mat4& shadowMatrix, + const glm::mat4& shadowMatrix2, + uint shadowMapResolution ); void refreshFbos(uint width, uint height); diff --git a/src/graphics/core/Shader.cpp b/src/graphics/core/Shader.cpp index 24ea0241..da6ea342 100644 --- a/src/graphics/core/Shader.cpp +++ b/src/graphics/core/Shader.cpp @@ -51,6 +51,12 @@ void Shader::uniformMatrix(const std::string& name, const glm::mat4& matrix) { ); } +void Shader::uniformMatrix(const std::string& name, const glm::mat3& matrix) { + glUniformMatrix3fv( + getUniformLocation(name), 1, GL_FALSE, glm::value_ptr(matrix) + ); +} + void Shader::uniform1i(const std::string& name, int x){ glUniform1i(getUniformLocation(name), x); } diff --git a/src/graphics/core/Shader.hpp b/src/graphics/core/Shader.hpp index 8f1aeb33..4808172e 100644 --- a/src/graphics/core/Shader.hpp +++ b/src/graphics/core/Shader.hpp @@ -33,6 +33,7 @@ public: void use(); void uniformMatrix(const std::string&, const glm::mat4& matrix); + void uniformMatrix(const std::string&, const glm::mat3& matrix); void uniform1i(const std::string& name, int x); void uniform1f(const std::string& name, float x); void uniform2f(const std::string& name, float x, float y); diff --git a/src/graphics/core/commons.hpp b/src/graphics/core/commons.hpp index 2ed03db1..ffc89068 100644 --- a/src/graphics/core/commons.hpp +++ b/src/graphics/core/commons.hpp @@ -50,6 +50,16 @@ enum class CursorShape { LAST=NOT_ALLOWED }; +namespace advanced_pipeline { + inline constexpr int TARGET_COLOR = 0; + inline constexpr int TARGET_SKYBOX = 1; + inline constexpr int TARGET_POSITIONS = 2; + inline constexpr int TARGET_NORMALS = 3; + inline constexpr int TARGET_SSAO = 4; + inline constexpr int TARGET_SHADOWS0 = 5; + inline constexpr int TARGET_SHADOWS1 = 6; +} + VC_ENUM_METADATA(CursorShape) {"arrow", CursorShape::ARROW}, {"text", CursorShape::TEXT}, diff --git a/src/graphics/render/Skybox.cpp b/src/graphics/render/Skybox.cpp index 2687dc20..ceb455d1 100644 --- a/src/graphics/render/Skybox.cpp +++ b/src/graphics/render/Skybox.cpp @@ -18,9 +18,7 @@ #include #include -#ifndef M_PI -#define M_PI 3.141592 -#endif // M_PI +using namespace advanced_pipeline; const int STARS_COUNT = 3000; const int STARS_SEED = 632; @@ -47,14 +45,6 @@ Skybox::Skybox(uint size, Shader& shader) mesh = std::make_unique>(vertices, 6); - sprites.push_back(SkySprite { - "misc/moon_flare", - glm::pi() * 0.5f, - 0.5f, - false, - glm::pi() * 0.25f, - }); - sprites.push_back(SkySprite { "misc/moon", glm::pi() * 0.5f, @@ -62,6 +52,14 @@ Skybox::Skybox(uint size, Shader& shader) false, glm::pi() * 0.25f, }); + + sprites.push_back(SkySprite { + "misc/moon_flare", + glm::pi() * 0.5f, + 0.5f, + false, + glm::pi() * 0.25f, + }); sprites.push_back(SkySprite { "misc/sun", @@ -118,6 +116,8 @@ void Skybox::draw( { const glm::uvec2& viewport = pctx.getViewport(); + glActiveTexture(GL_TEXTURE0); + drawBackground(camera, assets, viewport.x, viewport.y); DrawContext ctx = pctx.sub(); @@ -130,22 +130,23 @@ void Skybox::draw( batch3d->begin(); float angle = daytime * glm::pi() * 2.0f; - float opacity = glm::pow(1.0f-fog, 7.0f); + float opacity = glm::pow(1.0f - fog, 7.0f); + float depthScale = 1e3; for (auto& sprite : sprites) { batch3d->texture(assets.get(sprite.texture)); float sangle = daytime * glm::pi() * 2.0 + sprite.phase; - float distance = sprite.distance; + float distance = sprite.distance * depthScale; glm::mat4 rotation = glm::rotate(glm::mat4(1.0f), -sangle + glm::pi() * 0.5f, glm::vec3(0, 0, -1)); rotation = glm::rotate(rotation, sprite.altitude, glm::vec3(1, 0, 0)); glm::vec3 pos = glm::vec4(0, distance, 0, 1) * rotation; - glm::vec3 up = glm::vec4(1, 0, 0, 1) * rotation; - glm::vec3 right = glm::vec4(0, 0, 1, 1) * rotation; + glm::vec3 up = glm::vec4(depthScale, 0, 0, 1) * rotation; + glm::vec3 right = glm::vec4(0, 0, depthScale, 1) * rotation; glm::vec4 tint (1,1,1, opacity); if (!sprite.emissive) { - tint *= 0.6f+std::cos(angle)*0.4; + tint *= 0.6f + std::cos(angle)*0.4; } batch3d->sprite(pos, right, up, 1, 1, UVRegion(), tint); @@ -167,10 +168,10 @@ void Skybox::refresh(const DrawContext& pctx, float t, float mie, uint quality) assert(cubemap != nullptr); ready = true; - glActiveTexture(GL_TEXTURE1); + glActiveTexture(GL_TEXTURE0 + TARGET_SKYBOX); cubemap->bind(); shader.use(); - t *= glm::pi()*2.0f; + t *= glm::two_pi(); lightDir = glm::normalize(glm::vec3(sin(t), -cos(t), 0.0f)); shader.uniform1i("u_quality", quality); @@ -237,13 +238,13 @@ void Skybox::refreshFace(uint face, Cubemap* cubemap) { } void Skybox::bind() const { - glActiveTexture(GL_TEXTURE1); + glActiveTexture(GL_TEXTURE0 + TARGET_SKYBOX); fbo->getTexture()->bind(); glActiveTexture(GL_TEXTURE0); } void Skybox::unbind() const { - glActiveTexture(GL_TEXTURE1); + glActiveTexture(GL_TEXTURE0 + TARGET_SKYBOX); fbo->getTexture()->unbind(); glActiveTexture(GL_TEXTURE0); } diff --git a/src/graphics/render/WorldRenderer.cpp b/src/graphics/render/WorldRenderer.cpp index 3f74d8fb..390aeb32 100644 --- a/src/graphics/render/WorldRenderer.cpp +++ b/src/graphics/render/WorldRenderer.cpp @@ -54,8 +54,11 @@ #include "Emitter.hpp" #include "TextNote.hpp" +using namespace advanced_pipeline; + inline constexpr size_t BATCH3D_CAPACITY = 4096; inline constexpr size_t MODEL_BATCH_CAPACITY = 20'000; +inline constexpr GLenum TEXTURE_MAIN = GL_TEXTURE0; bool WorldRenderer::showChunkBorders = false; bool WorldRenderer::showEntitiesDebug = false; @@ -141,15 +144,15 @@ void WorldRenderer::setupWorldShader( shader.uniform1f("u_shadowsOpacity", 1.0f - cloudsIntensity); // TODO: make it configurable shader.uniform1f("u_shadowsSoftness", 1.0f + cloudsIntensity * 4); // TODO: make it configurable - glActiveTexture(GL_TEXTURE4); - shader.uniform1i("u_shadows[0]", 4); + glActiveTexture(GL_TEXTURE0 + TARGET_SHADOWS0); + shader.uniform1i("u_shadows[0]", TARGET_SHADOWS0); glBindTexture(GL_TEXTURE_2D, shadowMap->getDepthMap()); - glActiveTexture(GL_TEXTURE5); - shader.uniform1i("u_shadows[1]", 5); + glActiveTexture(GL_TEXTURE0 + TARGET_SHADOWS1); + shader.uniform1i("u_shadows[1]", TARGET_SHADOWS1); glBindTexture(GL_TEXTURE_2D, wideShadowMap->getDepthMap()); - glActiveTexture(GL_TEXTURE0); + glActiveTexture(TEXTURE_MAIN); } auto indices = level.content.getIndices(); @@ -438,9 +441,11 @@ void WorldRenderer::draw( auto& mainShader = assets.require("main"); auto& entityShader = assets.require("entity"); + auto& deferredShader = assets.require("deferred_lighting").getShader(); const auto& settings = engine.getSettings(); + gbufferPipeline = settings.graphics.advancedRender.get(); - int shadowsQuality = settings.graphics.shadowsQuality.get(); + int shadowsQuality = settings.graphics.shadowsQuality.get() * gbufferPipeline; int resolution = 512 << shadowsQuality; if (shadowsQuality > 0 && !shadows) { shadowMap = std::make_unique(resolution); @@ -449,6 +454,7 @@ void WorldRenderer::draw( Shader::preprocessor->define("ENABLE_SHADOWS", "true"); mainShader.recompile(); entityShader.recompile(); + deferredShader.recompile(); } else if (shadowsQuality == 0 && shadows) { shadowMap.reset(); wideShadowMap.reset(); @@ -456,6 +462,7 @@ void WorldRenderer::draw( Shader::preprocessor->undefine("ENABLE_SHADOWS"); mainShader.recompile(); entityShader.recompile(); + deferredShader.recompile(); } if (shadows && shadowMap->getResolution() != resolution) { shadowMap = std::make_unique(resolution); @@ -489,9 +496,6 @@ void WorldRenderer::draw( display::clearDepth(); - // Drawing background sky plane - skybox->draw(pctx, camera, assets, worldInfo.daytime, clouds); - /* Actually world render with depth buffer on */ { DrawContext ctx = wctx.sub(); ctx.setDepthTest(true); @@ -506,19 +510,32 @@ void WorldRenderer::draw( } } } - { - DrawContext ctx = wctx.sub(); - texts->render(ctx, camera, settings, hudVisible, true); - } + texts->render(pctx, camera, settings, hudVisible, true); } - + skybox->bind(); + deferredShader.use(); + float fogFactor = + 15.0f / static_cast(settings.chunks.loadDistance.get() - 2); + setupWorldShader(deferredShader, camera, settings, fogFactor); postProcessing.render( pctx, assets, timer, camera, - shadows ? shadowMap->getDepthMap() : 0 + shadows ? shadowMap->getDepthMap() : 0, + shadows ? wideShadowMap->getDepthMap() : 0, + shadowCamera.getProjView(), + wideShadowCamera.getProjView(), + shadows ? shadowMap->getResolution() : 0 ); + { + DrawContext ctx = pctx.sub(); + ctx.setDepthTest(true); + postProcessing.bindDepthBuffer(); + // Drawing background sky plane + skybox->draw(ctx, camera, assets, worldInfo.daytime, clouds); + } + skybox->unbind(); if (player.currentCamera == player.fpCamera) { DrawContext ctx = pctx.sub(); ctx.setDepthTest(true); diff --git a/src/window/Camera.hpp b/src/window/Camera.hpp index 11838234..677e0ede 100644 --- a/src/window/Camera.hpp +++ b/src/window/Camera.hpp @@ -19,7 +19,7 @@ public: bool perspective = true; bool flipped = false; float near = 0.05f; - float far = 1500.0f; + float far = 1e4f; bool projset = false; glm::mat4 projection;