Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
pinkponk committed Feb 15, 2023
2 parents fad31ec + 55780be commit ed5f79d
Show file tree
Hide file tree
Showing 8 changed files with 76 additions and 62 deletions.
2 changes: 1 addition & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,4 @@
"cwd": "${workspaceFolder}"
}
]
}
}
14 changes: 7 additions & 7 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,18 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
bevy = "0.8.0"
bevy = "0.9.1"
bytemuck = "1.11.0"
bevy_pbr = "0.8.0"
bevy_pbr = "0.9.1"
itertools = "*"
rand = "*"
# bevy_shader_utils = { path = "../bevy-examples/libs/bevy_shader_utils" }
wasm-bindgen = { version = "= 0.2.81" }
noise = "0.7" #Procedural Noise Generation library for Rust
iyes_loopless = "0.7.1"
iyes_progress = "0.5.0"
wasm-bindgen = { version = "0.2.84" }
noise = "0.8.2" #Procedural Noise Generation library for Rust
iyes_loopless = "0.9.1"
iyes_progress = "0.7.1"

bevy_asset_loader = { version = "0.12.0", features = [
bevy_asset_loader = { version = "0.14.1", features = [
"stageless",
] } #Needed to turn on a bunch of features in order to get assetloader to work with iyes_loopless+progress

Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ Rendering the grass with with the optimized grass renderer instead of the more g
I'm making a game for the web in which you have to code the behavior of forest animals in order to balance an ecosystem. Follow my devlogs if you are interested: https://www.youtube.com/channel/UCqzbiRaNXJa50J4kvJvKpAg

Compatible Bevy versions:
- Bevy 0.8
- Bevy 0.9 (main)
- Bevy 0.8 (branch bevy-0.8.1 or tag v0.1.0)

Forest:
Total instanced objects 192_000 (Not all visable at once, culling)
Expand Down
12 changes: 7 additions & 5 deletions assets/shaders/chunk_instancing.wgsl
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

#import bevy_pbr::mesh_types
#import bevy_pbr::mesh_view_bindings

Expand All @@ -7,7 +8,8 @@ var<uniform> mesh: Mesh;
// NOTE: Bindings must come before functions that use them!
#import bevy_pbr::mesh_functions

#import bevy_pbr::pbr_types
#import bevy_pbr::pbr_bindings

#import bevy_pbr::utils
#import bevy_pbr::clustered_forward
#import bevy_pbr::lighting
Expand Down Expand Up @@ -89,6 +91,7 @@ var diffuse_sampler: sampler;




struct FragmentInput {
@builtin(front_facing) is_front: bool,
@builtin(position) frag_coord: vec4<f32>,
Expand All @@ -113,13 +116,12 @@ fn fragment(in: FragmentInput) -> @location(0) vec4<f32> {

pbr_input.is_orthographic = view.projection[3].w == 1.0;

pbr_input.N = prepare_normal(
pbr_input.N = apply_normal_mapping(
pbr_input.material.flags,
in.world_normal,
pbr_input.world_normal,
in.uv,
in.is_front,
);
pbr_input.V = calculate_view(in.world_position, pbr_input.is_orthographic);

return tone_mapping(pbr(pbr_input));
return pbr(pbr_input);
}
9 changes: 7 additions & 2 deletions assets/shaders/grass.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -188,9 +188,14 @@ fn vertex(vertex: Vertex,
out.world_position.z = out.world_position.z*growth;

// "Hide" grass under map (This can be done better, probably by sampling 5x times and adjusting nr_instances based on texture sum over chunk)
// Randomaly hide some in order to get a smooth transition from grass to ground
if growth<0.5 && growth/0.5<rand(vec2<f32>(f32(vertex.instance_index), 18.956724*cos(f32(vertex.instance_index)*2.9515))){
out.world_position.z = out.world_position.z+(-10.0);
out.clip_position = mesh_position_world_to_clip(out.world_position);
// Hide under map:
// out.world_position.z = out.world_position.z+(-10.0);
// out.clip_position = mesh_position_world_to_clip(out.world_position);

// Remove from view: (no perforamance gain compared to hiding under map)
out.clip_position = vec4<f32>(-2.0,-2.0,-2.0,-2.0);
return out;
}

Expand Down
69 changes: 37 additions & 32 deletions examples/forest.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use bevy::{
asset::AssetServerSettings,
diagnostic::{FrameTimeDiagnosticsPlugin, LogDiagnosticsPlugin},
gltf::{Gltf, GltfMesh},
math::prelude::*,
Expand Down Expand Up @@ -39,7 +38,7 @@ pub enum GameState {
InGame,
}

#[derive(AssetCollection)]
#[derive(AssetCollection, Resource)]
pub struct MyGltfAssets {
#[asset(path = "mushroom.glb")]
mushroom: Handle<Gltf>,
Expand All @@ -51,7 +50,7 @@ pub struct MyGltfAssets {
rock: Handle<Gltf>,
}

#[derive(AssetCollection)]
#[derive(AssetCollection, Resource)]
pub struct MyImageAssets {
#[asset(path = "grass_ground_texture.png")]
grass: Handle<Image>,
Expand All @@ -74,30 +73,27 @@ fn main() {
.with_collection::<MyGltfAssets>()
.with_collection::<MyImageAssets>(),
)
.insert_resource(WindowDescriptor {
position: WindowPosition::At(vec2(1450., 550.0)),
width: 1000.0,
height: 1000.0,
present_mode: bevy::window::PresentMode::AutoNoVsync, //Dont cap at 60 fps
..default()
})
.add_plugins(
DefaultPlugins
.set(AssetPlugin {
watch_for_changes: true,
..default()
})
.set(WindowPlugin {
window: WindowDescriptor {
position: WindowPosition::At(vec2(1450., 550.0)),
width: 1000.0,
height: 1000.0,
present_mode: bevy::window::PresentMode::AutoNoVsync, //Dont cap at 60 fps
..default()
},
..default()
}),
)
.insert_resource(ClearColor(Color::rgb(0.7, 0.8, 0.8)))
.insert_resource(AssetServerSettings {
watch_for_changes: true,
..default()
})
.add_plugins(DefaultPlugins)
.add_plugin(OrbitCameraPlugin)
.add_plugin(LogDiagnosticsPlugin::default())
.add_plugin(FrameTimeDiagnosticsPlugin::default())
.insert_resource(GrowthTextures::default())
.insert_resource(GridConfig {
grid_center_xy: [0.0, 0.0],
grid_half_extents: [
NR_SIDE_CHUNKS as f32 * CHUNK_SIZE / 2.0,
NR_SIDE_CHUNKS as f32 * CHUNK_SIZE / 2.0,
],
})
.add_plugin(ChunkInstancingPlugin)
.add_plugin(ChunkGrassPlugin)
.add_enter_system(GameState::InGame, setup)
Expand All @@ -113,9 +109,18 @@ fn setup(
mut materials: ResMut<Assets<StandardMaterial>>,
mut images: ResMut<Assets<Image>>,
mut meshes: ResMut<Assets<Mesh>>,
grid_config: Res<GridConfig>,
mut grid_config: ResMut<GridConfig>,
mut growth_texture: ResMut<GrowthTextures>,
) {
//Set map size
*grid_config = GridConfig {
grid_center_xy: [0.0, 0.0],
grid_half_extents: [
NR_SIDE_CHUNKS as f32 * CHUNK_SIZE / 2.0,
NR_SIDE_CHUNKS as f32 * CHUNK_SIZE / 2.0,
],
};

//Growth Textures
*growth_texture = GrowthTextures::new(&mut images);

Expand All @@ -124,7 +129,7 @@ fn setup(
// color: Color::WHITE,
// brightness: 3.05,
// });
commands.spawn_bundle(DirectionalLightBundle {
commands.spawn(DirectionalLightBundle {
directional_light: DirectionalLight {
illuminance: 30000.0,
shadows_enabled: false, //Weird things happen
Expand Down Expand Up @@ -161,7 +166,7 @@ fn setup(

// Ground
commands
.spawn_bundle(PbrBundle {
.spawn(PbrBundle {
transform: Transform {
translation: (Vec3::new(0., 0., 0.)),
rotation: Quat::from_rotation_x(0.0_f32.to_radians()),
Expand Down Expand Up @@ -236,7 +241,7 @@ fn setup(
chunk_xy: [chunk_x, chunk_y],
};

commands.spawn_bundle(ChunkInstancingBundle {
commands.spawn(ChunkInstancingBundle {
transform: Transform::from_xyz(chunk_x_pos, chunk_y_pos, 0.0),
mesh_handle: mushroom_mesh_handle.clone(),
aabb: Aabb {
Expand All @@ -256,7 +261,7 @@ fn setup(
});
tot_instances += nr_instances / 5;

commands.spawn_bundle(ChunkInstancingBundle {
commands.spawn(ChunkInstancingBundle {
transform: Transform::from_xyz(chunk_x_pos, chunk_y_pos, 0.0),
mesh_handle: tree_mesh_handle.clone(),
aabb: Aabb {
Expand All @@ -276,7 +281,7 @@ fn setup(
});
tot_instances += nr_instances / 15;

commands.spawn_bundle(ChunkInstancingBundle {
commands.spawn(ChunkInstancingBundle {
transform: Transform::from_xyz(chunk_x_pos, chunk_y_pos, 0.0),
mesh_handle: bush_mesh_handle.clone(),
aabb: Aabb {
Expand All @@ -296,7 +301,7 @@ fn setup(
});
tot_instances += nr_instances / 6;

commands.spawn_bundle(ChunkInstancingBundle {
commands.spawn(ChunkInstancingBundle {
transform: Transform::from_xyz(chunk_x_pos, chunk_y_pos, 0.0),
mesh_handle: rock_mesh_handle.clone(),
aabb: Aabb {
Expand All @@ -316,7 +321,7 @@ fn setup(
});
tot_instances += nr_instances / 10;

commands.spawn_bundle(ChunkGrassBundle {
commands.spawn(ChunkGrassBundle {
transform: Transform::from_xyz(chunk_x_pos, chunk_y_pos, 0.0),
mesh_handle: meshes.add(get_grass_straw_mesh()),
aabb: Aabb {
Expand Down Expand Up @@ -352,7 +357,7 @@ fn setup(

// Camera
commands
.spawn_bundle(Camera3dBundle {
.spawn(Camera3dBundle {
..Default::default()
})
.insert(OrbitCamera {
Expand Down
24 changes: 13 additions & 11 deletions src/rendering/chunk_grass.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,7 @@ use bevy::{
};
use bytemuck::{Pod, Zeroable};

use noise::{NoiseFn, Perlin, Seedable};

use crate::camera::orbit::OrbitCamera;
use noise::{NoiseFn, Perlin};

use super::{Chunk, DistanceCulling};

Expand All @@ -55,7 +53,7 @@ pub struct ChunkGrassBundle {

fn update_time_for_custom_material(mut grass_chunks: Query<&mut ChunkGrass>, time: Res<Time>) {
for mut grass_chunk in grass_chunks.iter_mut() {
grass_chunk.time = time.seconds_since_startup() as f32;
grass_chunk.time = time.elapsed_seconds();
}
}

Expand Down Expand Up @@ -114,6 +112,8 @@ impl Plugin for ChunkGrassPlugin {
app.add_plugin(ExtractComponentPlugin::<ChunkGrass>::extract_visible());
app.add_plugin(ExtractResourcePlugin::<GrowthTextures>::default());
app.add_plugin(ExtractResourcePlugin::<GridConfig>::default());
app.insert_resource(GridConfig::default());
app.insert_resource(GrowthTextures::default());
app.add_system(update_time_for_custom_material);
app.add_system(grass_chunk_distance_culling);

Expand All @@ -130,7 +130,7 @@ impl Plugin for ChunkGrassPlugin {
}
}

#[derive(Clone, Component, Default)]
#[derive(Clone, Component, Default, Resource)]
pub struct GrowthTextures {
pub growth_texture_array_handle: Option<Handle<Image>>,
}
Expand All @@ -143,13 +143,14 @@ impl GrowthTextures {
let pattern_scale = 0.1;
let nr_textures = 2;
for i in 0..nr_textures {
let perlin = Perlin::new().set_seed(i + 1); // from -1 to 1
let perlin = Perlin::new(i + 1); // from -1 to 1

for y in 0..size {
for x in 0..size {
let noise =
perlin.get([x as f64 * pattern_scale, y as f64 * pattern_scale]) as f32;
let value = (noise + 1.0) / 2.0 * scale;
// value = (value - 100.0).max(0.0); //Truncate short grass to 0.0
data.push(value as u8)
}
}
Expand All @@ -172,7 +173,7 @@ impl GrowthTextures {
}
}

#[derive(Clone)]
#[derive(Clone, Default, Resource)]
pub struct GridConfig {
pub grid_center_xy: [f32; 2], //Assume axis aligned grid otherwise need to calc homogenous coordinate matrix
pub grid_half_extents: [f32; 2],
Expand Down Expand Up @@ -334,7 +335,7 @@ fn prepare_grass_chunk_bind_group(
}
}

#[derive(Default)]
#[derive(Default, Resource)]
pub struct GrowthTexturesBindGroup {
pub bind_group: Option<BindGroup>,
}
Expand Down Expand Up @@ -370,7 +371,7 @@ pub fn prepare_growth_textures_bind_group(
}
}

#[derive(Default)]
#[derive(Default, Resource)]
pub struct GridConfigBindGroup {
pub grid_config_bind_group: Option<BindGroup>,
}
Expand All @@ -397,7 +398,7 @@ fn prepare_grid_config_bind_group(
grid_config: Res<GridConfig>,
custom_pipeline: Res<CustomPipeline>,
) {
if !grid_config_bind_group_res.grid_config_bind_group.is_some() {
if grid_config.is_changed() {
let grid_config_buffer = render_device.create_buffer_with_data(&BufferInitDescriptor {
label: Some("grid_config_buffer"),
contents: bytemuck::cast_slice(&[grid_config.to_raw()]),
Expand Down Expand Up @@ -487,6 +488,7 @@ fn queue_custom_pipeline(
// █░░░░░░█████████░░░░░░░░░░█░░░░░░█████████░░░░░░░░░░░░░░█░░░░░░░░░░░░░░█░░░░░░░░░░█░░░░░░██████████░░░░░░█░░░░░░░░░░░░░░█
// █████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████

#[derive(Resource)]
pub struct CustomPipeline {
shader: Handle<Shader>,
mesh_pipeline: MeshPipeline,
Expand Down Expand Up @@ -562,7 +564,7 @@ impl FromWorld for CustomPipeline {
//grid END

let asset_server = world.resource::<AssetServer>();
asset_server.watch_for_changes().unwrap();
// asset_server.watch_for_changes().unwrap();
let shader = asset_server.load("shaders/grass.wgsl");

let mesh_pipeline = world.resource::<MeshPipeline>();
Expand Down
5 changes: 2 additions & 3 deletions src/rendering/chunk_instancing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ use bevy::{

use rand::Rng;

use crate::camera::orbit::OrbitCamera;

use super::{Chunk, DistanceCulling};

//Bundle
Expand Down Expand Up @@ -362,6 +360,7 @@ fn queue_custom(
// █░░░░░░█████████░░░░░░░░░░█░░░░░░█████████░░░░░░░░░░░░░░█░░░░░░░░░░░░░░█░░░░░░░░░░█░░░░░░██████████░░░░░░█░░░░░░░░░░░░░░█
// █████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████

#[derive(Resource)]
pub struct CustomPipeline {
shader: Handle<Shader>,
mesh_pipeline: MeshPipeline,
Expand Down Expand Up @@ -415,7 +414,7 @@ impl FromWorld for CustomPipeline {
});

let asset_server = world.resource::<AssetServer>();
asset_server.watch_for_changes().unwrap();
// asset_server.watch_for_changes().unwrap();
let shader = asset_server.load("shaders/chunk_instancing.wgsl");

let mesh_pipeline = world.resource::<MeshPipeline>();
Expand Down

0 comments on commit ed5f79d

Please sign in to comment.