Reduced light volume bounds according to underground depth

This commit is contained in:
Joshua Barretto 2023-02-13 21:31:47 +00:00
parent fc05638490
commit 81ec1f726c
5 changed files with 31 additions and 16 deletions

View File

@ -5,8 +5,8 @@ use crate::{
greedy::{self, GreedyConfig, GreedyMesh},
MeshGen,
},
render::{ColLightInfo, FluidVertex, Mesh, TerrainVertex, Vertex},
scene::terrain::{AltIndices, BlocksOfInterest, DEEP_ALT, SHALLOW_ALT},
render::{AltIndices, ColLightInfo, FluidVertex, Mesh, TerrainVertex, Vertex},
scene::terrain::{BlocksOfInterest, DEEP_ALT, SHALLOW_ALT},
};
use common::{
terrain::{Block, TerrainChunk},
@ -239,6 +239,7 @@ pub fn generate_mesh<'a>(
Arc<dyn Fn(Vec3<i32>) -> f32 + Send + Sync>,
Arc<dyn Fn(Vec3<i32>) -> f32 + Send + Sync>,
AltIndices,
(f32, f32),
),
> {
span!(
@ -513,6 +514,7 @@ pub fn generate_mesh<'a>(
6
},
};
let sun_occluder_z_bounds = (underground_alt.max(bounds.min.z), bounds.max.z);
(
opaque_deep
@ -528,6 +530,7 @@ pub fn generate_mesh<'a>(
Arc::new(light),
Arc::new(glow),
alt_indices,
sun_occluder_z_bounds,
),
)
}

View File

@ -54,7 +54,7 @@ pub use self::{
TerrainDrawer, TerrainShadowDrawer, ThirdPassDrawer, TrailDrawer,
TransparentPassDrawer, UiDrawer, VolumetricPassDrawer,
},
ColLightInfo, Renderer,
AltIndices, ColLightInfo, Renderer,
},
texture::Texture,
};

View File

@ -1552,3 +1552,12 @@ fn create_quad_index_buffer_u32(device: &wgpu::Device, vert_length: usize) -> Bu
Buffer::new(device, wgpu::BufferUsage::INDEX, &indices)
}
/// Terrain-related buffers segment themselves by depth to allow us to do
/// primitive occlusion culling based on whether the camera is underground or
/// not. This struct specifies the buffer offsets at whcih various layers start
/// and end.
pub struct AltIndices {
pub deep_end: usize,
pub underground_end: usize,
}

View File

