moonwell-gfx: darker nights and deeper shadows, as WoW Forever's
The post pass takes from the dark and middle tones (eased off toward the bright, so a torch's pool, a window or the moon keep theirs): post.shadow_depth at any hour, post.night_darkness far further with the sun down, cooler and a little greyer. The lit air keeps 15% for the moon (was 35%). The Forever preset sets both. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -217,6 +217,22 @@ const ITEMS: &[Item] = &[
|
||||
"Сила резкости",
|
||||
"Sharpen strength",
|
||||
),
|
||||
slider(
|
||||
"post.shadow_depth",
|
||||
0.0,
|
||||
1.0,
|
||||
0.05,
|
||||
"Глубина теней",
|
||||
"Shadow depth",
|
||||
),
|
||||
slider(
|
||||
"post.night_darkness",
|
||||
0.0,
|
||||
1.0,
|
||||
0.05,
|
||||
"Тёмные ночи",
|
||||
"Dark nights",
|
||||
),
|
||||
switch("post.grading", "Цветокоррекция", "Colour grading"),
|
||||
slider("post.brightness", -0.5, 0.5, 0.01, "Яркость", "Brightness"),
|
||||
slider("post.contrast", 0.5, 2.0, 0.01, "Контраст", "Contrast"),
|
||||
|
||||
@@ -188,7 +188,7 @@ fn publish(
|
||||
} else {
|
||||
0.0
|
||||
};
|
||||
let night_share = if shadows.moon { 0.35 } else { 0.0 };
|
||||
let night_share = if shadows.moon { 0.15 } else { 0.0 };
|
||||
// A low sun lights the air most: the glow and the rays are the dawn's and the dusk's, and the
|
||||
// noon keeps a third.
|
||||
let low_sun = 1.0 - 0.65 * smoothstep(0.25, 0.8, sun.y);
|
||||
@@ -203,8 +203,20 @@ fn publish(
|
||||
} else {
|
||||
0.0
|
||||
};
|
||||
// The dark: how much the dark and middle tones lose, deeper at night; and the night's cool,
|
||||
// grey share.
|
||||
let night = 1.0 - day;
|
||||
let dark = (s.shadow_depth as f32 * 0.25 + s.night_darkness as f32 * 0.6 * night).min(0.7);
|
||||
let night_tint = s.night_darkness as f32 * night;
|
||||
let post_on = s.enabled
|
||||
&& (s.grading || s.ao || s.sun_shafts || vol > 0.0 || sharpen > 0.0 || gi > 0.0 || fxaa);
|
||||
&& (s.grading
|
||||
|| s.ao
|
||||
|| s.sun_shafts
|
||||
|| vol > 0.0
|
||||
|| sharpen > 0.0
|
||||
|| gi > 0.0
|
||||
|| fxaa
|
||||
|| dark > 0.0);
|
||||
let next = (post_on || halo > 0.0).then(|| PostParams {
|
||||
grade: Vec4::new(
|
||||
s.brightness as f32,
|
||||
@@ -212,7 +224,12 @@ fn publish(
|
||||
s.saturation as f32,
|
||||
s.vibrance as f32,
|
||||
),
|
||||
tone: Vec4::new(s.warmth as f32, on(post_on && s.grading), 0.0, 0.0),
|
||||
tone: Vec4::new(
|
||||
s.warmth as f32,
|
||||
on(post_on && s.grading),
|
||||
if post_on { dark } else { 0.0 },
|
||||
if post_on { night_tint } else { 0.0 },
|
||||
),
|
||||
ao: Vec4::new(
|
||||
s.ao_strength as f32,
|
||||
s.ao_radius as f32,
|
||||
|
||||
@@ -120,6 +120,8 @@ impl GfxSettings {
|
||||
s.post.saturation = 1.15;
|
||||
s.post.vibrance = 0.2;
|
||||
s.post.secondary_light_strength = 1.2;
|
||||
s.post.shadow_depth = 0.5;
|
||||
s.post.night_darkness = 0.75;
|
||||
s.wind.enabled = true;
|
||||
s.water.enabled = true;
|
||||
s.lights.enabled = true;
|
||||
@@ -353,6 +355,11 @@ pub struct PostSettings {
|
||||
pub secondary_light: bool,
|
||||
/// Its strength, 0..2.
|
||||
pub secondary_light_strength: f64,
|
||||
/// Deeper shadows at any hour, 0..1: the dark and middle tones go down, the bright stay.
|
||||
pub shadow_depth: f64,
|
||||
/// Darker nights, 0..1: with the sun down the same curve goes much further, cooler and a
|
||||
/// little greyer, so a torch, a lamp or a window stands out of the dark.
|
||||
pub night_darkness: f64,
|
||||
}
|
||||
|
||||
impl Default for PostSettings {
|
||||
@@ -382,6 +389,8 @@ impl Default for PostSettings {
|
||||
antialias: true,
|
||||
secondary_light: true,
|
||||
secondary_light_strength: 0.8,
|
||||
shadow_depth: 0.4,
|
||||
night_darkness: 0.6,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -414,6 +423,8 @@ impl PostSettings {
|
||||
antialias: self.antialias,
|
||||
secondary_light: self.secondary_light,
|
||||
secondary_light_strength: self.secondary_light_strength.clamp(0.0, 2.0),
|
||||
shadow_depth: self.shadow_depth.clamp(0.0, 1.0),
|
||||
night_darkness: self.night_darkness.clamp(0.0, 1.0),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
struct Post {
|
||||
// brightness, contrast, saturation, vibrance
|
||||
grade: vec4<f32>,
|
||||
// warmth, grade on, unused, unused
|
||||
// warmth, grade on, what the dark tones lose (0 off), the night's tint
|
||||
tone: vec4<f32>,
|
||||
// strength, radius (yd), ao on, unused
|
||||
ao: vec4<f32>,
|
||||
@@ -488,6 +488,25 @@ fn fxaa(uv: vec2<f32>, centre: vec3<f32>) -> vec3<f32> {
|
||||
return fxaa_at(out_uv);
|
||||
}
|
||||
|
||||
// The dark: the dark and middle tones lose `tone.z` of their light and the bright (a torch's
|
||||
// pool, a window, the moon) keep theirs, eased between by the luma, as WoW Forever's dim places
|
||||
// and nights are; at night (`tone.w`) also cooler and a little greyer, as the eye sees in the dark.
|
||||
fn darkened(c: vec3<f32>) -> vec3<f32> {
|
||||
let k = post.tone.z;
|
||||
if (k <= 0.0) {
|
||||
return c;
|
||||
}
|
||||
let l = dot(c, vec3<f32>(0.2126, 0.7152, 0.0722));
|
||||
var x = c * mix(1.0 - k, 1.0, smoothstep(0.08, 0.75, l));
|
||||
let n = post.tone.w;
|
||||
if (n > 0.0) {
|
||||
let grey = dot(x, vec3<f32>(0.2126, 0.7152, 0.0722));
|
||||
x = mix(x, vec3<f32>(grey), 0.25 * n);
|
||||
x = x * mix(vec3<f32>(1.0), vec3<f32>(0.86, 0.94, 1.12), 0.6 * n);
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
// The grade, in the gamma bytes the world pass writes.
|
||||
fn grade(c: vec3<f32>) -> vec3<f32> {
|
||||
var x = c + vec3<f32>(post.grade.x);
|
||||
@@ -518,5 +537,6 @@ fn fragment(in: FullscreenVertexOutput) -> @location(0) vec4<f32> {
|
||||
if (post.tone.y > 0.5) {
|
||||
rgb = grade(rgb);
|
||||
}
|
||||
rgb = darkened(rgb);
|
||||
return vec4<f32>(rgb, color.a);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user