MONKEY (sky): SKY_FX / SKY_FX_CLOUDS pipeline keys so Classic compiles the reference shader unchanged
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
91ac4d1481
commit
b11c1cfbbf
@@ -29,6 +29,7 @@ pub type CloudMaterial = ExtendedMaterial<StandardMaterial, CloudExt>;
|
||||
/// The colored cloud texture. The color math is CPU-side as in the reference, so the texels are
|
||||
/// raw gamma bytes in a non-sRGB texture.
|
||||
#[derive(Asset, AsBindGroup, Clone, TypePath)]
|
||||
#[bind_group_data(CloudFxKey)]
|
||||
pub struct CloudExt {
|
||||
/// The colored tile, alpha the coverage, re-uploaded each regen (`0x58ac70`).
|
||||
#[texture(100)]
|
||||
@@ -43,6 +44,19 @@ pub struct CloudExt {
|
||||
pub(crate) lit: Vec4,
|
||||
}
|
||||
|
||||
/// MONKEY (sky): the pipeline key: High compiles `SKY_FX_CLOUDS` into `cloud.wgsl`; below High
|
||||
/// the reference's code runs with nothing added.
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub struct CloudFxKey {
|
||||
high: bool,
|
||||
}
|
||||
|
||||
impl From<&CloudExt> for CloudFxKey {
|
||||
fn from(e: &CloudExt) -> Self {
|
||||
Self { high: e.fx.x >= 1.5 }
|
||||
}
|
||||
}
|
||||
|
||||
impl MaterialExtension for CloudExt {
|
||||
/// The shared sky vertex stage, which pins every sky vertex to the far depth.
|
||||
fn vertex_shader() -> ShaderRef {
|
||||
@@ -57,8 +71,14 @@ impl MaterialExtension for CloudExt {
|
||||
_pipeline: &MaterialExtensionPipeline,
|
||||
descriptor: &mut RenderPipelineDescriptor,
|
||||
_layout: &MeshVertexBufferLayoutRef,
|
||||
_key: MaterialExtensionKey<Self>,
|
||||
key: MaterialExtensionKey<Self>,
|
||||
) -> Result<(), SpecializedMeshPipelineError> {
|
||||
// MONKEY (sky): the High cloud branch.
|
||||
if key.bind_group_data.high {
|
||||
if let Some(fragment) = descriptor.fragment.as_mut() {
|
||||
fragment.shader_defs.push("SKY_FX_CLOUDS".into());
|
||||
}
|
||||
}
|
||||
sky_pipeline_state(descriptor);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -7,7 +7,9 @@
|
||||
// Ported from WarcraftXL (https://github.com/WarcraftXL) by iThorgrim — module wxl-retail-clouds, Clouds.cpp.
|
||||
|
||||
#import bevy_pbr::forward_io::VertexOutput
|
||||
#ifdef SKY_FX_CLOUDS
|
||||
#import benilla_world::sky_fx
|
||||
#endif
|
||||
|
||||
@group(#{MATERIAL_BIND_GROUP}) @binding(100) var cloud_tex: texture_2d<f32>;
|
||||
@group(#{MATERIAL_BIND_GROUP}) @binding(101) var cloud_samp: sampler;
|
||||
@@ -21,6 +23,7 @@ struct CloudFx {
|
||||
};
|
||||
@group(#{MATERIAL_BIND_GROUP}) @binding(102) var<uniform> cfx: CloudFx;
|
||||
|
||||
#ifdef SKY_FX_CLOUDS
|
||||
// MONKEY (sky): coverage with detail at a sheet point; `oct` detail octaves.
|
||||
fn detailed_cover(uv: vec2<f32>, oct: i32) -> f32 {
|
||||
let a = textureSampleLevel(cloud_tex, cloud_samp, uv, 0.0).a;
|
||||
@@ -29,13 +32,16 @@ fn detailed_cover(uv: vec2<f32>, oct: i32) -> f32 {
|
||||
}
|
||||
return sky_fx::cloud_erode(a, sky_fx::cloud_detail(uv, cfx.fx.y, oct));
|
||||
}
|
||||
#endif
|
||||
|
||||
@fragment
|
||||
fn fragment(in: VertexOutput) -> @location(0) vec4<f32> {
|
||||
let texel = textureSample(cloud_tex, cloud_samp, in.uv);
|
||||
var a = texel.a;
|
||||
var rgb = texel.rgb;
|
||||
// MONKEY (sky): High only; Classic and Enhanced keep the kernel's texels as they are.
|
||||
// MONKEY (sky): High only (the `SKY_FX_CLOUDS` pipeline); Classic and Enhanced keep the
|
||||
// kernel's texels as they are.
|
||||
#ifdef SKY_FX_CLOUDS
|
||||
if (cfx.fx.x >= 1.5) {
|
||||
let n = sky_fx::cloud_detail(in.uv, cfx.fx.y, 4);
|
||||
a = sky_fx::cloud_erode(a, n);
|
||||
@@ -44,19 +50,20 @@ fn fragment(in: VertexOutput) -> @location(0) vec4<f32> {
|
||||
let strength = cfx.lit.w;
|
||||
if (a > 0.003 && strength > 0.0) {
|
||||
let sd = cfx.fx.zw;
|
||||
let step = 0.011;
|
||||
var occl = detailed_cover(in.uv + sd * step, 2);
|
||||
occl += detailed_cover(in.uv + sd * step * 2.0, 2) * 0.75;
|
||||
occl += detailed_cover(in.uv + sd * step * 3.5, 2) * 0.5;
|
||||
let stp = 0.011;
|
||||
var occl = detailed_cover(in.uv + sd * stp, 2);
|
||||
occl += detailed_cover(in.uv + sd * stp * 2.0, 2) * 0.75;
|
||||
occl += detailed_cover(in.uv + sd * stp * 3.5, 2) * 0.5;
|
||||
let transmit = exp(-occl * 1.44 * strength);
|
||||
// WarcraftXL's ambient floor 0.55, softened toward the painted texel.
|
||||
let light = 0.62 + 0.38 * transmit;
|
||||
let ahead = detailed_cover(in.uv + sd * step * 1.5, 2);
|
||||
let ahead = detailed_cover(in.uv + sd * stp * 1.5, 2);
|
||||
let rim = max(ahead - a, 0.0) * (1.0 - a) * transmit * strength;
|
||||
rgb = rgb * mix(1.0, light, strength) + cfx.lit.rgb * rim * 0.9;
|
||||
rgb = min(rgb, vec3<f32>(1.0));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef VERTEX_COLORS
|
||||
a *= in.color.a; // the dome's rim fade (ring alphas)
|
||||
#endif
|
||||
|
||||
@@ -5,8 +5,11 @@
|
||||
forward_io::VertexOutput,
|
||||
mesh_view_bindings::view,
|
||||
}
|
||||
// MONKEY (sky): the Enhanced/High library (smooth gradient, sun glow, night sky).
|
||||
// MONKEY (sky): the Enhanced/High library (smooth gradient, sun glow, night sky), compiled only
|
||||
// into the `SKY_FX` pipeline so Classic keeps the reference's exact code.
|
||||
#ifdef SKY_FX
|
||||
#import benilla_world::sky_fx
|
||||
#endif
|
||||
|
||||
struct SkyColors {
|
||||
sky0: vec4<f32>, // zenith (90°)
|
||||
@@ -77,6 +80,7 @@ fn fragment(in: VertexOutput) -> @location(0) vec4<f32> {
|
||||
|
||||
// MONKEY (sky): Enhanced/High. The same stops through a monotone cubic in linear light, then
|
||||
// the sun glow and the night sky added in linear light, back to gamma, dithered.
|
||||
#ifdef SKY_FX
|
||||
if (sky.fx.x >= 0.5) {
|
||||
let stops = array<vec3<f32>, 6>(
|
||||
sky_fx::srgb_to_linear(sky.fog.rgb),
|
||||
@@ -109,6 +113,7 @@ fn fragment(in: VertexOutput) -> @location(0) vec4<f32> {
|
||||
let out = sky_fx::linear_to_srgb(lin) + vec3<f32>(sky_fx::dither_tri(in.position.xy));
|
||||
return vec4<f32>(clamp(out, vec3<f32>(0.0), vec3<f32>(1.0)), 1.0);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Elevation gradient, linear between rings like the reference's Gouraud-shaded dome.
|
||||
var col: vec3<f32>;
|
||||
|
||||
@@ -183,7 +183,7 @@ fn star_field(dir: vec3<f32>, t: f32, px: f32, band: f32) -> vec3<f32> {
|
||||
let base = floor(p);
|
||||
let f = p - base;
|
||||
let o = select(vec3<f32>(-1.0), vec3<f32>(1.0), f > vec3<f32>(0.5));
|
||||
let density = 0.035 * (1.0 + 2.5 * band);
|
||||
let density = 0.022 * (1.0 + 2.5 * band);
|
||||
var acc = vec3<f32>(0.0);
|
||||
for (var i = 0u; i < 8u; i++) {
|
||||
let off = vec3<f32>(f32(i & 1u), f32((i >> 1u) & 1u), f32((i >> 2u) & 1u)) * o;
|
||||
|
||||
@@ -32,6 +32,7 @@ pub type SkyMaterial = ExtendedMaterial<StandardMaterial, SkyExt>;
|
||||
/// The five sky stops, zenith to horizon, and the fog colour on one binding (100); `sky.wgsl`'s
|
||||
/// struct must match this field order.
|
||||
#[derive(Asset, AsBindGroup, Clone, TypePath)]
|
||||
#[bind_group_data(SkyFxKey)]
|
||||
pub struct SkyExt {
|
||||
/// `SkyColor0`: zenith (90°).
|
||||
#[uniform(100)]
|
||||
@@ -67,6 +68,19 @@ pub struct SkyExt {
|
||||
pub(crate) glow: Vec4,
|
||||
}
|
||||
|
||||
/// MONKEY (sky): the pipeline key: Enhanced/High compile `SKY_FX` into `sky.wgsl`; Classic keeps
|
||||
/// the reference's code with nothing added.
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub struct SkyFxKey {
|
||||
fx: bool,
|
||||
}
|
||||
|
||||
impl From<&SkyExt> for SkyFxKey {
|
||||
fn from(e: &SkyExt) -> Self {
|
||||
Self { fx: e.fx.x >= 0.5 }
|
||||
}
|
||||
}
|
||||
|
||||
impl MaterialExtension for SkyExt {
|
||||
/// The shared sky vertex stage, which pins depth to the far plane ([`crate::sky_order`]).
|
||||
fn vertex_shader() -> ShaderRef {
|
||||
@@ -83,8 +97,14 @@ impl MaterialExtension for SkyExt {
|
||||
_pipeline: &MaterialExtensionPipeline,
|
||||
descriptor: &mut RenderPipelineDescriptor,
|
||||
_layout: &MeshVertexBufferLayoutRef,
|
||||
_key: MaterialExtensionKey<Self>,
|
||||
key: MaterialExtensionKey<Self>,
|
||||
) -> Result<(), SpecializedMeshPipelineError> {
|
||||
// MONKEY (sky): the Enhanced/High branch.
|
||||
if key.bind_group_data.fx {
|
||||
if let Some(fragment) = descriptor.fragment.as_mut() {
|
||||
fragment.shader_defs.push("SKY_FX".into());
|
||||
}
|
||||
}
|
||||
if let Some(depth) = descriptor.depth_stencil.as_mut() {
|
||||
depth.depth_write_enabled = false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user