diff --git a/res/shaders/effects/default.glsl b/res/shaders/effects/default.glsl index c2f9effa..f7a94851 100644 --- a/res/shaders/effects/default.glsl +++ b/res/shaders/effects/default.glsl @@ -1,3 +1,4 @@ vec4 effect() { + //return vec4(vec3(pow(texture(u_shadows, v_uv).r, 5.0) * 1000.0), 1.0); return texture(u_screen, v_uv); } diff --git a/res/shaders/lib/shadows.glsl b/res/shaders/lib/shadows.glsl index 9e96d3ea..4ba3ea6e 100644 --- a/res/shaders/lib/shadows.glsl +++ b/res/shaders/lib/shadows.glsl @@ -1,10 +1,22 @@ #ifndef SHADOWS_GLSL_ #define SHADOWS_GLSL_ +float sample_shadow(vec3 uv, vec3 xy) { + float color = 0.0; + vec3 off1 = vec3(1.3846153846) * xy; + vec3 off2 = vec3(3.2307692308) * xy; + color += texture(u_shadows, uv) * 0.2270270270; + color += texture(u_shadows, uv + (off1 / u_shadowsRes)) * 0.3162162162; + color += texture(u_shadows, uv - (off1 / u_shadowsRes)) * 0.3162162162; + color += texture(u_shadows, uv + (off2 / u_shadowsRes)) * 0.0702702703; + color += texture(u_shadows, uv - (off2 / u_shadowsRes)) * 0.0702702703; + return color; +} + float calc_shadow() { float shadow = 1.0; if (u_enableShadows) { - vec4 mpos = u_shadowsMatrix * vec4(a_modelpos.xyz + a_realnormal * 0.08, 1.0); + vec4 mpos = u_shadowsMatrix * vec4(a_modelpos.xyz + a_realnormal * 0.04, 1.0); vec3 projCoords = mpos.xyz / mpos.w; projCoords = projCoords * 0.5 + 0.5; projCoords.z -= 0.0001; @@ -22,6 +34,7 @@ float calc_shadow() { shadow += texture(u_shadows, projCoords.xyz + offsets[i] / u_shadowsRes); } shadow /= 4; + //shadow = sample_shadow(projCoords, normalize(vec3(1.0, 1.0, 0.0)) * 0.5); shadow = shadow * 0.5 + 0.5; } else { shadow = 0.5; diff --git a/src/graphics/render/BlocksRenderer.cpp b/src/graphics/render/BlocksRenderer.cpp index 1bc499fb..8480bd72 100644 --- a/src/graphics/render/BlocksRenderer.cpp +++ b/src/graphics/render/BlocksRenderer.cpp @@ -203,14 +203,21 @@ void BlocksRenderer::blockXSprite( const float w = size.x / 1.41f; const glm::vec4 tint (0.8f); - face({x + xs, y, z + zs}, w, size.y, 0, {-1, 0, 1}, {0, 1, 0}, glm::vec3(), + glm::vec3 n; + float bias = 0.05f; + + n = glm::vec3(-0.7f, 0, -0.7f); + face(glm::vec3(x + xs, y, z + zs) + n * bias, w, size.y, 0, {-1, 0, 1}, {0, 1, 0}, n, texface1, lights2, tint); - face({x + xs, y, z + zs}, w, size.y, 0, {1, 0, 1}, {0, 1, 0}, glm::vec3(), + n = glm::vec3(-0.7f, 0, 0.7f); + face(glm::vec3(x + xs, y, z + zs) + n * bias, w, size.y, 0, {1, 0, 1}, {0, 1, 0}, n, texface1, lights1, tint); - face({x + xs, y, z + zs}, w, size.y, 0, {-1, 0, -1}, {0, 1, 0}, glm::vec3(), + n = glm::vec3(0.7f, 0, -0.7f); + face(glm::vec3(x + xs, y, z + zs) + n * bias, w, size.y, 0, {-1, 0, -1}, {0, 1, 0}, n, texface2, lights2, tint); - face({x + xs, y, z + zs}, w, size.y, 0, {1, 0, -1}, {0, 1, 0}, glm::vec3(), + n = glm::vec3(0.7f, 0, 0.7f); + face(glm::vec3(x + xs, y, z + zs) + n * bias, w, size.y, 0, {1, 0, -1}, {0, 1, 0}, n, texface2, lights1, tint); } diff --git a/src/graphics/render/WorldRenderer.cpp b/src/graphics/render/WorldRenderer.cpp index 1fec6a47..501d39b9 100644 --- a/src/graphics/render/WorldRenderer.cpp +++ b/src/graphics/render/WorldRenderer.cpp @@ -345,23 +345,41 @@ void WorldRenderer::generateShadowsMap(const Camera& camera, const DrawContext& const auto& settings = engine.getSettings(); int resolution = shadowMap->getResolution(); - float shadowMapScale = 0.2f / (1 << glm::max(0L, settings.graphics.shadowsQuality.get())); + float shadowMapScale = 0.1f / (1 << glm::max(0L, settings.graphics.shadowsQuality.get())); float shadowMapSize = resolution * shadowMapScale; - shadowCamera = Camera(camera.position, shadowMapSize); + + glm::vec3 basePos = glm::floor(camera.position / 500.0f) * 500.0f; + shadowCamera = Camera(basePos + glm::mod(camera.position, 500.0f), shadowMapSize); shadowCamera.near = 0.1f; shadowCamera.far = 800.0f; shadowCamera.perspective = false; shadowCamera.setAspectRatio(1.0f); + + float sunAngle = glm::radians(fmod(90.0f - worldInfo.daytime * 360.0f, 180.0f)); shadowCamera.rotate( - glm::radians(fmod(90.0f - worldInfo.daytime * 360.0f, 180.0f)), - glm::radians(-40.0f), + sunAngle, + glm::radians(-45.0f), glm::radians(-0.0f) ); shadowCamera.updateVectors(); + shadowCamera.position -= shadowCamera.front * 200.0f; - shadowCamera.position -= shadowCamera.right * (resolution * shadowMapScale) * 0.5f; - shadowCamera.position -= shadowCamera.up * (resolution * shadowMapScale) * 0.5f; - shadowCamera.position = glm::floor(shadowCamera.position * 0.25f) * 4.0f; + shadowCamera.position += shadowCamera.up * 10.0f; + + auto view = shadowCamera.getView(); + + auto currentPos = shadowCamera.position; + auto min = view * glm::dvec4(currentPos - (shadowCamera.right + shadowCamera.up) * (shadowMapSize * 0.5f), 1.0f); + auto max = view * glm::dvec4(currentPos + (shadowCamera.right + shadowCamera.up) * (shadowMapSize * 0.5f), 1.0f); + + float texelSize = (max.x - min.x) / shadowMapSize; + float snappedLeft = glm::round(min.x / texelSize) * texelSize; + float snappedBottom = glm::round(min.y / texelSize) * texelSize; + float snappedRight = snappedLeft + shadowMapSize * texelSize; + float snappedTop = snappedBottom + shadowMapSize * texelSize; + + shadowCamera.setProjection(glm::ortho(snappedLeft, snappedRight, snappedBottom, snappedTop, 0.1f, 800.0f)); + { frustumCulling->update(shadowCamera.getProjView()); auto sctx = pctx.sub(); @@ -419,9 +437,11 @@ void WorldRenderer::draw( chunks->update(); - if (shadows) { + static int frameid = 0; + if (shadows && frameid % 2 == 0) { generateShadowsMap(camera, pctx); } + frameid++; auto& linesShader = assets.require("lines"); /* World render scope with diegetic HUD included */ { diff --git a/src/settings.hpp b/src/settings.hpp index 714372fe..699d2b28 100644 --- a/src/settings.hpp +++ b/src/settings.hpp @@ -78,7 +78,7 @@ struct GraphicsSettings { /// @brief Advanced render pipeline FlagSetting advancedRender {true}; /// @brief Shadows quality - IntegerSetting shadowsQuality {0, 0, 2}; + IntegerSetting shadowsQuality {0, 0, 3}; }; struct DebugSettings { diff --git a/src/window/Camera.cpp b/src/window/Camera.cpp index 1854ff0e..fb23676d 100644 --- a/src/window/Camera.cpp +++ b/src/window/Camera.cpp @@ -28,6 +28,9 @@ void Camera::rotate(float x, float y, float z) { } glm::mat4 Camera::getProjection() const { + if (projset) { + return projection; + } if (perspective) { return glm::perspective(fov * zoom, ar, near, far); } else if (flipped) { @@ -62,6 +65,11 @@ float Camera::getFov() const { return fov; } +void Camera::setProjection(const glm::mat4& matrix) { + projection = matrix; + projset = true; +} + float Camera::getAspectRatio() const { return ar; } diff --git a/src/window/Camera.hpp b/src/window/Camera.hpp index ba4a5331..11838234 100644 --- a/src/window/Camera.hpp +++ b/src/window/Camera.hpp @@ -21,6 +21,9 @@ public: float near = 0.05f; float far = 1500.0f; + bool projset = false; + glm::mat4 projection; + Camera() { updateVectors(); } @@ -36,6 +39,8 @@ public: void setFov(float fov); float getFov() const; + void setProjection(const glm::mat4& matrix); + float getAspectRatio() const; void setAspectRatio(float ar); };