diff --git a/builtin/settingtypes.txt b/builtin/settingtypes.txt index 47cbe38f1..fc65cd39b 100644 --- a/builtin/settingtypes.txt +++ b/builtin/settingtypes.txt @@ -676,20 +676,23 @@ enable_waving_water (Waving liquids) bool false # 0.0 = Wave doesn't move at all. # Default is 1.0 (1/2 node). # -# Requires: enable_waving_water water_wave_height (Waving liquids wave height) float 1.0 0.0 4.0 # Length of liquid waves. # -# Requires: enable_waving_water water_wave_length (Waving liquids wavelength) float 20.0 0.1 # How fast liquid waves will move. Higher = faster. # If negative, liquid waves will move backwards. # -# Requires: enable_waving_water water_wave_speed (Waving liquids wave speed) float 5.0 +# When enabled, crude liquid reflections are simulated. +# Wave height, length and speed will affect these reflections. +# +# Requires: enable_dynamic_shadows +enable_water_reflections (Liquid reflections) bool false + [**Dynamic shadows] # Set to true to enable Shadow Mapping. @@ -750,6 +753,11 @@ shadow_soft_radius (Soft shadow radius) float 5.0 1.0 15.0 # Requires: enable_dynamic_shadows, opengl shadow_sky_body_orbit_tilt (Sky Body Orbit Tilt) float 0.0 -60.0 60.0 +# Tint sunlight during sunrise/sunset. +# +# Requires: enable_dynamic_shadows, opengl +enable_sun_tint (Tinted sunlight) bool false + [**Post Processing] # Enables the post processing pipeline. @@ -778,6 +786,19 @@ enable_auto_exposure (Enable Automatic Exposure) bool false # Requires: enable_post_processing, enable_auto_exposure exposure_compensation (Exposure compensation) float 0.0 -1.0 1.0 +# Set the post processing gamma value. +# Higher values give lower contrast and vice versa. +# Range: from 1.0 to 5.0 +# Default: 1.6 +# +# Requires: enable_post_processing, tone_mapping +secondstage_gamma (Gamma) float 1.6 1.0 5.0 + +# Apply ASL CDL color grading to make brighter colors warmer and darker colors cooler. +# +# Requires: enable_post_processing +enable_color_grading (Color grading) bool false + # Apply dithering to reduce color banding artifacts. # Dithering significantly increases the size of losslessly-compressed # screenshots and it works incorrectly if the display or operating system @@ -798,11 +819,20 @@ enable_bloom (Enable Bloom) bool false # Set to true to enable volumetric lighting effect (a.k.a. "Godrays"). # # Requires: enable_post_processing, enable_bloom -enable_volumetric_lighting (Volumetric lighting) bool false +enable_volumetric_lighting (Volumetric Lighting) bool false + +# Make volumetrics weaker against closer objects to emulate physical volumetrics. +# +# Requires: enable_post_processing, enable_bloom, enable_volumetric_lighting +enable_volumetric_depth_attenuation (Volumetric Depth Attenuation) bool false [**Other Effects] +# Makes the color of light fog more saturated. +enable_tinted_fog (Tinted fog) bool false + # Simulate translucency when looking at foliage in the sunlight. +# It is recommended to use this with the leaves style set to fancy. # # Requires: enable_dynamic_shadows enable_translucent_foliage (Translucent foliage) bool false diff --git a/client/shaders/minimap_shader/opengl_fragment.glsl b/client/shaders/minimap_shader/opengl_fragment.glsl index 3f6b041da..70deceee9 100644 --- a/client/shaders/minimap_shader/opengl_fragment.glsl +++ b/client/shaders/minimap_shader/opengl_fragment.glsl @@ -1,6 +1,7 @@ uniform sampler2D baseTexture; uniform sampler2D normalTexture; uniform vec3 yawVec; +uniform float mapSize; varying lowp vec4 varColor; varying mediump vec2 varTexCoord; @@ -10,7 +11,7 @@ void main (void) vec2 uv = varTexCoord.st; //texture sampling rate - const float step = 1.0 / 256.0; + float step = 1.0 / mapSize; float tl = texture2D(normalTexture, vec2(uv.x - step, uv.y + step)).r; float t = texture2D(normalTexture, vec2(uv.x, uv.y + step)).r; float tr = texture2D(normalTexture, vec2(uv.x + step, uv.y + step)).r; diff --git a/client/shaders/nodes_shader/opengl_fragment.glsl b/client/shaders/nodes_shader/opengl_fragment.glsl index ed0404cea..1b9cf6df2 100644 --- a/client/shaders/nodes_shader/opengl_fragment.glsl +++ b/client/shaders/nodes_shader/opengl_fragment.glsl @@ -22,15 +22,17 @@ uniform float animationTimer; uniform float xyPerspectiveBias0; uniform float xyPerspectiveBias1; uniform vec3 shadow_tint; + uniform float foliage_translucency; + uniform float specular_intensity; varying float adj_shadow_strength; varying float cosLight; varying float f_normal_length; varying vec3 shadow_position; varying float perspective_factor; + varying vec3 sunTint; #endif - varying vec3 vNormal; varying vec3 vPosition; // World position in the visible world (i.e. relative to the cameraOffset.) @@ -49,9 +51,12 @@ centroid varying vec2 varTexCoord; centroid varying float nightRatio; #endif varying highp vec3 eyeVec; +varying float nightFactor; + +#define PI 3.141592653589 #ifdef ENABLE_DYNAMIC_SHADOWS -#if (defined(ENABLE_WATER_REFLECTIONS) && MATERIAL_WATER_REFLECTIONS && ENABLE_WAVING_WATER) +#if (MATERIAL_WAVING_LIQUID && defined(ENABLE_WATER_REFLECTIONS)) vec4 perm(vec4 x) { return mod(((x * 34.0) + 1.0) * x, 289.0); @@ -115,7 +120,7 @@ float mtsmoothstep(in float edge0, in float edge1, in float x) float shadowCutoff(float x) { #if defined(ENABLE_TRANSLUCENT_FOLIAGE) && MATERIAL_TYPE == TILE_MATERIAL_WAVING_LEAVES - return mtsmoothstep(0.0, 0.002, x); + return mtsmoothstep(0.0, 3.0 / f_shadowfar, x); #else return step(0.0, x); #endif @@ -407,7 +412,6 @@ float getShadow(sampler2D shadowsampler, vec2 smTexCoord, float realDistance) } #endif - #endif #endif @@ -436,6 +440,8 @@ void main(void) // Fragment normal, can differ from vNormal which is derived from vertex normals. vec3 fNormal = vNormal; + vec3 viewVec = normalize(worldPosition + cameraOffset - cameraPosition); + if (f_shadow_strength > 0.0) { float shadow_int = 0.0; vec3 shadow_color = vec3(0.0, 0.0, 0.0); @@ -445,6 +451,7 @@ void main(void) if (max(abs(posLightSpace.x - 0.5), abs(posLightSpace.y - 0.5)) > 0.5) distance_rate = 0.0; float f_adj_shadow_strength = max(adj_shadow_strength - mtsmoothstep(0.9, 1.1, posLightSpace.z),0.0); + float f_shadow_factor = adj_shadow_strength / f_shadow_strength; if (distance_rate > 1e-7) { @@ -477,6 +484,7 @@ void main(void) // Apply self-shadowing when light falls at a narrow angle to the surface // Cosine of the cut-off angle. const float self_shadow_cutoff_cosine = 0.035; + if (f_normal_length != 0 && cosLight < self_shadow_cutoff_cosine) { shadow_int = max(shadow_int, 1 - clamp(cosLight, 0.0, self_shadow_cutoff_cosine)/self_shadow_cutoff_cosine); shadow_color = mix(vec3(0.0), shadow_color, min(cosLight, self_shadow_cutoff_cosine)/self_shadow_cutoff_cosine); @@ -492,29 +500,27 @@ void main(void) // calculate fragment color from components: col.rgb = adjusted_night_ratio * col.rgb + // artificial light - (1.0 - adjusted_night_ratio) * ( // natural 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 dayLight * shadow_color * shadow_int); // reflected filtered sunlight/moonlight vec3 reflect_ray = -normalize(v_LightDirection - fNormal * dot(v_LightDirection, fNormal) * 2.0); - vec3 viewVec = normalize(worldPosition + cameraOffset - cameraPosition); - // Water reflections -#if (defined(ENABLE_WATER_REFLECTIONS) && MATERIAL_WATER_REFLECTIONS && ENABLE_WAVING_WATER) +#if (MATERIAL_WAVING_LIQUID && defined(ENABLE_WATER_REFLECTIONS)) 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; wavePos.z /= WATER_WAVE_LENGTH * 2.0; - // This is an analogous method to the bumpmap, except we get the gradient information directly from gnoise. + // We get the gradient information of the waves using gnoise. vec2 gradient = wave_noise(wavePos, off); fNormal = normalize(normalize(fNormal) + vec3(gradient.x, 0., gradient.y) * WATER_WAVE_HEIGHT * abs(fNormal.y) * 0.25); reflect_ray = -normalize(v_LightDirection - fNormal * dot(v_LightDirection, fNormal) * 2.0); float fresnel_factor = dot(fNormal, viewVec); - float brightness_factor = 1.0 - adjusted_night_ratio; + float brightness_factor = (1.0 - adjusted_night_ratio) / base.a; // A little trig hack. We go from the dot product of viewVec and normal to the dot product of viewVec and tangent to apply a fresnel effect. fresnel_factor = clamp(pow(1.0 - fresnel_factor * fresnel_factor, 8.0), 0.0, 1.0) * 0.8 + 0.2; @@ -522,34 +528,52 @@ void main(void) vec3 reflection_color = mix(vec3(max(fogColor.r, max(fogColor.g, fogColor.b))), fogColor.rgb, f_shadow_strength); // Sky reflection - col.rgb += reflection_color * pow(fresnel_factor, 2.0) * 0.5 * brightness_factor; - vec3 water_reflect_color = 12.0 * dayLight * fresnel_factor * mtsmoothstep(0.85, 0.9, pow(clamp(dot(reflect_ray, viewVec), 0.0, 1.0), 32.0)) * max(1.0 - shadow_uncorrected, 0.0); + col.rgb += reflection_color * pow(fresnel_factor, 2.0) * 0.3 * brightness_factor; - // This line exists to prevent ridiculously bright reflection colors. - water_reflect_color /= clamp(max(water_reflect_color.r, max(water_reflect_color.g, water_reflect_color.b)) * 0.375, 1.0, 400.0); - col.rgb += water_reflect_color * f_adj_shadow_strength * brightness_factor; + vec3 water_reflect_color = + 1.5 * specular_intensity * sunTint * dayLight * fresnel_factor * max(1.0 - shadow_uncorrected, 0.0) * + mtsmoothstep(0.85, 0.9, pow(clamp(dot(reflect_ray, viewVec), 0.0, 1.0), 32.0)); + + // Sun reflection + col.rgb += water_reflect_color * f_shadow_factor * brightness_factor; #endif #if (defined(ENABLE_NODE_SPECULAR) && !MATERIAL_WATER_REFLECTIONS) - // Apply specular to blocks. + // Apply specular to nodes. if (dot(v_LightDirection, vNormal) < 0.0) { - float intensity = 2.0 * (1.0 - (base.r * varColor.r)); - const float specular_exponent = 5.0; - const float fresnel_exponent = 4.0; + // This intensity/roughness is a placeholder and should be replaced by proper specular maps. + float intensity = 0.35 * min(1.0, length(varColor.rgb * base.rgb)); + float roughness = 0.5; + + float rms = 1.0 / (1.0 - roughness) - 1.0; + vec3 half_vector = normalize(viewVec + v_LightDirection); + const float F0 = 0.04; + + float HV = dot(viewVec, half_vector); + float HN = dot(fNormal, half_vector); + float VN = dot(viewVec, normalize(fNormal)); + float LN = dot(v_LightDirection, fNormal); + + float HN2 = HN*HN; + + float beckmann = exp((HN2 - 1.0) / (rms * rms * HN2)) / (PI * rms * rms * HN2*HN2); + float geometry = min(min(1.0, 2.0 * HN * VN / HV), 2.0 * HN * LN / HV); + float fresnel_schlick = F0 + (1.0 - F0) * pow(1.0 - HV, 5.0); col.rgb += - intensity * dayLight * (1.0 - nightRatio) * (1.0 - shadow_uncorrected) * f_adj_shadow_strength * - pow(max(dot(reflect_ray, viewVec), 0.0), fresnel_exponent) * pow(1.0 - abs(dot(viewVec, fNormal)), specular_exponent); + sunTint * specular_intensity * f_shadow_factor * dayLight * (1.0 - nightRatio) * (1.0 - shadow_uncorrected) * + intensity * beckmann * geometry * fresnel_schlick / (VN * LN * PI); } #endif #if (MATERIAL_TYPE == TILE_MATERIAL_WAVING_PLANTS || MATERIAL_TYPE == TILE_MATERIAL_WAVING_LEAVES) && defined(ENABLE_TRANSLUCENT_FOLIAGE) // Simulate translucent foliage. - col.rgb += 4.0 * dayLight * base.rgb * normalize(base.rgb * varColor.rgb * varColor.rgb) * f_adj_shadow_strength * pow(max(-dot(v_LightDirection, viewVec), 0.0), 4.0) * max(1.0 - shadow_uncorrected, 0.0); + col.rgb += + foliage_translucency * nightFactor * sunTint * dayLight * base.rgb * normalize(base.rgb * varColor.rgb * varColor.rgb) * + pow(max(-dot(v_LightDirection, viewVec), 0.0), 4.0) * max(1.0 - shadow_uncorrected, 0.0); #endif } #endif - // Due to a bug in some (older ?) graphics stacks (possibly in the glsl compiler ?), // the fog will only be rendered correctly if the last operation before the // clamp() is an addition. Else, the clamp() seems to be ignored. @@ -561,6 +585,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; @@ -568,6 +594,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/nodes_shader/opengl_vertex.glsl b/client/shaders/nodes_shader/opengl_vertex.glsl index 6fe7acd85..34fe2c5c7 100644 --- a/client/shaders/nodes_shader/opengl_vertex.glsl +++ b/client/shaders/nodes_shader/opengl_vertex.glsl @@ -45,14 +45,21 @@ centroid varying float nightRatio; #endif varying highp vec3 eyeVec; +varying vec3 sunTint; +varying float nightFactor; + // Color of the light emitted by the light sources. -const vec3 artificialLight = vec3(1.04, 1.04, 1.04); +uniform vec3 artificialLight; const float e = 2.718281828459; const float BS = 10.0; uniform float xyPerspectiveBias0; uniform float xyPerspectiveBias1; uniform float zPerspectiveBias; +#ifdef ENABLE_TINTED_SUNLIGHT + uniform vec3 scattering_coefficients; +#endif + #ifdef ENABLE_DYNAMIC_SHADOWS vec4 getRelativePosition(in vec4 position) @@ -144,8 +151,17 @@ float snoise(vec3 p) #endif +#ifdef ENABLE_TINTED_SUNLIGHT +vec3 getDirectLightScatteringAtGround(vec3 v_LightDirection) +{ + // Based on talk at 2002 Game Developers Conference by Naty Hoffman and Arcot J. Preetham + const float unit_conversion = 1e-5; // Rayleigh scattering beta - + 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(-scattering_coefficients * unit_conversion * atmosphere_height / (1e-5 - dot(v_LightDirection, vec3(0., 1., 0.)))); +} +#endif void main(void) { @@ -205,7 +221,7 @@ void main(void) // The alpha gives the ratio of sunlight in the incoming light. nightRatio = 1.0 - color.a; color.rgb = color.rgb * (color.a * dayLight.rgb + - nightRatio * artificialLight.rgb) * 2.0; + nightRatio * max(artificialLight.rgb, vec3(0.0))) * 2.0; color.a = 1.0; // Emphase blue a bit in darker places @@ -255,16 +271,24 @@ void main(void) #endif perspective_factor = pFactor; - if (f_timeofday < 0.2) { + sunTint = vec3(1.0); + nightFactor = 0.; + // The sun rises at 5:00 and sets at 19:00, which corresponds to 5/24=0.208 and 19/24 = 0.792. + if (f_timeofday < 0.208) { adj_shadow_strength = f_shadow_strength * 0.5 * - (1.0 - mtsmoothstep(0.18, 0.2, f_timeofday)); - } else if (f_timeofday >= 0.8) { + (1.0 - mtsmoothstep(0.178, 0.208, f_timeofday)); + } else if (f_timeofday >= 0.792) { adj_shadow_strength = f_shadow_strength * 0.5 * - mtsmoothstep(0.8, 0.83, f_timeofday); + mtsmoothstep(0.792, 0.822, f_timeofday); } else { adj_shadow_strength = f_shadow_strength * - mtsmoothstep(0.20, 0.25, f_timeofday) * - (1.0 - mtsmoothstep(0.7, 0.8, f_timeofday)); + mtsmoothstep(0.208, 0.238, f_timeofday) * + (1.0 - mtsmoothstep(0.762, 0.792, f_timeofday)); + nightFactor = adj_shadow_strength / f_shadow_strength; +#ifdef ENABLE_TINTED_SUNLIGHT + float tint_strength = 1.0 - mtsmoothstep(0.792, 0.5, f_timeofday) * mtsmoothstep(0.208, 0.5, f_timeofday); + sunTint = mix(vec3(1.0), getDirectLightScatteringAtGround(v_LightDirection), nightFactor * tint_strength); +#endif } } #endif diff --git a/client/shaders/object_shader/opengl_fragment.glsl b/client/shaders/object_shader/opengl_fragment.glsl index db72d7f7d..504a10964 100644 --- a/client/shaders/object_shader/opengl_fragment.glsl +++ b/client/shaders/object_shader/opengl_fragment.glsl @@ -1,5 +1,6 @@ uniform sampler2D baseTexture; +varying vec3 sunTint; uniform vec3 dayLight; uniform lowp vec4 fogColor; uniform float fogDistance; @@ -20,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; @@ -432,8 +432,8 @@ void main(void) // calculate fragment color from components: col.rgb = adjusted_night_ratio * col.rgb + // artificial light - (1.0 - adjusted_night_ratio) * ( // natural light - col.rgb * (1.0 - shadow_int * (1.0 - shadow_color) * (1.0 - shadow_tint)) + // filtered texture color + sunTint * (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 @@ -449,6 +449,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; @@ -456,6 +458,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_vertex.glsl b/client/shaders/object_shader/opengl_vertex.glsl index 4bb109f68..f6fe0e4e6 100644 --- a/client/shaders/object_shader/opengl_vertex.glsl +++ b/client/shaders/object_shader/opengl_vertex.glsl @@ -32,8 +32,9 @@ centroid varying vec2 varTexCoord; varying highp vec3 eyeVec; varying float nightRatio; +varying vec3 sunTint; // Color of the light emitted by the light sources. -const vec3 artificialLight = vec3(1.04, 1.04, 1.04); +uniform vec3 artificialLight; varying float vIDiff; const float e = 2.718281828459; const float BS = 10.0; @@ -41,6 +42,10 @@ uniform float xyPerspectiveBias0; uniform float xyPerspectiveBias1; uniform float zPerspectiveBias; +#ifdef ENABLE_TINTED_SUNLIGHT + uniform vec3 scattering_coefficients; +#endif + #ifdef ENABLE_DYNAMIC_SHADOWS vec4 getRelativePosition(in vec4 position) @@ -89,6 +94,18 @@ float directional_ambient(vec3 normal) return dot(v, vec3(0.670820, 1.000000, 0.836660)); } +#ifdef ENABLE_TINTED_SUNLIGHT + vec3 getDirectLightScatteringAtGround(vec3 v_LightDirection) + { + // Based on talk at 2002 Game Developers Conference by Naty Hoffman and Arcot J. Preetham + const float unit_conversion = 1e-5; // Rayleigh scattering beta + + 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(-scattering_coefficients * unit_conversion * atmosphere_height / (1e-5 - dot(v_LightDirection, vec3(0., 1., 0.)))); + } +#endif + void main(void) { varTexCoord = (mTexture * vec4(inTexCoord0.xy, 1.0, 1.0)).st; @@ -116,7 +133,7 @@ void main(void) // The alpha gives the ratio of sunlight in the incoming light. nightRatio = 1.0 - color.a; color.rgb = color.rgb * (color.a * dayLight.rgb + - nightRatio * artificialLight.rgb) * 2.0; + nightRatio * max(artificialLight.rgb, vec3(0.0))) * 2.0; color.a = 1.0; // Emphase blue a bit in darker places @@ -158,16 +175,24 @@ void main(void) shadow_position.z -= z_bias; perspective_factor = pFactor; - if (f_timeofday < 0.2) { + // The sun rises at 5:00 and sets at 19:00, which corresponds to 5/24=0.208 and 19/24 = 0.792. + float nightFactor = 0.; + sunTint = vec3(1.0); + if (f_timeofday < 0.208) { adj_shadow_strength = f_shadow_strength * 0.5 * - (1.0 - mtsmoothstep(0.18, 0.2, f_timeofday)); - } else if (f_timeofday >= 0.8) { + (1.0 - mtsmoothstep(0.178, 0.208, f_timeofday)); + } else if (f_timeofday >= 0.792) { adj_shadow_strength = f_shadow_strength * 0.5 * - mtsmoothstep(0.8, 0.83, f_timeofday); + mtsmoothstep(0.792, 0.822, f_timeofday); } else { adj_shadow_strength = f_shadow_strength * - mtsmoothstep(0.20, 0.25, f_timeofday) * - (1.0 - mtsmoothstep(0.7, 0.8, f_timeofday)); + mtsmoothstep(0.208, 0.238, f_timeofday) * + (1.0 - mtsmoothstep(0.762, 0.792, f_timeofday)); + nightFactor = adj_shadow_strength / f_shadow_strength; +#ifdef ENABLE_TINTED_SUNLIGHT + float tint_strength = 1.0 - mtsmoothstep(0.792, 0.5, f_timeofday) * mtsmoothstep(0.208, 0.5, f_timeofday); + sunTint = mix(vec3(1.0), getDirectLightScatteringAtGround(v_LightDirection), nightFactor * tint_strength); +#endif } } #endif diff --git a/client/shaders/second_stage/opengl_fragment.glsl b/client/shaders/second_stage/opengl_fragment.glsl index 6053884bc..f98287655 100644 --- a/client/shaders/second_stage/opengl_fragment.glsl +++ b/client/shaders/second_stage/opengl_fragment.glsl @@ -12,6 +12,14 @@ struct ExposureParams { float compensationFactor; }; +uniform vec3 cdl_slope; +uniform vec3 cdl_offset; +uniform vec3 cdl_power; + +uniform float vignette_dark; +uniform float vignette_bright; +uniform float vignette_power; + uniform sampler2D rendered; uniform sampler2D bloom; @@ -20,6 +28,7 @@ uniform vec2 texelSize0; uniform ExposureParams exposureParams; uniform lowp float bloomIntensity; uniform lowp float saturation; +uniform float gamma; #ifdef GL_ES varying mediump vec2 varTexCoord; @@ -70,7 +79,6 @@ highp vec3 uncharted2Tonemap(highp vec3 x) vec4 applyToneMapping(vec4 color) { color = vec4(pow(color.rgb, vec3(2.2)), color.a); - const float gamma = 1.6; const float exposureBias = 5.5; color.rgb = uncharted2Tonemap(exposureBias * color.rgb); // Precalculated white_scale from @@ -132,8 +140,6 @@ void main(void) #ifdef ENABLE_BLOOM color = applyBloom(color, uv); #endif - - color.rgb = clamp(color.rgb, vec3(0.), vec3(1.)); // return to sRGB colorspace (approximate) @@ -143,10 +149,17 @@ void main(void) if (uv.x > 0.5 || uv.y > 0.5) #endif { + + color.rgb *= (vignette_bright - vignette_dark) * (1.0 - pow(length(uv - vec2(0.5)) * 1.4, vignette_power)) + vignette_dark; + #if ENABLE_TONE_MAPPING color = applyToneMapping(color); #endif +#ifdef ENABLE_COLOR_GRADING + // ASC CDL color grading + color.rgb = mix(color.rgb, pow(max(color.rgb * cdl_slope + cdl_offset, 0.0), cdl_power), 1.); +#endif color.rgb = applySaturation(color.rgb, saturation); } diff --git a/client/shaders/volumetric_light/opengl_fragment.glsl b/client/shaders/volumetric_light/opengl_fragment.glsl index 001f59465..cc7045d22 100644 --- a/client/shaders/volumetric_light/opengl_fragment.glsl +++ b/client/shaders/volumetric_light/opengl_fragment.glsl @@ -24,6 +24,8 @@ varying mediump vec2 varTexCoord; centroid varying vec2 varTexCoord; #endif +uniform vec3 scattering_coefficients; + const float far = 1000.; float mapDepth(float depth) { @@ -46,23 +48,26 @@ float sampleVolumetricLight(vec2 uv, vec3 lightVec, float rawDepth) if (min(samplepos.x, samplepos.y) > 0. && max(samplepos.x, samplepos.y) < 1.) result += texture2D(depthmap, samplepos).r < 1. ? 0.0 : 1.0; } + +#ifdef VOLUMETRIC_DEPTH_ATTENUATION // We use the depth map to approximate the effect of depth on the light intensity. // The exponent was chosen based on aesthetic preference. + // To make this phsyically accurate, the brightness here should scale linearly with depth, + // but this would make the godrays either too faint or too strong in many cases. return result / samples * pow(texture2D(depthmap, uv).r, 128.0); +#else + return result / samples; +#endif } 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 unit_conversion = 1e-5; // Rayleigh scattering beta 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.)))); + return exp(-scattering_coefficients * unit_conversion * atmosphere_height / (1e-5 - dot(v_LightDirection, vec3(0., 1., 0.)))); } vec3 applyVolumetricLight(vec3 color, vec2 uv, float rawDepth) diff --git a/doc/lua_api.md b/doc/lua_api.md index 438769085..d06609ba3 100644 --- a/doc/lua_api.md +++ b/doc/lua_api.md @@ -9025,6 +9025,12 @@ child will follow movement and rotation of that bone. but keeping original luma and being symmetrical in terms of saturation (eg. -1 and 1 is the same saturation and luma, but different hues) * This value has no effect on clients who have shaders or post-processing disabled. + * `foliage_translucency` controls the intensity of the foliage translucency effect (default: `1.5`). + * Subject to change and can be removed at any time. + * This has no effect when dynamic shadows are disabled and on clients who have the "Translucent foliage" effect disabled. + * `specular_intensity` controls the intensity of specular highlights on nodes and liquids (default: `0.0`). + * Subject to change and can be removed at any time. + * This has no effect when dynamic shadows are disabled. * `shadows` is a table that controls ambient shadows * This has no effect on clients who have the "Dynamic Shadows" effect disabled. * `intensity` sets the intensity of the shadows from 0 (no shadows, default) to 1 (blackness) @@ -9061,6 +9067,24 @@ child will follow movement and rotation of that bone. * Currently, bloom `intensity` and `strength_factor` affect volumetric lighting `strength` and vice versa. This behavior is to be changed in the future, do not rely on it. + * `scattering_coefficients`: the scattering coefficients that control the tint of sunlight during sunrise and sunset. + * Defaults to { x = 3.3362176e-01, y = 8.75378289198826e-01, z = 1.95342379700656} which is physically accurate. + * This may be used to create effects like differently colored sunsets on alien planets. + * Setting all components to zero effectively disables tinted sunlight. + * `vignette`: is a table that controls the vignette post-processing effect. + * This has no effect on clients who have post processing disabled. + * `dark`: brightness of the vignette's darkest part (default: `1.0`) + * `bright`: brightness of the vignette's brightest part (default: `1.0`) + * `power`: the higher this is set, the more the vignette "retreats" to the edges of the screen (default: `1.0`) + * `cdl`: is a table that controls the ASL CDL color grading effect. + * This has no effect on clients who have the "Color grading" effect disabled. + * The output color follows the equation: `out = pow(in*slope+offset, power)` + * `slope`: "Tints" the scene, affects brighter colors more (default: `{x=1.2, y=1.0, z=0.8}`) + * `offset`: This can be used to brighten or darken the scene (default: `{x=0.0, y=0.0, z=0.0}`) + * `power`: Tints mostly the darker parts of the scene (default: `{x=1.25, y=1.0, z=0.9}`) + * `artificial_light`: is a table that controls the color of artificial light (torches etc.). + * Values should be positive and vaguely around `1.0`, but can be higher or lower. + * Default: `{r=1.04, g=1.04, b=1.04}` * `get_lighting()`: returns the current state of lighting for the player. * Result is a table with the same fields as `light_definition` in `set_lighting`. diff --git a/src/client/game.cpp b/src/client/game.cpp index ebfc3f1c8..c68a00b7a 100644 --- a/src/client/game.cpp +++ b/src/client/game.cpp @@ -199,12 +199,14 @@ class GameGlobalShaderUniformSetter : public IShaderUniformSetter m_animation_timer_delta_vertex{"animationTimerDelta"}; CachedPixelShaderSetting m_animation_timer_delta_pixel{"animationTimerDelta"}; + CachedPixelShaderSetting m_artificial_light{ "artificialLight" }; CachedPixelShaderSetting m_day_light{"dayLight"}; CachedPixelShaderSetting m_minimap_yaw{"yawVec"}; - CachedPixelShaderSetting m_camera_offset_pixel{"cameraOffset"}; + CachedPixelShaderSetting m_minimap_size{"mapSize"}; CachedVertexShaderSetting m_camera_offset_vertex{"cameraOffset"}; - CachedPixelShaderSetting m_camera_position_pixel{ "cameraPosition" }; - CachedVertexShaderSetting m_camera_position_vertex{ "cameraPosition" }; + CachedPixelShaderSetting m_camera_offset_pixel{ "cameraOffset" }; + CachedVertexShaderSetting m_camera_position_vertex{"cameraPosition"}; + CachedPixelShaderSetting m_camera_position_pixel{"cameraPosition"}; CachedVertexShaderSetting m_texel_size0_vertex{"texelSize0"}; CachedPixelShaderSetting m_texel_size0_pixel{"texelSize0"}; v2f m_texel_size0; @@ -221,6 +223,8 @@ class GameGlobalShaderUniformSetter : public IShaderUniformSetter CachedPixelShaderSetting m_bloom_strength_pixel{"bloomStrength"}; CachedPixelShaderSetting m_bloom_radius_pixel{"bloomRadius"}; CachedPixelShaderSetting m_saturation_pixel{"saturation"}; + float m_gamma; + CachedPixelShaderSetting m_gamma_pixel{"gamma"}; bool m_volumetric_light_enabled; CachedPixelShaderSetting m_sun_position_pixel{"sunPositionScreen"}; @@ -230,6 +234,18 @@ class GameGlobalShaderUniformSetter : public IShaderUniformSetter CachedPixelShaderSetting m_moon_brightness_pixel{"moonBrightness"}; CachedPixelShaderSetting m_volumetric_light_strength_pixel{"volumetricLightStrength"}; + CachedPixelShaderSetting + m_atmospheric_scattering_coefficients_pixel{ "scattering_coefficients" }; + CachedVertexShaderSetting + m_atmospheric_scattering_coefficients_vertex{ "scattering_coefficients" }; + CachedPixelShaderSetting m_cdl_slope_pixel{"cdl_slope"}; + CachedPixelShaderSetting m_cdl_offset_pixel{"cdl_offset"}; + CachedPixelShaderSetting m_cdl_power_pixel{"cdl_power"}; + CachedPixelShaderSetting m_vignette_dark_pixel{"vignette_dark"}; + CachedPixelShaderSetting m_vignette_bright_pixel{"vignette_bright"}; + CachedPixelShaderSetting m_vignette_power_pixel{"vignette_power"}; + CachedPixelShaderSetting m_foliage_translucency_pixel{ "foliage_translucency" }; + CachedPixelShaderSetting m_specular_intensity_pixel{ "specular_intensity" }; static constexpr std::array SETTING_CALLBACKS = { "exposure_compensation", @@ -259,6 +275,7 @@ public: m_user_exposure_compensation = g_settings->getFloat("exposure_compensation", -1.0f, 1.0f); m_bloom_enabled = g_settings->getBool("enable_bloom"); m_volumetric_light_enabled = g_settings->getBool("enable_volumetric_lighting") && m_bloom_enabled; + m_gamma = g_settings->getFloat("secondstage_gamma"); } ~GameGlobalShaderUniformSetter() @@ -285,14 +302,16 @@ public: if (m_client->getMinimap()) { v3f minimap_yaw = m_client->getMinimap()->getYawVec(); m_minimap_yaw.set(minimap_yaw, services); + float minimap_size = m_client->getMinimap()->getModeDef().map_size; + m_minimap_size.set(&minimap_size, services); } v3f offset = intToFloat(m_client->getCamera()->getOffset(), BS); - m_camera_offset_pixel.set(offset, services); m_camera_offset_vertex.set(offset, services); + m_camera_offset_pixel.set(offset, services); v3f camera_position = m_client->getCamera()->getPosition(); - m_camera_position_pixel.set(camera_position, services); + m_camera_position_vertex.set(camera_position, services); m_camera_position_pixel.set(camera_position, services); m_texel_size0_vertex.set(m_texel_size0, services); @@ -323,6 +342,24 @@ public: float saturation = lighting.saturation; m_saturation_pixel.set(&saturation, services); + video::SColorf artificial_light = lighting.artificial_light_color; + m_artificial_light.set(artificial_light, services); + + float gamma = m_gamma; + m_gamma_pixel.set(&gamma, services); + + const Vignette &vignette_params = lighting.vignette; + m_vignette_dark_pixel.set(&vignette_params.dark, services); + m_vignette_bright_pixel.set(&vignette_params.bright, services); + m_vignette_power_pixel.set(&vignette_params.power, services); + + m_foliage_translucency_pixel.set(&lighting.foliage_translucency, services); + m_specular_intensity_pixel.set(&lighting.specular_intensity, services); + + const ColorDecisionList& cdl_params = lighting.cdl; + m_cdl_slope_pixel.set(cdl_params.slope, services); + m_cdl_offset_pixel.set(cdl_params.offset, services); + m_cdl_power_pixel.set(cdl_params.power, services); if (m_volumetric_light_enabled) { // Map directional light to screen space @@ -367,6 +404,10 @@ public: float volumetric_light_strength = lighting.volumetric_light_strength; m_volumetric_light_strength_pixel.set(&volumetric_light_strength, services); } + + v3f scattering_coefficients = lighting.scattering_coefficients; + m_atmospheric_scattering_coefficients_vertex.set(scattering_coefficients, services); + m_atmospheric_scattering_coefficients_pixel.set(scattering_coefficients, services); } void onSetMaterial(const video::SMaterial &material) override @@ -461,8 +502,9 @@ public: #undef PROVIDE bool enable_waving_water = g_settings->getBool("enable_waving_water"); + bool enable_water_reflections = g_settings->getBool("enable_water_reflections"); constants["ENABLE_WAVING_WATER"] = enable_waving_water ? 1 : 0; - if (enable_waving_water) { + if (enable_waving_water || enable_water_reflections) { constants["WATER_WAVE_HEIGHT"] = g_settings->getFloat("water_wave_height"); constants["WATER_WAVE_LENGTH"] = g_settings->getFloat("water_wave_length"); constants["WATER_WAVE_SPEED"] = g_settings->getFloat("water_wave_speed"); diff --git a/src/client/minimap.cpp b/src/client/minimap.cpp index ae6244b93..c2bda1b0f 100644 --- a/src/client/minimap.cpp +++ b/src/client/minimap.cpp @@ -589,8 +589,8 @@ void Minimap::drawMinimap(core::rect rect) video::SMaterial &material = m_meshbuffer->getMaterial(); material.forEachTexture([] (auto &tex) { - tex.MinFilter = video::ETMINF_LINEAR_MIPMAP_LINEAR; - tex.MagFilter = video::ETMAGF_LINEAR; + tex.MinFilter = video::ETMINF_NEAREST_MIPMAP_NEAREST; + tex.MagFilter = video::ETMAGF_NEAREST; }); material.TextureLayers[0].Texture = minimap_texture; material.TextureLayers[1].Texture = data->heightmap_texture; diff --git a/src/client/shader.cpp b/src/client/shader.cpp index 3238969ff..3116ed236 100644 --- a/src/client/shader.cpp +++ b/src/client/shader.cpp @@ -225,6 +225,9 @@ public: float shadow_soft_radius = std::max(1.f, g_settings->getFloat("shadow_soft_radius")); constants["SOFTSHADOWRADIUS"] = shadow_soft_radius; + + if (g_settings->getBool("enable_sun_tint")) + constants["ENABLE_TINTED_SUNLIGHT"] = 1; } if (g_settings->getBool("enable_bloom")) { @@ -731,6 +734,10 @@ ShaderInfo ShaderSource::generateShader(const std::string &name, shaders_header << '\n'; } + if (g_settings->getBool("enable_volumetric_depth_attenuation")) { + shaders_header << "#define VOLUMETRIC_DEPTH_ATTENUATION 1\n"; + } + std::string common_header = shaders_header.str(); const char *final_header = "#line 0\n"; // reset the line counter for meaningful diagnostics diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index 916ce9e51..143d1eafe 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -333,13 +333,16 @@ void set_default_settings() settings->setDefault("enable_waving_plants", "false"); settings->setDefault("exposure_compensation", "0.0"); settings->setDefault("enable_auto_exposure", "false"); + settings->setDefault("secondstage_gamma", "1.6"); settings->setDefault("debanding", "true"); settings->setDefault("antialiasing", "none"); settings->setDefault("enable_bloom", "false"); settings->setDefault("enable_bloom_debug", "false"); settings->setDefault("enable_volumetric_lighting", "false"); + settings->setDefault("enable_volumetric_depth_attenuation", "false"); settings->setDefault("enable_water_reflections", "false"); settings->setDefault("enable_translucent_foliage", "false"); + settings->setDefault("enable_tinted_fog", "false"); // Effects Shadows settings->setDefault("enable_dynamic_shadows", "false"); @@ -353,6 +356,7 @@ void set_default_settings() settings->setDefault("shadow_update_frames", "16"); settings->setDefault("shadow_soft_radius", "5.0"); settings->setDefault("shadow_sky_body_orbit_tilt", "0.0"); + settings->setDefault("enable_sun_tint", "false"); // Input settings->setDefault("invert_mouse", "false"); diff --git a/src/lighting.h b/src/lighting.h index 4ba1b37ef..8ec935b26 100644 --- a/src/lighting.h +++ b/src/lighting.h @@ -4,8 +4,7 @@ #pragma once #include "SColor.h" - -using namespace irr; +#include "irr_v3d.h" /** * Parameters for automatic exposure compensation @@ -40,14 +39,49 @@ struct AutoExposure {} }; +/** + * Parameters for vignette in post-processing + * + */ +struct Vignette { + /// @brief The darkest part of the vignette will be darkened/brightened by this factor. + float dark = 1.0f; + /// @brief The brightest part of the vignette will be darkened/brightened by this factor. + float bright = 1.0f; + /// @brief Describes the blending between dark and bright. Higher values mean darkening is more intense at the screen edges. + float power = 1.0f; +}; + +/** + * ASL CDL parameters + * + * Colors in ASL CDL follow the following equation: + * + * out = pow(in * slope + offset, power) + * + */ +struct ColorDecisionList { + v3f slope{1.0, 1.0, 1.0}; + v3f offset{0.0, 0.0, 0.0}; + v3f power{1.0, 1.0, 1.0}; +}; + /** Describes ambient light settings for a player */ struct Lighting { AutoExposure exposure; + Vignette vignette; + ColorDecisionList cdl; float shadow_intensity {0.0f}; float saturation {1.0f}; float volumetric_light_strength {0.0f}; + float foliage_translucency{1.5f}; + float specular_intensity{0.0f}; + // These factors are calculated based on expected value of scattering factor of 1e-5 + // for Nitrogen at 532nm (green), 2e25 molecules/m3 in atmosphere + v3f scattering_coefficients{ 3.3362176e-01f, 8.753783e-01f, 1.9534237f }; + video::SColorf artificial_light_color{ 1.0f, 1.04f, 1.04f, 1.04f }; video::SColor shadow_tint {255, 0, 0, 0}; float bloom_intensity {0.05f}; float bloom_strength_factor {1.0f}; diff --git a/src/log.h b/src/log.h index 0e34b2c83..599c253e4 100644 --- a/src/log.h +++ b/src/log.h @@ -62,7 +62,7 @@ private: // These calls explicitly use the templated version of operator<<, // so that they won't use the overloads created by ADD_NULL_CHECK. if (arg == nullptr) - return this->operator<< ("(null)"); + return this->operator<< ((const char*) ("(null)")); else return this->operator<< (std::forward(arg)); } diff --git a/src/network/clientpackethandler.cpp b/src/network/clientpackethandler.cpp index 6cd7150c6..aed760981 100644 --- a/src/network/clientpackethandler.cpp +++ b/src/network/clientpackethandler.cpp @@ -1795,4 +1795,18 @@ void Client::handleCommand_SetLighting(NetworkPacket *pkt) >> lighting.bloom_strength_factor >> lighting.bloom_radius; } + if (pkt->getRemainingBytes() >= 72) { + *pkt >> lighting.artificial_light_color.r + >> lighting.artificial_light_color.g + >> lighting.artificial_light_color.b; + *pkt >> lighting.scattering_coefficients; + *pkt >> lighting.vignette.dark + >> lighting.vignette.bright + >> lighting.vignette.power; + *pkt >> lighting.cdl.slope; + *pkt >> lighting.cdl.offset; + *pkt >> lighting.cdl.power; + *pkt >> lighting.foliage_translucency; + *pkt >> lighting.specular_intensity; + } } diff --git a/src/network/networkprotocol.cpp b/src/network/networkprotocol.cpp index a88b5b091..020b939f3 100644 --- a/src/network/networkprotocol.cpp +++ b/src/network/networkprotocol.cpp @@ -63,7 +63,8 @@ Add particle blend mode "clip" [scheduled bump for 5.11.0] PROTOCOL VERSION 48 - Add compression to some existing packets + Add compression to some existing packets, artificial light color, scattering_coefficients, + vignette, specular intensity, foliage translucency and cdl parameters to Lighting packets [scheduled bump for 5.12.0] */ diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp index eed2215ac..22b80ec26 100644 --- a/src/script/lua_api/l_object.cpp +++ b/src/script/lua_api/l_object.cpp @@ -2660,6 +2660,15 @@ int ObjectRef::l_set_lighting(lua_State *L) if (!lua_isnoneornil(L, 2)) { luaL_checktype(L, 2, LUA_TTABLE); lighting = player->getLighting(); + + lua_getfield(L, 2, "artificial_light"); + if (lua_istable(L, -1)) { + getfloatfield(L, -1, "r", lighting.artificial_light_color.r); + getfloatfield(L, -1, "g", lighting.artificial_light_color.g); + getfloatfield(L, -1, "b", lighting.artificial_light_color.b); + } + lua_pop(L, 1); // artificial_light + lua_getfield(L, 2, "shadows"); if (lua_istable(L, -1)) { getfloatfield(L, -1, "intensity", lighting.shadow_intensity); @@ -2670,6 +2679,8 @@ int ObjectRef::l_set_lighting(lua_State *L) lua_pop(L, 1); // shadows getfloatfield(L, -1, "saturation", lighting.saturation); + getfloatfield(L, -1, "foliage_translucency", lighting.foliage_translucency); + getfloatfield(L, -1, "specular_intensity", lighting.specular_intensity); lua_getfield(L, 2, "exposure"); if (lua_istable(L, -1)) { @@ -2686,6 +2697,12 @@ int ObjectRef::l_set_lighting(lua_State *L) if (lua_istable(L, -1)) { getfloatfield(L, -1, "strength", lighting.volumetric_light_strength); lighting.volumetric_light_strength = rangelim(lighting.volumetric_light_strength, 0.0f, 1.0f); + + lua_getfield(L, -1, "scattering_coefficients"); + if (!lua_isnil(L, -1)) { + lighting.scattering_coefficients = read_v3f(L, -1); + } + lua_pop(L, 1); // scattering_coefficients } lua_pop(L, 1); // volumetric_light @@ -2696,6 +2713,31 @@ int ObjectRef::l_set_lighting(lua_State *L) lighting.bloom_radius = getfloatfield_default(L, -1, "radius", lighting.bloom_radius); } lua_pop(L, 1); // bloom + + lua_getfield(L, 2, "vignette"); + if (lua_istable(L, -1)) { + getfloatfield(L, -1, "dark", lighting.vignette.dark); + getfloatfield(L, -1, "bright", lighting.vignette.bright); + getfloatfield(L, -1, "power", lighting.vignette.power); + } + lua_pop(L, 1); // vignette + + lua_getfield(L, 2, "cdl"); + if (lua_istable(L, -1)) { + lua_getfield(L, -1, "slope"); + if (!lua_isnil(L, -1)) + lighting.cdl.slope = read_v3f(L, -1); + lua_pop(L, 1); // slope + lua_getfield(L, -1, "offset"); + if (!lua_isnil(L, -1)) + lighting.cdl.offset = read_v3f(L, -1); + lua_pop(L, 1); // offset + lua_getfield(L, -1, "power"); + if (!lua_isnil(L, -1)) + lighting.cdl.power = read_v3f(L, -1); + lua_pop(L, 1); // power + } + lua_pop(L, 1); // cdl } getServer(L)->setLighting(player, lighting); @@ -2714,6 +2756,18 @@ int ObjectRef::l_get_lighting(lua_State *L) const Lighting &lighting = player->getLighting(); lua_newtable(L); // result + lua_newtable(L); // artificial_light + lua_pushnumber(L, lighting.artificial_light_color.r); + lua_setfield(L, -2, "r"); + lua_pushnumber(L, lighting.artificial_light_color.g); + lua_setfield(L, -2, "g"); + lua_pushnumber(L, lighting.artificial_light_color.b); + lua_setfield(L, -2, "b"); + lua_setfield(L, -2, "artificial_light"); + lua_pushnumber(L, lighting.foliage_translucency); + lua_setfield(L, -2, "foliage_translucency"); + lua_pushnumber(L, lighting.specular_intensity); + lua_setfield(L, -2, "specular_intensity"); lua_newtable(L); // "shadows" lua_pushnumber(L, lighting.shadow_intensity); lua_setfield(L, -2, "intensity"); @@ -2739,6 +2793,8 @@ int ObjectRef::l_get_lighting(lua_State *L) lua_newtable(L); // "volumetric_light" lua_pushnumber(L, lighting.volumetric_light_strength); lua_setfield(L, -2, "strength"); + push_v3f(L, lighting.scattering_coefficients); + lua_setfield(L, -2, "scattering_coefficients"); lua_setfield(L, -2, "volumetric_light"); lua_newtable(L); // "bloom" lua_pushnumber(L, lighting.bloom_intensity); @@ -2748,6 +2804,22 @@ int ObjectRef::l_get_lighting(lua_State *L) lua_pushnumber(L, lighting.bloom_radius); lua_setfield(L, -2, "radius"); lua_setfield(L, -2, "bloom"); + lua_newtable(L); // "vignette" + lua_pushnumber(L, lighting.vignette.dark); + lua_setfield(L, -2, "dark"); + lua_pushnumber(L, lighting.vignette.bright); + lua_setfield(L, -2, "bright"); + lua_pushnumber(L, lighting.vignette.power); + lua_setfield(L, -2, "power"); + lua_setfield(L, -2, "vignette"); + lua_newtable(L); // "cdl" + push_v3f(L, lighting.cdl.slope); + lua_setfield(L, -2, "slope"); + push_v3f(L, lighting.cdl.offset); + lua_setfield(L, -2, "offset"); + push_v3f(L, lighting.cdl.power); + lua_setfield(L, -2, "power"); + lua_setfield(L, -2, "cdl"); return 1; } diff --git a/src/server.cpp b/src/server.cpp index 16434f447..3c0b65109 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -1951,6 +1951,18 @@ void Server::SendSetLighting(session_t peer_id, const Lighting &lighting) pkt << lighting.volumetric_light_strength << lighting.shadow_tint; pkt << lighting.bloom_intensity << lighting.bloom_strength_factor << lighting.bloom_radius; + pkt << lighting.artificial_light_color.r + << lighting.artificial_light_color.g + << lighting.artificial_light_color.b; + pkt << lighting.scattering_coefficients; + pkt << lighting.vignette.dark + << lighting.vignette.bright + << lighting.vignette.power; + pkt << lighting.cdl.slope; + pkt << lighting.cdl.offset; + pkt << lighting.cdl.power; + pkt << lighting.foliage_translucency; + pkt << lighting.specular_intensity; Send(&pkt); }