mirror of
https://github.com/minetest/minetest.git
synced 2024-12-22 06:02:23 +01:00
Visual Effects Vol. 1 (#14610)
This PR adds a variety of effects to enhance the visual experience. "soft" clouds look Tinted shadows Crude water reflections (sky and sun) and waves Translucent foliage Node specular highlights Adjusted fog color (more saturated where the fog is lighter) Minor changes to volumetric lighting (crudely simulates the effect of depth) Co-authored-by: sfan5 <sfan5@live.de>
This commit is contained in:
parent
4ac86db8e3
commit
d8f1daac25
@ -403,6 +403,11 @@ enable_clouds (Clouds) bool true
|
||||
# Requires: enable_clouds
|
||||
enable_3d_clouds (3D clouds) bool true
|
||||
|
||||
# Use smooth cloud shading.
|
||||
#
|
||||
# Requires: enable_3d_clouds, enable_clouds
|
||||
soft_clouds (Soft clouds) bool false
|
||||
|
||||
[**Filtering and Antialiasing]
|
||||
|
||||
# Use mipmaps when scaling textures. May slightly increase performance,
|
||||
@ -505,6 +510,11 @@ 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.
|
||||
#
|
||||
# Requires: shaders, enable_waving_water, enable_dynamic_shadows
|
||||
enable_water_reflections (Liquid reflections) bool false
|
||||
|
||||
[**Dynamic shadows]
|
||||
|
||||
# Set to true to enable Shadow Mapping.
|
||||
@ -661,6 +671,18 @@ bloom_radius (Bloom Radius) float 1 0.1 8
|
||||
# Requires: shaders, enable_post_processing, enable_bloom
|
||||
enable_volumetric_lighting (Volumetric lighting) bool false
|
||||
|
||||
[**Other Effects]
|
||||
|
||||
# Simulate translucency when looking at foliage in the sunlight.
|
||||
#
|
||||
# Requires: shaders, enable_dynamic_shadows
|
||||
enable_translucent_foliage (Translucent foliage) bool false
|
||||
|
||||
# Apply specular shading to nodes.
|
||||
#
|
||||
# Requires: shaders, enable_dynamic_shadows
|
||||
enable_node_specular (Node specular) bool false
|
||||
|
||||
[*Audio]
|
||||
|
||||
# Volume of all sounds.
|
||||
|
@ -1,3 +1,7 @@
|
||||
#if (MATERIAL_TYPE == TILE_MATERIAL_WAVING_LIQUID_TRANSPARENT || MATERIAL_TYPE == TILE_MATERIAL_WAVING_LIQUID_OPAQUE || MATERIAL_TYPE == TILE_MATERIAL_WAVING_LIQUID_BASIC || MATERIAL_TYPE == TILE_MATERIAL_LIQUID_TRANSPARENT)
|
||||
#define MATERIAL_WAVING_LIQUID 1
|
||||
#endif
|
||||
|
||||
uniform sampler2D baseTexture;
|
||||
|
||||
uniform vec3 dayLight;
|
||||
@ -7,6 +11,7 @@ uniform float fogShadingParameter;
|
||||
|
||||
// The cameraOffset is the current center of the visible world.
|
||||
uniform highp vec3 cameraOffset;
|
||||
uniform vec3 cameraPosition;
|
||||
uniform float animationTimer;
|
||||
#ifdef ENABLE_DYNAMIC_SHADOWS
|
||||
// shadow texture
|
||||
@ -20,6 +25,7 @@ uniform float animationTimer;
|
||||
uniform vec4 CameraPos;
|
||||
uniform float xyPerspectiveBias0;
|
||||
uniform float xyPerspectiveBias1;
|
||||
uniform vec3 shadow_tint;
|
||||
|
||||
varying float adj_shadow_strength;
|
||||
varying float cosLight;
|
||||
@ -47,6 +53,49 @@ varying highp vec3 eyeVec;
|
||||
varying float nightRatio;
|
||||
|
||||
#ifdef ENABLE_DYNAMIC_SHADOWS
|
||||
#if (defined(MATERIAL_WAVING_LIQUID) && defined(ENABLE_WATER_REFLECTIONS) && ENABLE_WAVING_WATER)
|
||||
vec4 perm(vec4 x)
|
||||
{
|
||||
return mod(((x * 34.0) + 1.0) * x, 289.0);
|
||||
}
|
||||
|
||||
// Corresponding gradient of snoise
|
||||
vec3 gnoise(vec3 p){
|
||||
vec3 a = floor(p);
|
||||
vec3 d = p - a;
|
||||
vec3 dd = 6.0 * d * (1.0 - d);
|
||||
d = d * d * (3.0 - 2.0 * d);
|
||||
|
||||
vec4 b = a.xxyy + vec4(0.0, 1.0, 0.0, 1.0);
|
||||
vec4 k1 = perm(b.xyxy);
|
||||
vec4 k2 = perm(k1.xyxy + b.zzww);
|
||||
|
||||
vec4 c = k2 + a.zzzz;
|
||||
vec4 k3 = perm(c);
|
||||
vec4 k4 = perm(c + 1.0);
|
||||
|
||||
vec4 o1 = fract(k3 * (1.0 / 41.0));
|
||||
vec4 o2 = fract(k4 * (1.0 / 41.0));
|
||||
|
||||
vec4 o3 = o2 * d.z + o1 * (1.0 - d.z);
|
||||
vec2 o4 = o3.yw * d.x + o3.xz * (1.0 - d.x);
|
||||
|
||||
vec4 dz1 = (o2 - o1) * dd.z;
|
||||
vec2 dz2 = dz1.yw * d.x + dz1.xz * (1.0 - d.x);
|
||||
|
||||
vec2 dx = (o3.yw - o3.xz) * dd.x;
|
||||
|
||||
return vec3(
|
||||
dx.y * d.y + dx.x * (1. - d.y),
|
||||
(o4.y - o4.x) * dd.y,
|
||||
dz2.y * d.y + dz2.x * (1. - d.y)
|
||||
);
|
||||
}
|
||||
|
||||
vec2 wave_noise(vec3 p, float off) {
|
||||
return (gnoise(p + vec3(0.0, 0.0, off)) * 0.4 + gnoise(2.0 * p + vec3(0.0, off, off)) * 0.2 + gnoise(3.0 * p + vec3(0.0, off, off)) * 0.225 + gnoise(4.0 * p + vec3(-off, off, 0.0)) * 0.2).xz;
|
||||
}
|
||||
#endif
|
||||
|
||||
// assuming near is always 1.0
|
||||
float getLinearDepth()
|
||||
@ -66,6 +115,14 @@ float mtsmoothstep(in float edge0, in float edge1, in float x)
|
||||
return t * t * (3.0 - 2.0 * t);
|
||||
}
|
||||
|
||||
float shadowCutoff(float x) {
|
||||
#if defined(ENABLE_TRANSLUCENT_FOLIAGE) && MATERIAL_TYPE == TILE_MATERIAL_WAVING_LEAVES
|
||||
return mtsmoothstep(0.0, 0.002, x);
|
||||
#else
|
||||
return step(0.0, x);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef COLORED_SHADOWS
|
||||
|
||||
// c_precision of 128 fits within 7 base-10 digits
|
||||
@ -92,10 +149,10 @@ vec4 getHardShadowColor(sampler2D shadowsampler, vec2 smTexCoord, float realDist
|
||||
{
|
||||
vec4 texDepth = texture2D(shadowsampler, smTexCoord.xy).rgba;
|
||||
|
||||
float visibility = step(0.0, realDistance - texDepth.r);
|
||||
float visibility = shadowCutoff(realDistance - texDepth.r);
|
||||
vec4 result = vec4(visibility, vec3(0.0,0.0,0.0));//unpackColor(texDepth.g));
|
||||
if (visibility < 0.1) {
|
||||
visibility = step(0.0, realDistance - texDepth.b);
|
||||
visibility = shadowCutoff(realDistance - texDepth.b);
|
||||
result = vec4(visibility, unpackColor(texDepth.a));
|
||||
}
|
||||
return result;
|
||||
@ -106,7 +163,7 @@ vec4 getHardShadowColor(sampler2D shadowsampler, vec2 smTexCoord, float realDist
|
||||
float getHardShadow(sampler2D shadowsampler, vec2 smTexCoord, float realDistance)
|
||||
{
|
||||
float texDepth = texture2D(shadowsampler, smTexCoord.xy).r;
|
||||
float visibility = step(0.0, realDistance - texDepth);
|
||||
float visibility = shadowCutoff(realDistance - texDepth);
|
||||
return visibility;
|
||||
}
|
||||
|
||||
@ -378,6 +435,9 @@ void main(void)
|
||||
vec4 col = vec4(color.rgb * varColor.rgb, 1.0);
|
||||
|
||||
#ifdef ENABLE_DYNAMIC_SHADOWS
|
||||
// Fragment normal, can differ from vNormal which is derived from vertex normals.
|
||||
vec3 fNormal = vNormal;
|
||||
|
||||
if (f_shadow_strength > 0.0) {
|
||||
float shadow_int = 0.0;
|
||||
vec3 shadow_color = vec3(0.0, 0.0, 0.0);
|
||||
@ -414,12 +474,19 @@ void main(void)
|
||||
// Power ratio was measured on torches in MTG (brightness = 14).
|
||||
float adjusted_night_ratio = pow(max(0.0, nightRatio), 0.6);
|
||||
|
||||
float shadow_uncorrected = shadow_int;
|
||||
|
||||
// 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);
|
||||
|
||||
#if (MATERIAL_TYPE == TILE_MATERIAL_WAVING_LEAVES || MATERIAL_TYPE == TILE_MATERIAL_WAVING_PLANTS)
|
||||
// Prevents foliage from becoming insanely bright outside the shadow map.
|
||||
shadow_uncorrected = mix(shadow_int, shadow_uncorrected, clamp(distance_rate * 4.0 - 3.0, 0.0, 1.0));
|
||||
#endif
|
||||
}
|
||||
|
||||
shadow_int *= f_adj_shadow_strength;
|
||||
@ -428,8 +495,60 @@ void main(void)
|
||||
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)) + // filtered texture color
|
||||
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(MATERIAL_WAVING_LIQUID) && defined(ENABLE_WATER_REFLECTIONS) && ENABLE_WAVING_WATER)
|
||||
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.
|
||||
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;
|
||||
|
||||
// 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;
|
||||
col.rgb *= 0.5;
|
||||
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);
|
||||
|
||||
// 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;
|
||||
#endif
|
||||
|
||||
#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));
|
||||
const float specular_exponent = 5.0;
|
||||
const float fresnel_exponent = 4.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);
|
||||
}
|
||||
#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);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -444,7 +563,13 @@ void main(void)
|
||||
// Note: clarity = (1 - fogginess)
|
||||
float clarity = clamp(fogShadingParameter
|
||||
- fogShadingParameter * length(eyeVec) / fogDistance, 0.0, 1.0);
|
||||
col = mix(fogColor, col, clarity);
|
||||
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 = vec4(col.rgb, base.a);
|
||||
|
||||
gl_FragData[0] = col;
|
||||
|
@ -256,7 +256,9 @@ void main(void)
|
||||
z_bias *= pFactor * pFactor / f_textureresolution / f_shadowfar;
|
||||
|
||||
shadow_position = applyPerspectiveDistortion(m_ShadowViewProj * mWorld * (shadow_pos + vec4(normalOffsetScale * nNormal, 0.0))).xyz;
|
||||
#if !defined(ENABLE_TRANSLUCENT_FOLIAGE) || MATERIAL_TYPE != TILE_MATERIAL_WAVING_LEAVES
|
||||
shadow_position.z -= z_bias;
|
||||
#endif
|
||||
perspective_factor = pFactor;
|
||||
|
||||
if (f_timeofday < 0.2) {
|
||||
|
@ -20,6 +20,7 @@ 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,7 +433,7 @@ void main(void)
|
||||
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)) + // filtered texture color
|
||||
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
|
||||
}
|
||||
#endif
|
||||
@ -448,7 +449,13 @@ void main(void)
|
||||
// Note: clarity = (1 - fogginess)
|
||||
float clarity = clamp(fogShadingParameter
|
||||
- fogShadingParameter * length(eyeVec) / fogDistance, 0.0, 1.0);
|
||||
col = mix(fogColor, col, clarity);
|
||||
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 = vec4(col.rgb, base.a);
|
||||
|
||||
gl_FragData[0] = col;
|
||||
|
@ -46,7 +46,9 @@ 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;
|
||||
}
|
||||
return result / samples;
|
||||
// We use the depth map to approximate the effect of depth on the light intensity.
|
||||
// The exponent was chosen based on aesthetic preference.
|
||||
return result / samples * pow(texture2D(depthmap, uv).r, 128.0);
|
||||
}
|
||||
|
||||
vec3 getDirectLightScatteringAtGround(vec3 v_LightDirection)
|
||||
|
@ -8518,6 +8518,8 @@ child will follow movement and rotation of that bone.
|
||||
if set to zero the clouds are rendered flat.
|
||||
* `speed`: 2D cloud speed + direction in nodes per second
|
||||
(default `{x=0, z=-2}`).
|
||||
* `shadow`: shadow color, applied to the base of the cloud
|
||||
(default `#cccccc`).
|
||||
* `get_clouds()`: returns a table with the current cloud parameters as in
|
||||
`set_clouds`.
|
||||
* `override_day_night_ratio(ratio or nil)`
|
||||
@ -8565,6 +8567,9 @@ child will follow movement and rotation of that bone.
|
||||
* `shadows` is a table that controls ambient shadows
|
||||
* `intensity` sets the intensity of the shadows from 0 (no shadows, default) to 1 (blackness)
|
||||
* This value has no effect on clients who have the "Dynamic Shadows" shader disabled.
|
||||
* `tint` tints the shadows with the provided color, with RGB values ranging from 0 to 255.
|
||||
(default `{r=0, g=0, b=0}`)
|
||||
* This value has no effect on clients who have the "Dynamic Shadows" shader disabled.
|
||||
* `exposure` is a table that controls automatic exposure.
|
||||
The basic exposure factor equation is `e = 2^exposure_correction / clamp(luminance, 2^luminance_min, 2^luminance_max)`
|
||||
* `luminance_min` set the lower luminance boundary to use in the calculation (default: `-3.0`)
|
||||
|
@ -137,6 +137,7 @@ struct ClientEvent
|
||||
f32 density;
|
||||
u32 color_bright;
|
||||
u32 color_ambient;
|
||||
u32 color_shadow;
|
||||
f32 height;
|
||||
f32 thickness;
|
||||
f32 speed_x;
|
||||
|
@ -1209,11 +1209,22 @@ void ClientMap::renderMapShadows(video::IVideoDriver *driver,
|
||||
// Render all mesh buffers in order
|
||||
drawcall_count += draw_order.size();
|
||||
|
||||
bool translucent_foliage = g_settings->getBool("enable_translucent_foliage");
|
||||
|
||||
video::E_MATERIAL_TYPE leaves_material = video::EMT_SOLID;
|
||||
|
||||
// For translucent leaves, we want to use backface culling instead of frontface.
|
||||
if (translucent_foliage) {
|
||||
// this is the material leaves would use, compare to nodedef.cpp
|
||||
auto* shdsrc = m_client->getShaderSource();
|
||||
const u32 leaves_shader = shdsrc->getShader("nodes_shader", TILE_MATERIAL_WAVING_LEAVES, NDT_ALLFACES);
|
||||
leaves_material = shdsrc->getShaderInfo(leaves_shader).material;
|
||||
}
|
||||
|
||||
for (auto &descriptor : draw_order) {
|
||||
if (!descriptor.m_reuse_material) {
|
||||
// override some material properties
|
||||
video::SMaterial local_material = descriptor.getMaterial();
|
||||
local_material.MaterialType = material.MaterialType;
|
||||
// do not override culling if the original material renders both back
|
||||
// and front faces in solid mode (e.g. plantlike)
|
||||
// Transparent plants would still render shadows only from one side,
|
||||
@ -1222,6 +1233,11 @@ void ClientMap::renderMapShadows(video::IVideoDriver *driver,
|
||||
local_material.BackfaceCulling = material.BackfaceCulling;
|
||||
local_material.FrontfaceCulling = material.FrontfaceCulling;
|
||||
}
|
||||
if (local_material.MaterialType == leaves_material && translucent_foliage) {
|
||||
local_material.BackfaceCulling = true;
|
||||
local_material.FrontfaceCulling = false;
|
||||
}
|
||||
local_material.MaterialType = material.MaterialType;
|
||||
local_material.BlendOperation = material.BlendOperation;
|
||||
driver->setMaterial(local_material);
|
||||
++material_swaps;
|
||||
|
@ -65,6 +65,8 @@ Clouds::Clouds(scene::ISceneManager* mgr, IShaderSource *ssrc,
|
||||
readSettings();
|
||||
g_settings->registerChangedCallback("enable_3d_clouds",
|
||||
&cloud_3d_setting_changed, this);
|
||||
g_settings->registerChangedCallback("soft_clouds",
|
||||
&cloud_3d_setting_changed, this);
|
||||
|
||||
updateBox();
|
||||
|
||||
@ -76,6 +78,8 @@ Clouds::~Clouds()
|
||||
{
|
||||
g_settings->deregisterChangedCallback("enable_3d_clouds",
|
||||
&cloud_3d_setting_changed, this);
|
||||
g_settings->deregisterChangedCallback("soft_clouds",
|
||||
&cloud_3d_setting_changed, this);
|
||||
}
|
||||
|
||||
void Clouds::OnRegisterSceneNode()
|
||||
@ -141,15 +145,18 @@ void Clouds::updateMesh()
|
||||
// shader mixes the base color, set via ColorParam
|
||||
c_top_f = c_side_1_f = c_side_2_f = c_bottom_f = video::SColorf(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
c_side_1_f.r *= 0.95f;
|
||||
c_side_1_f.g *= 0.95f;
|
||||
c_side_1_f.b *= 0.95f;
|
||||
c_side_2_f.r *= 0.90f;
|
||||
c_side_2_f.g *= 0.90f;
|
||||
c_side_2_f.b *= 0.90f;
|
||||
c_bottom_f.r *= 0.80f;
|
||||
c_bottom_f.g *= 0.80f;
|
||||
c_bottom_f.b *= 0.80f;
|
||||
video::SColorf shadow = m_params.color_shadow;
|
||||
|
||||
c_side_1_f.r *= shadow.r * 0.25f + 0.75f;
|
||||
c_side_1_f.g *= shadow.g * 0.25f + 0.75f;
|
||||
c_side_1_f.b *= shadow.b * 0.25f + 0.75f;
|
||||
c_side_2_f.r *= shadow.r * 0.5f + 0.5f;
|
||||
c_side_2_f.g *= shadow.g * 0.5f + 0.5f;
|
||||
c_side_2_f.b *= shadow.b * 0.5f + 0.5f;
|
||||
c_bottom_f.r *= shadow.r;
|
||||
c_bottom_f.g *= shadow.g;
|
||||
c_bottom_f.b *= shadow.b;
|
||||
|
||||
video::SColor c_top = c_top_f.toSColor();
|
||||
video::SColor c_side_1 = c_side_1_f.toSColor();
|
||||
video::SColor c_side_2 = c_side_2_f.toSColor();
|
||||
@ -221,13 +228,14 @@ void Clouds::updateMesh()
|
||||
const f32 ry = is3D() ? m_params.thickness * BS : 0.0f;
|
||||
const f32 rz = cloud_size / 2;
|
||||
|
||||
for(u32 i = 0; i < num_faces_to_draw; i++)
|
||||
bool soft_clouds_enabled = g_settings->getBool("soft_clouds");
|
||||
for (u32 i = 0; i < num_faces_to_draw; i++)
|
||||
{
|
||||
switch(i)
|
||||
switch (i)
|
||||
{
|
||||
case 0: // top
|
||||
for (video::S3DVertex &vertex : v) {
|
||||
vertex.Normal.set(0,1,0);
|
||||
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);
|
||||
@ -237,12 +245,20 @@ void Clouds::updateMesh()
|
||||
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])
|
||||
if (grid[j])
|
||||
continue;
|
||||
}
|
||||
for (video::S3DVertex &vertex : v) {
|
||||
vertex.Color = c_side_1;
|
||||
vertex.Normal.set(0,0,-1);
|
||||
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);
|
||||
@ -251,28 +267,45 @@ void Clouds::updateMesh()
|
||||
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])
|
||||
u32 j = GETINDEX(xi + 1, zi, m_cloud_radius_i);
|
||||
if (grid[j])
|
||||
continue;
|
||||
}
|
||||
for (video::S3DVertex &vertex : v) {
|
||||
vertex.Color = c_side_2;
|
||||
vertex.Normal.set(1,0,0);
|
||||
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;
|
||||
}
|
||||
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);
|
||||
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])
|
||||
if (grid[j])
|
||||
continue;
|
||||
}
|
||||
for (video::S3DVertex &vertex : v) {
|
||||
vertex.Color = c_side_1;
|
||||
vertex.Normal.set(0,0,-1);
|
||||
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);
|
||||
@ -280,14 +313,22 @@ void Clouds::updateMesh()
|
||||
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])
|
||||
if (INAREA(xi - 1, zi, m_cloud_radius_i)) {
|
||||
u32 j = GETINDEX(xi - 1, zi, m_cloud_radius_i);
|
||||
if (grid[j])
|
||||
continue;
|
||||
}
|
||||
for (video::S3DVertex &vertex : v) {
|
||||
vertex.Color = c_side_2;
|
||||
vertex.Normal.set(-1,0,0);
|
||||
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);
|
||||
@ -295,9 +336,9 @@ void Clouds::updateMesh()
|
||||
v[3].Pos.set(-rx, 0, rz);
|
||||
break;
|
||||
case 5: // bottom
|
||||
for (video::S3DVertex &vertex : v) {
|
||||
for (video::S3DVertex& vertex : v) {
|
||||
vertex.Color = c_bottom;
|
||||
vertex.Normal.set(0,-1,0);
|
||||
vertex.Normal.set(0, -1, 0);
|
||||
}
|
||||
v[0].Pos.set( rx, 0, rz);
|
||||
v[1].Pos.set(-rx, 0, rz);
|
||||
|
@ -109,6 +109,14 @@ public:
|
||||
m_params.color_ambient = color_ambient;
|
||||
}
|
||||
|
||||
void setColorShadow(video::SColor color_shadow)
|
||||
{
|
||||
if (m_params.color_shadow == color_shadow)
|
||||
return;
|
||||
m_params.color_shadow = color_shadow;
|
||||
invalidateMesh();
|
||||
}
|
||||
|
||||
void setHeight(float height)
|
||||
{
|
||||
if (m_params.height == height)
|
||||
|
@ -83,7 +83,8 @@ MapblockMeshGenerator::MapblockMeshGenerator(MeshMakeData *input, MeshCollector
|
||||
meshmanip(mm),
|
||||
blockpos_nodes(data->m_blockpos * MAP_BLOCKSIZE),
|
||||
enable_mesh_cache(g_settings->getBool("enable_mesh_cache") &&
|
||||
!data->m_smooth_lighting) // Mesh cache is not supported with smooth lighting
|
||||
!data->m_smooth_lighting), // Mesh cache is not supported with smooth lighting
|
||||
smooth_liquids(g_settings->getBool("enable_water_reflections"))
|
||||
{
|
||||
}
|
||||
|
||||
@ -717,7 +718,7 @@ void MapblockMeshGenerator::drawLiquidSides()
|
||||
if (data->m_smooth_lighting)
|
||||
cur_node.color = blendLightColor(pos);
|
||||
pos += cur_node.origin;
|
||||
vertices[j] = video::S3DVertex(pos.X, pos.Y, pos.Z, 0, 0, 0, cur_node.color, vertex.u, v);
|
||||
vertices[j] = video::S3DVertex(pos.X, pos.Y, pos.Z, face.dir.X, face.dir.Y, face.dir.Z, cur_node.color, vertex.u, v);
|
||||
};
|
||||
collector->append(cur_liquid.tile, vertices, 4, quad_indices, 6);
|
||||
}
|
||||
@ -740,6 +741,19 @@ void MapblockMeshGenerator::drawLiquidTop()
|
||||
for (int i = 0; i < 4; i++) {
|
||||
int u = corner_resolve[i][0];
|
||||
int w = corner_resolve[i][1];
|
||||
|
||||
if (smooth_liquids) {
|
||||
int x = vertices[i].Pos.X > 0;
|
||||
int z = vertices[i].Pos.Z > 0;
|
||||
|
||||
f32 dx = 0.5f * (cur_liquid.neighbors[z][x].level - cur_liquid.neighbors[z][x + 1].level +
|
||||
cur_liquid.neighbors[z + 1][x].level - cur_liquid.neighbors[z + 1][x + 1].level);
|
||||
f32 dz = 0.5f * (cur_liquid.neighbors[z][x].level - cur_liquid.neighbors[z + 1][x].level +
|
||||
cur_liquid.neighbors[z][x + 1].level - cur_liquid.neighbors[z + 1][x + 1].level);
|
||||
|
||||
vertices[i].Normal = v3f(dx, 1., dz).normalize();
|
||||
}
|
||||
|
||||
vertices[i].Pos.Y += cur_liquid.corner_levels[w][u] * BS;
|
||||
if (data->m_smooth_lighting)
|
||||
vertices[i].Color = blendLightColor(vertices[i].Pos);
|
||||
@ -779,6 +793,10 @@ void MapblockMeshGenerator::drawLiquidTop()
|
||||
vertex.TCoords += tcoord_center;
|
||||
|
||||
vertex.TCoords += tcoord_translate;
|
||||
|
||||
if (!smooth_liquids) {
|
||||
vertex.Normal = v3f(dx, 1., dz).normalize();
|
||||
}
|
||||
}
|
||||
|
||||
std::swap(vertices[0].TCoords, vertices[2].TCoords);
|
||||
|
@ -134,6 +134,7 @@ private:
|
||||
f32 corner_levels[2][2];
|
||||
};
|
||||
LiquidData cur_liquid;
|
||||
bool smooth_liquids = false;
|
||||
|
||||
void prepareLiquidNodeDrawing();
|
||||
void getLiquidNeighborhood();
|
||||
|
@ -386,6 +386,8 @@ class GameGlobalShaderConstantSetter : public IShaderConstantSetter
|
||||
CachedPixelShaderSetting<float, 3> m_minimap_yaw{"yawVec"};
|
||||
CachedPixelShaderSetting<float, 3> m_camera_offset_pixel{"cameraOffset"};
|
||||
CachedVertexShaderSetting<float, 3> m_camera_offset_vertex{"cameraOffset"};
|
||||
CachedPixelShaderSetting<float, 3> m_camera_position_pixel{ "cameraPosition" };
|
||||
CachedVertexShaderSetting<float, 3> m_camera_position_vertex{ "cameraPosition" };
|
||||
CachedPixelShaderSetting<SamplerLayer_t> m_texture0{"texture0"};
|
||||
CachedPixelShaderSetting<SamplerLayer_t> m_texture1{"texture1"};
|
||||
CachedPixelShaderSetting<SamplerLayer_t> m_texture2{"texture2"};
|
||||
@ -492,6 +494,10 @@ public:
|
||||
m_camera_offset_pixel.set(offset, services);
|
||||
m_camera_offset_vertex.set(offset, services);
|
||||
|
||||
v3f camera_position = m_client->getCamera()->getPosition();
|
||||
m_camera_position_pixel.set(camera_position, services);
|
||||
m_camera_position_pixel.set(camera_position, services);
|
||||
|
||||
SamplerLayer_t tex_id;
|
||||
tex_id = 0;
|
||||
m_texture0.set(&tex_id, services);
|
||||
@ -3184,6 +3190,7 @@ void Game::handleClientEvent_CloudParams(ClientEvent *event, CameraOrientation *
|
||||
clouds->setDensity(event->cloud_params.density);
|
||||
clouds->setColorBright(video::SColor(event->cloud_params.color_bright));
|
||||
clouds->setColorAmbient(video::SColor(event->cloud_params.color_ambient));
|
||||
clouds->setColorShadow(video::SColor(event->cloud_params.color_shadow));
|
||||
clouds->setHeight(event->cloud_params.height);
|
||||
clouds->setThickness(event->cloud_params.thickness);
|
||||
clouds->setSpeed(v2f(event->cloud_params.speed_x, event->cloud_params.speed_y));
|
||||
@ -4315,7 +4322,9 @@ void Game::updateShadows()
|
||||
float timeoftheday = getWickedTimeOfDay(in_timeofday);
|
||||
bool is_day = timeoftheday > 0.25 && timeoftheday < 0.75;
|
||||
bool is_shadow_visible = is_day ? sky->getSunVisible() : sky->getMoonVisible();
|
||||
shadow->setShadowIntensity(is_shadow_visible ? client->getEnv().getLocalPlayer()->getLighting().shadow_intensity : 0.0f);
|
||||
const auto &lighting = client->getEnv().getLocalPlayer()->getLighting();
|
||||
shadow->setShadowIntensity(is_shadow_visible ? lighting.shadow_intensity : 0.0f);
|
||||
shadow->setShadowTint(lighting.shadow_tint);
|
||||
|
||||
timeoftheday = std::fmod(timeoftheday + 0.75f, 0.5f) + 0.25f;
|
||||
const float offset_constant = 10000.0f;
|
||||
|
@ -689,6 +689,15 @@ ShaderInfo ShaderSource::generateShader(const std::string &name,
|
||||
if (g_settings->getBool("shadow_poisson_filter"))
|
||||
shaders_header << "#define POISSON_FILTER 1\n";
|
||||
|
||||
if (g_settings->getBool("enable_water_reflections"))
|
||||
shaders_header << "#define ENABLE_WATER_REFLECTIONS 1\n";
|
||||
|
||||
if (g_settings->getBool("enable_translucent_foliage"))
|
||||
shaders_header << "#define ENABLE_TRANSLUCENT_FOLIAGE 1\n";
|
||||
|
||||
if (g_settings->getBool("enable_node_specular"))
|
||||
shaders_header << "#define ENABLE_NODE_SPECULAR 1\n";
|
||||
|
||||
s32 shadow_filter = g_settings->getS32("shadow_filters");
|
||||
shaders_header << "#define SHADOW_FILTER " << shadow_filter << "\n";
|
||||
|
||||
|
@ -94,9 +94,11 @@ public:
|
||||
bool is_active() const { return m_shadows_enabled && shadowMapTextureFinal != nullptr; }
|
||||
void setTimeOfDay(float isDay) { m_time_day = isDay; };
|
||||
void setShadowIntensity(float shadow_intensity);
|
||||
void setShadowTint(video::SColor shadow_tint) { m_shadow_tint = shadow_tint; }
|
||||
|
||||
s32 getShadowSamples() const { return m_shadow_samples; }
|
||||
float getShadowStrength() const { return m_shadows_enabled ? m_shadow_strength : 0.0f; }
|
||||
video::SColor getShadowTint() const { return m_shadow_tint; }
|
||||
float getTimeOfDay() const { return m_time_day; }
|
||||
|
||||
f32 getPerspectiveBiasXY() { return m_perspective_bias_xy; }
|
||||
@ -131,6 +133,7 @@ private:
|
||||
std::vector<NodeToApply> m_shadow_node_array;
|
||||
|
||||
float m_shadow_strength;
|
||||
video::SColor m_shadow_tint{ 255, 0, 0, 0 };
|
||||
float m_shadow_strength_gamma;
|
||||
float m_shadow_map_max_distance;
|
||||
float m_shadow_map_texture_size;
|
||||
|
@ -40,6 +40,9 @@ void ShadowConstantSetter::onSetConstants(video::IMaterialRendererServices *serv
|
||||
f32 ShadowStrength = shadow->getShadowStrength();
|
||||
m_shadow_strength.set(&ShadowStrength, services);
|
||||
|
||||
video::SColor ShadowTint = shadow->getShadowTint();
|
||||
m_shadow_tint.set(ShadowTint, services);
|
||||
|
||||
f32 timeOfDay = shadow->getTimeOfDay();
|
||||
m_time_of_day.set(&timeOfDay, services);
|
||||
|
||||
|
@ -31,6 +31,7 @@ class ShadowConstantSetter : public IShaderConstantSetter
|
||||
CachedPixelShaderSetting<f32, 3> m_light_direction{"v_LightDirection"};
|
||||
CachedPixelShaderSetting<f32> m_texture_res{"f_textureresolution"};
|
||||
CachedPixelShaderSetting<f32> m_shadow_strength{"f_shadow_strength"};
|
||||
CachedPixelShaderSetting<f32, 3> m_shadow_tint{ "shadow_tint" };
|
||||
CachedPixelShaderSetting<f32> m_time_of_day{"f_timeofday"};
|
||||
CachedPixelShaderSetting<f32> m_shadowfar{"f_shadowfar"};
|
||||
CachedPixelShaderSetting<f32, 4> m_camera_pos{"CameraPos"};
|
||||
|
@ -275,6 +275,7 @@ void set_default_settings()
|
||||
settings->setDefault("view_bobbing_amount", "1.0");
|
||||
settings->setDefault("fall_bobbing_amount", "0.03");
|
||||
settings->setDefault("enable_3d_clouds", "true");
|
||||
settings->setDefault("soft_clouds", "false");
|
||||
settings->setDefault("cloud_radius", "12");
|
||||
settings->setDefault("menu_clouds", "true");
|
||||
settings->setDefault("translucent_liquids", "true");
|
||||
@ -335,6 +336,9 @@ void set_default_settings()
|
||||
settings->setDefault("bloom_intensity", "0.05");
|
||||
settings->setDefault("bloom_radius", "1");
|
||||
settings->setDefault("enable_volumetric_lighting", "false");
|
||||
settings->setDefault("enable_water_reflections", "false");
|
||||
settings->setDefault("enable_translucent_foliage", "false");
|
||||
settings->setDefault("enable_node_specular", "false");
|
||||
|
||||
// Effects Shadows
|
||||
settings->setDefault("enable_dynamic_shadows", "false");
|
||||
|
@ -18,7 +18,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "SColor.h"
|
||||
|
||||
using namespace irr;
|
||||
|
||||
/**
|
||||
* Parameters for automatic exposure compensation
|
||||
@ -54,4 +56,5 @@ struct Lighting
|
||||
float shadow_intensity {0.0f};
|
||||
float saturation {1.0f};
|
||||
float volumetric_light_strength {0.0f};
|
||||
video::SColor shadow_tint;
|
||||
};
|
||||
|
@ -1476,6 +1476,7 @@ void Client::handleCommand_CloudParams(NetworkPacket* pkt)
|
||||
f32 density;
|
||||
video::SColor color_bright;
|
||||
video::SColor color_ambient;
|
||||
video::SColor color_shadow = video::SColor(255, 204, 204, 204);
|
||||
f32 height;
|
||||
f32 thickness;
|
||||
v2f speed;
|
||||
@ -1483,6 +1484,10 @@ void Client::handleCommand_CloudParams(NetworkPacket* pkt)
|
||||
*pkt >> density >> color_bright >> color_ambient
|
||||
>> height >> thickness >> speed;
|
||||
|
||||
if (pkt->getRemainingBytes() >= 4) {
|
||||
*pkt >> color_shadow;
|
||||
}
|
||||
|
||||
ClientEvent *event = new ClientEvent();
|
||||
event->type = CE_CLOUD_PARAMS;
|
||||
event->cloud_params.density = density;
|
||||
@ -1491,6 +1496,7 @@ void Client::handleCommand_CloudParams(NetworkPacket* pkt)
|
||||
// we avoid using new() and delete() for no good reason
|
||||
event->cloud_params.color_bright = color_bright.color;
|
||||
event->cloud_params.color_ambient = color_ambient.color;
|
||||
event->cloud_params.color_shadow = color_shadow.color;
|
||||
event->cloud_params.height = height;
|
||||
event->cloud_params.thickness = thickness;
|
||||
// same here: deconstruct to skip constructor
|
||||
@ -1821,4 +1827,6 @@ void Client::handleCommand_SetLighting(NetworkPacket *pkt)
|
||||
}
|
||||
if (pkt->getRemainingBytes() >= 4)
|
||||
*pkt >> lighting.volumetric_light_strength;
|
||||
if (pkt->getRemainingBytes() >= 4)
|
||||
*pkt >> lighting.shadow_tint;
|
||||
}
|
||||
|
@ -229,10 +229,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
[bump for 5.9.1]
|
||||
PROTOCOL VERSION 46:
|
||||
Move default hotbar from client-side C++ to server-side builtin Lua
|
||||
Add shadow tint to Lighting packets
|
||||
Add shadow color to CloudParam packets
|
||||
[scheduled bump for 5.10.0]
|
||||
*/
|
||||
|
||||
#define LATEST_PROTOCOL_VERSION 46
|
||||
|
||||
#define LATEST_PROTOCOL_VERSION_STRING TOSTRING(LATEST_PROTOCOL_VERSION)
|
||||
|
||||
// Server's supported network protocol range
|
||||
@ -1176,4 +1179,4 @@ enum InteractAction : u8
|
||||
INTERACT_PLACE, // 3: place block or item (to abovesurface)
|
||||
INTERACT_USE, // 4: use item
|
||||
INTERACT_ACTIVATE // 5: rightclick air ("activate")
|
||||
};
|
||||
};
|
@ -2448,6 +2448,10 @@ int ObjectRef::l_set_clouds(lua_State *L)
|
||||
if (!lua_isnil(L, -1))
|
||||
read_color(L, -1, &cloud_params.color_ambient);
|
||||
lua_pop(L, 1);
|
||||
lua_getfield(L, 2, "shadow");
|
||||
if (!lua_isnil(L, -1))
|
||||
read_color(L, -1, &cloud_params.color_shadow);
|
||||
lua_pop(L, 1);
|
||||
|
||||
cloud_params.height = getfloatfield_default(L, 2, "height", cloud_params.height);
|
||||
cloud_params.thickness = getfloatfield_default(L, 2, "thickness", cloud_params.thickness);
|
||||
@ -2483,6 +2487,8 @@ int ObjectRef::l_get_clouds(lua_State *L)
|
||||
lua_setfield(L, -2, "color");
|
||||
push_ARGB8(L, cloud_params.color_ambient);
|
||||
lua_setfield(L, -2, "ambient");
|
||||
push_ARGB8(L, cloud_params.color_shadow);
|
||||
lua_setfield(L, -2, "shadow");
|
||||
lua_pushnumber(L, cloud_params.height);
|
||||
lua_setfield(L, -2, "height");
|
||||
lua_pushnumber(L, cloud_params.thickness);
|
||||
@ -2611,6 +2617,8 @@ int ObjectRef::l_set_lighting(lua_State *L)
|
||||
lua_getfield(L, 2, "shadows");
|
||||
if (lua_istable(L, -1)) {
|
||||
getfloatfield(L, -1, "intensity", lighting.shadow_intensity);
|
||||
lua_getfield(L, -1, "tint");
|
||||
read_color(L, -1, &lighting.shadow_tint);
|
||||
}
|
||||
lua_pop(L, 1); // shadows
|
||||
|
||||
@ -2654,6 +2662,8 @@ int ObjectRef::l_get_lighting(lua_State *L)
|
||||
lua_newtable(L); // "shadows"
|
||||
lua_pushnumber(L, lighting.shadow_intensity);
|
||||
lua_setfield(L, -2, "intensity");
|
||||
push_ARGB8(L, lighting.shadow_tint);
|
||||
lua_setfield(L, -2, "tint");
|
||||
lua_setfield(L, -2, "shadows");
|
||||
lua_pushnumber(L, lighting.saturation);
|
||||
lua_setfield(L, -2, "saturation");
|
||||
|
@ -1843,7 +1843,7 @@ void Server::SendCloudParams(session_t peer_id, const CloudParams ¶ms)
|
||||
{
|
||||
NetworkPacket pkt(TOCLIENT_CLOUD_PARAMS, 0, peer_id);
|
||||
pkt << params.density << params.color_bright << params.color_ambient
|
||||
<< params.height << params.thickness << params.speed;
|
||||
<< params.height << params.thickness << params.speed << params.color_shadow;
|
||||
Send(&pkt);
|
||||
}
|
||||
|
||||
@ -1873,7 +1873,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;
|
||||
pkt << lighting.volumetric_light_strength << lighting.shadow_tint;
|
||||
|
||||
Send(&pkt);
|
||||
}
|
||||
|
@ -81,6 +81,7 @@ struct CloudParams
|
||||
float density;
|
||||
video::SColor color_bright;
|
||||
video::SColor color_ambient;
|
||||
video::SColor color_shadow;
|
||||
float thickness;
|
||||
float height;
|
||||
v2f speed;
|
||||
@ -160,6 +161,7 @@ public:
|
||||
clouds.density = 0.4f;
|
||||
clouds.color_bright = video::SColor(229, 240, 240, 255);
|
||||
clouds.color_ambient = video::SColor(255, 0, 0, 0);
|
||||
clouds.color_shadow = video::SColor(255, 204, 204, 204);
|
||||
clouds.thickness = 16.0f;
|
||||
clouds.height = 120;
|
||||
clouds.speed = v2f(0.0f, -2.0f);
|
||||
|
Loading…
Reference in New Issue
Block a user