diff --git a/assets/shaders/skybox.wgsl b/assets/shaders/skybox.wgsl new file mode 100644 index 0000000..63946f7 --- /dev/null +++ b/assets/shaders/skybox.wgsl @@ -0,0 +1,11 @@ +#import bevy_pbr::{ + mesh_view_bindings::globals, + forward_io::VertexOutput, +} + +@fragment +fn fragment(in: VertexOutput) -> @location(0) vec4 { + let pos: vec2 = 10 * floor(3500 * in.uv); + let brightness: vec3 = vec3(max((fract(dot(sin(pos),pos)) - 0.995) * 90.0, 0.0)); + return vec4(0.01 * brightness, 1.0); +} diff --git a/src/shading.rs b/src/shading.rs index 3de398a..71dfa8f 100644 --- a/src/shading.rs +++ b/src/shading.rs @@ -6,10 +6,12 @@ pub struct ShadingPlugin; impl Plugin for ShadingPlugin { fn build(&self, app: &mut App) { app.add_plugins(MaterialPlugin::::default()); + app.add_plugins(MaterialPlugin::::default()); app.add_plugins(MaterialPlugin::>::default()); } } +// Jupiter's Ring #[derive(Asset, TypePath, AsBindGroup, Debug, Clone)] pub struct JupitersRing { pub alpha_mode: AlphaMode, @@ -28,7 +30,16 @@ impl Material for JupitersRing { } } +// Sky Box +#[derive(Asset, TypePath, AsBindGroup, Debug, Clone)] +pub struct SkyBox {} +impl Material for SkyBox { + fn fragment_shader() -> ShaderRef { + "shaders/skybox.wgsl".into() + } +} +// Asteroid Surface #[derive(Asset, Reflect, AsBindGroup, Debug, Clone)] pub struct AsteroidSurface { #[uniform(100)] diff --git a/src/world.rs b/src/world.rs index cec5bce..8052baf 100644 --- a/src/world.rs +++ b/src/world.rs @@ -2,6 +2,7 @@ use crate::{actor, audio, hud, nature, shading, var}; use bevy::prelude::*; use bevy::math::{DVec3, I64Vec3}; use bevy::scene::{InstanceId, SceneInstance}; +use bevy::render::mesh::Indices; use bevy_xpbd_3d::prelude::*; use bevy_xpbd_3d::plugins::sync; use std::collections::HashMap; @@ -102,7 +103,8 @@ pub fn setup( mut commands: Commands, mut meshes: ResMut>, mut materials: ResMut>, - mut materials_custom: ResMut>, + mut materials_jupiter: ResMut>, + mut materials_skybox: ResMut>, asset_server: Res, ) { // Load assets @@ -179,13 +181,34 @@ pub fn setup( } info!("Generated {starcount} stars"); + // Add shaded skybox + //let mut mesh = Mesh::from(Sphere::new(1e9).mesh().uv(50, 50)); + let mut mesh = Mesh::from(Sphere::new(1e10).mesh().uv(5, 5)); + //let mut mesh = Mesh::from(Cuboid::from_size(Vec3::splat(2e10))); + if let Some(Indices::U32(indices)) = mesh.indices_mut() { + // Reverse the order of each triangle to avoid backface culling + for slice in indices.chunks_mut(3) { + slice.reverse(); + } + } + commands.spawn(( + MaterialMeshBundle { + mesh: meshes.add(mesh), + material: materials_skybox.add(shading::SkyBox {}), + transform: Transform::from_translation(Vec3::new(0.0, 0.0, 0.0)), + ..default() + }, + Position::from_xyz(0.0, 0.0, 0.0), + Rotation::from(Quat::IDENTITY), + )); + // Add shaded ring let ring_radius = 229_000_000.0; let jupiter_radius = 71_492_000.0; commands.spawn(( MaterialMeshBundle { mesh: meshes.add(Mesh::from(Cylinder::new(ring_radius, 1.0))), - material: materials_custom.add(shading::JupitersRing { + material: materials_jupiter.add(shading::JupitersRing { alpha_mode: AlphaMode::Blend, ring_radius: ring_radius, jupiter_radius: jupiter_radius,