From 1bf1d0b2ff756b15453ebcc9daa9bd4c418d0360 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gef=C3=BCllte=20Taubenbrust?= <72752000+GefullteTaubenbrust2@users.noreply.github.com> Date: Tue, 1 Oct 2024 20:00:24 +0200 Subject: [PATCH] Remove volumetrics stuff and some changes --- builtin/settingtypes.txt | 31 +- .../shaders/clouds_merge/opengl_fragment.glsl | 87 ---- .../shaders/clouds_merge/opengl_vertex.glsl | 48 --- .../shaders/nodes_shader/opengl_fragment.glsl | 22 +- .../object_shader/opengl_fragment.glsl | 15 +- .../shaders/soft_clouds/opengl_fragment.glsl | 22 + client/shaders/soft_clouds/opengl_vertex.glsl | 24 ++ .../volumetric_clouds/opengl_fragment.glsl | 214 ---------- .../volumetric_clouds/opengl_vertex.glsl | 37 -- src/client/client.h | 5 - src/client/clouds.cpp | 385 ++++++++++-------- src/client/clouds.h | 28 -- src/client/game.cpp | 22 +- src/client/render/pipeline.cpp | 15 - src/client/render/pipeline.h | 2 - src/client/render/secondstage.cpp | 187 +-------- src/client/render/secondstage.h | 7 - src/client/shader.cpp | 7 +- src/defaultsettings.cpp | 2 +- src/network/clientpackethandler.cpp | 4 +- src/server.cpp | 4 +- 21 files changed, 311 insertions(+), 857 deletions(-) delete mode 100644 client/shaders/clouds_merge/opengl_fragment.glsl delete mode 100644 client/shaders/clouds_merge/opengl_vertex.glsl create mode 100644 client/shaders/soft_clouds/opengl_fragment.glsl create mode 100644 client/shaders/soft_clouds/opengl_vertex.glsl delete mode 100644 client/shaders/volumetric_clouds/opengl_fragment.glsl delete mode 100644 client/shaders/volumetric_clouds/opengl_vertex.glsl diff --git a/builtin/settingtypes.txt b/builtin/settingtypes.txt index 187e1f45f..da3a23324 100644 --- a/builtin/settingtypes.txt +++ b/builtin/settingtypes.txt @@ -510,9 +510,10 @@ water_wave_length (Waving liquids wavelength) float 20.0 0.1 # Requires: shaders, enable_waving_water water_wave_speed (Waving liquids wave speed) float 5.0 -# When enabled, liquid reflections are simulated. +# When enabled, crude liquid reflections are simulated. +# When waving liquids are enabled, the wave parameters will affect these reflections. # -# Requires: shaders, enable_waving_water, enable_dynamic_shadows +# Requires: shaders, enable_dynamic_shadows enable_water_reflections (Liquid reflections) bool false [**Dynamic shadows] @@ -684,39 +685,25 @@ bloom_strength_factor (Bloom Strength Factor) float 1.0 0.1 10.0 # Requires: shaders, enable_post_processing, enable_bloom bloom_radius (Bloom Radius) float 1 0.1 8 -[**Volumetric Effects] - # Set to true to enable volumetric lighting effect (a.k.a. "Godrays"). # # Requires: shaders, enable_post_processing, enable_bloom enable_volumetric_lighting (Volumetric Lighting) bool false -# Set to true to render clouds as scatter volumes. -# -# Requires: shaders, enable_post_processing, enable_clouds -enable_volumetric_clouds (Volumetric Clouds) bool false - -# Higher values reduce visual quality and may introduce artifacts, but improve performance of volumetric cloud/aurora effects. -# Range: from 1 to 4, default: 2 -# -# Requires: shaders, enable_post_processing -volumetrics_undersampling (Volumetric Undersampling) int 2 1 4 - -# Set to true to render volumetric auroras ("Northern Lights"). -# -# Requires: shaders, enable_post_processing -enable_volumetric_auroras (Volumetric Auroras) bool false - [**Other Effects] +# Makes the color of light fog more saturated. +# +# Requires: shaders +enable_tinted_fog (Tinted fog) bool false + # Apply bump maps to nodes based on their textures. It is recommended to use a tilted sun orbit to go with this (Sky Body Orbit Tilt). # # Requires: shaders, enable_dynamic_shadows enable_bumpmaps (Bump maps) bool false -[**Other Effects] - # Simulate translucency when looking at foliage in the sunlight. +# It is recommended to use this with the leaves style set to fancy. # # Requires: shaders, enable_dynamic_shadows enable_translucent_foliage (Translucent foliage) bool false diff --git a/client/shaders/clouds_merge/opengl_fragment.glsl b/client/shaders/clouds_merge/opengl_fragment.glsl deleted file mode 100644 index cc78de2b6..000000000 --- a/client/shaders/clouds_merge/opengl_fragment.glsl +++ /dev/null @@ -1,87 +0,0 @@ -#define cloudsTexture texture0 -#define sceneTexture texture1 -#define depthmap texture2 - -uniform sampler2D cloudsTexture; -uniform sampler2D sceneTexture; -uniform sampler2D depthmap; -uniform vec2 texelSize0; - -uniform vec3 dayLight; -uniform vec3 cloudColor; - -varying vec2 screenspaceCoordinate; -varying vec3 relativePosition; -varying vec3 viewDirection; -varying vec3 sunTint; -varying float auroraFactor; - -uniform vec3 cameraOffset; -uniform vec3 cameraPosition; - -uniform float cameraNear; -uniform float cameraFar; - -uniform float cloudHeight; -uniform float cloudThickness; - -float getDepth(vec2 screenspacePosition) { - float depth = texture2D(depthmap, screenspacePosition * 0.5 + 0.5).r; - return cameraNear * cameraFar / (cameraFar + depth * (cameraNear - cameraFar)); -} - -vec4 sampleClouds(vec2 uv) { - vec4 cloudsKey = texture2D(cloudsTexture, uv); - - //const vec3 darkColor = vec3(0.05, 0.1, 0.2); - vec3 darkColor = vec3(0.2, 0.4, 0.8) * dayLight; - const vec3 auroraDark = vec3(0., 0.5, 0.5); - const vec3 auroraBright = vec3(0., 0.5, .0); - - //const vec3 auroraDark = vec3(0.); - //const vec3 auroraBright = vec3(0.); - - return vec4( - mix(auroraDark, auroraBright, cloudsKey.b) * cloudsKey.b * auroraFactor + - cloudsKey.r * cloudColor * (darkColor * max(0., 1. - cloudsKey.g) + dayLight * sunTint * cloudsKey.g), - cloudsKey.r); -} - -vec4 getClouds(vec2 uv) { -#if (VOLUMETRICS_UNDERSAMPLING <= 1) - return sampleClouds(uv); -#else - return - sampleClouds(uv - texelSize0 * vec2(-1.0, -1.0)) / 9.0 + - sampleClouds(uv - texelSize0 * vec2( 0.0, -1.0)) / 9.0 + - sampleClouds(uv - texelSize0 * vec2( 1.0, -1.0)) / 9.0 + - sampleClouds(uv - texelSize0 * vec2(-1.0, 0.0)) / 9.0 + - sampleClouds(uv - texelSize0 * vec2( 0.0, 0.0)) / 9.0 + - sampleClouds(uv - texelSize0 * vec2( 1.0, 0.0)) / 9.0 + - sampleClouds(uv - texelSize0 * vec2(-1.0, 1.0)) / 9.0 + - sampleClouds(uv - texelSize0 * vec2( 0.0, 1.0)) / 9.0 + - sampleClouds(uv - texelSize0 * vec2( 1.0, 1.0)) / 9.0; -#endif -} - -void main(void) -{ - vec3 viewVec = normalize(relativePosition); - - vec3 position = cameraOffset + cameraPosition; - - float depth = getDepth(screenspaceCoordinate) / normalize(viewDirection).z; - float bottomPlaneIntersect = max((cloudHeight - cameraPosition.y) / viewVec.y, 0.); - float topPlaneIntersect = max((cloudHeight + cloudThickness - cameraPosition.y) / viewVec.y, 0.); - float minPlane = min(bottomPlaneIntersect, topPlaneIntersect); - - vec4 sceneColor = texture2D(sceneTexture, screenspaceCoordinate * 0.5 + 0.5); - - if (depth > minPlane) { - vec4 finalColor = getClouds(screenspaceCoordinate * 0.5 + 0.5); - - gl_FragColor = vec4(sceneColor.rgb * (1. - finalColor.a) + finalColor.rgb, 1.); - } else { - gl_FragColor = sceneColor; - } -} diff --git a/client/shaders/clouds_merge/opengl_vertex.glsl b/client/shaders/clouds_merge/opengl_vertex.glsl deleted file mode 100644 index dc0516dfb..000000000 --- a/client/shaders/clouds_merge/opengl_vertex.glsl +++ /dev/null @@ -1,48 +0,0 @@ -uniform mat4 mCameraProjInv; -uniform mat4 mCameraView; -uniform vec3 v_LightDirection; -uniform float f_timeofday; - -varying vec3 relativePosition; -varying vec3 viewDirection; -varying vec2 screenspaceCoordinate; -varying vec3 sunTint; -varying float auroraFactor; - -vec3 getDirectLightScatteringAtGround(vec3 v_LightDirection) -{ - // Based on talk at 2002 Game Developers Conference by Naty Hoffman and Arcot J. Preetham - const float beta_r0 = 1e-5; // Rayleigh scattering beta - - // These factors are calculated based on expected value of scattering factor of 1e-5 - // for Nitrogen at 532nm (green), 2e25 molecules/m3 in atmosphere - const vec3 beta_r0_l = vec3(3.3362176e-01, 8.75378289198826e-01, 1.95342379700656) * beta_r0; // wavelength-dependent scattering - - const float atmosphere_height = 15000.; // height of the atmosphere in meters - // sun/moon light at the ground level, after going through the atmosphere - return exp(-beta_r0_l * atmosphere_height / (1e-5 - dot(v_LightDirection, vec3(0., 1., 0.)))); -} - -// custom smoothstep implementation because it's not defined in glsl1.2 -// https://docs.gl/sl4/smoothstep -float mtsmoothstep(in float edge0, in float edge1, in float x) -{ - float t = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0); - return t * t * (3.0 - 2.0 * t); -} - -void main(void) -{ - vec4 p = mCameraProjInv * inVertexPosition; - viewDirection = p.xyz / p.w; - relativePosition = (p.xyz / p.w) * mat3(mCameraView); - screenspaceCoordinate = inVertexPosition.xy; - - auroraFactor = 1. - mtsmoothstep(0.13, 0.15, f_timeofday) * mtsmoothstep(0.87, 0.85, f_timeofday); - - float tintFactor = mtsmoothstep(0.21, 0.24, f_timeofday) * mtsmoothstep(0.793, 0.753, f_timeofday); - - sunTint = mix(vec3(1.0), getDirectLightScatteringAtGround(v_LightDirection), tintFactor); - - gl_Position = inVertexPosition; -} diff --git a/client/shaders/nodes_shader/opengl_fragment.glsl b/client/shaders/nodes_shader/opengl_fragment.glsl index f06f92f0a..6be928538 100644 --- a/client/shaders/nodes_shader/opengl_fragment.glsl +++ b/client/shaders/nodes_shader/opengl_fragment.glsl @@ -59,7 +59,7 @@ varying highp vec3 eyeVec; varying float nightRatio; #ifdef ENABLE_DYNAMIC_SHADOWS -#if ((defined(MATERIAL_WAVING_LIQUID) && defined(ENABLE_WATER_REFLECTIONS) && ENABLE_WAVING_WATER) || defined(ENABLE_BUMPMAPS)) +#if ((defined(MATERIAL_WAVING_LIQUID) && defined(ENABLE_WATER_REFLECTIONS)) || defined(ENABLE_BUMPMAPS)) vec4 perm(vec4 x) { return mod(((x * 34.0) + 1.0) * x, 289.0); @@ -450,7 +450,7 @@ void main(void) float fx0y0 = texture2D(baseTexture, uv).r; float fx1y0 = texture2D(baseTexture, uv + vec2(dr.x, 0.0)).r; float fx0y1 = texture2D(baseTexture, uv + vec2(0.0, dr.y)).r; - vec2 gradient = 0.2 * vec2((fx1y0 - fx0y0) / dr.x, (fx0y1 - fx0y0) / dr.y) + 0.1 * gnoise(vec3(2.0 * uv / texelSize0, 0.0)).xy; + vec2 gradient = 0.1 * vec2((fx1y0 - fx0y0) / dr.x, (fx0y1 - fx0y0) / dr.y) + 0.05 * gnoise(vec3(2.0 * uv / texelSize0, 0.0)).xy; // Compute a set of orthogonal basis vectors representing the node's surface plane. vec3 orth1 = normalize(cross(vNormal, mix(vec3(0.0, -1.0, 0.0), vec3(0.0, 0.0, -1.0), step(0.9, abs(vNormal.y))))); vec3 orth2 = normalize(cross(vNormal, orth1)); @@ -529,7 +529,14 @@ void main(void) vec3 viewVec = normalize(worldPosition + cameraOffset - cameraPosition); // Water reflections -#if (defined(MATERIAL_WAVING_LIQUID) && defined(ENABLE_WATER_REFLECTIONS) && ENABLE_WAVING_WATER) +#if (defined(MATERIAL_WAVING_LIQUID) && defined(ENABLE_WATER_REFLECTIONS)) + +#if !ENABLE_WAVING_WATER +#define WATER_WAVE_HEIGHT 0.5 +#define WATER_WAVE_SPEED 5.0 +#define WATER_WAVE_LENGTH 10.0 +#endif + vec3 wavePos = worldPosition * vec3(2.0, 0.0, 2.0); float off = animationTimer * WATER_WAVE_SPEED * 10.0; wavePos.x /= WATER_WAVE_LENGTH * 3.0; @@ -560,7 +567,8 @@ void main(void) #if (defined(ENABLE_NODE_SPECULAR) && !defined(MATERIAL_WAVING_LIQUID)) // Apply specular to blocks. if (dot(v_LightDirection, vNormal) < 0.0) { - float intensity = 2.0 * (1.0 - (base.r * varColor.r)); + // This intensity is a placeholder and should be replaced by proper specular maps. + float intensity = 4.0 * min(1.0, length(varColor.rgb * base.rgb)); const float specular_exponent = 5.0; const float fresnel_exponent = 4.0; @@ -588,6 +596,8 @@ void main(void) // Note: clarity = (1 - fogginess) float clarity = clamp(fogShadingParameter - fogShadingParameter * length(eyeVec) / fogDistance, 0.0, 1.0); + +#ifdef ENABLE_TINTED_FOG float fogColorMax = max(max(fogColor.r, fogColor.g), fogColor.b); // Prevent zero division. if (fogColorMax < 0.0000001) fogColorMax = 1.0; @@ -595,6 +605,10 @@ void main(void) // For this to not make the fog color artificially dark we need to normalize using the // fog color's brightest value. We then blend our base color with this to make the fog. col = mix(fogColor * pow(fogColor / fogColorMax, vec4(2.0 * clarity)), col, clarity); +#else + col = mix(fogColor, col, clarity); +#endif + col = vec4(col.rgb, base.a); gl_FragData[0] = col; diff --git a/client/shaders/object_shader/opengl_fragment.glsl b/client/shaders/object_shader/opengl_fragment.glsl index 1ac05dfed..b963b1ed5 100644 --- a/client/shaders/object_shader/opengl_fragment.glsl +++ b/client/shaders/object_shader/opengl_fragment.glsl @@ -21,7 +21,6 @@ uniform float animationTimer; uniform vec4 CameraPos; uniform float xyPerspectiveBias0; uniform float xyPerspectiveBias1; - uniform vec3 shadow_tint; varying float adj_shadow_strength; varying float cosLight; @@ -433,8 +432,8 @@ void main(void) // calculate fragment color from components: col.rgb = adjusted_night_ratio * col.rgb + // artificial light - sunTint * (1.0 - adjusted_night_ratio) * ( // natural light - col.rgb * (1.0 - shadow_int * (1.0 - shadow_color) * (1.0 - shadow_tint)) + // filtered texture color + (1.0 - adjusted_night_ratio) * ( // natural light + col.rgb * (1.0 - shadow_int * (1.0 - shadow_color)) + // filtered texture color dayLight * shadow_color * shadow_int); // reflected filtered sunlight/moonlight } #endif @@ -450,13 +449,9 @@ void main(void) // Note: clarity = (1 - fogginess) float clarity = clamp(fogShadingParameter - fogShadingParameter * length(eyeVec) / fogDistance, 0.0, 1.0); - float fogColorMax = max(max(fogColor.r, fogColor.g), fogColor.b); - // Prevent zero division. - if (fogColorMax < 0.0000001) fogColorMax = 1.0; - // For high clarity (light fog) we tint the fog color. - // For this to not make the fog color artificially dark we need to normalize using the - // fog color's brightest value. We then blend our base color with this to make the fog. - col = mix(fogColor * pow(fogColor / fogColorMax, vec4(2.0 * clarity)), col, clarity); + + col = mix(fogColor, col, clarity); + col = vec4(col.rgb, base.a); gl_FragData[0] = col; diff --git a/client/shaders/soft_clouds/opengl_fragment.glsl b/client/shaders/soft_clouds/opengl_fragment.glsl new file mode 100644 index 000000000..1cf0ef0bb --- /dev/null +++ b/client/shaders/soft_clouds/opengl_fragment.glsl @@ -0,0 +1,22 @@ +uniform lowp vec4 fogColor; +uniform float fogDistance; +uniform float fogShadingParameter; +varying highp vec3 eyeVec; + +varying lowp vec4 varColor; +varying lowp vec3 normal; +uniform vec3 v_LightDirection; + +void main(void) +{ + float brightness = max(dot(-v_LightDirection, normal), 0.0); + vec4 col = varColor; + + col.rgb *= brightness; + + float clarity = clamp(fogShadingParameter + - fogShadingParameter * length(eyeVec) / fogDistance, 0.0, 1.0); + col.rgb = mix(fogColor.rgb, col.rgb, clarity); + + gl_FragColor = col; +} diff --git a/client/shaders/soft_clouds/opengl_vertex.glsl b/client/shaders/soft_clouds/opengl_vertex.glsl new file mode 100644 index 000000000..72f747b87 --- /dev/null +++ b/client/shaders/soft_clouds/opengl_vertex.glsl @@ -0,0 +1,24 @@ +uniform lowp vec4 materialColor; + +varying lowp vec4 varColor; + +varying highp vec3 eyeVec; + +varying lowp vec3 normal; + +void main(void) +{ + gl_Position = mWorldViewProj * inVertexPosition; + +#ifdef GL_ES + vec4 color = inVertexColor.bgra; +#else + vec4 color = inVertexColor; +#endif + + color *= materialColor; + varColor = color; + normal = inVertexNormal; + + eyeVec = -(mWorldView * inVertexPosition).xyz; +} diff --git a/client/shaders/volumetric_clouds/opengl_fragment.glsl b/client/shaders/volumetric_clouds/opengl_fragment.glsl deleted file mode 100644 index 7f7e69ab4..000000000 --- a/client/shaders/volumetric_clouds/opengl_fragment.glsl +++ /dev/null @@ -1,214 +0,0 @@ -#define depthmap texture0 -#define noiseTexture texture1 -#define noiseTextureCoarse texture2 - -#define PROBING_ITERATIONS 30 -#define ITERATIONS 50 -#define LIGHT_ITERATIONS 3 -#define AURORA_ITERATIONS 80 - -// See clouds.cpp -#define CLOUD_SIZE 640.0 - -uniform sampler2D depthmap; -uniform sampler2D noiseTexture; -uniform sampler2D noiseTextureCoarse; - -uniform vec2 texelSize0; - -uniform float cloudHeight; -uniform float cloudThickness; -uniform float cloudDensity; - -varying vec3 relativePosition; -varying vec3 viewDirection; -uniform vec3 cameraOffset; -uniform vec3 cameraPosition; - -uniform float cameraNear; -uniform float cameraFar; - -uniform vec2 cloudOffset; -uniform float cloudRadius; - -varying vec2 screenspaceCoordinate; -varying float sunStrength; - -uniform float fogDistance; -uniform float fogShadingParameter; - -uniform vec3 v_LightDirection; - -uniform float animationTimer; - -// Derived From http://alex.vlachos.com/graphics/Alex_Vlachos_Advanced_VR_Rendering_GDC2015.pdf -// and https://www.shadertoy.com/view/MslGR8 (5th one starting from the bottom) -// NOTE: `frag_coord` is in pixels (i.e. not normalized UV). -float screenSpaceDither(highp vec2 frag_coord) -{ - // Iestyn's RGB dither (7 asm instructions) from Portal 2 X360, slightly modified for VR. - highp float dither = dot(vec2(171.0, 231.0), frag_coord); - dither = fract(dither / 103.0); - - return dither; -} - -// custom smoothstep implementation because it's not defined in glsl1.2 -// https://docs.gl/sl4/smoothstep -float mtsmoothstep(in float edge0, in float edge1, in float x) -{ - float t = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0); - return t * t * (3.0 - 2.0 * t); -} - -float toLinearDepth(float depth) -{ - return cameraNear * cameraFar / (cameraFar + depth * (cameraNear - cameraFar)); -} - -float getDepth(vec2 screenspacePosition) -{ - return texture2D(depthmap, screenspacePosition * 0.5 + 0.5).r; -} - -float noise(vec3 p) -{ - float y = floor(p.y); - float f1 = texture2D(noiseTexture, p.xz / 256. + y * 0.2).r; - float f2 = texture2D(noiseTexture, p.xz / 256. + y * 0.2 + 0.2).r; - return mix(f1, f2, fract(p.y)); -} - -float fnoise(vec3 p) -{ - return noise(p * 4.) * 0.5 + noise(p * 8.) * 0.25; -} - -float fnoise3(vec3 p) -{ - return noise(p * 4.) * 0.5 + noise(p * 8.) * 0.25 + noise(p * 16.) * 0.125; -} - -float getAuroraDensity(vec3 position) -{ - float density = pow(max(0., 1. - 10. * abs(fnoise3(vec3(position.x * 0.25, animationTimer, position.z * 0.25)) - 0.5)), 4.); - return 0.7 * density * mtsmoothstep(0.0, 0.05, position.y - 1.) * pow(1. - mtsmoothstep(0.05, 2.0, position.y - 1.), 4.); -} - -float getCoarse(vec3 position) { - return texture2D(noiseTextureCoarse, (position.xz - cloudOffset) * 0.5 / CLOUD_SIZE / cloudRadius).r; -} - -float getDensity(vec3 position) -{ - float density = texture2D(noiseTextureCoarse, (position.xz - cloudOffset) * 0.5 / CLOUD_SIZE / cloudRadius).r * - mtsmoothstep(0.0, cloudThickness * 0.2, position.y - cloudHeight) * - (1.0 - mtsmoothstep(cloudThickness * 0.5, cloudThickness, position.y - cloudHeight)); - - density = max(0., density - 0.5 * fnoise(position * 0.005)); - - return 0.04 * density; -} - -float getBrightness(vec3 position, float lightDistance) -{ - float density = 0.; - for (int i = 1; i <= LIGHT_ITERATIONS; i++) { - vec3 rayPosition = position - v_LightDirection * lightDistance * float(i) / float(LIGHT_ITERATIONS); - - density += getDensity(rayPosition) * float(lightDistance) / float(LIGHT_ITERATIONS); - } - return exp(-density); -} - -float blend(float A, float B, float alphaA, float alphaB) -{ - float alphaC = alphaA + (1. - alphaA) * alphaB; - return (alphaA * A + (1. - alphaA) * alphaB * B) / alphaC; -} - -void main(void) -{ - vec3 viewVec = normalize(relativePosition); - - vec3 position = cameraOffset + cameraPosition; - - float depth = toLinearDepth(getDepth(screenspaceCoordinate)) / normalize(viewDirection).z; - float bottomPlaneIntersect = clamp((cloudHeight - cameraPosition.y) / viewVec.y, 0., 4. * fogDistance); - float topPlaneIntersect = clamp((cloudHeight + cloudThickness - cameraPosition.y) / viewVec.y, 0., 4. * fogDistance); - -#if (VOLUMETRICS_UNDERSAMPLING <= 1) - bottomPlaneIntersect = min(depth, bottomPlaneIntersect); - topPlaneIntersect = min(depth, topPlaneIntersect); -#else - if ((bottomPlaneIntersect > depth + 5.0) != (topPlaneIntersect > depth + 5.0)) { - bottomPlaneIntersect = min(depth, bottomPlaneIntersect); - topPlaneIntersect = min(depth, topPlaneIntersect); - } -#endif - - float startDepth = min(bottomPlaneIntersect, topPlaneIntersect); - float endDepth = max(bottomPlaneIntersect, topPlaneIntersect); - - float bias = screenSpaceDither(gl_FragCoord.xy + animationTimer * 2400.0); - - vec3 color = vec3(0.); - - float density = 0.; - - float auroraStartDepth = min(max(0., 1.0 / viewVec.y), 8.); - float auroraEndDepth = min(max(0., 3.0 / viewVec.y), 8.); - float rawDepth = getDepth(screenspaceCoordinate); - - if (auroraEndDepth - auroraStartDepth > 0.1 && rawDepth >= 1.0) { - for (int i = 0; i < AURORA_ITERATIONS; i++) { - vec3 rayPosition = viewVec * (auroraStartDepth + (auroraEndDepth - auroraStartDepth) * (float(i) + bias) / float(AURORA_ITERATIONS)); - - float localDensity = getAuroraDensity(rayPosition); - - localDensity *= 1.0 - mtsmoothstep(4.0, 8.0, length(rayPosition)); - - density += localDensity; - } - } - - color.b = density * (auroraEndDepth - auroraStartDepth) / float(AURORA_ITERATIONS); - - float sunlightContribution = 0.; - float alpha = 0.; - float outScatter = 2. * (dot(v_LightDirection, viewVec) * 0.5 + 0.5); - float forwardScatter = 1. + 2. * pow(min(dot(v_LightDirection, viewVec), 0.), 4.); - density = 0.; - - float fogDepth = min(4. * fogDistance, startDepth + 2000.); - endDepth = min(endDepth, fogDepth); - - float dx = (endDepth - startDepth) / float(ITERATIONS); - float lightDistance = cloudThickness * 0.5; - - if (endDepth - startDepth > 0.1) { - for (int i = 0; i < ITERATIONS; i++) { - vec3 rayPosition = cameraPosition + viewVec * (startDepth + (endDepth - startDepth) * (float(i) + bias) / float(ITERATIONS)); - - float localDensity = getDensity(rayPosition) * dx; - - if (localDensity < 0.0001) continue; - - float clarity = clamp(fogShadingParameter - fogShadingParameter * length(rayPosition - cameraPosition) / (fogDepth), 0.0, 1.0); - float outScatterContribution = exp(-0.5 * outScatter * localDensity); - float brightness = getBrightness(rayPosition, lightDistance) * forwardScatter * outScatterContribution * sunStrength + (1. - outScatterContribution); - sunlightContribution = blend(sunlightContribution, brightness, 1. - exp(-density), 1. - exp(-localDensity)); - alpha = blend(alpha, clarity, 1. - exp(-density), 1. - exp(-localDensity)); - - density += localDensity; - - if (density > 10.0) break; - } - } - - color.r = (1. - exp(-density)) * alpha; - color.g = sunlightContribution; - color.b *= exp(-density); - - gl_FragColor = vec4(color, 1.0); -} diff --git a/client/shaders/volumetric_clouds/opengl_vertex.glsl b/client/shaders/volumetric_clouds/opengl_vertex.glsl deleted file mode 100644 index 3b1d247a9..000000000 --- a/client/shaders/volumetric_clouds/opengl_vertex.glsl +++ /dev/null @@ -1,37 +0,0 @@ -uniform mat4 mCameraProjInv; -uniform mat4 mCameraView; -uniform float f_timeofday; - -varying vec3 relativePosition; -varying vec3 viewDirection; - -varying vec2 screenspaceCoordinate; -varying float sunStrength; - -float mtsmoothstep(in float edge0, in float edge1, in float x) -{ - float t = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0); - return t * t * (3.0 - 2.0 * t); -} - -void main(void) -{ - screenspaceCoordinate = inVertexPosition.xy; - vec4 p = mCameraProjInv * inVertexPosition; - viewDirection = p.xyz / p.w; - relativePosition = (p.xyz / p.w) * mat3(mCameraView); - - if (f_timeofday < 0.21) { - sunStrength = - (1.0 - mtsmoothstep(0.18, 0.21, f_timeofday)); - } else if (f_timeofday >= 0.793) { - sunStrength = - mtsmoothstep(0.793, 0.823, f_timeofday); - } else { - sunStrength = - mtsmoothstep(0.21, 0.26, f_timeofday) * - (1.0 - mtsmoothstep(0.743, 0.793, f_timeofday)); - } - - gl_Position = inVertexPosition; -} diff --git a/src/client/client.h b/src/client/client.h index 8fba92fad..f9f77ede4 100644 --- a/src/client/client.h +++ b/src/client/client.h @@ -35,7 +35,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "gameparams.h" #include "script/common/c_types.h" // LuaError #include "util/numeric.h" -#include "clouds.h" #ifdef SERVER #error Do not include in server builds @@ -373,9 +372,6 @@ public: Camera* getCamera () { return m_camera; } scene::ISceneManager *getSceneManager(); - Clouds* getClouds() { return m_clouds; } - void setClouds(Clouds* clouds) { m_clouds = clouds; } - // IGameDef interface IItemDefManager* getItemDefManager() override; const NodeDefManager* getNodeDefManager() override; @@ -501,7 +497,6 @@ private: ELoginRegister m_allow_login_or_register = ELoginRegister::Any; Camera *m_camera = nullptr; Minimap *m_minimap = nullptr; - Clouds *m_clouds = nullptr; // Server serialization version u8 m_server_ser_ver; diff --git a/src/client/clouds.cpp b/src/client/clouds.cpp index 1bbd5f206..9d4d28300 100644 --- a/src/client/clouds.cpp +++ b/src/client/clouds.cpp @@ -28,7 +28,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "settings.h" #include -class Clouds; scene::ISceneManager *g_menucloudsmgr = nullptr; Clouds *g_menuclouds = nullptr; @@ -44,7 +43,7 @@ Clouds::Clouds(scene::ISceneManager* mgr, IShaderSource *ssrc, s32 id, u32 seed ): - scene::ISceneNode(g_settings->getBool("enable_volumetric_clouds") ? nullptr : mgr->getRootSceneNode(), mgr, id), + scene::ISceneNode(mgr->getRootSceneNode(), mgr, id), m_seed(seed) { assert(ssrc); @@ -54,7 +53,8 @@ Clouds::Clouds(scene::ISceneManager* mgr, IShaderSource *ssrc, m_material.FogEnable = true; m_material.AntiAliasing = video::EAAM_SIMPLE; if (m_enable_shaders) { - auto sid = ssrc->getShader("cloud_shader", TILE_MATERIAL_ALPHA); + bool shaded_clouds = g_settings->getBool("soft_clouds") && g_settings->getBool("enable_dynamic_shadows"); + auto sid = ssrc->getShader(shaded_clouds ? "soft_clouds" : "cloud_shader", TILE_MATERIAL_ALPHA); m_material.MaterialType = ssrc->getShaderInfo(sid).material; } else { m_material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; @@ -107,14 +107,6 @@ void Clouds::updateMesh() std::floor(center_of_drawing_in_noise_f.Y / cloud_size) ); - // The world position of the integer center point of drawing in the noise - v2f world_center_of_drawing_in_noise_f = v2f( - center_of_drawing_in_noise_i.X * cloud_size, - center_of_drawing_in_noise_i.Y * cloud_size - ) + m_origin; - - m_noise_position = world_center_of_drawing_in_noise_f - ((float)m_cloud_radius_i + 0.5f) * cloud_size; - // Only update mesh if it has moved enough, this saves lots of GPU buffer uploads. constexpr float max_d = 5 * BS; @@ -137,6 +129,12 @@ void Clouds::updateMesh() const u32 num_faces_to_draw = is3D() ? 6 : 1; + // The world position of the integer center point of drawing in the noise + v2f world_center_of_drawing_in_noise_f = v2f( + center_of_drawing_in_noise_i.X * cloud_size, + center_of_drawing_in_noise_i.Y * cloud_size + ) + m_origin; + // Colors with primitive shading video::SColorf c_top_f(m_color); @@ -166,7 +164,7 @@ void Clouds::updateMesh() // Read noise - m_grid.resize(m_cloud_radius_i * 2 * m_cloud_radius_i * 2); + std::vector grid(m_cloud_radius_i * 2 * m_cloud_radius_i * 2); for(s16 zi = -m_cloud_radius_i; zi < m_cloud_radius_i; zi++) { u32 si = (zi + m_cloud_radius_i) * m_cloud_radius_i * 2 + m_cloud_radius_i; @@ -174,7 +172,7 @@ void Clouds::updateMesh() for (s16 xi = -m_cloud_radius_i; xi < m_cloud_radius_i; xi++) { u32 i = si + xi; - m_grid[i] = gridFilled( + grid[i] = gridFilled( xi + center_of_drawing_in_noise_i.X, zi + center_of_drawing_in_noise_i.Y ); @@ -213,147 +211,225 @@ void Clouds::updateMesh() u32 i = GETINDEX(xi, zi, m_cloud_radius_i); - if (!m_grid[i]) + if (!grid[i]) continue; v2f p0 = v2f(xi,zi)*cloud_size + world_center_of_drawing_in_noise_f; - video::S3DVertex v[4] = { - video::S3DVertex(0,0,0, 0,0,0, c_top, 0, 1), - video::S3DVertex(0,0,0, 0,0,0, c_top, 1, 1), - video::S3DVertex(0,0,0, 0,0,0, c_top, 1, 0), - video::S3DVertex(0,0,0, 0,0,0, c_top, 0, 0) - }; - const f32 rx = cloud_size / 2.0f; // if clouds are flat, the top layer should be at the given height const f32 ry = is3D() ? m_params.thickness * BS : 0.0f; const f32 rz = cloud_size / 2; bool soft_clouds_enabled = g_settings->getBool("soft_clouds"); - for (u32 i = 0; i < num_faces_to_draw; i++) - { - switch (i) - { - case 0: // top - for (video::S3DVertex& vertex : v) { - vertex.Normal.set(0, 1, 0); - } - v[0].Pos.set(-rx, ry,-rz); - v[1].Pos.set(-rx, ry, rz); - v[2].Pos.set( rx, ry, rz); - v[3].Pos.set( rx, ry,-rz); - break; - case 1: // back - if (INAREA(xi, zi - 1, m_cloud_radius_i)) { - u32 j = GETINDEX(xi, zi - 1, m_cloud_radius_i); - if (m_grid[j]) - continue; - } - if (soft_clouds_enabled) { - for (video::S3DVertex& vertex : v) { - vertex.Normal.set(0, 0, -1); - } - v[2].Color = c_bottom; - v[3].Color = c_bottom; - } else { - for (video::S3DVertex& vertex : v) { - vertex.Color = c_side_1; - vertex.Normal.set(0, 0, -1); - } - } - v[0].Pos.set(-rx, ry,-rz); - v[1].Pos.set( rx, ry,-rz); - v[2].Pos.set( rx, 0,-rz); - v[3].Pos.set(-rx, 0,-rz); - break; - case 2: //right - if (INAREA(xi + 1, zi, m_cloud_radius_i)) { - u32 j = GETINDEX(xi + 1, zi, m_cloud_radius_i); - if (m_grid[j]) - continue; - } - if (soft_clouds_enabled) { - for (video::S3DVertex& vertex : v) { - vertex.Normal.set(1, 0, 0); - } - v[2].Color = c_bottom; - v[3].Color = c_bottom; - } - else { - for (video::S3DVertex& vertex : v) { - vertex.Color = c_side_2; - vertex.Normal.set(1, 0, 0); - } - } - v[0].Pos.set(rx, ry,-rz); - v[1].Pos.set(rx, ry, rz); - v[2].Pos.set(rx, 0, rz); - v[3].Pos.set(rx, 0,-rz); - break; - case 3: // front - if (INAREA(xi, zi + 1, m_cloud_radius_i)) { - u32 j = GETINDEX(xi, zi + 1, m_cloud_radius_i); - if (m_grid[j]) - continue; - } - if (soft_clouds_enabled) { - for (video::S3DVertex& vertex : v) { - vertex.Normal.set(0, 0, -1); - } - v[2].Color = c_bottom; - v[3].Color = c_bottom; - } else { - for (video::S3DVertex& vertex : v) { - vertex.Color = c_side_1; - vertex.Normal.set(0, 0, -1); - } - } - v[0].Pos.set( rx, ry, rz); - v[1].Pos.set(-rx, ry, rz); - v[2].Pos.set(-rx, 0, rz); - v[3].Pos.set( rx, 0, rz); - break; - case 4: // left - if (INAREA(xi - 1, zi, m_cloud_radius_i)) { - u32 j = GETINDEX(xi - 1, zi, m_cloud_radius_i); - if (m_grid[j]) - continue; - } - if (soft_clouds_enabled) { - for (video::S3DVertex& vertex : v) { - vertex.Normal.set(-1, 0, 0); - } - v[2].Color = c_bottom; - v[3].Color = c_bottom; - } else { - for (video::S3DVertex& vertex : v) { - vertex.Color = c_side_2; - vertex.Normal.set(-1, 0, 0); - } - } - v[0].Pos.set(-rx, ry, rz); - v[1].Pos.set(-rx, ry,-rz); - v[2].Pos.set(-rx, 0,-rz); - v[3].Pos.set(-rx, 0, rz); - break; - case 5: // bottom - for (video::S3DVertex& vertex : v) { - vertex.Color = c_bottom; - vertex.Normal.set(0, -1, 0); - } - v[0].Pos.set( rx, 0, rz); - v[1].Pos.set(-rx, 0, rz); - v[2].Pos.set(-rx, 0,-rz); - v[3].Pos.set( rx, 0,-rz); - break; + bool shaded_clouds_enabled = soft_clouds_enabled && g_settings->getBool("enable_dynamic_shadows") && g_settings->getBool("enable_3d_clouds"); + + v3f pos(p0.X, m_params.height * BS, p0.Y); + + if (shaded_clouds_enabled) { + bool neighbours[4] = {false, false, false, false}; + if (INAREA(xi - 1, zi, m_cloud_radius_i)) + neighbours[0] = grid[GETINDEX(xi - 1, zi, m_cloud_radius_i)]; + if (INAREA(xi, zi - 1, m_cloud_radius_i)) + neighbours[1] = grid[GETINDEX(xi, zi - 1, m_cloud_radius_i)]; + if (INAREA(xi + 1, zi, m_cloud_radius_i)) + neighbours[2] = grid[GETINDEX(xi + 1, zi, m_cloud_radius_i)]; + if (INAREA(xi, zi + 1, m_cloud_radius_i)) + neighbours[3] = grid[GETINDEX(xi, zi + 1, m_cloud_radius_i)]; + + video::S3DVertex v[32]; + v[ 0].Pos = core::vector3df( -rx, ry, -rz); + v[ 1].Pos = core::vector3df(-0.75 * rx, ry, -rz); + v[ 2].Pos = core::vector3df( 0.75 * rx, ry, -rz); + v[ 3].Pos = core::vector3df( rx, ry, -rz); + v[ 4].Pos = core::vector3df( -rx, ry, -0.75 * rz); + v[ 5].Pos = core::vector3df(-0.75 * rx, ry, -0.75 * rz); + v[ 6].Pos = core::vector3df( 0.75 * rx, ry, -0.75 * rz); + v[ 7].Pos = core::vector3df( rx, ry, -0.75 * rz); + v[ 8].Pos = core::vector3df( -rx, ry, 0.75 * rz); + v[ 9].Pos = core::vector3df(-0.75 * rx, ry, 0.75 * rz); + v[10].Pos = core::vector3df( 0.75 * rx, ry, 0.75 * rz); + v[11].Pos = core::vector3df( rx, ry, 0.75 * rz); + v[12].Pos = core::vector3df( -rx, ry, rz); + v[13].Pos = core::vector3df(-0.75 * rx, ry, rz); + v[14].Pos = core::vector3df( 0.75 * rx, ry, rz); + v[15].Pos = core::vector3df( rx, ry, rz); + + // These normals are intentionally left unnormalized + if (neighbours[0]) { + v[ 0].Normal.X -= 1.0; + v[ 4].Normal.X -= 1.0; + v[ 8].Normal.X -= 1.0; + v[12].Normal.X -= 1.0; + } + if (neighbours[1]) { + v[0].Normal.Z -= 1.0; + v[1].Normal.Z -= 1.0; + v[2].Normal.Z -= 1.0; + v[3].Normal.Z -= 1.0; + } + if (neighbours[2]) { + v[ 3].Normal.X += 1.0; + v[ 7].Normal.X += 1.0; + v[11].Normal.X += 1.0; + v[15].Normal.X += 1.0; + } + if (neighbours[3]) { + v[12].Normal.Z += 1.0; + v[13].Normal.Z += 1.0; + v[14].Normal.Z += 1.0; + v[15].Normal.Z += 1.0; } - v3f pos(p0.X, m_params.height * BS, p0.Y); + for (int i = 0; i < 16; ++i) { + v[i + 32] = v[i]; + v[i + 32].Pos.Y = -ry; - for (video::S3DVertex &vertex : v) { + v[i].Normal = core::vector3df(0.0, 1.0, 0.0); + v[i + 32].Normal = core::vector3df(0.0, -1.0, 0.0); + } + + for (video::S3DVertex& vertex : v) { + vertex.Color = shadow.toSColor(); vertex.Pos += pos; - vertices.push_back(vertex); + } + + //top + + } + else { + video::S3DVertex v[4] = { + video::S3DVertex(0,0,0, 0,0,0, c_top, 0, 1), + video::S3DVertex(0,0,0, 0,0,0, c_top, 1, 1), + video::S3DVertex(0,0,0, 0,0,0, c_top, 1, 0), + video::S3DVertex(0,0,0, 0,0,0, c_top, 0, 0) + }; + + for (u32 i = 0; i < num_faces_to_draw; i++) + { + switch (i) + { + case 0: // top + for (video::S3DVertex& vertex : v) { + vertex.Normal.set(0, 1, 0); + } + v[0].Pos.set(-rx, ry, -rz); + v[1].Pos.set(-rx, ry, rz); + v[2].Pos.set(rx, ry, rz); + v[3].Pos.set(rx, ry, -rz); + break; + case 1: // back + if (INAREA(xi, zi - 1, m_cloud_radius_i)) { + u32 j = GETINDEX(xi, zi - 1, m_cloud_radius_i); + if (grid[j]) + continue; + } + if (soft_clouds_enabled) { + for (video::S3DVertex& vertex : v) { + vertex.Normal.set(0, 0, -1); + } + v[2].Color = c_bottom; + v[3].Color = c_bottom; + } + else { + for (video::S3DVertex& vertex : v) { + vertex.Color = c_side_1; + vertex.Normal.set(0, 0, -1); + } + } + v[0].Pos.set(-rx, ry, -rz); + v[1].Pos.set(rx, ry, -rz); + v[2].Pos.set(rx, 0, -rz); + v[3].Pos.set(-rx, 0, -rz); + break; + case 2: //right + if (INAREA(xi + 1, zi, m_cloud_radius_i)) { + u32 j = GETINDEX(xi + 1, zi, m_cloud_radius_i); + if (grid[j]) + continue; + } + if (soft_clouds_enabled) { + for (video::S3DVertex& vertex : v) { + vertex.Normal.set(1, 0, 0); + } + v[2].Color = c_bottom; + v[3].Color = c_bottom; + } + else { + for (video::S3DVertex& vertex : v) { + vertex.Color = c_side_2; + vertex.Normal.set(1, 0, 0); + } + } + v[0].Pos.set(rx, ry, -rz); + v[1].Pos.set(rx, ry, rz); + v[2].Pos.set(rx, 0, rz); + v[3].Pos.set(rx, 0, -rz); + break; + case 3: // front + if (INAREA(xi, zi + 1, m_cloud_radius_i)) { + u32 j = GETINDEX(xi, zi + 1, m_cloud_radius_i); + if (grid[j]) + continue; + } + if (soft_clouds_enabled) { + for (video::S3DVertex& vertex : v) { + vertex.Normal.set(0, 0, -1); + } + v[2].Color = c_bottom; + v[3].Color = c_bottom; + } + else { + for (video::S3DVertex& vertex : v) { + vertex.Color = c_side_1; + vertex.Normal.set(0, 0, -1); + } + } + v[0].Pos.set(rx, ry, rz); + v[1].Pos.set(-rx, ry, rz); + v[2].Pos.set(-rx, 0, rz); + v[3].Pos.set(rx, 0, rz); + break; + case 4: // left + if (INAREA(xi - 1, zi, m_cloud_radius_i)) { + u32 j = GETINDEX(xi - 1, zi, m_cloud_radius_i); + if (grid[j]) + continue; + } + if (soft_clouds_enabled) { + for (video::S3DVertex& vertex : v) { + vertex.Normal.set(-1, 0, 0); + } + v[2].Color = c_bottom; + v[3].Color = c_bottom; + } + else { + for (video::S3DVertex& vertex : v) { + vertex.Color = c_side_2; + vertex.Normal.set(-1, 0, 0); + } + } + v[0].Pos.set(-rx, ry, rz); + v[1].Pos.set(-rx, ry, -rz); + v[2].Pos.set(-rx, 0, -rz); + v[3].Pos.set(-rx, 0, rz); + break; + case 5: // bottom + for (video::S3DVertex& vertex : v) { + vertex.Color = c_bottom; + vertex.Normal.set(0, -1, 0); + } + v[0].Pos.set(rx, 0, rz); + v[1].Pos.set(-rx, 0, rz); + v[2].Pos.set(-rx, 0, -rz); + v[3].Pos.set(rx, 0, -rz); + break; + } + + for (video::S3DVertex& vertex : v) { + vertex.Pos += pos; + vertices.push_back(vertex); + } } } } @@ -430,40 +506,13 @@ void Clouds::render() cloud_full_radius*1.2, fog_density, fog_pixelfog, fog_rangefog); } -//#if 0 driver->drawMeshBuffer(m_meshbuffer.get()); -//#endif + // Restore fog settings driver->setFog(fog_color, fog_type, fog_start, fog_end, fog_density, fog_pixelfog, fog_rangefog); } -void Clouds::renderDepth() { - if (m_params.density <= 0.0f) - return; // no need to do anything - - video::IVideoDriver* driver = SceneManager->getVideoDriver(); - - updateMesh(); - - // Update position - { - v2f off_origin = m_origin - m_mesh_origin; - v3f rel(off_origin.X, 0, off_origin.Y); - rel -= intToFloat(m_camera_offset, BS); - setPosition(rel); - updateAbsolutePosition(); - } - - video::SMaterial material = m_material; - material.MaterialType = video::EMT_SOLID; - material.ZWriteEnable = video::EZW_ON; - - driver->setTransform(video::ETS_WORLD, AbsoluteTransformation); - driver->setMaterial(material); - driver->drawMeshBuffer(m_meshbuffer.get()); -} - void Clouds::step(float dtime) { m_origin = m_origin + dtime * BS * m_params.speed; diff --git a/src/client/clouds.h b/src/client/clouds.h index 67a2aed28..7193c03f9 100644 --- a/src/client/clouds.h +++ b/src/client/clouds.h @@ -60,8 +60,6 @@ public: virtual void render(); - void renderDepth(); - virtual const aabb3f &getBoundingBox() const { return m_box; @@ -101,10 +99,6 @@ public: invalidateMesh(); } - float getDensity() const { - return m_params.density; - } - void setColorBright(video::SColor color_bright) { m_params.color_bright = color_bright; @@ -132,10 +126,6 @@ public: invalidateMesh(); } - float getHeight() const { - return m_params.height; - } - void setSpeed(v2f speed) { m_params.speed = speed; @@ -150,24 +140,10 @@ public: invalidateMesh(); } - float getThickness() const { - return m_params.thickness; - } - bool isCameraInsideCloud() const { return m_camera_inside_cloud; } const video::SColor getColor() const { return m_color.toSColor(); } - bool getGrid(int x, int y) - { - int index = x + y * m_cloud_radius_i * 2; - if (index < 0 || index >= m_grid.size()) - return false; - return m_grid[index]; - } - - v2f getCloudOffset() const { return m_noise_position; } - private: void updateBox() { @@ -204,7 +180,6 @@ private: u16 m_cloud_radius_i; u32 m_seed; v3f m_camera_pos; - v2f m_noise_position; v3s16 m_camera_offset; bool m_camera_inside_cloud = false; @@ -212,7 +187,4 @@ private: bool m_enable_shaders, m_enable_3d; video::SColorf m_color = video::SColorf(1.0f, 1.0f, 1.0f, 1.0f); CloudParams m_params; - - std::vector m_grid; - }; diff --git a/src/client/game.cpp b/src/client/game.cpp index 3c4f42031..faf0ef65d 100644 --- a/src/client/game.cpp +++ b/src/client/game.cpp @@ -435,8 +435,6 @@ class GameGlobalShaderConstantSetter : public IShaderConstantSetter CachedPixelShaderSetting m_moon_brightness_pixel{"moonBrightness"}; CachedPixelShaderSetting m_volumetric_light_strength_pixel{"volumetricLightStrength"}; - CachedPixelShaderSetting - m_volumetric_cloud_color{"cloudColor"}; static constexpr std::array SETTING_CALLBACKS = { "exposure_compensation", @@ -575,23 +573,6 @@ public: video::SColorf artificial_light = lighting.artificial_light_color; m_artificial_light.set(artificial_light, services); - // TODO: settings - Clouds* clouds = m_client->getClouds(); - if (clouds && g_settings->getBool("enable_volumetric_clouds")) { - float cloud_height = clouds->getHeight() * 10.0f; - m_cloud_height_pixel.set(&cloud_height, services); - float cloud_thickness = clouds->getThickness() * 10.0f; - m_cloud_thickness_pixel.set(&cloud_thickness, services); - float cloud_density = clouds->getDensity(); - m_cloud_density_pixel.set(&cloud_density, services); - v2f cloud_offset = clouds->getCloudOffset(); - m_cloud_offset_pixel.set(cloud_offset, services); - float cloud_radius = g_settings->getU16("cloud_radius"); - m_cloud_radius_pixel.set(&cloud_radius, services); - video::SColor cloud_color = clouds->getColor(); - m_volumetric_cloud_color.set(cloud_color, services); - } - if (m_volumetric_light_enabled) { // Map directional light to screen space auto camera_node = m_client->getCamera()->getCameraNode(); @@ -1588,7 +1569,6 @@ bool Game::createClient(const GameStartData &start_data) */ if (m_cache_enable_clouds) clouds = make_irr(smgr, shader_src, -1, rand()); - client->setClouds(clouds.get()); /* Skybox */ @@ -4334,7 +4314,7 @@ void Game::updateClouds(float dtime) camera_node_position.Y = camera_node_position.Y + camera_offset.Y * BS; camera_node_position.Z = camera_node_position.Z + camera_offset.Z * BS; this->clouds->update(camera_node_position, this->sky->getCloudColor()); - if (this->clouds->isCameraInsideCloud() && this->fogEnabled() && !g_settings->getBool("enable_volumetric_clouds")) { + if (this->clouds->isCameraInsideCloud() && this->fogEnabled()) { // If camera is inside cloud and fog is enabled, use cloud's colors as sky colors. video::SColor clouds_dark = this->clouds->getColor().getInterpolated( video::SColor(255, 0, 0, 0), 0.9); diff --git a/src/client/render/pipeline.cpp b/src/client/render/pipeline.cpp index 7700e8aeb..37adcbaf2 100644 --- a/src/client/render/pipeline.cpp +++ b/src/client/render/pipeline.cpp @@ -113,19 +113,6 @@ void TextureBuffer::swapTextures(u8 texture_a, u8 texture_b) m_textures[texture_b] = temp; } -void TextureBuffer::setTextureImage(u8 id, video::IImage* image) { - assert(m_definitions[id].valid); - - auto &definition = m_definitions[id]; - - if (m_textures[id]) m_driver->removeTexture(m_textures[id]); - - m_textures[id] = m_driver->addTexture(definition.name.c_str(), image); - definition.fixed_size = true; - definition.size = image->getDimension(); - definition.dirty = false; -} - bool TextureBuffer::ensureTexture(video::ITexture **texture, const TextureDefinition& definition, PipelineContext &context) { bool modify; @@ -195,8 +182,6 @@ void TextureBufferOutput::activate(PipelineContext &context) if (!render_target) render_target = driver->addRenderTarget(); - if (disable_clear) m_clear = false; - core::array textures; core::dimension2du size(0, 0); for (size_t i = 0; i < texture_map.size(); i++) { diff --git a/src/client/render/pipeline.h b/src/client/render/pipeline.h index 31ceabe20..8a6b55c07 100644 --- a/src/client/render/pipeline.h +++ b/src/client/render/pipeline.h @@ -190,7 +190,6 @@ public: TextureBufferOutput(TextureBuffer *buffer, const std::vector &texture_map, u8 depth_stencil); virtual ~TextureBufferOutput() override; void activate(PipelineContext &context) override; - void disableClearing() { disable_clear = true; } private: static const u8 NO_DEPTH_TEXTURE = 255; @@ -199,7 +198,6 @@ private: u8 depth_stencil { NO_DEPTH_TEXTURE }; video::IRenderTarget* render_target { nullptr }; video::IVideoDriver* driver { nullptr }; - bool disable_clear = false; }; /** diff --git a/src/client/render/secondstage.cpp b/src/client/render/secondstage.cpp index 082c4c11c..da6536b97 100644 --- a/src/client/render/secondstage.cpp +++ b/src/client/render/secondstage.cpp @@ -24,116 +24,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "client/shader.h" #include "client/tile.h" #include "settings.h" -#include "noise.h" - -// TODO: Probably this could still be improved, having a step for this seems silly -class NoiseStep : public RenderStep { -public: - NoiseStep(TextureBuffer* buffer, u8 id, u32 size) : - buffer(buffer), id(id), size(size) - { - } - - void setRenderSource(RenderSource* _source) override {} - - void setRenderTarget(RenderTarget* _target) override {} - - void reset(PipelineContext& context) override {} - - void run(PipelineContext& context) override - { - if (!needs_run) return; - - needs_run = false; - - video::IImage* noise_image = context.device->getVideoDriver()->createImage(video::ECF_A8R8G8B8, core::dimension2du(256, 256)); - PseudoRandom random; - for (u32 i = 0; i < size * size; ++i) { - noise_image->setPixel(i % size, i / size, video::SColor(0, random.next() % 256, 0, 0)); - } - buffer->setTextureImage(id, noise_image); - noise_image->drop(); - } - -private: - u32 size; - u8 id; - TextureBuffer* buffer = nullptr; - bool needs_run = true; -}; - -class CloudDensityStep : public RenderStep { -public: - CloudDensityStep(TextureBuffer* buffer, u8 id, Clouds* clouds) : - buffer(buffer), id(id), clouds(clouds) - { - } - - void setRenderSource(RenderSource* _source) override {} - - void setRenderTarget(RenderTarget* _target) override {} - - void reset(PipelineContext& context) override {} - - void run(PipelineContext& context) override - { - u16 cloud_radius = g_settings->getU16("cloud_radius"); - if (cloud_radius < 1) cloud_radius = 1; - - video::IImage* image = context.device->getVideoDriver()->createImage(video::ECF_A8R8G8B8, core::dimension2du(8 * cloud_radius, 8 * cloud_radius)); - - for (int x = 0; x < 2 * cloud_radius; ++x) { - for (int y = 0; y < 2 * cloud_radius; ++y) { - bool isFilled = clouds->getGrid(x, y); - - for (int i = 0; i < 16; ++i) { - int xp = x * 4 + i % 4; - int yp = y * 4 + i / 4; - - image->setPixel(xp, yp, video::SColor(255, isFilled * 255, 0, 0)); - } - } - } - - buffer->setTextureImage(id, image); - - image->drop(); - } - -private: - Clouds* clouds = nullptr; - u8 id = 0; - TextureBuffer* buffer = nullptr; -}; - -class CloudDepthStep : public RenderStep { -public: - CloudDepthStep(Clouds* clouds) : - clouds(clouds) - { - } - - void setRenderSource(RenderSource* _source) override {} - - void setRenderTarget(RenderTarget* _target) override - { - target = _target; - } - - void reset(PipelineContext& context) override {} - - void run(PipelineContext& context) override - { - if (target) - target->activate(context); - - clouds->renderDepth(); - } - -private: - Clouds* clouds = nullptr; - RenderTarget* target = nullptr; -}; PostProcessingStep::PostProcessingStep(u32 _shader_id, const std::vector &_texture_map) : shader_id(_shader_id), texture_map(_texture_map) @@ -175,6 +65,7 @@ void PostProcessingStep::run(PipelineContext &context) if (target) target->activate(context); + // attach the shader material.MaterialType = context.client->getShaderSource()->getShaderInfo(shader_id).material; auto driver = context.device->getVideoDriver(); @@ -205,17 +96,6 @@ void PostProcessingStep::setBilinearFilter(u8 index, bool value) material.TextureLayers[index].MagFilter = value ? video::ETMAGF_LINEAR : video::ETMAGF_NEAREST; } -void PostProcessingStep::setWrapRepeat(u8 index, bool value) { - assert(index < video::MATERIAL_MAX_TEXTURES); - material.TextureLayers[index].TextureWrapU = value ? video::ETC_REPEAT : video::ETC_CLAMP_TO_EDGE; - material.TextureLayers[index].TextureWrapV = value ? video::ETC_REPEAT : video::ETC_CLAMP_TO_EDGE; -} - -void PostProcessingStep::disableDepthTest() { - material.ZBuffer = video::ECFN_DISABLED; - material.ZWriteEnable = video::EZW_OFF; -} - RenderStep *addPostProcessing(RenderPipeline *pipeline, RenderStep *previousStep, v2f scale, Client *client) { auto buffer = pipeline->createOwned(); @@ -241,13 +121,8 @@ RenderStep *addPostProcessing(RenderPipeline *pipeline, RenderStep *previousStep static const u8 TEXTURE_EXPOSURE_2 = 4; static const u8 TEXTURE_FXAA = 5; static const u8 TEXTURE_VOLUME = 6; - static const u8 TEXTURE_CLOUDS_1 = 7; - static const u8 TEXTURE_CLOUDS_2 = 8; - static const u8 TEXTURE_CLOUD_DENSITY = 9; - static const u8 TEXTURE_NOISE = 10; - static const u8 TEXTURE_NOISE_COARSE = 11; - static const u8 TEXTURE_SCALE_DOWN = 20; - static const u8 TEXTURE_SCALE_UP = 30; + static const u8 TEXTURE_SCALE_DOWN = 10; + static const u8 TEXTURE_SCALE_UP = 20; // Super-sampling is simply rendering into a larger texture. // Downscaling is done by the final step when rendering to the screen. @@ -257,8 +132,6 @@ RenderStep *addPostProcessing(RenderPipeline *pipeline, RenderStep *previousStep const bool enable_ssaa = antialiasing == "ssaa"; const bool enable_fxaa = antialiasing == "fxaa"; const bool enable_volumetric_light = g_settings->getBool("enable_volumetric_lighting") && enable_bloom; - // TODO: Proper constraints - const bool enable_volumetric_clouds = g_settings->getBool("enable_volumetric_clouds") && client->getClouds(); if (enable_ssaa) { u16 ssaa_scale = MYMAX(2, g_settings->getU16("fsaa")); @@ -279,55 +152,11 @@ RenderStep *addPostProcessing(RenderPipeline *pipeline, RenderStep *previousStep // Number of mipmap levels of the bloom downsampling texture const u8 MIPMAP_LEVELS = 4; + // post-processing stage u8 source = TEXTURE_COLOR; - u8 final_color_source = TEXTURE_COLOR; - - if (enable_volumetric_clouds) { - const u16 cloud_radius = g_settings->getU16("cloud_radius"); - - buffer->setTexture(TEXTURE_NOISE, core::dimension2du(256, 256), "noise", color_format); - pipeline->addStep(buffer, TEXTURE_NOISE, 256); - - buffer->setTexture(TEXTURE_NOISE_COARSE, core::dimension2du(cloud_radius * 8, cloud_radius * 8), "noise_coarse", color_format); - pipeline->addStep(buffer, TEXTURE_NOISE_COARSE, client->getClouds()); - - u32 undersampling = core::clamp(g_settings->getU32("volumetrics_undersampling"), (u32)1, (u32)4); - - buffer->setTexture(TEXTURE_CLOUDS_1, scale / (float)undersampling, "clouds_1", color_format, /*clear:*/ true); - buffer->setTexture(TEXTURE_CLOUDS_2, scale, "clouds_2", color_format); - buffer->setTexture(TEXTURE_CLOUD_DENSITY, scale, "cloud_density", color_format); - - shader_id = client->getShaderSource()->getShader("volumetric_clouds", TILE_MATERIAL_PLAIN, NDT_MESH); - PostProcessingStep *volumetric_clouds = pipeline->addStep(shader_id, std::vector { TEXTURE_DEPTH, TEXTURE_NOISE, TEXTURE_NOISE_COARSE }); - volumetric_clouds->setRenderSource(buffer); - volumetric_clouds->setRenderTarget(pipeline->createOwned(buffer, TEXTURE_CLOUDS_1)); - volumetric_clouds->setBilinearFilter(1, true); - volumetric_clouds->setBilinearFilter(2, true); - volumetric_clouds->setWrapRepeat(1, true); - volumetric_clouds->setWrapRepeat(2, true); - volumetric_clouds->disableDepthTest(); - - source = TEXTURE_CLOUDS_1; - - shader_id = client->getShaderSource()->getShader("clouds_merge", TILE_MATERIAL_PLAIN, NDT_MESH); - PostProcessingStep* blend_clouds = pipeline->addStep(shader_id, std::vector { TEXTURE_CLOUDS_1, TEXTURE_COLOR, TEXTURE_DEPTH }); - blend_clouds->setRenderSource(buffer); - blend_clouds->setRenderTarget(pipeline->createOwned(buffer, TEXTURE_CLOUDS_2)); - blend_clouds->setBilinearFilter(0, true); - blend_clouds->disableDepthTest(); - - CloudDepthStep* cloud_depth = pipeline->addStep(client->getClouds()); - TextureBufferOutput* cloud_depth_output = pipeline->createOwned(buffer, std::vector{ TEXTURE_COLOR }, TEXTURE_DEPTH); - cloud_depth_output->disableClearing(); - cloud_depth->setRenderTarget(cloud_depth_output); - - source = TEXTURE_CLOUDS_2; - final_color_source = TEXTURE_CLOUDS_2; - } - // common downsampling step for bloom or autoexposure if (enable_bloom || enable_auto_exposure) { @@ -344,7 +173,7 @@ RenderStep *addPostProcessing(RenderPipeline *pipeline, RenderStep *previousStep // get bright spots u32 shader_id = client->getShaderSource()->getShader("extract_bloom", TILE_MATERIAL_PLAIN, NDT_MESH); - RenderStep* extract_bloom = pipeline->addStep(shader_id, std::vector { source, TEXTURE_EXPOSURE_1 }); + RenderStep *extract_bloom = pipeline->addStep(shader_id, std::vector { source, TEXTURE_EXPOSURE_1 }); extract_bloom->setRenderSource(buffer); extract_bloom->setRenderTarget(pipeline->createOwned(buffer, TEXTURE_BLOOM)); source = TEXTURE_BLOOM; @@ -395,14 +224,14 @@ RenderStep *addPostProcessing(RenderPipeline *pipeline, RenderStep *previousStep } // FXAA - u8 final_stage_source = final_color_source; + u8 final_stage_source = TEXTURE_COLOR; if (enable_fxaa) { final_stage_source = TEXTURE_FXAA; buffer->setTexture(TEXTURE_FXAA, scale, "fxaa", color_format); shader_id = client->getShaderSource()->getShader("fxaa", TILE_MATERIAL_PLAIN); - PostProcessingStep* effect = pipeline->createOwned(shader_id, std::vector { final_color_source }); + PostProcessingStep *effect = pipeline->createOwned(shader_id, std::vector { TEXTURE_COLOR }); pipeline->addStep(effect); effect->setBilinearFilter(0, true); effect->setRenderSource(buffer); @@ -411,7 +240,7 @@ RenderStep *addPostProcessing(RenderPipeline *pipeline, RenderStep *previousStep // final merge shader_id = client->getShaderSource()->getShader("second_stage", TILE_MATERIAL_PLAIN, NDT_MESH); - PostProcessingStep* effect = pipeline->createOwned(shader_id, std::vector { final_stage_source, TEXTURE_SCALE_UP, TEXTURE_EXPOSURE_2 }); + PostProcessingStep *effect = pipeline->createOwned(shader_id, std::vector { final_stage_source, TEXTURE_SCALE_UP, TEXTURE_EXPOSURE_2 }); pipeline->addStep(effect); if (enable_ssaa) effect->setBilinearFilter(0, true); diff --git a/src/client/render/secondstage.h b/src/client/render/secondstage.h index 224b27e33..9e3640927 100644 --- a/src/client/render/secondstage.h +++ b/src/client/render/secondstage.h @@ -49,13 +49,6 @@ public: * @param value true to enable the bilinear filter, false to disable */ void setBilinearFilter(u8 index, bool value); - - void setWrapRepeat(u8 index, bool value); - - void setColor(video::SColor color); - - void disableDepthTest(); - private: u32 shader_id; std::vector texture_map; diff --git a/src/client/shader.cpp b/src/client/shader.cpp index 39730463f..f75d48d53 100644 --- a/src/client/shader.cpp +++ b/src/client/shader.cpp @@ -681,6 +681,9 @@ ShaderInfo ShaderSource::generateShader(const std::string &name, shaders_header << "#define ENABLE_WAVING_PLANTS " << g_settings->getBool("enable_waving_plants") << "\n"; shaders_header << "#define ENABLE_TONE_MAPPING " << g_settings->getBool("tone_mapping") << "\n"; + if (g_settings->getBool("enable_tinted_fog")) + shaders_header << "#define ENABLE_TINTED_FOG 1\n"; + if (g_settings->getBool("enable_dynamic_shadows")) { shaders_header << "#define ENABLE_DYNAMIC_SHADOWS 1\n"; if (g_settings->getBool("shadow_map_color")) @@ -738,10 +741,6 @@ ShaderInfo ShaderSource::generateShader(const std::string &name, shaders_header << "#define VOLUMETRIC_LIGHT 1\n"; } - if (g_settings->getBool("enable_volumetric_clouds")) { - shaders_header << "#define VOLUMETRICS_UNDERSAMPLING " << g_settings->getU32("volumetrics_undersampling") << '\n'; - } - shaders_header << "#line 0\n"; // reset the line counter for meaningful diagnostics std::string common_header = shaders_header.str(); diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index 5ac62534e..6625dfb03 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -339,11 +339,11 @@ void set_default_settings() settings->setDefault("bloom_intensity", "0.05"); settings->setDefault("bloom_radius", "1"); settings->setDefault("enable_volumetric_lighting", "false"); - settings->setDefault("enable_volumetric_clouds", "false"); settings->setDefault("enable_bumpmaps", "false"); settings->setDefault("enable_water_reflections", "false"); settings->setDefault("enable_translucent_foliage", "false"); settings->setDefault("enable_node_specular", "false"); + settings->setDefault("enable_tinted_fog", "false"); // Effects Shadows settings->setDefault("enable_dynamic_shadows", "false"); diff --git a/src/network/clientpackethandler.cpp b/src/network/clientpackethandler.cpp index d5c9067e9..40d11f73c 100644 --- a/src/network/clientpackethandler.cpp +++ b/src/network/clientpackethandler.cpp @@ -1817,8 +1817,8 @@ void Client::handleCommand_SetLighting(NetworkPacket *pkt) } if (pkt->getRemainingBytes() >= 4) *pkt >> lighting.volumetric_light_strength; - if (pkt->getRemainingBytes() >= 4) - *pkt >> lighting.artificial_light_color; if (pkt->getRemainingBytes() >= 4) *pkt >> lighting.shadow_tint; + if (pkt->getRemainingBytes() >= 4) + *pkt >> lighting.artificial_light_color; } diff --git a/src/server.cpp b/src/server.cpp index d624c5f5c..1a2d8cf4f 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -1861,9 +1861,7 @@ void Server::SendSetLighting(session_t peer_id, const Lighting &lighting) << lighting.exposure.speed_bright_dark << lighting.exposure.center_weight_power; - pkt << lighting.volumetric_light_strength << lighting.shadow_tint; - - pkt << lighting.artificial_light_color; + pkt << lighting.volumetric_light_strength << lighting.shadow_tint << lighting.artificial_light_color; Send(&pkt); }