mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Limit figures drawn for rain occlusion
This commit is contained in:
parent
ac82689f83
commit
a7c724a46d
@ -108,6 +108,11 @@ void main() {
|
|||||||
vec2 view_pos = vec2(atan2(dir_2d.x, dir_2d.y), z);
|
vec2 view_pos = vec2(atan2(dir_2d.x, dir_2d.y), z);
|
||||||
|
|
||||||
vec3 cam_wpos = cam_pos.xyz + focus_off.xyz;
|
vec3 cam_wpos = cam_pos.xyz + focus_off.xyz;
|
||||||
|
// Rain density is now only based on the cameras current position.
|
||||||
|
// This could be affected by a setting where rain_density_at is instead
|
||||||
|
// called each iteration of the loop. With the current implementation
|
||||||
|
// of rain_dir this has issues with being in a place where it doesn't rain
|
||||||
|
// and seeing rain.
|
||||||
float rain = rain_density_at(cam_wpos.xy);
|
float rain = rain_density_at(cam_wpos.xy);
|
||||||
if (rain > 0.0) {
|
if (rain > 0.0) {
|
||||||
float rain_dist = 50.0;
|
float rain_dist = 50.0;
|
||||||
|
@ -354,11 +354,12 @@ impl State {
|
|||||||
/// Get a mutable reference the current in-game weather grid.
|
/// Get a mutable reference the current in-game weather grid.
|
||||||
pub fn weather_grid_mut(&mut self) -> FetchMut<WeatherGrid> { self.ecs.write_resource() }
|
pub fn weather_grid_mut(&mut self) -> FetchMut<WeatherGrid> { self.ecs.write_resource() }
|
||||||
|
|
||||||
/// Get the current weather at a position.
|
/// Get the current weather at a position in worldspace.
|
||||||
pub fn weather_at(&self, pos: Vec2<f32>) -> Weather {
|
pub fn weather_at(&self, pos: Vec2<f32>) -> Weather {
|
||||||
self.weather_grid().get_interpolated(pos)
|
self.weather_grid().get_interpolated(pos)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the max weather near a position in worldspace.
|
||||||
pub fn max_weather_near(&self, pos: Vec2<f32>) -> Weather {
|
pub fn max_weather_near(&self, pos: Vec2<f32>) -> Weather {
|
||||||
self.weather_grid().get_max_near(pos)
|
self.weather_grid().get_max_near(pos)
|
||||||
}
|
}
|
||||||
|
@ -95,7 +95,7 @@ impl RainOcclusionFigurePipeline {
|
|||||||
|
|
||||||
let render_pipeline_layout =
|
let render_pipeline_layout =
|
||||||
device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||||
label: Some("Rain occlusion pipeline layout"),
|
label: Some("Rain occlusion figure pipeline layout"),
|
||||||
push_constant_ranges: &[],
|
push_constant_ranges: &[],
|
||||||
bind_group_layouts: &[&global_layout.globals, &figure_layout.locals],
|
bind_group_layouts: &[&global_layout.globals, &figure_layout.locals],
|
||||||
});
|
});
|
||||||
|
@ -17,7 +17,7 @@ use crate::{
|
|||||||
camera::{Camera, CameraMode, Dependents},
|
camera::{Camera, CameraMode, Dependents},
|
||||||
math,
|
math,
|
||||||
terrain::Terrain,
|
terrain::Terrain,
|
||||||
SceneData, TrailMgr,
|
SceneData, TrailMgr, RAIN_THRESHOLD,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use anim::{
|
use anim::{
|
||||||
@ -620,6 +620,7 @@ impl FigureMgr {
|
|||||||
scene_data: &SceneData,
|
scene_data: &SceneData,
|
||||||
// Visible chunk data.
|
// Visible chunk data.
|
||||||
visible_psr_bounds: math::Aabr<f32>,
|
visible_psr_bounds: math::Aabr<f32>,
|
||||||
|
visible_por_bounds: math::Aabr<f32>,
|
||||||
camera: &Camera,
|
camera: &Camera,
|
||||||
terrain: Option<&Terrain>,
|
terrain: Option<&Terrain>,
|
||||||
) -> anim::vek::Aabb<f32> {
|
) -> anim::vek::Aabb<f32> {
|
||||||
@ -637,25 +638,27 @@ impl FigureMgr {
|
|||||||
// of the image rendered from the light). If the position projected
|
// of the image rendered from the light). If the position projected
|
||||||
// with the ray_mat matrix is valid, and shadows are otherwise enabled,
|
// with the ray_mat matrix is valid, and shadows are otherwise enabled,
|
||||||
// we mark can_shadow.
|
// we mark can_shadow.
|
||||||
let can_shadow_sun = {
|
// Rain occlusion is very similar to sun shadows, but using a different ray_mat,
|
||||||
let ray_direction = scene_data.get_sun_dir();
|
// and only if it's raining.
|
||||||
let is_daylight = ray_direction.z < 0.0/*0.6*/;
|
let (can_shadow_sun, can_occlude_rain) = {
|
||||||
// Are shadows enabled at all?
|
|
||||||
let can_shadow_sun = renderer.pipeline_modes().shadow.is_map() && is_daylight;
|
|
||||||
let Dependents {
|
let Dependents {
|
||||||
proj_mat: _,
|
proj_mat: _,
|
||||||
view_mat: _,
|
view_mat: _,
|
||||||
cam_pos,
|
cam_pos,
|
||||||
..
|
..
|
||||||
} = camera.dependents();
|
} = camera.dependents();
|
||||||
let cam_pos = math::Vec3::from(cam_pos);
|
|
||||||
let ray_direction = math::Vec3::from(ray_direction);
|
|
||||||
|
|
||||||
// Transform (semi) world space to light space.
|
let sun_dir = scene_data.get_sun_dir();
|
||||||
let ray_mat: math::Mat4<f32> =
|
let is_daylight = sun_dir.z < 0.0/*0.6*/;
|
||||||
math::Mat4::look_at_rh(cam_pos, cam_pos + ray_direction, math::Vec3::unit_y());
|
// Are shadows enabled at all?
|
||||||
|
let can_shadow_sun = renderer.pipeline_modes().shadow.is_map() && is_daylight;
|
||||||
|
|
||||||
|
let weather = scene_data.state.weather_at(cam_pos.xy());
|
||||||
|
|
||||||
|
let cam_pos = math::Vec3::from(cam_pos);
|
||||||
|
|
||||||
let focus_off = math::Vec3::from(camera.get_focus_pos().map(f32::trunc));
|
let focus_off = math::Vec3::from(camera.get_focus_pos().map(f32::trunc));
|
||||||
let ray_mat = ray_mat * math::Mat4::translation_3d(-focus_off);
|
let focus_off_mat = math::Mat4::translation_3d(-focus_off);
|
||||||
|
|
||||||
let collides_with_aabr = |a: math::Aabr<f32>, b: math::Aabr<f32>| {
|
let collides_with_aabr = |a: math::Aabr<f32>, b: math::Aabr<f32>| {
|
||||||
let min = math::Vec4::new(a.min.x, a.min.y, b.min.x, b.min.y);
|
let min = math::Vec4::new(a.min.x, a.min.y, b.min.x, b.min.y);
|
||||||
@ -665,22 +668,40 @@ impl FigureMgr {
|
|||||||
#[cfg(not(feature = "simd"))]
|
#[cfg(not(feature = "simd"))]
|
||||||
return min.partial_cmple(&max).reduce_and();
|
return min.partial_cmple(&max).reduce_and();
|
||||||
};
|
};
|
||||||
move |pos: (anim::vek::Vec3<f32>,), radius: f32| {
|
|
||||||
// Short circuit when there are no shadows to cast.
|
let can_shadow = |ray_direction: Vec3<f32>,
|
||||||
if !can_shadow_sun {
|
enabled: bool,
|
||||||
return false;
|
visible_bounds: math::Aabr<f32>| {
|
||||||
|
let ray_direction = math::Vec3::from(ray_direction);
|
||||||
|
// Transform (semi) world space to light space.
|
||||||
|
let ray_mat: math::Mat4<f32> =
|
||||||
|
math::Mat4::look_at_rh(cam_pos, cam_pos + ray_direction, math::Vec3::unit_y());
|
||||||
|
let ray_mat = ray_mat * focus_off_mat;
|
||||||
|
move |pos: (anim::vek::Vec3<f32>,), radius: f32| {
|
||||||
|
// Short circuit when there are no shadows to cast.
|
||||||
|
if !enabled {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// First project center onto shadow map.
|
||||||
|
let center = (ray_mat * math::Vec4::new(pos.0.x, pos.0.y, pos.0.z, 1.0)).xy();
|
||||||
|
// Then, create an approximate bounding box (± radius).
|
||||||
|
let figure_box = math::Aabr {
|
||||||
|
min: center - radius,
|
||||||
|
max: center + radius,
|
||||||
|
};
|
||||||
|
// Quick intersection test for membership in the PSC (potential shader caster)
|
||||||
|
// list.
|
||||||
|
collides_with_aabr(figure_box, visible_bounds)
|
||||||
}
|
}
|
||||||
// First project center onto shadow map.
|
};
|
||||||
let center = (ray_mat * math::Vec4::new(pos.0.x, pos.0.y, pos.0.z, 1.0)).xy();
|
(
|
||||||
// Then, create an approximate bounding box (± radius).
|
can_shadow(sun_dir, can_shadow_sun, visible_psr_bounds),
|
||||||
let figure_box = math::Aabr {
|
can_shadow(
|
||||||
min: center - radius,
|
weather.rain_vel(),
|
||||||
max: center + radius,
|
weather.rain > RAIN_THRESHOLD,
|
||||||
};
|
visible_por_bounds,
|
||||||
// Quick intersection test for membership in the PSC (potential shader caster)
|
),
|
||||||
// list.
|
)
|
||||||
collides_with_aabr(figure_box, visible_psr_bounds)
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Get player position.
|
// Get player position.
|
||||||
@ -812,6 +833,8 @@ impl FigureMgr {
|
|||||||
} else if vd_frac > 1.0 {
|
} else if vd_frac > 1.0 {
|
||||||
state.as_mut().map(|state| state.visible = false);
|
state.as_mut().map(|state| state.visible = false);
|
||||||
// Keep processing if this might be a shadow caster.
|
// Keep processing if this might be a shadow caster.
|
||||||
|
// NOTE: Not worth to do for rain_occlusion, since that only happens in closeby
|
||||||
|
// chunks.
|
||||||
if !can_shadow_prev {
|
if !can_shadow_prev {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -841,6 +864,7 @@ impl FigureMgr {
|
|||||||
} else {
|
} else {
|
||||||
// Check whether we can shadow.
|
// Check whether we can shadow.
|
||||||
meta.can_shadow_sun = can_shadow_sun(pos, radius);
|
meta.can_shadow_sun = can_shadow_sun(pos, radius);
|
||||||
|
meta.can_occlude_rain = can_occlude_rain(pos, radius);
|
||||||
}
|
}
|
||||||
(in_frustum, lpindex)
|
(in_frustum, lpindex)
|
||||||
} else {
|
} else {
|
||||||
@ -5551,17 +5575,16 @@ impl FigureMgr {
|
|||||||
visible_aabb
|
visible_aabb
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render_shadows<'a>(
|
fn render_shadow_mapping<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
drawer: &mut FigureShadowDrawer<'_, 'a>,
|
drawer: &mut FigureShadowDrawer<'_, 'a>,
|
||||||
state: &State,
|
state: &State,
|
||||||
tick: u64,
|
tick: u64,
|
||||||
(camera, figure_lod_render_distance): CameraData,
|
(camera, figure_lod_render_distance): CameraData,
|
||||||
|
filter_state: impl Fn(&FigureStateMeta) -> bool,
|
||||||
) {
|
) {
|
||||||
span!(_guard, "render_shadows", "FigureManager::render_shadows");
|
|
||||||
let ecs = state.ecs();
|
let ecs = state.ecs();
|
||||||
let items = ecs.read_storage::<Item>();
|
let items = ecs.read_storage::<Item>();
|
||||||
|
|
||||||
(
|
(
|
||||||
&ecs.entities(),
|
&ecs.entities(),
|
||||||
&ecs.read_storage::<Pos>(),
|
&ecs.read_storage::<Pos>(),
|
||||||
@ -5590,7 +5613,7 @@ impl FigureMgr {
|
|||||||
Some(Collider::Volume(vol)) => vol.mut_count,
|
Some(Collider::Volume(vol)) => vol.mut_count,
|
||||||
_ => 0,
|
_ => 0,
|
||||||
},
|
},
|
||||||
|state| state.can_shadow_sun(),
|
&filter_state,
|
||||||
if matches!(body, Body::ItemDrop(_)) { items.get(entity).map(ItemKey::from) } else { None },
|
if matches!(body, Body::ItemDrop(_)) { items.get(entity).map(ItemKey::from) } else { None },
|
||||||
) {
|
) {
|
||||||
drawer.draw(model, bound);
|
drawer.draw(model, bound);
|
||||||
@ -5598,6 +5621,32 @@ impl FigureMgr {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn render_shadows<'a>(
|
||||||
|
&'a self,
|
||||||
|
drawer: &mut FigureShadowDrawer<'_, 'a>,
|
||||||
|
state: &State,
|
||||||
|
tick: u64,
|
||||||
|
camera_data: CameraData,
|
||||||
|
) {
|
||||||
|
span!(_guard, "render_shadows", "FigureManager::render_shadows");
|
||||||
|
self.render_shadow_mapping(drawer, state, tick, camera_data, |state| {
|
||||||
|
state.can_shadow_sun()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn render_rain_occlusion<'a>(
|
||||||
|
&'a self,
|
||||||
|
drawer: &mut FigureShadowDrawer<'_, 'a>,
|
||||||
|
state: &State,
|
||||||
|
tick: u64,
|
||||||
|
camera_data: CameraData,
|
||||||
|
) {
|
||||||
|
span!(_guard, "render_rain_occlusion", "FigureManager::render_rain_occlusion");
|
||||||
|
self.render_shadow_mapping(drawer, state, tick, camera_data, |state| {
|
||||||
|
state.can_occlude_rain()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
pub fn render<'a>(
|
pub fn render<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
drawer: &mut FigureDrawer<'_, 'a>,
|
drawer: &mut FigureDrawer<'_, 'a>,
|
||||||
@ -6237,6 +6286,7 @@ pub struct FigureStateMeta {
|
|||||||
last_ori: anim::vek::Quaternion<f32>,
|
last_ori: anim::vek::Quaternion<f32>,
|
||||||
lpindex: u8,
|
lpindex: u8,
|
||||||
can_shadow_sun: bool,
|
can_shadow_sun: bool,
|
||||||
|
can_occlude_rain: bool,
|
||||||
visible: bool,
|
visible: bool,
|
||||||
last_pos: Option<anim::vek::Vec3<f32>>,
|
last_pos: Option<anim::vek::Vec3<f32>>,
|
||||||
avg_vel: anim::vek::Vec3<f32>,
|
avg_vel: anim::vek::Vec3<f32>,
|
||||||
@ -6253,6 +6303,11 @@ impl FigureStateMeta {
|
|||||||
// Either visible, or explicitly a shadow caster.
|
// Either visible, or explicitly a shadow caster.
|
||||||
self.visible || self.can_shadow_sun
|
self.visible || self.can_shadow_sun
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn can_occlude_rain(&self) -> bool {
|
||||||
|
// Either visible, or explicitly a rain occluder.
|
||||||
|
self.visible || self.can_occlude_rain
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct FigureState<S> {
|
pub struct FigureState<S> {
|
||||||
@ -6311,6 +6366,7 @@ impl<S: Skeleton> FigureState<S> {
|
|||||||
lpindex: 0,
|
lpindex: 0,
|
||||||
visible: false,
|
visible: false,
|
||||||
can_shadow_sun: false,
|
can_shadow_sun: false,
|
||||||
|
can_occlude_rain: false,
|
||||||
last_pos: None,
|
last_pos: None,
|
||||||
avg_vel: anim::vek::Vec3::zero(),
|
avg_vel: anim::vek::Vec3::zero(),
|
||||||
last_light: 1.0,
|
last_light: 1.0,
|
||||||
|
@ -183,6 +183,8 @@ impl Lod {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Update weather texture
|
// Update weather texture
|
||||||
|
// NOTE: consider moving the lerping to a shader if the overhead of uploading to
|
||||||
|
// the gpu each frame becomes an issue.
|
||||||
let weather = client.state().weather_grid();
|
let weather = client.state().weather_grid();
|
||||||
let size = weather.size().as_::<u32>();
|
let size = weather.size().as_::<u32>();
|
||||||
renderer.update_texture(
|
renderer.update_texture(
|
||||||
|
@ -65,6 +65,9 @@ const SHADOW_FAR: f32 = 128.0; // Far plane for shadow map point light rendering
|
|||||||
/// Used for first person camera effects
|
/// Used for first person camera effects
|
||||||
const RUNNING_THRESHOLD: f32 = 0.7;
|
const RUNNING_THRESHOLD: f32 = 0.7;
|
||||||
|
|
||||||
|
/// The threashold for starting calculations with rain.
|
||||||
|
const RAIN_THRESHOLD: f32 = 0.0;
|
||||||
|
|
||||||
/// is_daylight, array of active lights.
|
/// is_daylight, array of active lights.
|
||||||
pub type LightData<'a> = (bool, &'a [Light]);
|
pub type LightData<'a> = (bool, &'a [Light]);
|
||||||
|
|
||||||
@ -705,14 +708,19 @@ impl Scene {
|
|||||||
self.debug.maintain(renderer);
|
self.debug.maintain(renderer);
|
||||||
|
|
||||||
// Maintain the terrain.
|
// Maintain the terrain.
|
||||||
let (_visible_bounds, visible_light_volume, visible_psr_bounds, visible_occlusion_volume) =
|
let (
|
||||||
self.terrain.maintain(
|
_visible_bounds,
|
||||||
renderer,
|
visible_light_volume,
|
||||||
scene_data,
|
visible_psr_bounds,
|
||||||
focus_pos,
|
visible_occlusion_volume,
|
||||||
self.loaded_distance,
|
visible_por_bounds,
|
||||||
&self.camera,
|
) = self.terrain.maintain(
|
||||||
);
|
renderer,
|
||||||
|
scene_data,
|
||||||
|
focus_pos,
|
||||||
|
self.loaded_distance,
|
||||||
|
&self.camera,
|
||||||
|
);
|
||||||
|
|
||||||
// Maintain the figures.
|
// Maintain the figures.
|
||||||
let _figure_bounds = self.figure_mgr.maintain(
|
let _figure_bounds = self.figure_mgr.maintain(
|
||||||
@ -720,6 +728,7 @@ impl Scene {
|
|||||||
&mut self.trail_mgr,
|
&mut self.trail_mgr,
|
||||||
scene_data,
|
scene_data,
|
||||||
visible_psr_bounds,
|
visible_psr_bounds,
|
||||||
|
visible_por_bounds,
|
||||||
&self.camera,
|
&self.camera,
|
||||||
Some(&self.terrain),
|
Some(&self.terrain),
|
||||||
);
|
);
|
||||||
@ -1003,7 +1012,7 @@ impl Scene {
|
|||||||
let weather = client
|
let weather = client
|
||||||
.state()
|
.state()
|
||||||
.max_weather_near(focus_off.xy() + cam_pos.xy());
|
.max_weather_near(focus_off.xy() + cam_pos.xy());
|
||||||
if weather.rain > 0.0 {
|
if weather.rain > RAIN_THRESHOLD {
|
||||||
let weather = client.state().weather_at(focus_off.xy() + cam_pos.xy());
|
let weather = client.state().weather_at(focus_off.xy() + cam_pos.xy());
|
||||||
let rain_vel = weather.rain_vel();
|
let rain_vel = weather.rain_vel();
|
||||||
let rain_view_mat = math::Mat4::look_at_rh(look_at, look_at + rain_vel, up);
|
let rain_view_mat = math::Mat4::look_at_rh(look_at, look_at + rain_vel, up);
|
||||||
@ -1139,7 +1148,7 @@ impl Scene {
|
|||||||
let is_daylight = sun_dir.z < 0.0;
|
let is_daylight = sun_dir.z < 0.0;
|
||||||
let focus_pos = self.camera.get_focus_pos();
|
let focus_pos = self.camera.get_focus_pos();
|
||||||
let cam_pos = self.camera.dependents().cam_pos + focus_pos.map(|e| e.trunc());
|
let cam_pos = self.camera.dependents().cam_pos + focus_pos.map(|e| e.trunc());
|
||||||
let is_rain = state.max_weather_near(cam_pos.xy()).rain > 0.0;
|
let is_rain = state.max_weather_near(cam_pos.xy()).rain > RAIN_THRESHOLD;
|
||||||
|
|
||||||
let camera_data = (&self.camera, scene_data.figure_lod_render_distance);
|
let camera_data = (&self.camera, scene_data.figure_lod_render_distance);
|
||||||
|
|
||||||
@ -1178,7 +1187,7 @@ impl Scene {
|
|||||||
self.terrain
|
self.terrain
|
||||||
.render_rain_occlusion(&mut occlusion_pass.draw_terrain_shadows(), cam_pos);
|
.render_rain_occlusion(&mut occlusion_pass.draw_terrain_shadows(), cam_pos);
|
||||||
|
|
||||||
self.figure_mgr.render_shadows(
|
self.figure_mgr.render_rain_occlusion(
|
||||||
&mut occlusion_pass.draw_figure_shadows(),
|
&mut occlusion_pass.draw_figure_shadows(),
|
||||||
state,
|
state,
|
||||||
tick,
|
tick,
|
||||||
|
@ -18,7 +18,7 @@ use crate::{
|
|||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
camera::{self, Camera},
|
camera::{self, Camera},
|
||||||
math, SceneData,
|
math, SceneData, RAIN_THRESHOLD,
|
||||||
};
|
};
|
||||||
use common::{
|
use common::{
|
||||||
assets::{self, AssetExt, DotVoxAsset},
|
assets::{self, AssetExt, DotVoxAsset},
|
||||||
@ -821,6 +821,7 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
Vec<math::Vec3<f32>>,
|
Vec<math::Vec3<f32>>,
|
||||||
math::Aabr<f32>,
|
math::Aabr<f32>,
|
||||||
Vec<math::Vec3<f32>>,
|
Vec<math::Vec3<f32>>,
|
||||||
|
math::Aabr<f32>,
|
||||||
) {
|
) {
|
||||||
let camera::Dependents {
|
let camera::Dependents {
|
||||||
view_mat,
|
view_mat,
|
||||||
@ -1313,6 +1314,9 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
#[cfg(not(feature = "simd"))]
|
#[cfg(not(feature = "simd"))]
|
||||||
return min.partial_cmple(&max).reduce_and();
|
return min.partial_cmple(&max).reduce_and();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let cam_pos = math::Vec4::from(view_mat.inverted() * Vec4::unit_w()).xyz();
|
||||||
|
|
||||||
let (visible_light_volume, visible_psr_bounds) = if ray_direction.z < 0.0
|
let (visible_light_volume, visible_psr_bounds) = if ray_direction.z < 0.0
|
||||||
&& renderer.pipeline_modes().shadow.is_map()
|
&& renderer.pipeline_modes().shadow.is_map()
|
||||||
{
|
{
|
||||||
@ -1335,9 +1339,7 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
.map(|v| v.as_::<f32>())
|
.map(|v| v.as_::<f32>())
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
let cam_pos = math::Vec4::from(view_mat.inverted() * Vec4::unit_w()).xyz();
|
|
||||||
let up: math::Vec3<f32> = { math::Vec3::unit_y() };
|
let up: math::Vec3<f32> = { math::Vec3::unit_y() };
|
||||||
|
|
||||||
let ray_mat = math::Mat4::look_at_rh(cam_pos, cam_pos + ray_direction, up);
|
let ray_mat = math::Mat4::look_at_rh(cam_pos, cam_pos + ray_direction, up);
|
||||||
let visible_bounds = math::Aabr::from(math::fit_psr(
|
let visible_bounds = math::Aabr::from(math::fit_psr(
|
||||||
ray_mat,
|
ray_mat,
|
||||||
@ -1407,7 +1409,7 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
span!(guard, "Rain occlusion magic");
|
span!(guard, "Rain occlusion magic");
|
||||||
// Check if there is rain near the camera
|
// Check if there is rain near the camera
|
||||||
let max_weather = scene_data.state.max_weather_near(focus_pos.xy());
|
let max_weather = scene_data.state.max_weather_near(focus_pos.xy());
|
||||||
let visible_occlusion_volume = if max_weather.rain > 0.0 {
|
let (visible_occlusion_volume, visible_por_bounds) = if max_weather.rain > RAIN_THRESHOLD {
|
||||||
let visible_bounding_box = math::Aabb::<f32> {
|
let visible_bounding_box = math::Aabb::<f32> {
|
||||||
min: math::Vec3::from(visible_bounding_box.min - focus_off),
|
min: math::Vec3::from(visible_bounding_box.min - focus_off),
|
||||||
max: math::Vec3::from(visible_bounding_box.max - focus_off),
|
max: math::Vec3::from(visible_bounding_box.max - focus_off),
|
||||||
@ -1422,16 +1424,25 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
// NOTE: We use proj_mat_treeculler here because
|
// NOTE: We use proj_mat_treeculler here because
|
||||||
// calc_focused_light_volume_points makes the assumption that the
|
// calc_focused_light_volume_points makes the assumption that the
|
||||||
// near plane lies before the far plane.
|
// near plane lies before the far plane.
|
||||||
math::calc_focused_light_volume_points(
|
let visible_volume = math::calc_focused_light_volume_points(
|
||||||
inv_proj_view,
|
inv_proj_view,
|
||||||
ray_direction.as_::<f64>(),
|
ray_direction.as_::<f64>(),
|
||||||
visible_bounds_fine,
|
visible_bounds_fine,
|
||||||
1e-6,
|
1e-6,
|
||||||
)
|
)
|
||||||
.map(|v| v.as_::<f32>())
|
.map(|v| v.as_::<f32>())
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>();
|
||||||
|
let ray_mat =
|
||||||
|
math::Mat4::look_at_rh(cam_pos, cam_pos + ray_direction, math::Vec3::unit_y());
|
||||||
|
let visible_bounds = math::Aabr::from(math::fit_psr(
|
||||||
|
ray_mat,
|
||||||
|
visible_volume.iter().copied(),
|
||||||
|
|p| p,
|
||||||
|
));
|
||||||
|
|
||||||
|
(visible_volume, visible_bounds)
|
||||||
} else {
|
} else {
|
||||||
Vec::new()
|
(Vec::new(), math::Aabr::default())
|
||||||
};
|
};
|
||||||
|
|
||||||
drop(guard);
|
drop(guard);
|
||||||
@ -1440,6 +1451,7 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
visible_light_volume,
|
visible_light_volume,
|
||||||
visible_psr_bounds,
|
visible_psr_bounds,
|
||||||
visible_occlusion_volume,
|
visible_occlusion_volume,
|
||||||
|
visible_por_bounds,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user