first attempt at jovian ring with shader

This commit is contained in:
yuni 2024-04-01 02:05:38 +02:00
parent 83b44d4dbc
commit 2121642b92
3 changed files with 84 additions and 47 deletions

View file

@ -0,0 +1,33 @@
#import bevy_pbr::{
mesh_view_bindings::globals,
forward_io::VertexOutput,
}
@group(2) @binding(0) var<uniform> ring_radius: f32;
@group(2) @binding(1) var<uniform> jupiter_radius: f32;
@fragment
fn fragment(in: VertexOutput) -> @location(0) vec4<f32> {
let jupiter_percent = jupiter_radius / ring_radius;
let color = vec3<f32>(0.3, 0.3, 0.3);
var alpha = 0.01;
let r = distance(in.uv, vec2<f32>(0.5));
alpha *= (sin(11*r / 0.71 * 3.1415) + 1) / 2;
alpha *= (cos(r / 0.72 * 3.1415) + 1) / 2;
if in.uv[0] < 0.5 {
let dist = (0.5 - in.uv[0]) * 2.0; // 0.0=jupiter's center, 1.0=edge of the ring
let side_dist = abs(in.uv[1] - 0.5);
let cutoff = 0.5 * jupiter_percent * cos(dist);
if side_dist < cutoff {
return vec4<f32>(color, 0.0);
}
let fuzzy_boundary = 0.01;
if side_dist < cutoff + fuzzy_boundary {
return vec4<f32>(color, alpha * (side_dist - cutoff) / fuzzy_boundary);
}
}
return vec4<f32>(color, alpha);
}

View file

@ -1,22 +0,0 @@
#import bevy_pbr::{
mesh_view_bindings::globals,
forward_io::VertexOutput,
}
@fragment
fn fragment(in: VertexOutput) -> @location(0) vec4<f32> {
let speed = 3.0;
let t_1 = sin(globals.time * speed) * 0.5 + 0.5;
let t_2 = cos(globals.time * speed);
let distance_to_center = distance(in.uv, vec2<f32>(0.5)) * 1.4;
let red = vec3<f32>(0.627955, 0.224863, 0.125846);
let green = vec3<f32>(0.86644, -0.233887, 0.179498);
let blue = vec3<f32>(0.701674, 0.274566, -0.169156);
let white = vec3<f32>(1.0, 0.0, 0.0);
let pos = vec3<f32>(in.position[0], in.position[1], in.position[2]);
let mixed = mix(pos, mix(green, white, t_2), distance_to_center);
return vec4<f32>(mixed, 1.0);
}

View file

@ -40,18 +40,27 @@ impl Plugin for WorldPlugin {
//app.add_systems(Update, asset_loaded.after(load_cubemap_asset));
//app.add_systems(Update, swap_world_on_ar_toggle);
app.add_plugins(PhysicsPlugins::default());
app.add_plugins(MaterialPlugin::<CustomMaterial>::default());
app.add_plugins(MaterialPlugin::<RingMaterial>::default());
//app.add_plugins(PhysicsDebugPlugin::default());
app.insert_resource(Gravity(Vec3::splat(0.0)));
}
}
#[derive(Asset, TypePath, AsBindGroup, Debug, Clone)]
pub struct CustomMaterial {}
pub struct RingMaterial {
alpha_mode: AlphaMode,
#[uniform(0)]
ring_radius: f32,
#[uniform(1)]
jupiter_radius: f32,
}
impl Material for CustomMaterial {
impl Material for RingMaterial {
fn fragment_shader() -> ShaderRef {
"shaders/testshader.wgsl".into()
"shaders/jupiters_rings.wgsl".into()
}
fn alpha_mode(&self) -> AlphaMode {
self.alpha_mode
}
}
@ -79,7 +88,7 @@ pub fn setup(
mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>,
mut materials_custom: ResMut<Assets<CustomMaterial>>,
mut materials_custom: ResMut<Assets<RingMaterial>>,
asset_server: Res<AssetServer>,
) {
// let cubemap_handle = asset_server.load(ASSET_CUBEMAP);
@ -175,26 +184,43 @@ pub fn setup(
info!("Generated {starcount} stars");
// Add shaded ring
let max = 20;
for i in 0..max {
let f = i as f32;
let maxf = max as f32;
let ringmesh = Mesh::from(Cylinder::new(400000.0 + f * 10000.0, 5000.0 - 150.0 * f));
let clr = 0.4 + (f/maxf).clamp(0.0,0.6);
commands.spawn(MaterialMeshBundle {
mesh: meshes.add(ringmesh),
transform: Transform::from_xyz(300000.0, 0.0, 500000.0),
//material: materials_custom.add(CustomMaterial {}),
material: materials.add(StandardMaterial {
base_color: Color::rgba(clr, clr, clr, 0.0001),
unlit: true,
cull_mode: None,
alpha_mode: AlphaMode::Blend,
..default()
}),
..default()
});
}
let ring_radius = 900000.0;
let jupiter_radius = 200000.0;
commands.spawn(MaterialMeshBundle {
mesh: meshes.add(Mesh::from(Cylinder::new(ring_radius, 1.0))),
transform: Transform::from_xyz(300000.0, -4000.0, 500000.0)
.with_rotation(Quat::from_rotation_z(PI*0.05))
,
//transform: Transform::from_xyz(300000.0, 0.0, 500000.0)),
material: materials_custom.add(RingMaterial {
alpha_mode: AlphaMode::Blend,
ring_radius: ring_radius,
jupiter_radius: jupiter_radius,
}),
..default()
});
//let max = 20;
//for i in 0..max {
// let f = i as f32;
// let maxf = max as f32;
// let ringmesh = Mesh::from(Cylinder::new(400000.0 + f * 10000.0, 5000.0 - 150.0 * f));
// let clr = 0.4 + (f/maxf).clamp(0.0,0.6);
// commands.spawn(MaterialMeshBundle {
// mesh: meshes.add(ringmesh),
// transform: Transform::from_xyz(300000.0, 0.0, 500000.0),
// material: materials_custom.add(RingMaterial {
// alpha_mode: AlphaMode::Blend,
// }),
// material: materials.add(StandardMaterial {
// base_color: Color::rgba(clr, clr, clr, 0.0001),
// unlit: true,
// cull_mode: None,
// alpha_mode: AlphaMode::Blend,
// ..default()
// }),
// ..default()
// });
//}
// Add Light from the Sun
commands.spawn(DirectionalLightBundle {