@ -7,6 +7,7 @@ use super::{
blit, bloom, clouds, debug, figure, fluid, lod_object, lod_terrain, particle, shadow,
skybox, sprite, terrain, trail, ui, ColLights, GlobalsBindGroup,
},
AltIndices,
},
rain_occlusion_map::{RainOcclusionMap, RainOcclusionMapRenderer},
Renderer, ShadowMap, ShadowMapRenderer,
@ -794,7 +795,7 @@ impl<'pass_ref, 'pass: 'pass_ref> TerrainShadowDrawer<'pass_ref, 'pass> {
&mut self,
model: &'data Model<terrain::Vertex>,
locals: &'data terrain::BoundLocals,
alt_indices: &'data crate::scene::terrain::AltIndices,
alt_indices: &'data AltIndices,
is_underground: Option<bool>,
) {
// Don't render anything if there's nothing to render!
@ -990,7 +991,7 @@ impl<'pass_ref, 'pass: 'pass_ref> TerrainDrawer<'pass_ref, 'pass> {
model: &'data Model<terrain::Vertex>,
col_lights: &'data Arc<ColLights<terrain::Locals>>,
locals: &'data terrain::BoundLocals,
alt_indices: &'data crate::scene::terrain::AltIndices,
alt_indices: &'data AltIndices,
is_underground: Option<bool>,
) {
// Don't render anything if there's nothing to render!
@ -1058,7 +1059,7 @@ impl<'pass_ref, 'pass: 'pass_ref> SpriteDrawer<'pass_ref, 'pass> {
&mut self,
terrain_locals: &'data terrain::BoundLocals,
instances: &'data Instances<sprite::Instance>,
alt_indices: &'data crate::scene::terrain::AltIndices,
alt_indices: &'data AltIndices,
is_underground: Option<bool>,
) {
// Don't render anything if there's nothing to render!

View File

@ -10,9 +10,9 @@ use crate::{
},
render::{
pipelines::{self, ColLights},
ColLightInfo, FirstPassDrawer, FluidVertex, GlobalModel, Instances, LodData, Mesh, Model,
RenderError, Renderer, SpriteGlobalsBindGroup, SpriteInstance, SpriteVertex, SpriteVerts,
TerrainLocals, TerrainShadowDrawer, TerrainVertex, SPRITE_VERT_PAGE_SIZE,
AltIndices, ColLightInfo, FirstPassDrawer, FluidVertex, GlobalModel, Instances, LodData,
Mesh, Model, RenderError, Renderer, SpriteGlobalsBindGroup, SpriteInstance, SpriteVertex,
SpriteVerts, TerrainLocals, TerrainShadowDrawer, TerrainVertex, SPRITE_VERT_PAGE_SIZE,
},
};
@ -97,6 +97,7 @@ pub struct TerrainChunkData {
can_shadow_point: bool,
can_shadow_sun: bool,
z_bounds: (f32, f32),
sun_occluder_z_bounds: (f32, f32),
frustum_last_plane_index: u8,
alt_indices: AltIndices,
@ -105,11 +106,6 @@ pub struct TerrainChunkData {
pub const SHALLOW_ALT: f32 = 24.0;
pub const DEEP_ALT: f32 = 96.0;
pub struct AltIndices {
pub deep_end: usize,
pub underground_end: usize,
}
#[derive(Copy, Clone)]
struct ChunkMeshState {
pos: Vec2<i32>,
@ -122,6 +118,7 @@ struct ChunkMeshState {
/// Just the mesh part of a mesh worker response.
pub struct MeshWorkerResponseMesh {
z_bounds: (f32, f32),
sun_occluder_z_bounds: (f32, f32),
opaque_mesh: Mesh<TerrainVertex>,
fluid_mesh: Mesh<FluidVertex>,
col_lights_info: ColLightInfo,
@ -259,7 +256,7 @@ fn mesh_worker(
opaque_mesh,
fluid_mesh,
_shadow_mesh,
(bounds, col_lights_info, light_map, glow_map, alt_indices),
(bounds, col_lights_info, light_map, glow_map, alt_indices, sun_occluder_z_bounds),
) = generate_mesh(
&volume,
(
@ -271,6 +268,7 @@ fn mesh_worker(
mesh = Some(MeshWorkerResponseMesh {
// TODO: Take sprite bounds into account somehow?
z_bounds: (bounds.min.z, bounds.max.z),
sun_occluder_z_bounds,
opaque_mesh,
fluid_mesh,
col_lights_info,
@ -1277,6 +1275,7 @@ impl<V: RectRasterableVol> Terrain<V> {
can_shadow_sun: false,
blocks_of_interest: response.blocks_of_interest,
z_bounds: mesh.z_bounds,
sun_occluder_z_bounds: mesh.sun_occluder_z_bounds,
frustum_last_plane_index: 0,
alt_indices: mesh.alt_indices,
});
@ -1342,7 +1341,10 @@ impl<V: RectRasterableVol> Terrain<V> {
};
if in_frustum {
let visible_box = chunk_box;
let visible_box = Aabb {
min: chunk_box.min.xy().with_z(chunk.sun_occluder_z_bounds.0),
max: chunk_box.max.xy().with_z(chunk.sun_occluder_z_bounds.1),
};
visible_bounding_box = visible_bounding_box
.map(|e| e.union(visible_box))
.or(Some(visible_box));