diff --git a/res/preload.json b/res/preload.json index 558fb1f0e..00948068e 100644 --- a/res/preload.json +++ b/res/preload.json @@ -8,7 +8,8 @@ "translucent", "background", "skybox_gen", - "shadows" + "shadows", + "clouds" ], "post-effects": [ "default", diff --git a/res/presets/weather/cloudy.json b/res/presets/weather/cloudy.json index 645b0a287..c9af2f0d6 100644 --- a/res/presets/weather/cloudy.json +++ b/res/presets/weather/cloudy.json @@ -1,4 +1,4 @@ { - "clouds": 0.8 + "clouds": 1.0 } diff --git a/res/presets/weather/fog.json b/res/presets/weather/fog.json index e9c3a2b34..6f65685c8 100644 --- a/res/presets/weather/fog.json +++ b/res/presets/weather/fog.json @@ -2,5 +2,5 @@ "fog_opacity": 0.98, "fog_dencity": 3.6, "fog_curve": 0.25, - "clouds": 0.8 + "clouds": 0.9 } diff --git a/res/shaders/clouds.glslf b/res/shaders/clouds.glslf new file mode 100644 index 000000000..9b29ef110 --- /dev/null +++ b/res/shaders/clouds.glslf @@ -0,0 +1,31 @@ +layout (location = 0) out vec4 f_color; +layout (location = 1) out vec4 f_position; +layout (location = 2) out vec4 f_normal; +layout (location = 3) out vec4 f_emission; + +#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; +uniform vec4 u_tint; + +void main() { + f_color.rgb = max(a_torchLight.rgb, a_skyLight); + f_color.a = 1.0; + f_color *= u_tint; + +#ifndef ADVANCED_RENDER + vec3 fogColor = texture(u_skybox, a_dir).rgb; + f_color = mix(f_color, vec4(fogColor, 1.0), a_fog); +#endif + f_position = vec4(a_position, 1.0); + f_normal = vec4(a_normal, 1.0); + f_emission = vec4(vec3(a_emission), 1.0); +} diff --git a/res/shaders/clouds.glslv b/res/shaders/clouds.glslv new file mode 100644 index 000000000..6c36aa464 --- /dev/null +++ b/res/shaders/clouds.glslv @@ -0,0 +1,49 @@ +#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 + +uniform float u_dayTime; + +out vec4 a_torchLight; + +void main() { + a_modelpos = u_model * vec4(v_position, 1.0f); + a_modelpos.x += sin(u_timer * 0.05 + a_modelpos.z * 0.002) * 1.5; + a_modelpos.z += sin(u_timer * 0.2 + a_modelpos.x * 0.002) * 1.5; + a_modelpos.y += sin(u_timer * 0.1 + (a_modelpos.x + a_modelpos.z) * 0.001) * 2.0; + + 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, u_dayTime); + a_skyLight = skyLightColor.rgb*v_light.a; + + 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; + a_position = viewmodelpos.xyz; + gl_Position = u_proj * viewmodelpos; +} diff --git a/src/graphics/render/CloudsRenderer.cpp b/src/graphics/render/CloudsRenderer.cpp index 6b38ee215..71fc4496f 100755 --- a/src/graphics/render/CloudsRenderer.cpp +++ b/src/graphics/render/CloudsRenderer.cpp @@ -12,6 +12,7 @@ #include "maths/FastNoiseLite.h" #include "util/timeutil.hpp" #include "window/Camera.hpp" +#include "world/Weather.hpp" #include #include @@ -163,7 +164,7 @@ static inline constexpr int WIDTH = 256; static inline constexpr int DEPTH = 256; -CloudsRenderer::CloudsRenderer(const Assets& assets) : assets(assets) { +CloudsRenderer::CloudsRenderer() { VolumeRenderer volumeRenderer(1024 * 1024); for (int layer = 0; layer < 2; layer++) { @@ -216,7 +217,6 @@ CloudsRenderer::CloudsRenderer(const Assets& assets) : assets(assets) { CloudsMap map({w, h, d}, voxels); - timeutil::ScopeLogTimer log2(222); volumeRenderer.build(map); testMeshes[layer] = std::make_unique>(volumeRenderer.createMesh()); } @@ -224,9 +224,20 @@ CloudsRenderer::CloudsRenderer(const Assets& assets) : assets(assets) { CloudsRenderer::~CloudsRenderer() = default; -void CloudsRenderer::draw(float timer, float fogFactor, const Camera& camera) { - auto& shader = assets.require("main"); - assets.require("misc/blank").bind(); +void CloudsRenderer::draw( + Shader& shader, + const Weather& weather, + float timer, + float fogFactor, + const Camera& camera +) { + float clouds = weather.clouds(); + shader.uniform4f( + "u_tint", + glm::vec4( + 1.0f - clouds * 0.5, 1.0f - clouds * 0.45, 1.0f - clouds * 0.4, 1.0f + ) + ); float scale = 8; float totalWidth = WIDTH * scale; @@ -235,7 +246,7 @@ void CloudsRenderer::draw(float timer, float fogFactor, const Camera& camera) { int cellX = glm::floor(camera.position.x / totalWidth + 0.5f); int cellZ = glm::floor(camera.position.z / totalDepth + 0.5f); - float speed = 10.0f; + float speed = 4.0f; for (int i = 0; i < 2; i++) { float speedX = glm::sin(i * 0.3f + 0.4f) * speed / (i + 1); float speedZ = -glm::cos(i * 0.3f + 0.4f) * speed / (i + 1); diff --git a/src/graphics/render/CloudsRenderer.hpp b/src/graphics/render/CloudsRenderer.hpp index 2eec12e53..84c8e1c2b 100755 --- a/src/graphics/render/CloudsRenderer.hpp +++ b/src/graphics/render/CloudsRenderer.hpp @@ -4,16 +4,22 @@ #include -class Assets; class Camera; +class Shader; +struct Weather; class CloudsRenderer final { public: - CloudsRenderer(const Assets& assets); + CloudsRenderer(); ~CloudsRenderer(); - void draw(float timer, float fogFactor, const Camera& camera); + void draw( + Shader& shader, + const Weather& weather, + float timer, + float fogFactor, + const Camera& camera + ); private: - const Assets& assets; std::array>, 2> testMeshes; }; diff --git a/src/graphics/render/WorldRenderer.cpp b/src/graphics/render/WorldRenderer.cpp index b00a6756e..1a7e8f055 100644 --- a/src/graphics/render/WorldRenderer.cpp +++ b/src/graphics/render/WorldRenderer.cpp @@ -117,7 +117,7 @@ WorldRenderer::WorldRenderer( ); shadowMapping = std::make_unique(level); debugLines = std::make_unique(level); - cloudsRenderer = std::make_unique(assets); + cloudsRenderer = std::make_unique(); } WorldRenderer::~WorldRenderer() = default; @@ -207,14 +207,17 @@ void WorldRenderer::renderOpaque( particles->render(camera); auto& shader = assets.require("main"); + auto& cloudsShader = assets.require("clouds"); auto& linesShader = assets.require("lines"); setupWorldShader(shader, camera, settings, fogFactor); chunksRenderer->drawChunks(camera, shader); - cloudsRenderer->draw(timer, fogFactor, camera); blockWraps->draw(ctx, player); + setupWorldShader(cloudsShader, camera, settings, fogFactor); + cloudsRenderer->draw(cloudsShader, weather, timer, fogFactor, camera); + if (hudVisible) { renderLines(camera, linesShader, ctx); } @@ -317,13 +320,19 @@ void WorldRenderer::renderFrame( auto& mainShader = assets.require("main"); auto& entityShader = assets.require("entity"); + auto& cloudsShader = assets.require("clouds"); auto& translucentShader = assets.require("translucent"); auto& deferredShader = assets.require("deferred_lighting").getShader(); const auto& settings = engine.getSettings(); Shader* affectedShaders[] { - &mainShader, &entityShader, &translucentShader, &deferredShader, nullptr + &mainShader, + &entityShader, + &cloudsShader, + &translucentShader, + &deferredShader, + nullptr }; refreshSettings(affectedShaders);