17
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-11-02 10:29:13 +01:00

Hold the sky back only around tunnels and keep the cab lit by day

This commit is contained in:
2026-10-28 14:01:37 +01:00
parent e8a90507f0
commit 413cebed9c
10 changed files with 187 additions and 21 deletions

View File

@@ -825,7 +825,7 @@ vec3 cab_probe_reflection(vec3 surroundings, vec3 fragnormal, float roughness, v
// Texturecolor is the albedo (the base colour of a metal), Specularity the specular level of a dielectric (0.5 is the
// reflectance of 4% at normal incidence), Reflectivity how much of the reflected surroundings is the cubemap rather than the
// ambient light, Shadowtone the share of the sun left in its shadow (1 for the materials which take no shadows).
// a Sunless surface (the interior of a cab) gets no light of the sun, its shadow only darkens the ambient light
// a Sunless surface (the interior of a cab) gets no light of the sun, where the sun falls it brightens the ambient light
vec3 shade_surface(vec3 fragcolor, vec3 fragnormal, vec3 texturecolor, float reflectivity, float specularity, float shadowtone, bool sunless)
{
// Diffuse colour is applied once, to the albedo; the light terms below are not scaled by it again
@@ -964,10 +964,12 @@ vec3 shade_surface(vec3 fragcolor, vec3 fragnormal, vec3 texturecolor, float ref
float cubemap_shadow = 1.0;
if (sunless)
{
// the sun adds no light in the cab, where it would fall its shadow darkens the ambient light
// the sun adds no light of its own in the cab; where it falls the ambient light is raised as much as the shadow used to lower
// it (the share Shadowtone, at most 4 times), so the shadows of the walls of the cab and of the clouds leave the ambient light
// as it is instead of darkening the cab
float diffuseamount = sun_NdotL * lights[0].intensity;
float darkness = (shadowtone < 1.0 ? max(shadow, 1.0 - cloudsun) : 0.0);
fragcolor = mix(fragcolor, fragcolor * shadowtone, clamp(diffuseamount * darkness, 0.0, 1.0));
float sunlit = (shadowtone < 1.0 ? 1.0 - max(shadow, 1.0 - cloudsun) : 0.0);
fragcolor *= 1.0 + clamp(diffuseamount * sunlit, 0.0, 1.0) * (1.0 - shadowtone) / max(shadowtone, 0.25);
}
else
cubemap_shadow = 1.0 - (1.0 - shadowtone) * shadow * 0.5;
@@ -1003,7 +1005,7 @@ vec3 apply_lights(vec3 fragcolor, vec3 fragnormal, vec3 texturecolor, float refl
return shade_surface(fragcolor, fragnormal, texturecolor, reflectivity, specularity, shadowtone, false);
}
// the interior of a cab: no light of the sun, its shadow darkens the ambient light
// the interior of a cab: no light of the sun, where it falls it brightens the ambient light
vec3 apply_lights_sunless(vec3 fragcolor, vec3 fragnormal, vec3 texturecolor, float reflectivity, float specularity, float shadowtone)
{
return shade_surface(fragcolor, fragnormal, texturecolor, reflectivity, specularity, shadowtone, true);

View File

@@ -57,13 +57,17 @@ vec2 sky_occlusion_world(vec3 world, vec3 worldnormal)
vec4 skydeep = textureGather(sky_occlusion_map, uv, 2);
vec4 litabove = textureGather(sky_occlusion_map, uv, 3);
vec4 height = vec4(point.y + sky_occlusion_origin.z);
vec4 cover = clamp((tops - height - SKY_OCCLUSION_COVER_START) / SKY_OCCLUSION_COVER_SPAN, 0.0, 1.0);
// a point is under the scenery only where a ceiling is over it (the vault of a tunnel, the deck of a bridge, a roof): under the top
// with nothing over it (the edge of a platform or a wall the texels are blended over, a hole cut in the terrain, a part of a
// model in the ground) it's taken as at the top, in the open
vec4 roofed = step(ceilings, vec4(5000.0)) * clamp(ceilings - height + 1.0, 0.0, 1.0);
vec4 cover = clamp((tops - height - SKY_OCCLUSION_COVER_START) / SKY_OCCLUSION_COVER_SPAN, 0.0, 1.0) * roofed;
vec4 nearheight = ceilings - SKY_OCCLUSION_BELOW_CEILING;
vec4 skyunder = mix(skydeep, skynear, clamp((height - deeps) / max(nearheight - deeps, vec4(1e-3)), 0.0, 1.0));
// no ceiling: the inside of what is solid
skyunder *= step(ceilings, vec4(5000.0));
vec4 sky = mix(skytop, skyunder, cover);
vec4 suntop = smoothstep(vec4(-SKY_OCCLUSION_SUN_SOFTNESS), vec4(SKY_OCCLUSION_SUN_SOFTNESS), height - (tops + litabove));
vec4 suntop = smoothstep(vec4(-SKY_OCCLUSION_SUN_SOFTNESS), vec4(SKY_OCCLUSION_SUN_SOFTNESS), max(height, tops - SKY_OCCLUSION_COVER_START) - (tops + litabove));
vec4 sununder = smoothstep(vec4(-SKY_OCCLUSION_SUN_SOFTNESS), vec4(SKY_OCCLUSION_SUN_SOFTNESS), litbelow - height);
vec4 sun = mix(suntop, sununder, cover);
return mix(vec2(dot(sky, weights), dot(sun, weights)), vec2(1.0), fade);
@@ -81,7 +85,11 @@ float sky_occlusion_cover(vec3 world)
if (false == sky_occlusion_texels(world.xz, uv, weights, fade))
return 0.0;
vec4 tops = textureGather(sky_occlusion_height, uv, 0);
vec4 cover = clamp((tops - vec4(world.y + sky_occlusion_origin.z) - SKY_OCCLUSION_COVER_START) / SKY_OCCLUSION_COVER_SPAN, 0.0, 1.0);
vec4 ceilings = textureGather(sky_occlusion_height, uv, 1);
vec4 height = vec4(world.y + sky_occlusion_origin.z);
// under a ceiling only, as sky_occlusion_world() takes it
vec4 roofed = step(ceilings, vec4(5000.0)) * clamp(ceilings - height + 1.0, 0.0, 1.0);
vec4 cover = clamp((tops - height - SKY_OCCLUSION_COVER_START) / SKY_OCCLUSION_COVER_SPAN, 0.0, 1.0) * roofed;
return dot(cover, weights) * (1.0 - fade);
}

View File

@@ -838,7 +838,7 @@ vec3 cab_probe_reflection(vec3 surroundings, vec3 fragnormal, float roughness, v
// Texturecolor is the albedo (the base colour of a metal), Specularity the specular level of a dielectric (0.5 is the
// reflectance of 4% at normal incidence), Reflectivity how much of the reflected surroundings is the cubemap rather than the
// ambient light, Shadowtone the share of the sun left in its shadow (1 for the materials which take no shadows).
// a Sunless surface (the interior of a cab) gets no light of the sun, its shadow only darkens the ambient light
// a Sunless surface (the interior of a cab) gets no light of the sun, where the sun falls it brightens the ambient light
vec3 shade_surface(vec3 fragcolor, vec3 fragnormal, vec3 texturecolor, float reflectivity, float specularity, float shadowtone, bool sunless)
{
// Diffuse colour is applied once, to the albedo; the light terms below are not scaled by it again
@@ -978,10 +978,12 @@ vec3 shade_surface(vec3 fragcolor, vec3 fragnormal, vec3 texturecolor, float ref
float cubemap_shadow = 1.0;
if (sunless)
{
// the sun adds no light in the cab, where it would fall its shadow darkens the ambient light
// the sun adds no light of its own in the cab; where it falls the ambient light is raised as much as the shadow used to lower
// it (the share Shadowtone, at most 4 times), so the shadows of the walls of the cab and of the clouds leave the ambient light
// as it is instead of darkening the cab
float diffuseamount = sun_NdotL * lights[0].intensity;
float darkness = (shadowtone < 1.0 ? max(shadow, 1.0 - cloudsun) : 0.0);
fragcolor = mix(fragcolor, fragcolor * shadowtone, clamp(diffuseamount * darkness, 0.0, 1.0));
float sunlit = (shadowtone < 1.0 ? 1.0 - max(shadow, 1.0 - cloudsun) : 0.0);
fragcolor *= 1.0 + clamp(diffuseamount * sunlit, 0.0, 1.0) * (1.0 - shadowtone) / max(shadowtone, 0.25);
}
else
cubemap_shadow = 1.0 - (1.0 - shadowtone) * shadow * 0.5;
@@ -1017,7 +1019,7 @@ vec3 apply_lights(vec3 fragcolor, vec3 fragnormal, vec3 texturecolor, float refl
return shade_surface(fragcolor, fragnormal, texturecolor, reflectivity, specularity, shadowtone, false);
}
// the interior of a cab: no light of the sun, its shadow darkens the ambient light
// the interior of a cab: no light of the sun, where it falls it brightens the ambient light
vec3 apply_lights_sunless(vec3 fragcolor, vec3 fragnormal, vec3 texturecolor, float reflectivity, float specularity, float shadowtone)
{
return shade_surface(fragcolor, fragnormal, texturecolor, reflectivity, specularity, shadowtone, true);

View File

@@ -57,13 +57,17 @@ vec2 sky_occlusion_world(vec3 world, vec3 worldnormal)
vec4 skydeep = textureGather(sky_occlusion_map, uv, 2);
vec4 litabove = textureGather(sky_occlusion_map, uv, 3);
vec4 height = vec4(point.y + sky_occlusion_origin.z);
vec4 cover = clamp((tops - height - SKY_OCCLUSION_COVER_START) / SKY_OCCLUSION_COVER_SPAN, 0.0, 1.0);
// a point is under the scenery only where a ceiling is over it (the vault of a tunnel, the deck of a bridge, a roof): under the top
// with nothing over it (the edge of a platform or a wall the texels are blended over, a hole cut in the terrain, a part of a
// model in the ground) it's taken as at the top, in the open
vec4 roofed = step(ceilings, vec4(5000.0)) * clamp(ceilings - height + 1.0, 0.0, 1.0);
vec4 cover = clamp((tops - height - SKY_OCCLUSION_COVER_START) / SKY_OCCLUSION_COVER_SPAN, 0.0, 1.0) * roofed;
vec4 nearheight = ceilings - SKY_OCCLUSION_BELOW_CEILING;
vec4 skyunder = mix(skydeep, skynear, clamp((height - deeps) / max(nearheight - deeps, vec4(1e-3)), 0.0, 1.0));
// no ceiling: the inside of what is solid
skyunder *= step(ceilings, vec4(5000.0));
vec4 sky = mix(skytop, skyunder, cover);
vec4 suntop = smoothstep(vec4(-SKY_OCCLUSION_SUN_SOFTNESS), vec4(SKY_OCCLUSION_SUN_SOFTNESS), height - (tops + litabove));
vec4 suntop = smoothstep(vec4(-SKY_OCCLUSION_SUN_SOFTNESS), vec4(SKY_OCCLUSION_SUN_SOFTNESS), max(height, tops - SKY_OCCLUSION_COVER_START) - (tops + litabove));
vec4 sununder = smoothstep(vec4(-SKY_OCCLUSION_SUN_SOFTNESS), vec4(SKY_OCCLUSION_SUN_SOFTNESS), litbelow - height);
vec4 sun = mix(suntop, sununder, cover);
return mix(vec2(dot(sky, weights), dot(sun, weights)), vec2(1.0), fade);
@@ -81,7 +85,11 @@ float sky_occlusion_cover(vec3 world)
if (false == sky_occlusion_texels(world.xz, uv, weights, fade))
return 0.0;
vec4 tops = textureGather(sky_occlusion_height, uv, 0);
vec4 cover = clamp((tops - vec4(world.y + sky_occlusion_origin.z) - SKY_OCCLUSION_COVER_START) / SKY_OCCLUSION_COVER_SPAN, 0.0, 1.0);
vec4 ceilings = textureGather(sky_occlusion_height, uv, 1);
vec4 height = vec4(world.y + sky_occlusion_origin.z);
// under a ceiling only, as sky_occlusion_world() takes it
vec4 roofed = step(ceilings, vec4(5000.0)) * clamp(ceilings - height + 1.0, 0.0, 1.0);
vec4 cover = clamp((tops - height - SKY_OCCLUSION_COVER_START) / SKY_OCCLUSION_COVER_SPAN, 0.0, 1.0) * roofed;
return dot(cover, weights) * (1.0 - fade);
}