mirror of
https://github.com/SK8-ENGINE/skate-3-rust-engine.git
synced 2026-10-26 19:47:44 +00:00
Reduce weathering decal strength and mip-filter clamped decals
This commit is contained in:
1 parent
151a69d619
commit
79ea829ca9
5 files changed
+53
-7
No files matched your search
@@ -5,7 +5,7 @@
|
||||
#ifdef MOTION_VECTOR_PREPASS
|
||||
#import bevy_pbr::pbr_prepass_functions::calculate_motion_vector
|
||||
#endif
|
||||
struct WorldParams { mode: vec4<f32>, foliage_debug: vec4<f32>, surface: vec4<f32>, family: vec4<f32>, fog_ramp: vec4<f32>, fog_color: vec4<f32>, shadow_color: vec4<f32>, sun_direction: vec4<f32>, water: array<vec4<f32>, 4> }
|
||||
struct WorldParams { mode: vec4<f32>, foliage_debug: vec4<f32>, surface: vec4<f32>, family: vec4<f32>, fog_ramp: vec4<f32>, fog_color: vec4<f32>, shadow_color: vec4<f32>, sun_direction: vec4<f32>, decal: vec4<f32>, water: array<vec4<f32>, 4> }
|
||||
@group(#{MATERIAL_BIND_GROUP}) @binding(0) var<uniform> p: WorldParams;
|
||||
@group(#{MATERIAL_BIND_GROUP}) @binding(1) var diffuse: texture_2d<f32>;
|
||||
@group(#{MATERIAL_BIND_GROUP}) @binding(2) var diffuse_sampler: sampler;
|
||||
|
||||
@@ -47,7 +47,7 @@ fn compare_weathering(
|
||||
1 => "Repeating grime OFF; decals ON",
|
||||
2 => "Repeating grime ON; decals OFF",
|
||||
3 => "Repeating grime OFF; decals OFF",
|
||||
_ => "Authored grime and decals ON",
|
||||
_ => "Normal grime and decals ON",
|
||||
};
|
||||
for (_, material) in materials.iter_mut() {
|
||||
let family = material.params.mode.x as u32;
|
||||
@@ -98,6 +98,8 @@ pub(crate) struct WorldParams {
|
||||
pub fog_color: Vec4,
|
||||
pub shadow_color: Vec4,
|
||||
pub sun_direction: Vec4,
|
||||
// Wear-only visual tuning; artwork retains unit opacity.
|
||||
pub decal: Vec4,
|
||||
pub water: [Vec4; 4],
|
||||
}
|
||||
|
||||
@@ -270,7 +272,7 @@ impl Definition {
|
||||
texture(
|
||||
b.map_or(fallback, |b| b.texture),
|
||||
if clamp || b.is_some_and(|b| b.u == 1 && b.v == 1) {
|
||||
4
|
||||
if role == "decal" { 6 } else { 4 }
|
||||
} else {
|
||||
3
|
||||
},
|
||||
@@ -339,6 +341,7 @@ impl Definition {
|
||||
fog_color: Vec4::ZERO,
|
||||
shadow_color: Vec4::ZERO,
|
||||
sun_direction: Vec3::new(4., 7., 4.).normalize().extend(0.),
|
||||
decal: Vec4::new(stain_opacity(self.parameters.get("decal").and_then(|v| v.first()).map(String::as_str).unwrap_or("")), 0., 0., 0.),
|
||||
water,
|
||||
},
|
||||
diffuse,
|
||||
@@ -356,6 +359,29 @@ impl Definition {
|
||||
}
|
||||
}
|
||||
|
||||
// The source labels distinguish weathering from graphics. This is an explicit
|
||||
// visual tuning choice, not a recovered native material constant. Keep arrows,
|
||||
// logos, paint, scratches and edge wear at their authored alpha.
|
||||
fn stain_opacity(texture_label: &str) -> f32 {
|
||||
let label = texture_label.to_ascii_lowercase();
|
||||
if ["grime", "grunge", "stain", "oildirt", "drainage", "ground_decals"]
|
||||
.iter().any(|word| label.contains(word)) { 0.35 } else { 1. }
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod stain_tests {
|
||||
use super::stain_opacity;
|
||||
#[test]
|
||||
fn weathering_tuning_preserves_artwork() {
|
||||
for name in ["decal_WEAR_WaterStain_01", "subway_grunge03", "decal_GrimePuddle", "OT_Ground_decals"] {
|
||||
assert_eq!(stain_opacity(name), 0.35);
|
||||
}
|
||||
for name in ["decal_Graphic_SP_UN_Shark_01", "decal_other_sp_arrowramps_01", "decal_Graphic_SP_UN_MegaRmp_01", "decal_Wear_GL_UN_MPedge_01", "decal_skateboardscratcheswood01", ""] {
|
||||
assert_eq!(stain_opacity(name), 1.);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Native renderer box-filters decoded UNORM cube faces down to 1x1.
|
||||
/// The same chain prevents aliasing of repeating world maps at distance.
|
||||
pub(crate) fn mip_chain(rgba: &[u8], width: u32, height: u32, layers: u32) -> (Vec<u8>, u32) {
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
struct WorldParams {
|
||||
mode: vec4<f32>, foliage_debug: vec4<f32>, surface: vec4<f32>, family: vec4<f32>,
|
||||
fog_ramp: vec4<f32>, fog_color: vec4<f32>, shadow_color: vec4<f32>, sun_direction: vec4<f32>, water: array<vec4<f32>, 4>,
|
||||
fog_ramp: vec4<f32>, fog_color: vec4<f32>, shadow_color: vec4<f32>, sun_direction: vec4<f32>, decal: vec4<f32>, water: array<vec4<f32>, 4>,
|
||||
}
|
||||
@group(#{MATERIAL_BIND_GROUP}) @binding(0) var<uniform> p: WorldParams;
|
||||
@group(#{MATERIAL_BIND_GROUP}) @binding(1) var diffuse: texture_2d<f32>;
|
||||
@@ -174,7 +174,7 @@ fn fragment(i: VertexOutput) -> @location(0) vec4<f32> {
|
||||
lin = d;
|
||||
if fam == 11u { lin *= p.family.w; }
|
||||
} else {
|
||||
if (fam == 3u || fam == 4u) && (flags & 8u) != 0u && (flags & 512u) == 0u { d = mix(d,art.rgb*art.rgb,art.a); }
|
||||
if (fam == 3u || fam == 4u) && (flags & 8u) != 0u && (flags & 512u) == 0u { d = mix(d,art.rgb*art.rgb,art.a*p.decal.x); }
|
||||
if (flags & 4u) != 0u && fam < 13u && (flags & 256u) == 0u { d *= saturate((overlay_sample-0.5)*p.surface.y+0.5); }
|
||||
var kd = 0.93429;
|
||||
if (fam <= 6u || fam == 13u) && (flags & 1u) != 0u {
|
||||
|
||||
@@ -481,7 +481,7 @@ pub(crate) fn spawn(
|
||||
format,
|
||||
RenderAssetUsages::RENDER_WORLD,
|
||||
);
|
||||
if role == 3 || cube {
|
||||
if role == 3 || role == 6 || cube {
|
||||
let (bytes, levels) = crate::retail_render::mip_chain(&source.rgba, source.width, height, layers);
|
||||
image.data = Some(bytes);
|
||||
image.texture_descriptor.mip_level_count = levels;
|
||||
@@ -492,7 +492,7 @@ pub(crate) fn spawn(
|
||||
});
|
||||
}
|
||||
let mut sampler = bevy::image::ImageSamplerDescriptor::linear();
|
||||
if role != 1 && role != 4 && !cube {
|
||||
if role != 1 && role != 4 && role != 6 && !cube {
|
||||
sampler.address_mode_u = bevy::image::ImageAddressMode::Repeat;
|
||||
sampler.address_mode_v = bevy::image::ImageAddressMode::Repeat;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,25 @@
|
||||
# Authored props and grime follow-up
|
||||
|
||||
## Targeted decal correction after layer test
|
||||
|
||||
The user rechecked the comparison and identified decals as the unwanted layer.
|
||||
Repeating grime is unchanged. Wear/stain decals now use 35% of their texture's
|
||||
alpha; source UVs, dimensions, texture RGB and placement are retained. This is
|
||||
explicit visual tuning based on the user's feedback, not proof of the original
|
||||
game's intended opacity and not a recovered native shader constant.
|
||||
|
||||
Classification uses the material's authored `decal` texture label for grime,
|
||||
grunge, stain, oil-dirt, drainage and ground-decal entries. Arrows, logos,
|
||||
scratches and ramp edge paint retain full authored opacity. A regression test
|
||||
covers this separation. This is not a blanket fade on every decal material.
|
||||
|
||||
Clamped decals also now receive a mip chain, independently of lightmaps, which
|
||||
remain bilinear mip zero. Previously the shared clamp texture role omitted mips
|
||||
for both, leaving fine decal alpha detail unfiltered at distance. The new decal
|
||||
role retains clamp addressing while permitting mip filtering. No map re-export
|
||||
or owned texture modification is needed. GPU visual verification remains for
|
||||
the user; source and shader checks cannot confirm the preferred visual strength.
|
||||
|
||||
## Grime investigation after user retest
|
||||
|
||||
The UV-scale correction did not resolve the user's reported visual mismatch.
|
||||
|
||||
Reference in new issue
Block a user