diff --git a/assets/shaders/terrain/calc_normals.wgsl b/assets/shaders/heightmap/calc_normals.wgsl similarity index 100% rename from assets/shaders/terrain/calc_normals.wgsl rename to assets/shaders/heightmap/calc_normals.wgsl diff --git a/assets/shaders/terrain/terrain.frag.wgsl b/assets/shaders/heightmap/heightmap.frag.wgsl similarity index 100% rename from assets/shaders/terrain/terrain.frag.wgsl rename to assets/shaders/heightmap/heightmap.frag.wgsl diff --git a/assets/shaders/terrain/terrain.vert.wgsl b/assets/shaders/heightmap/heightmap.vert.wgsl similarity index 100% rename from assets/shaders/terrain/terrain.vert.wgsl rename to assets/shaders/heightmap/heightmap.vert.wgsl diff --git a/assets/shaders/terrain/resample.wgsl b/assets/shaders/heightmap/resample.wgsl similarity index 100% rename from assets/shaders/terrain/resample.wgsl rename to assets/shaders/heightmap/resample.wgsl diff --git a/assets/shaders/terrain/unpack.wgsl b/assets/shaders/heightmap/unpack.wgsl similarity index 100% rename from assets/shaders/terrain/unpack.wgsl rename to assets/shaders/heightmap/unpack.wgsl diff --git a/engine/src/drawables/terrain.rs b/engine/src/drawables/heightmap.rs similarity index 86% rename from engine/src/drawables/terrain.rs rename to engine/src/drawables/heightmap.rs index 4f131d92..4ffb06c3 100644 --- a/engine/src/drawables/terrain.rs +++ b/engine/src/drawables/heightmap.rs @@ -18,16 +18,12 @@ const LOD: usize = 5; const LOD_MIN_DIST_LOG2: f32 = 9.0; // 2^9 = 512, meaning until 1048m away, we use the highest lod const MAX_HEIGHT: f32 = 2008.0; const MIN_HEIGHT: f32 = -40.0; -const UPSCALE_LOD: usize = 2; // amount of LOD that are superior to base terrain data - -pub struct TerrainChunk { - pub dirt_id: u32, -} +const UPSCALE_LOD: usize = 2; // amount of LOD that are superior to base heightmap data /// CSIZE is the size of a chunk in meters /// CRESOLUTION is the resolution of a chunk, in vertices, at the chunk data level (not LOD0 since we upsample) -pub struct TerrainRender { - terrain_tex: Arc, +pub struct HeightmapRender { + heightmap_tex: Arc, normal_tex: Arc, indices: [(PBuffer, u32); LOD], @@ -42,19 +38,19 @@ pub struct TerrainRender { upsample_pipeline: RenderPipeline, } -pub struct TerrainPrepared { - terrainbgs: Arc<[wgpu::BindGroup; LOD]>, +pub struct HeightmapPrepared { + heightmapbgs: Arc<[wgpu::BindGroup; LOD]>, indices: [(PBuffer, u32); LOD], instances: [(PBuffer, u32); LOD], } -impl TerrainRender { +impl HeightmapRender { const LOD0_RESOLUTION: usize = CRESOLUTION * (1 << UPSCALE_LOD); pub fn new(gfx: &mut GfxContext, w: u32, h: u32) -> Self { debug_assert!( Self::LOD0_RESOLUTION >= 1 << LOD, - "LOD0 TERRAIN RESOLUTION must be >= {}", + "LOD0 HEIGHTMAP RESOLUTION must be >= {}", 1 << LOD ); @@ -63,7 +59,7 @@ impl TerrainRender TerrainRender TerrainRender TerrainRender TerrainRender TerrainRender TerrainRender TerrainRender) { - profiling::scope!("terrain::draw_terrain"); + pub fn draw_heightmap(&mut self, cam: &Camera, fctx: &mut FrameContext<'_>) { + profiling::scope!("heightmap::draw_heightmap"); let eye = cam.eye(); - let mut instances = vec![Vec::::new(); LOD]; + let mut instances = vec![Vec::::new(); LOD]; // We calculate lod in 2 passes to be able to generate the stitches // special: lod 0 = dont render, stored as 1 + lod @@ -255,7 +251,7 @@ impl TerrainRender lod); let stitch_down = (y != 0) && (assigned_lod[idx - w] > lod); - instances[lod as usize - 1].push(TerrainInstance { + instances[lod as usize - 1].push(HeightmapInstance { offset: vec2(x as f32, y as f32) * CSIZE as f32, stitch_dir_flags: (stitch_right as u32) | (stitch_up as u32) << 1 @@ -272,8 +268,8 @@ impl TerrainRender TerrainRender TerrainRender TerrainRender TerrainRender TerrainRender RenderPipeline { - let normal_module = gfx.get_module("terrain/calc_normals"); + let normal_module = gfx.get_module("heightmap/calc_normals"); gfx.device .create_render_pipeline(&RenderPipelineDescriptor { - label: Some("terrain normals pipeline"), + label: Some("heightmap normals pipeline"), layout: Some( &gfx.device .create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { - label: Some("terrain normals pipeline layout"), + label: Some("heightmap normals pipeline layout"), bind_group_layouts: &[ &gfx.device .create_bind_group_layout(&BindGroupLayoutDescriptor { @@ -450,7 +446,7 @@ fn normal_update( }); let mut rp = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { - label: Some("terrain normals render pass"), + label: Some("heightmap normals render pass"), color_attachments: &[Some(wgpu::RenderPassColorAttachment { view: normal_view, resolve_target: None, @@ -471,11 +467,11 @@ fn normal_update( } fn resample_pipeline(gfx: &GfxContext, height_tex: &Texture, entry_point: &str) -> RenderPipeline { - let resample_module = gfx.get_module("terrain/resample"); + let resample_module = gfx.get_module("heightmap/resample"); gfx.device .create_render_pipeline(&RenderPipelineDescriptor { - label: Some("terrain downsample pipeline"), + label: Some("heightmap downsample pipeline"), layout: None, vertex: wgpu::VertexState { module: &resample_module, @@ -502,7 +498,7 @@ fn resample_pipeline(gfx: &GfxContext, height_tex: &Texture, entry_point: &str) }) } -/// Downsamples the terrain 1 mip up, the mip argument should be the base level +/// Downsamples the heightmap 1 mip up, the mip argument should be the base level fn downsample_update( gfx: &GfxContext, downsample_pipeline: &RenderPipeline, @@ -521,7 +517,7 @@ fn downsample_update( let render_view = height_tex.mip_view(mip + 1); let mut rp = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { - label: Some("terrain downsample render pass"), + label: Some("heightmap downsample render pass"), color_attachments: &[Some(wgpu::RenderPassColorAttachment { view: &render_view, resolve_target: None, @@ -540,7 +536,7 @@ fn downsample_update( drop(rp); } -/// Downsamples the terrain 1 mip down, the mip argument should be the base level +/// Downsamples the heightmap 1 mip down, the mip argument should be the base level fn upsample_update( gfx: &GfxContext, upsample_pipeline: &RenderPipeline, @@ -559,7 +555,7 @@ fn upsample_update( let render_view = height_tex.mip_view(mip - 1); let mut rp = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { - label: Some("terrain upsample render pass"), + label: Some("heightmap upsample render pass"), color_attachments: &[Some(wgpu::RenderPassColorAttachment { view: &render_view, resolve_target: None, @@ -579,22 +575,22 @@ fn upsample_update( } #[derive(Hash)] -struct TerrainPipeline { +struct HeightmapPipeline { depth: bool, smap: bool, } #[derive(Copy, Clone)] #[repr(C)] -pub(crate) struct TerrainInstance { +pub(crate) struct HeightmapInstance { pub offset: Vec2, pub stitch_dir_flags: u32, // 4 lowest bits are 1 if we need to stitch in that direction. 0 = x+, 1 = y+, 2 = x-, 3 = y- } -u8slice_impl!(TerrainInstance); +u8slice_impl!(HeightmapInstance); #[derive(Copy, Clone)] #[repr(C)] -pub struct TerrainChunkData { +pub struct HeightmapChunkData { lod: u32, // 0 = highest resolution, 1 = half resolution, etc.* lod_pow2: u32, // 2^lod resolution: u32, // width of the vertex grid @@ -602,11 +598,11 @@ pub struct TerrainChunkData { cell_size: f32, inv_cell_size: f32, } -u8slice_impl!(TerrainChunkData); +u8slice_impl!(HeightmapChunkData); const ATTRS: &[VertexAttribute] = &wgpu::vertex_attr_array![0 => Float32x2, 1 => Uint32]; -impl TerrainInstance { +impl HeightmapInstance { fn desc() -> VertexBufferLayout<'static> { VertexBufferLayout { array_stride: std::mem::size_of::() as wgpu::BufferAddress, @@ -616,13 +612,13 @@ impl TerrainInstance { } } -impl PipelineKey for TerrainPipeline { +impl PipelineKey for HeightmapPipeline { fn build( &self, gfx: &GfxContext, mut mk_module: impl FnMut(&str, &[&str]) -> CompiledModule, ) -> RenderPipeline { - let terrainlayout = gfx + let heightmaplayout = gfx .device .create_bind_group_layout(&BindGroupLayoutDescriptor { entries: &Texture::bindgroup_layout_entries( @@ -630,24 +626,24 @@ impl PipelineKey for TerrainPipeline { [TL::UInt, TL::UInt, TL::Float, TL::Float].into_iter(), ) .chain(std::iter::once( - Uniform::::bindgroup_layout_entry(8), + Uniform::::bindgroup_layout_entry(8), )) .collect::>(), - label: Some("terrain bindgroup layout"), + label: Some("heightmap bindgroup layout"), }); - let vert = &mk_module("terrain/terrain.vert", &[]); + let vert = &mk_module("heightmap/heightmap.vert", &[]); if !self.depth { - let frag = &mk_module("terrain/terrain.frag", &[]); + let frag = &mk_module("heightmap/heightmap.frag", &[]); return PipelineBuilder::color( - "terrain", + "heightmap", &[ &gfx.render_params.layout, - &terrainlayout, + &heightmaplayout, &bg_layout_litmesh(&gfx.device), ], - &[TerrainInstance::desc()], + &[HeightmapInstance::desc()], vert, frag, gfx.sc_desc.format, @@ -657,18 +653,18 @@ impl PipelineKey for TerrainPipeline { } gfx.depth_pipeline_bglayout( - &[TerrainInstance::desc()], + &[HeightmapInstance::desc()], vert, None, self.smap, - &[&gfx.render_params.layout, &terrainlayout], + &[&gfx.render_params.layout, &heightmaplayout], ) } } -impl Drawable for TerrainPrepared { +impl Drawable for HeightmapPrepared { fn draw<'a>(&'a self, gfx: &'a GfxContext, rp: &mut RenderPass<'a>) { - let pipeline = gfx.get_pipeline(TerrainPipeline { + let pipeline = gfx.get_pipeline(HeightmapPipeline { depth: false, smap: false, }); @@ -684,7 +680,7 @@ impl Drawable for TerrainPrepared { let (_, n_indices) = &self.indices[lod]; gfx.perf - .terrain_drawcall(*n_indices as usize / 3 * *n_instances as usize) + .heightmap_drawcall(*n_indices as usize / 3 * *n_instances as usize) } } @@ -695,11 +691,11 @@ impl Drawable for TerrainPrepared { shadow_cascade: Option<&Matrix4>, ) { if shadow_cascade.is_some() { - // Terrain don't cast shadows for now as they are hard to do properly + // Heightmap don't cast shadows for now as they are hard to do properly // It needs separate frustrum culling + actual good shadow acne fix return; } - rp.set_pipeline(gfx.get_pipeline(TerrainPipeline { + rp.set_pipeline(gfx.get_pipeline(HeightmapPipeline { depth: true, smap: shadow_cascade.is_some(), })); @@ -710,7 +706,7 @@ impl Drawable for TerrainPrepared { let (_, n_instances) = &self.instances[lod]; let (_, n_indices) = &self.indices[lod]; - gfx.perf.terrain_depth_drawcall( + gfx.perf.heightmap_depth_drawcall( *n_indices as usize / 3 * *n_instances as usize, shadow_cascade.is_some(), ); @@ -718,7 +714,7 @@ impl Drawable for TerrainPrepared { } } -impl TerrainPrepared { +impl HeightmapPrepared { fn set_buffers<'a>(&'a self, rp: &mut RenderPass<'a>) { for lod in 0..LOD { let (instances, n_instances) = &self.instances[lod]; @@ -728,7 +724,7 @@ impl TerrainPrepared { let (ind, n_indices) = &self.indices[lod]; - rp.set_bind_group(1, &self.terrainbgs[lod], &[]); + rp.set_bind_group(1, &self.heightmapbgs[lod], &[]); rp.set_vertex_buffer(0, instances.slice().unwrap()); rp.set_index_buffer(ind.slice().unwrap(), IndexFormat::Uint32); rp.draw_indexed(0..*n_indices, 0, 0..*n_instances); diff --git a/engine/src/drawables/mod.rs b/engine/src/drawables/mod.rs index 06d5451c..073f79f2 100644 --- a/engine/src/drawables/mod.rs +++ b/engine/src/drawables/mod.rs @@ -5,7 +5,7 @@ mod instanced_mesh; mod lit_mesh; mod multispritebatch; mod spritebatch; -pub mod terrain; +pub mod heightmap; mod water; pub use instanced_mesh::*; diff --git a/engine/src/perf_counters.rs b/engine/src/perf_counters.rs index 97a03bbd..397f79a3 100644 --- a/engine/src/perf_counters.rs +++ b/engine/src/perf_counters.rs @@ -11,9 +11,9 @@ pub struct PerfCounters { shadows_triangles: AtomicUsize, shadows_drawcalls: AtomicUsize, - terrain_triangles: AtomicUsize, - terrain_depth_triangles: AtomicUsize, - terrain_shadows_triangles: AtomicUsize, + heightmap_triangles: AtomicUsize, + heightmap_depth_triangles: AtomicUsize, + heightmap_shadows_triangles: AtomicUsize, } pub struct PerfCountersStatic { @@ -26,9 +26,9 @@ pub struct PerfCountersStatic { pub shadows_triangles: usize, pub shadows_drawcalls: usize, - pub terrain_triangles: usize, - pub terrain_depth_triangles: usize, - pub terrain_shadows_triangles: usize, + pub heightmap_triangles: usize, + pub heightmap_depth_triangles: usize, + pub heightmap_shadows_triangles: usize, } impl PerfCounters { @@ -44,9 +44,9 @@ impl PerfCounters { depth_drawcalls: *self.depth_drawcalls.get_mut(), shadows_triangles: *self.shadows_triangles.get_mut(), shadows_drawcalls: *self.shadows_drawcalls.get_mut(), - terrain_triangles: *self.terrain_triangles.get_mut(), - terrain_depth_triangles: *self.terrain_depth_triangles.get_mut(), - terrain_shadows_triangles: *self.terrain_shadows_triangles.get_mut(), + heightmap_triangles: *self.heightmap_triangles.get_mut(), + heightmap_depth_triangles: *self.heightmap_depth_triangles.get_mut(), + heightmap_shadows_triangles: *self.heightmap_shadows_triangles.get_mut(), } } @@ -57,9 +57,9 @@ impl PerfCounters { *self.depth_drawcalls.get_mut() = 0; *self.shadows_triangles.get_mut() = 0; *self.shadows_drawcalls.get_mut() = 0; - *self.terrain_triangles.get_mut() = 0; - *self.terrain_depth_triangles.get_mut() = 0; - *self.terrain_shadows_triangles.get_mut() = 0; + *self.heightmap_triangles.get_mut() = 0; + *self.heightmap_depth_triangles.get_mut() = 0; + *self.heightmap_shadows_triangles.get_mut() = 0; } pub fn drawcall(&self, triangles: impl TryInto) { @@ -89,22 +89,22 @@ impl PerfCounters { .fetch_add(1, std::sync::atomic::Ordering::Relaxed); } - pub fn terrain_drawcall(&self, triangles: impl TryInto) { - self.terrain_triangles.fetch_add( + pub fn heightmap_drawcall(&self, triangles: impl TryInto) { + self.heightmap_triangles.fetch_add( triangles.try_into().unwrap_or(0), std::sync::atomic::Ordering::Relaxed, ); } - pub fn terrain_depth_drawcall(&self, triangles: impl TryInto, shadows: bool) { + pub fn heightmap_depth_drawcall(&self, triangles: impl TryInto, shadows: bool) { if shadows { - self.terrain_shadows_triangles.fetch_add( + self.heightmap_shadows_triangles.fetch_add( triangles.try_into().unwrap_or(0), std::sync::atomic::Ordering::Relaxed, ); return; } - self.terrain_depth_triangles.fetch_add( + self.heightmap_depth_triangles.fetch_add( triangles.try_into().unwrap_or(0), std::sync::atomic::Ordering::Relaxed, ); diff --git a/engine_demo/src/terrain.rs b/engine_demo/src/terrain.rs index 68e72e48..942fac4b 100644 --- a/engine_demo/src/terrain.rs +++ b/engine_demo/src/terrain.rs @@ -1,4 +1,4 @@ -use engine::terrain::TerrainRender as EngineTerrainRender; +use engine::heightmap::HeightmapRender; use engine::{Context, FrameContext, InstancedMeshBuilder, MeshInstance}; use geom::{pack_height, vec2, Camera, Heightmap, HeightmapChunk, LinearColor, Vec3}; @@ -9,7 +9,7 @@ const CRESO: usize = 16; const MAP_SIZE: usize = 50; pub struct Terrain { - terrain: EngineTerrainRender, + heightmap: HeightmapRender, heights: Heightmap, reload: bool, @@ -52,11 +52,11 @@ impl DemoElement for Terrain { } } - let mut terrain = EngineTerrainRender::new(gfx, MAP_SIZE as u32, MAP_SIZE as u32); + let mut heightmap = HeightmapRender::new(gfx, MAP_SIZE as u32, MAP_SIZE as u32); for x in 0..MAP_SIZE { for y in 0..MAP_SIZE { - terrain.update_chunk( + heightmap.update_chunk( gfx, (x as u32, y as u32), h.get_chunk((x as u16, y as u16)).unwrap(), @@ -64,10 +64,10 @@ impl DemoElement for Terrain { } } - terrain.invalidate_height_normals(&ctx.gfx); + heightmap.invalidate_height_normals(&ctx.gfx); Self { - terrain, + heightmap, heights: h, reload: false, last_hitpos: None, @@ -79,7 +79,7 @@ impl DemoElement for Terrain { fn update(&mut self, ctx: &mut Context, cam: &Camera) { if self.reload { self.reload = false; - self.terrain.invalidate_height_normals(&ctx.gfx); + self.heightmap.invalidate_height_normals(&ctx.gfx); } self.last_hitpos = None; @@ -98,7 +98,7 @@ impl DemoElement for Terrain { } fn render(&mut self, fc: &mut FrameContext, cam: &Camera) { - self.terrain.draw_terrain(cam, fc); + self.heightmap.draw_heightmap(cam, fc); self.hitmesh.instances.clear(); if let Some(pos) = self.last_hitpos { @@ -120,8 +120,8 @@ impl DemoElement for Terrain { } fn render_gui(&mut self, ui: &mut egui::Ui) { - ui.indent("terrain", |ui| { - if cfg!(debug_assertions) && ui.button("reload terrain").clicked() { + ui.indent("heightmap", |ui| { + if cfg!(debug_assertions) && ui.button("reload heightmap").clicked() { self.reload = true; } }); diff --git a/geom/src/heightmap.rs b/geom/src/heightmap.rs index aabaa20f..c69ebf03 100644 --- a/geom/src/heightmap.rs +++ b/geom/src/heightmap.rs @@ -675,7 +675,7 @@ mod erosion { // 0..1 const INERTIA: f32 = 0.1; // At zero, water will instantly change direction to flow downhill. At 1, water will never change direction. const SEDIMENT_CAPACITY_FACTOR: f32 = 1.0; // Multiplier for how much sediment a droplet can carry - const MIN_SEDIMENT_CAPACITY: f32 = 0.003; // Used to prevent carry capacity getting too close to zero on flatter terrain + const MIN_SEDIMENT_CAPACITY: f32 = 0.003; // Used to prevent carry capacity getting too close to zero on flatter heightmap // 0..1 const ERODE_SPEED: f32 = 0.3; @@ -796,7 +796,7 @@ mod erosion { } } else { // Erode a fraction of the droplet's current carry capacity. - // Clamp the erosion to the change in height so that it doesn't dig a hole in the terrain behind the droplet + // Clamp the erosion to the change in height so that it doesn't dig a hole in the heightmap behind the droplet let amount_to_erode = f32::min((sediment_capacity - sediment) * ERODE_SPEED, -delta_height); diff --git a/native_app/src/gui/windows/debug.rs b/native_app/src/gui/windows/debug.rs index c7b9662d..c164a87c 100644 --- a/native_app/src/gui/windows/debug.rs +++ b/native_app/src/gui/windows/debug.rs @@ -183,16 +183,16 @@ pub fn debug(window: egui::Window<'_>, ui: &egui::Context, uiworld: &UiWorld, si )); ui.add_space(5.0); ui.label(format!( - "{}k terrain triangles", - counters.terrain_triangles / 1000 + "{}k heightmap triangles", + counters.heightmap_triangles / 1000 )); ui.label(format!( - "{}k terrain depth triangles", - counters.terrain_depth_triangles / 1000 + "{}k heightmap depth triangles", + counters.heightmap_depth_triangles / 1000 )); ui.label(format!( - "{}k terrain shadow triangles", - counters.terrain_shadows_triangles / 1000 + "{}k heightmap shadow triangles", + counters.heightmap_shadows_triangles / 1000 )); drop(counters); diff --git a/native_app/src/rendering/map_rendering/terrain.rs b/native_app/src/rendering/map_rendering/terrain.rs index 0ed65351..d15c6e8f 100644 --- a/native_app/src/rendering/map_rendering/terrain.rs +++ b/native_app/src/rendering/map_rendering/terrain.rs @@ -1,4 +1,4 @@ -use engine::terrain::TerrainRender as EngineTerrainRender; +use engine::heightmap::HeightmapRender; use engine::{Context, FrameContext, GfxContext}; use geom::Camera; use simulation::map::{Map, MapSubscriber, UpdateType}; @@ -8,7 +8,7 @@ const CSIZE: u32 = simulation::map::Heightmap::SIZE; const CRESO: usize = simulation::map::Heightmap::RESOLUTION; pub struct TerrainRender { - terrain: EngineTerrainRender, + heightmap: HeightmapRender, terrain_sub: MapSubscriber, } @@ -16,16 +16,16 @@ impl TerrainRender { pub fn new(gfx: &mut GfxContext, sim: &Simulation) -> Self { let (w, h) = sim.map().environment.size(); - let terrain = EngineTerrainRender::new(gfx, w as u32, h as u32); + let terrain = HeightmapRender::new(gfx, w as u32, h as u32); Self { - terrain, + heightmap: terrain, terrain_sub: sim.map().subscribe(UpdateType::Terrain), } } pub fn draw(&mut self, cam: &Camera, fctx: &mut FrameContext<'_>) { - self.terrain.draw_terrain(cam, fctx); + self.heightmap.draw_heightmap(cam, fctx); } pub fn update(&mut self, ctx: &mut Context, map: &Map) { @@ -33,14 +33,14 @@ impl TerrainRender { if self.terrain_sub.take_cleared() { for (chunk_id, chunk) in ter.chunks() { - self.terrain.update_chunk( + self.heightmap.update_chunk( &mut ctx.gfx, (chunk_id.0 as u32, chunk_id.1 as u32), chunk, ); } - self.terrain.invalidate_height_normals(&ctx.gfx); + self.heightmap.invalidate_height_normals(&ctx.gfx); return; } @@ -50,7 +50,7 @@ impl TerrainRender { let chunk = unwrap_retlog!(ter.get_chunk(chunkid), "trying to update nonexistent chunk"); - self.terrain.update_chunk( + self.heightmap.update_chunk( &mut ctx.gfx, (chunkid.0 as u32, chunkid.1 as u32), chunk, @@ -60,7 +60,7 @@ impl TerrainRender { } if changed { - self.terrain.invalidate_height_normals(&ctx.gfx); + self.heightmap.invalidate_height_normals(&ctx.gfx); } } }