mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Avoid extra set_pipeline calls
This commit is contained in:
parent
b2f94c1485
commit
624183e3f3
@ -42,8 +42,9 @@ pub use self::{
|
|||||||
},
|
},
|
||||||
renderer::{
|
renderer::{
|
||||||
drawer::{
|
drawer::{
|
||||||
Drawer, FirstPassDrawer, ParticleDrawer, PreparedUiDrawer, SecondPassDrawer,
|
ChunkSpriteDrawer, Drawer, FigureDrawer, FigureShadowDrawer, FirstPassDrawer,
|
||||||
ShadowDrawer, ThirdPassDrawer, UiDrawer,
|
ParticleDrawer, PreparedUiDrawer, SecondPassDrawer, ShadowPassDrawer, SpriteDrawer,
|
||||||
|
TerrainDrawer, TerrainShadowDrawer, ThirdPassDrawer, UiDrawer,
|
||||||
},
|
},
|
||||||
ColLightInfo, Renderer,
|
ColLightInfo, Renderer,
|
||||||
},
|
},
|
||||||
|
@ -36,6 +36,38 @@ impl<'a> Drawer<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn shadow_pass(&mut self) -> Option<ShadowPassDrawer> {
|
||||||
|
if let ShadowMap::Enabled(ref shadow_renderer) = self.renderer.shadow_map {
|
||||||
|
let mut render_pass =
|
||||||
|
self.encoder
|
||||||
|
.as_mut()
|
||||||
|
.unwrap()
|
||||||
|
.begin_render_pass(&wgpu::RenderPassDescriptor {
|
||||||
|
color_attachments: &[],
|
||||||
|
depth_stencil_attachment: Some(
|
||||||
|
wgpu::RenderPassDepthStencilAttachmentDescriptor {
|
||||||
|
attachment: &shadow_renderer.directed_depth.view,
|
||||||
|
depth_ops: Some(wgpu::Operations {
|
||||||
|
load: wgpu::LoadOp::Clear(1.0),
|
||||||
|
store: true,
|
||||||
|
}),
|
||||||
|
stencil_ops: None,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
});
|
||||||
|
|
||||||
|
render_pass.set_bind_group(0, &self.globals.bind_group, &[]);
|
||||||
|
|
||||||
|
Some(ShadowPassDrawer {
|
||||||
|
render_pass,
|
||||||
|
renderer: &self.renderer,
|
||||||
|
shadow_renderer,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn first_pass(&mut self) -> FirstPassDrawer {
|
pub fn first_pass(&mut self) -> FirstPassDrawer {
|
||||||
let mut render_pass =
|
let mut render_pass =
|
||||||
self.encoder
|
self.encoder
|
||||||
@ -71,38 +103,6 @@ impl<'a> Drawer<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn shadow_pass(&mut self) -> Option<ShadowDrawer> {
|
|
||||||
if let ShadowMap::Enabled(ref shadow_renderer) = self.renderer.shadow_map {
|
|
||||||
let mut render_pass =
|
|
||||||
self.encoder
|
|
||||||
.as_mut()
|
|
||||||
.unwrap()
|
|
||||||
.begin_render_pass(&wgpu::RenderPassDescriptor {
|
|
||||||
color_attachments: &[],
|
|
||||||
depth_stencil_attachment: Some(
|
|
||||||
wgpu::RenderPassDepthStencilAttachmentDescriptor {
|
|
||||||
attachment: &shadow_renderer.directed_depth.view,
|
|
||||||
depth_ops: Some(wgpu::Operations {
|
|
||||||
load: wgpu::LoadOp::Clear(1.0),
|
|
||||||
store: true,
|
|
||||||
}),
|
|
||||||
stencil_ops: None,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
});
|
|
||||||
|
|
||||||
render_pass.set_bind_group(0, &self.globals.bind_group, &[]);
|
|
||||||
|
|
||||||
Some(ShadowDrawer {
|
|
||||||
render_pass,
|
|
||||||
renderer: &self.renderer,
|
|
||||||
shadow_renderer,
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn second_pass(&mut self) -> SecondPassDrawer {
|
pub fn second_pass(&mut self) -> SecondPassDrawer {
|
||||||
let mut render_pass =
|
let mut render_pass =
|
||||||
self.encoder
|
self.encoder
|
||||||
@ -154,10 +154,11 @@ impl<'a> Drawer<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw_point_shadow<'b: 'a>(
|
pub fn draw_point_shadows<'data: 'a>(
|
||||||
&mut self,
|
&mut self,
|
||||||
matrices: &[shadow::PointLightMatrix; 126],
|
matrices: &[shadow::PointLightMatrix; 126],
|
||||||
chunks: impl Clone + Iterator<Item = (&'b Model<terrain::Vertex>, &'b terrain::BoundLocals)>,
|
chunks: impl Clone
|
||||||
|
+ Iterator<Item = (&'data Model<terrain::Vertex>, &'data terrain::BoundLocals)>,
|
||||||
) {
|
) {
|
||||||
if let ShadowMap::Enabled(ref shadow_renderer) = self.renderer.shadow_map {
|
if let ShadowMap::Enabled(ref shadow_renderer) = self.renderer.shadow_map {
|
||||||
const STRIDE: usize = std::mem::size_of::<shadow::PointLightMatrix>();
|
const STRIDE: usize = std::mem::size_of::<shadow::PointLightMatrix>();
|
||||||
@ -228,57 +229,110 @@ impl<'a> Drop for Drawer<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct FirstPassDrawer<'a> {
|
// Shadow pass
|
||||||
pub(super) render_pass: wgpu::RenderPass<'a>,
|
pub struct ShadowPassDrawer<'pass> {
|
||||||
pub renderer: &'a Renderer,
|
render_pass: wgpu::RenderPass<'pass>,
|
||||||
|
pub renderer: &'pass Renderer,
|
||||||
|
shadow_renderer: &'pass ShadowMapRenderer,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> FirstPassDrawer<'a> {
|
impl<'pass> ShadowPassDrawer<'pass> {
|
||||||
pub fn draw_skybox<'b: 'a>(&mut self, model: &'b Model<skybox::Vertex>) {
|
pub fn draw_figure_shadows(&mut self) -> FigureShadowDrawer<'_, 'pass> {
|
||||||
|
self.render_pass
|
||||||
|
.set_pipeline(&self.shadow_renderer.figure_directed_pipeline.pipeline);
|
||||||
|
|
||||||
|
FigureShadowDrawer {
|
||||||
|
render_pass: &mut self.render_pass,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn draw_terrain_shadows(&mut self) -> TerrainShadowDrawer<'_, 'pass> {
|
||||||
|
self.render_pass
|
||||||
|
.set_pipeline(&self.shadow_renderer.terrain_directed_pipeline.pipeline);
|
||||||
|
|
||||||
|
TerrainShadowDrawer {
|
||||||
|
render_pass: &mut self.render_pass,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct FigureShadowDrawer<'pass_ref, 'pass: 'pass_ref> {
|
||||||
|
render_pass: &'pass_ref mut wgpu::RenderPass<'pass>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'pass_ref, 'pass: 'pass_ref> FigureShadowDrawer<'pass_ref, 'pass> {
|
||||||
|
pub fn draw<'data: 'pass>(
|
||||||
|
&mut self,
|
||||||
|
model: SubModel<'data, terrain::Vertex>,
|
||||||
|
locals: &'data figure::BoundLocals,
|
||||||
|
) {
|
||||||
|
self.render_pass.set_bind_group(1, &locals.bind_group, &[]);
|
||||||
|
self.render_pass.set_vertex_buffer(0, model.buf());
|
||||||
|
self.render_pass.draw(0..model.len(), 0..1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct TerrainShadowDrawer<'pass_ref, 'pass: 'pass_ref> {
|
||||||
|
render_pass: &'pass_ref mut wgpu::RenderPass<'pass>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'pass_ref, 'pass: 'pass_ref> TerrainShadowDrawer<'pass_ref, 'pass> {
|
||||||
|
pub fn draw<'data: 'pass>(
|
||||||
|
&mut self,
|
||||||
|
model: &'data Model<terrain::Vertex>,
|
||||||
|
locals: &'data terrain::BoundLocals,
|
||||||
|
) {
|
||||||
|
self.render_pass.set_bind_group(1, &locals.bind_group, &[]);
|
||||||
|
self.render_pass.set_vertex_buffer(0, model.buf().slice(..));
|
||||||
|
self.render_pass.draw(0..model.len() as u32, 0..1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// First pass
|
||||||
|
pub struct FirstPassDrawer<'pass> {
|
||||||
|
pub(super) render_pass: wgpu::RenderPass<'pass>,
|
||||||
|
pub renderer: &'pass Renderer,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'pass> FirstPassDrawer<'pass> {
|
||||||
|
pub fn draw_skybox<'data: 'pass>(&mut self, model: &'data Model<skybox::Vertex>) {
|
||||||
self.render_pass
|
self.render_pass
|
||||||
.set_pipeline(&self.renderer.skybox_pipeline.pipeline);
|
.set_pipeline(&self.renderer.skybox_pipeline.pipeline);
|
||||||
self.render_pass.set_vertex_buffer(0, model.buf().slice(..));
|
self.render_pass.set_vertex_buffer(0, model.buf().slice(..));
|
||||||
self.render_pass.draw(0..model.len() as u32, 0..1);
|
self.render_pass.draw(0..model.len() as u32, 0..1);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw_lod_terrain<'b: 'a>(&mut self, model: &'b Model<lod_terrain::Vertex>) {
|
pub fn draw_lod_terrain<'data: 'pass>(&mut self, model: &'data Model<lod_terrain::Vertex>) {
|
||||||
self.render_pass
|
self.render_pass
|
||||||
.set_pipeline(&self.renderer.lod_terrain_pipeline.pipeline);
|
.set_pipeline(&self.renderer.lod_terrain_pipeline.pipeline);
|
||||||
self.render_pass.set_vertex_buffer(0, model.buf().slice(..));
|
self.render_pass.set_vertex_buffer(0, model.buf().slice(..));
|
||||||
self.render_pass.draw(0..model.len() as u32, 0..1);
|
self.render_pass.draw(0..model.len() as u32, 0..1);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw_figure<'b: 'a>(
|
pub fn draw_figures(&mut self) -> FigureDrawer<'_, 'pass> {
|
||||||
&mut self,
|
|
||||||
model: SubModel<'b, terrain::Vertex>,
|
|
||||||
locals: &'b figure::BoundLocals,
|
|
||||||
col_lights: &'b ColLights<figure::Locals>,
|
|
||||||
) {
|
|
||||||
self.render_pass
|
self.render_pass
|
||||||
.set_pipeline(&self.renderer.figure_pipeline.pipeline);
|
.set_pipeline(&self.renderer.figure_pipeline.pipeline);
|
||||||
self.render_pass.set_bind_group(2, &locals.bind_group, &[]);
|
|
||||||
self.render_pass
|
FigureDrawer {
|
||||||
.set_bind_group(3, &col_lights.bind_group, &[]);
|
render_pass: &mut self.render_pass,
|
||||||
self.render_pass.set_vertex_buffer(0, model.buf());
|
}
|
||||||
self.render_pass.draw(0..model.len(), 0..1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw_terrain<'b: 'a>(
|
pub fn draw_terrain<'data: 'pass>(
|
||||||
&mut self,
|
&mut self,
|
||||||
model: &'b Model<terrain::Vertex>,
|
col_lights: &'data ColLights<terrain::Locals>,
|
||||||
locals: &'b terrain::BoundLocals,
|
) -> TerrainDrawer<'_, 'pass> {
|
||||||
col_lights: &'b ColLights<terrain::Locals>,
|
|
||||||
) {
|
|
||||||
self.render_pass
|
self.render_pass
|
||||||
.set_pipeline(&self.renderer.terrain_pipeline.pipeline);
|
.set_pipeline(&self.renderer.terrain_pipeline.pipeline);
|
||||||
self.render_pass.set_bind_group(2, &locals.bind_group, &[]);
|
|
||||||
self.render_pass
|
self.render_pass
|
||||||
.set_bind_group(3, &col_lights.bind_group, &[]);
|
.set_bind_group(3, &col_lights.bind_group, &[]);
|
||||||
self.render_pass.set_vertex_buffer(0, model.buf().slice(..));
|
|
||||||
self.render_pass.draw(0..model.len() as u32, 0..1)
|
TerrainDrawer {
|
||||||
|
render_pass: &mut self.render_pass,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw_particles(&mut self) -> ParticleDrawer<'_, 'a> {
|
pub fn draw_particles(&mut self) -> ParticleDrawer<'_, 'pass> {
|
||||||
self.render_pass
|
self.render_pass
|
||||||
.set_pipeline(&self.renderer.particle_pipeline.pipeline);
|
.set_pipeline(&self.renderer.particle_pipeline.pipeline);
|
||||||
|
|
||||||
@ -287,29 +341,24 @@ impl<'a> FirstPassDrawer<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw_sprite<'b: 'a>(
|
pub fn draw_sprites<'data: 'pass>(
|
||||||
&mut self,
|
&mut self,
|
||||||
model: &'b Model<sprite::Vertex>,
|
col_lights: &'data ColLights<sprite::Locals>,
|
||||||
instances: &'b Instances<sprite::Instance>,
|
) -> SpriteDrawer<'_, 'pass> {
|
||||||
terrain_locals: &'b terrain::BoundLocals,
|
|
||||||
locals: &'b sprite::BoundLocals,
|
|
||||||
col_lights: &'b ColLights<sprite::Locals>,
|
|
||||||
) {
|
|
||||||
self.render_pass
|
self.render_pass
|
||||||
.set_pipeline(&self.renderer.sprite_pipeline.pipeline);
|
.set_pipeline(&self.renderer.sprite_pipeline.pipeline);
|
||||||
self.render_pass
|
|
||||||
.set_bind_group(2, &terrain_locals.bind_group, &[]);
|
|
||||||
self.render_pass.set_bind_group(3, &locals.bind_group, &[]);
|
|
||||||
self.render_pass
|
self.render_pass
|
||||||
.set_bind_group(4, &col_lights.bind_group, &[]);
|
.set_bind_group(4, &col_lights.bind_group, &[]);
|
||||||
self.render_pass.set_vertex_buffer(0, model.buf().slice(..));
|
|
||||||
self.render_pass
|
SpriteDrawer {
|
||||||
.set_vertex_buffer(1, instances.buf().slice(..));
|
render_pass: &mut self.render_pass,
|
||||||
self.render_pass
|
}
|
||||||
.draw(0..model.len() as u32, 0..instances.count() as u32);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw_fluid<'b: 'a>(&mut self, waves: &'b fluid::BindGroup) -> FluidDrawer<'_, 'a> {
|
pub fn draw_fluid<'data: 'pass>(
|
||||||
|
&mut self,
|
||||||
|
waves: &'data fluid::BindGroup,
|
||||||
|
) -> FluidDrawer<'_, 'pass> {
|
||||||
self.render_pass
|
self.render_pass
|
||||||
.set_pipeline(&self.renderer.fluid_pipeline.pipeline);
|
.set_pipeline(&self.renderer.fluid_pipeline.pipeline);
|
||||||
self.render_pass.set_bind_group(2, &waves.bind_group, &[]);
|
self.render_pass.set_bind_group(2, &waves.bind_group, &[]);
|
||||||
@ -320,6 +369,42 @@ impl<'a> FirstPassDrawer<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct FigureDrawer<'pass_ref, 'pass: 'pass_ref> {
|
||||||
|
render_pass: &'pass_ref mut wgpu::RenderPass<'pass>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'pass_ref, 'pass: 'pass_ref> FigureDrawer<'pass_ref, 'pass> {
|
||||||
|
pub fn draw<'data: 'pass>(
|
||||||
|
&mut self,
|
||||||
|
model: SubModel<'data, terrain::Vertex>,
|
||||||
|
locals: &'data figure::BoundLocals,
|
||||||
|
// TODO: don't rebind this every time once they are shared between figures
|
||||||
|
col_lights: &'data ColLights<figure::Locals>,
|
||||||
|
) {
|
||||||
|
self.render_pass.set_bind_group(2, &locals.bind_group, &[]);
|
||||||
|
self.render_pass
|
||||||
|
.set_bind_group(3, &col_lights.bind_group, &[]);
|
||||||
|
self.render_pass.set_vertex_buffer(0, model.buf());
|
||||||
|
self.render_pass.draw(0..model.len(), 0..1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct TerrainDrawer<'pass_ref, 'pass: 'pass_ref> {
|
||||||
|
render_pass: &'pass_ref mut wgpu::RenderPass<'pass>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'pass_ref, 'pass: 'pass_ref> TerrainDrawer<'pass_ref, 'pass> {
|
||||||
|
pub fn draw<'data: 'pass>(
|
||||||
|
&mut self,
|
||||||
|
model: &'data Model<terrain::Vertex>,
|
||||||
|
locals: &'data terrain::BoundLocals,
|
||||||
|
) {
|
||||||
|
self.render_pass.set_bind_group(2, &locals.bind_group, &[]);
|
||||||
|
self.render_pass.set_vertex_buffer(0, model.buf().slice(..));
|
||||||
|
self.render_pass.draw(0..model.len() as u32, 0..1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct ParticleDrawer<'pass_ref, 'pass: 'pass_ref> {
|
pub struct ParticleDrawer<'pass_ref, 'pass: 'pass_ref> {
|
||||||
render_pass: &'pass_ref mut wgpu::RenderPass<'pass>,
|
render_pass: &'pass_ref mut wgpu::RenderPass<'pass>,
|
||||||
}
|
}
|
||||||
@ -341,35 +426,40 @@ impl<'pass_ref, 'pass: 'pass_ref> ParticleDrawer<'pass_ref, 'pass> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ShadowDrawer<'pass> {
|
pub struct SpriteDrawer<'pass_ref, 'pass: 'pass_ref> {
|
||||||
render_pass: wgpu::RenderPass<'pass>,
|
render_pass: &'pass_ref mut wgpu::RenderPass<'pass>,
|
||||||
pub renderer: &'pass Renderer,
|
|
||||||
shadow_renderer: &'pass ShadowMapRenderer,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'pass> ShadowDrawer<'pass> {
|
impl<'pass_ref, 'pass: 'pass_ref> SpriteDrawer<'pass_ref, 'pass> {
|
||||||
pub fn draw_figure_shadow<'b: 'pass>(
|
pub fn in_chunk<'data: 'pass>(
|
||||||
&mut self,
|
&mut self,
|
||||||
model: SubModel<'b, terrain::Vertex>,
|
terrain_locals: &'data terrain::BoundLocals,
|
||||||
locals: &'b figure::BoundLocals,
|
) -> ChunkSpriteDrawer<'_, 'pass> {
|
||||||
) {
|
|
||||||
self.render_pass
|
self.render_pass
|
||||||
.set_pipeline(&self.shadow_renderer.figure_directed_pipeline.pipeline);
|
.set_bind_group(2, &terrain_locals.bind_group, &[]);
|
||||||
self.render_pass.set_bind_group(1, &locals.bind_group, &[]);
|
|
||||||
self.render_pass.set_vertex_buffer(0, model.buf());
|
|
||||||
self.render_pass.draw(0..model.len(), 0..1);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn draw_terrain_shadow<'b: 'pass>(
|
ChunkSpriteDrawer {
|
||||||
|
render_pass: &mut self.render_pass,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub struct ChunkSpriteDrawer<'pass_ref, 'pass: 'pass_ref> {
|
||||||
|
render_pass: &'pass_ref mut wgpu::RenderPass<'pass>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'pass_ref, 'pass: 'pass_ref> ChunkSpriteDrawer<'pass_ref, 'pass> {
|
||||||
|
pub fn draw<'data: 'pass>(
|
||||||
&mut self,
|
&mut self,
|
||||||
model: &'b Model<terrain::Vertex>,
|
model: &'data Model<sprite::Vertex>,
|
||||||
locals: &'b terrain::BoundLocals,
|
instances: &'data Instances<sprite::Instance>,
|
||||||
|
locals: &'data sprite::BoundLocals,
|
||||||
) {
|
) {
|
||||||
self.render_pass
|
|
||||||
.set_pipeline(&self.shadow_renderer.terrain_directed_pipeline.pipeline);
|
|
||||||
self.render_pass.set_bind_group(1, &locals.bind_group, &[]);
|
|
||||||
self.render_pass.set_vertex_buffer(0, model.buf().slice(..));
|
self.render_pass.set_vertex_buffer(0, model.buf().slice(..));
|
||||||
self.render_pass.draw(0..model.len() as u32, 0..1);
|
self.render_pass
|
||||||
|
.set_vertex_buffer(1, instances.buf().slice(..));
|
||||||
|
self.render_pass.set_bind_group(3, &locals.bind_group, &[]);
|
||||||
|
self.render_pass
|
||||||
|
.draw(0..model.len() as u32, 0..instances.count() as u32);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -389,13 +479,14 @@ impl<'pass_ref, 'pass: 'pass_ref> FluidDrawer<'pass_ref, 'pass> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct SecondPassDrawer<'a> {
|
// Second pass: clouds
|
||||||
pub(super) render_pass: wgpu::RenderPass<'a>,
|
pub struct SecondPassDrawer<'pass> {
|
||||||
pub renderer: &'a Renderer,
|
pub(super) render_pass: wgpu::RenderPass<'pass>,
|
||||||
|
pub renderer: &'pass Renderer,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> SecondPassDrawer<'a> {
|
impl<'pass> SecondPassDrawer<'pass> {
|
||||||
pub fn draw_clouds<'b: 'a>(&mut self) {
|
pub fn draw_clouds(&mut self) {
|
||||||
self.render_pass
|
self.render_pass
|
||||||
.set_pipeline(&self.renderer.clouds_pipeline.pipeline);
|
.set_pipeline(&self.renderer.clouds_pipeline.pipeline);
|
||||||
self.render_pass
|
self.render_pass
|
||||||
@ -404,13 +495,14 @@ impl<'a> SecondPassDrawer<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ThirdPassDrawer<'a> {
|
// Third pass: postprocess + ui
|
||||||
render_pass: wgpu::RenderPass<'a>,
|
pub struct ThirdPassDrawer<'pass> {
|
||||||
renderer: &'a Renderer,
|
render_pass: wgpu::RenderPass<'pass>,
|
||||||
|
renderer: &'pass Renderer,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ThirdPassDrawer<'a> {
|
impl<'pass> ThirdPassDrawer<'pass> {
|
||||||
pub fn draw_post_process<'b: 'a>(&mut self) {
|
pub fn draw_post_process(&mut self) {
|
||||||
self.render_pass
|
self.render_pass
|
||||||
.set_pipeline(&self.renderer.postprocess_pipeline.pipeline);
|
.set_pipeline(&self.renderer.postprocess_pipeline.pipeline);
|
||||||
self.render_pass
|
self.render_pass
|
||||||
@ -418,7 +510,7 @@ impl<'a> ThirdPassDrawer<'a> {
|
|||||||
self.render_pass.draw(0..3, 0..1);
|
self.render_pass.draw(0..3, 0..1);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw_ui(&mut self) -> UiDrawer<'_, 'a> {
|
pub fn draw_ui(&mut self) -> UiDrawer<'_, 'pass> {
|
||||||
self.render_pass
|
self.render_pass
|
||||||
.set_pipeline(&self.renderer.ui_pipeline.pipeline);
|
.set_pipeline(&self.renderer.ui_pipeline.pipeline);
|
||||||
|
|
||||||
@ -443,7 +535,7 @@ impl<'pass_ref, 'pass: 'pass_ref> UiDrawer<'pass_ref, 'pass> {
|
|||||||
pub fn prepare<'data: 'pass>(
|
pub fn prepare<'data: 'pass>(
|
||||||
&mut self,
|
&mut self,
|
||||||
locals: &'data ui::BoundLocals,
|
locals: &'data ui::BoundLocals,
|
||||||
//texture: &'b ui::TextureBindGroup,
|
//texture: &'data ui::TextureBindGroup,
|
||||||
buf: &'data DynamicModel<ui::Vertex>,
|
buf: &'data DynamicModel<ui::Vertex>,
|
||||||
scissor: Aabr<u16>,
|
scissor: Aabr<u16>,
|
||||||
) -> PreparedUiDrawer<'_, 'pass> {
|
) -> PreparedUiDrawer<'_, 'pass> {
|
||||||
@ -467,8 +559,9 @@ impl<'pass_ref, 'pass: 'pass_ref> PreparedUiDrawer<'pass_ref, 'pass> {
|
|||||||
self.render_pass.set_bind_group(1, &locals.bind_group, &[]);
|
self.render_pass.set_bind_group(1, &locals.bind_group, &[]);
|
||||||
}
|
}
|
||||||
|
|
||||||
//pub fn set_texture<'b: 'a>(&mut self, texture: &'b ui::TextureBindGroup) {
|
//pub fn set_texture<'data: 'pass>(&mut self, texture: &'data
|
||||||
// self.render_pass.set_bind_group(1, &texture.bind_group, &[]);
|
// ui::TextureBindGroup) { self.render_pass.set_bind_group(1,
|
||||||
|
// &texture.bind_group, &[]);
|
||||||
//}
|
//}
|
||||||
|
|
||||||
pub fn set_model<'data: 'pass>(&mut self, model: &'data DynamicModel<ui::Vertex>) {
|
pub fn set_model<'data: 'pass>(&mut self, model: &'data DynamicModel<ui::Vertex>) {
|
||||||
|
@ -8,8 +8,9 @@ use crate::{
|
|||||||
ecs::comp::Interpolated,
|
ecs::comp::Interpolated,
|
||||||
render::{
|
render::{
|
||||||
pipelines::{self, ColLights},
|
pipelines::{self, ColLights},
|
||||||
ColLightInfo, FigureBoneData, FigureLocals, FigureModel, FirstPassDrawer, GlobalModel,
|
ColLightInfo, FigureBoneData, FigureDrawer, FigureLocals, FigureModel, FigureShadowDrawer,
|
||||||
LodData, Mesh, RenderError, Renderer, ShadowDrawer, SubModel, TerrainVertex,
|
FirstPassDrawer, GlobalModel, LodData, Mesh, RenderError, Renderer, SubModel,
|
||||||
|
TerrainVertex,
|
||||||
},
|
},
|
||||||
scene::{
|
scene::{
|
||||||
camera::{Camera, CameraMode, Dependents},
|
camera::{Camera, CameraMode, Dependents},
|
||||||
@ -4397,7 +4398,7 @@ impl FigureMgr {
|
|||||||
|
|
||||||
pub fn render_shadows<'a>(
|
pub fn render_shadows<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
drawer: &mut ShadowDrawer<'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,
|
||||||
@ -4430,7 +4431,7 @@ impl FigureMgr {
|
|||||||
figure_lod_render_distance * scale.map_or(1.0, |s| s.0),
|
figure_lod_render_distance * scale.map_or(1.0, |s| s.0),
|
||||||
|state| state.can_shadow_sun(),
|
|state| state.can_shadow_sun(),
|
||||||
) {
|
) {
|
||||||
drawer.draw_figure_shadow(model, bound);
|
drawer.draw(model, bound);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -4438,12 +4439,10 @@ impl FigureMgr {
|
|||||||
#[allow(clippy::too_many_arguments)] // TODO: Pending review in #587
|
#[allow(clippy::too_many_arguments)] // TODO: Pending review in #587
|
||||||
pub fn render<'a>(
|
pub fn render<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
drawer: &mut FirstPassDrawer<'a>,
|
drawer: &mut FigureDrawer<'_, 'a>,
|
||||||
state: &State,
|
state: &State,
|
||||||
player_entity: EcsEntity,
|
player_entity: EcsEntity,
|
||||||
tick: u64,
|
tick: u64,
|
||||||
global: &GlobalModel,
|
|
||||||
lod: &LodData,
|
|
||||||
(camera, figure_lod_render_distance): CameraData,
|
(camera, figure_lod_render_distance): CameraData,
|
||||||
) {
|
) {
|
||||||
span!(_guard, "render", "FigureManager::render");
|
span!(_guard, "render", "FigureManager::render");
|
||||||
@ -4452,22 +4451,20 @@ impl FigureMgr {
|
|||||||
let character_state_storage = state.read_storage::<common::comp::CharacterState>();
|
let character_state_storage = state.read_storage::<common::comp::CharacterState>();
|
||||||
let character_state = character_state_storage.get(player_entity);
|
let character_state = character_state_storage.get(player_entity);
|
||||||
|
|
||||||
for (entity, pos, _, body, _, inventory, scale) in (
|
for (entity, pos, body, _, inventory, scale) in (
|
||||||
&ecs.entities(),
|
&ecs.entities(),
|
||||||
&ecs.read_storage::<Pos>(),
|
&ecs.read_storage::<Pos>(),
|
||||||
ecs.read_storage::<Ori>().maybe(),
|
|
||||||
&ecs.read_storage::<Body>(),
|
&ecs.read_storage::<Body>(),
|
||||||
ecs.read_storage::<Health>().maybe(),
|
ecs.read_storage::<Health>().maybe(),
|
||||||
ecs.read_storage::<Inventory>().maybe(),
|
ecs.read_storage::<Inventory>().maybe(),
|
||||||
ecs.read_storage::<Scale>().maybe(),
|
ecs.read_storage::<Scale>().maybe()
|
||||||
)
|
)
|
||||||
.join()
|
.join()
|
||||||
// Don't render dead entities
|
// Don't render dead entities
|
||||||
.filter(|(_, _, _, _, health, _, _)| health.map_or(true, |h| !h.is_dead))
|
.filter(|(_, _, _, health, _)| health.map_or(true, |h| !h.is_dead))
|
||||||
|
// Don't render player
|
||||||
|
.filter(|(entity, _, _, _, _)| *entity != player_entity)
|
||||||
{
|
{
|
||||||
let is_player = entity == player_entity;
|
|
||||||
|
|
||||||
if !is_player {
|
|
||||||
if let Some((bound, model, col_lights)) = self.get_model_for_render(
|
if let Some((bound, model, col_lights)) = self.get_model_for_render(
|
||||||
tick,
|
tick,
|
||||||
camera,
|
camera,
|
||||||
@ -4480,8 +4477,7 @@ impl FigureMgr {
|
|||||||
figure_lod_render_distance * scale.map_or(1.0, |s| s.0),
|
figure_lod_render_distance * scale.map_or(1.0, |s| s.0),
|
||||||
|state| state.visible(),
|
|state| state.visible(),
|
||||||
) {
|
) {
|
||||||
drawer.draw_figure(model, bound, col_lights);
|
drawer.draw(model, bound, col_lights);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4489,12 +4485,10 @@ impl FigureMgr {
|
|||||||
#[allow(clippy::too_many_arguments)] // TODO: Pending review in #587
|
#[allow(clippy::too_many_arguments)] // TODO: Pending review in #587
|
||||||
pub fn render_player<'a>(
|
pub fn render_player<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
drawer: &mut FirstPassDrawer<'a>,
|
drawer: &mut FigureDrawer<'_, 'a>,
|
||||||
state: &State,
|
state: &State,
|
||||||
player_entity: EcsEntity,
|
player_entity: EcsEntity,
|
||||||
tick: u64,
|
tick: u64,
|
||||||
global: &GlobalModel,
|
|
||||||
lod: &LodData,
|
|
||||||
(camera, figure_lod_render_distance): CameraData,
|
(camera, figure_lod_render_distance): CameraData,
|
||||||
) {
|
) {
|
||||||
span!(_guard, "render_player", "FigureManager::render_player");
|
span!(_guard, "render_player", "FigureManager::render_player");
|
||||||
@ -4528,7 +4522,7 @@ impl FigureMgr {
|
|||||||
figure_lod_render_distance,
|
figure_lod_render_distance,
|
||||||
|state| state.visible(),
|
|state| state.visible(),
|
||||||
) {
|
) {
|
||||||
drawer.draw_figure(model, bound, col_lights);
|
drawer.draw(model, bound, col_lights);
|
||||||
/*renderer.render_player_shadow(
|
/*renderer.render_player_shadow(
|
||||||
model,
|
model,
|
||||||
&col_lights,
|
&col_lights,
|
||||||
|
@ -18,7 +18,7 @@ use crate::{
|
|||||||
render::{
|
render::{
|
||||||
create_skybox_mesh, CloudsLocals, Consts, Drawer, FirstPassDrawer, GlobalModel, Globals,
|
create_skybox_mesh, CloudsLocals, Consts, Drawer, FirstPassDrawer, GlobalModel, Globals,
|
||||||
GlobalsBindGroup, Light, Model, PointLightMatrix, PostProcessLocals, Renderer, Shadow,
|
GlobalsBindGroup, Light, Model, PointLightMatrix, PostProcessLocals, Renderer, Shadow,
|
||||||
ShadowDrawer, ShadowLocals, SkyboxVertex,
|
ShadowLocals, SkyboxVertex,
|
||||||
},
|
},
|
||||||
settings::Settings,
|
settings::Settings,
|
||||||
window::{AnalogGameInput, Event},
|
window::{AnalogGameInput, Event},
|
||||||
@ -1034,90 +1034,10 @@ impl Scene {
|
|||||||
|
|
||||||
pub fn global_bind_group(&self) -> &GlobalsBindGroup { &self.globals_bind_group }
|
pub fn global_bind_group(&self) -> &GlobalsBindGroup { &self.globals_bind_group }
|
||||||
|
|
||||||
pub fn render_terrain_shadows<'a>(
|
/// Render the scene using the provided `Drawer`.
|
||||||
&'a self,
|
|
||||||
drawer: &mut ShadowDrawer<'a>,
|
|
||||||
state: &State,
|
|
||||||
player_entity: EcsEntity,
|
|
||||||
tick: u64,
|
|
||||||
scene_data: &SceneData,
|
|
||||||
) {
|
|
||||||
let sun_dir = scene_data.get_sun_dir();
|
|
||||||
let is_daylight = sun_dir.z < 0.0;
|
|
||||||
let focus_pos = self.camera.get_focus_pos();
|
|
||||||
let cam_pos = self.camera.dependents().cam_pos + focus_pos.map(|e| e.trunc());
|
|
||||||
|
|
||||||
let global = &self.data;
|
|
||||||
let light_data = (is_daylight, &*self.light_data);
|
|
||||||
let camera_data = (&self.camera, scene_data.figure_lod_render_distance);
|
|
||||||
|
|
||||||
// would instead have this as an extension.
|
|
||||||
if drawer.renderer.render_mode().shadow.is_map()
|
|
||||||
&& (is_daylight || !light_data.1.is_empty())
|
|
||||||
{
|
|
||||||
// Render terrain shadows.
|
|
||||||
self.terrain
|
|
||||||
.render_shadows(drawer, global, light_data, focus_pos);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn render_point_shadows<'a>(
|
|
||||||
&'a self,
|
|
||||||
drawer: &mut Drawer<'a>,
|
|
||||||
state: &State,
|
|
||||||
player_entity: EcsEntity,
|
|
||||||
tick: u64,
|
|
||||||
scene_data: &SceneData,
|
|
||||||
) {
|
|
||||||
let sun_dir = scene_data.get_sun_dir();
|
|
||||||
let is_daylight = sun_dir.z < 0.0;
|
|
||||||
let focus_pos = self.camera.get_focus_pos();
|
|
||||||
let cam_pos = self.camera.dependents().cam_pos + focus_pos.map(|e| e.trunc());
|
|
||||||
|
|
||||||
let global = &self.data;
|
|
||||||
let light_data = (is_daylight, &*self.light_data);
|
|
||||||
let camera_data = (&self.camera, scene_data.figure_lod_render_distance);
|
|
||||||
|
|
||||||
if drawer.renderer.render_mode().shadow.is_map()
|
|
||||||
&& (is_daylight || !light_data.1.is_empty())
|
|
||||||
{
|
|
||||||
// Render terrain shadows.
|
|
||||||
self.terrain
|
|
||||||
.render_point_shadows(drawer, global, light_data, focus_pos);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn render_figure_shadows<'a>(
|
|
||||||
&'a self,
|
|
||||||
drawer: &mut ShadowDrawer<'a>,
|
|
||||||
state: &State,
|
|
||||||
player_entity: EcsEntity,
|
|
||||||
tick: u64,
|
|
||||||
scene_data: &SceneData,
|
|
||||||
) {
|
|
||||||
let sun_dir = scene_data.get_sun_dir();
|
|
||||||
let is_daylight = sun_dir.z < 0.0;
|
|
||||||
let focus_pos = self.camera.get_focus_pos();
|
|
||||||
let cam_pos = self.camera.dependents().cam_pos + focus_pos.map(|e| e.trunc());
|
|
||||||
|
|
||||||
let global = &self.data;
|
|
||||||
let light_data = (is_daylight, &*self.light_data);
|
|
||||||
let camera_data = (&self.camera, scene_data.figure_lod_render_distance);
|
|
||||||
|
|
||||||
// would instead have this as an extension.
|
|
||||||
if drawer.renderer.render_mode().shadow.is_map()
|
|
||||||
&& (is_daylight || !light_data.1.is_empty())
|
|
||||||
{
|
|
||||||
// Render figure shadows.
|
|
||||||
self.figure_mgr
|
|
||||||
.render_shadows(drawer, state, tick, camera_data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Render the scene using the provided `FirstPassDrawer`.
|
|
||||||
pub fn render<'a>(
|
pub fn render<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
drawer: &mut FirstPassDrawer<'a>,
|
drawer: &mut Drawer<'a>,
|
||||||
state: &State,
|
state: &State,
|
||||||
player_entity: EcsEntity,
|
player_entity: EcsEntity,
|
||||||
tick: u64,
|
tick: u64,
|
||||||
@ -1129,26 +1049,63 @@ impl Scene {
|
|||||||
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 global = &self.data;
|
|
||||||
let camera_data = (&self.camera, scene_data.figure_lod_render_distance);
|
let camera_data = (&self.camera, scene_data.figure_lod_render_distance);
|
||||||
|
|
||||||
let lod = self.lod.get_data();
|
// would instead have this as an extension.
|
||||||
|
if drawer.renderer.render_mode().shadow.is_map()
|
||||||
|
&& (is_daylight || !self.light_data.is_empty())
|
||||||
|
{
|
||||||
|
if is_daylight {
|
||||||
|
if let Some(mut shadow_pass) = drawer.shadow_pass() {
|
||||||
|
// Render terrain directed shadows.
|
||||||
|
self.terrain
|
||||||
|
.render_shadows(&mut shadow_pass.draw_terrain_shadows(), focus_pos);
|
||||||
|
|
||||||
self.figure_mgr
|
// Render figure directed shadows.
|
||||||
.render_player(drawer, state, player_entity, tick, global, lod, camera_data);
|
self.figure_mgr.render_shadows(
|
||||||
|
&mut shadow_pass.draw_figure_shadows(),
|
||||||
|
state,
|
||||||
|
tick,
|
||||||
|
camera_data,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
self.terrain.render(drawer, focus_pos);
|
// Render terrain point light shadows.
|
||||||
|
drawer.draw_point_shadows(
|
||||||
|
&self.data.point_light_matrices,
|
||||||
|
self.terrain.chunks_for_point_shadows(focus_pos),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
self.figure_mgr
|
let mut first_pass = drawer.first_pass();
|
||||||
.render(drawer, state, player_entity, tick, global, lod, camera_data);
|
|
||||||
|
|
||||||
self.lod.render(drawer);
|
self.figure_mgr.render_player(
|
||||||
|
&mut first_pass.draw_figures(),
|
||||||
|
state,
|
||||||
|
player_entity,
|
||||||
|
tick,
|
||||||
|
camera_data,
|
||||||
|
);
|
||||||
|
|
||||||
|
self.terrain.render(&mut first_pass, focus_pos);
|
||||||
|
|
||||||
|
self.figure_mgr.render(
|
||||||
|
&mut first_pass.draw_figures(),
|
||||||
|
state,
|
||||||
|
player_entity,
|
||||||
|
tick,
|
||||||
|
camera_data,
|
||||||
|
);
|
||||||
|
|
||||||
|
self.lod.render(&mut first_pass);
|
||||||
|
|
||||||
// Render the skybox.
|
// Render the skybox.
|
||||||
drawer.draw_skybox(&self.skybox.model);
|
first_pass.draw_skybox(&self.skybox.model);
|
||||||
|
|
||||||
|
// Draws translucent terrain and sprites
|
||||||
self.terrain.render_translucent(
|
self.terrain.render_translucent(
|
||||||
drawer,
|
&mut first_pass,
|
||||||
focus_pos,
|
focus_pos,
|
||||||
cam_pos,
|
cam_pos,
|
||||||
scene_data.sprite_render_distance,
|
scene_data.sprite_render_distance,
|
||||||
@ -1156,6 +1113,6 @@ impl Scene {
|
|||||||
|
|
||||||
// Render particle effects.
|
// Render particle effects.
|
||||||
self.particle_mgr
|
self.particle_mgr
|
||||||
.render(&mut drawer.draw_particles(), scene_data);
|
.render(&mut first_pass.draw_particles(), scene_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -354,6 +354,7 @@ impl Scene {
|
|||||||
body: Option<humanoid::Body>,
|
body: Option<humanoid::Body>,
|
||||||
inventory: Option<&Inventory>,
|
inventory: Option<&Inventory>,
|
||||||
) {
|
) {
|
||||||
|
let mut figure_drawer = drawer.draw_figures();
|
||||||
if let Some(body) = body {
|
if let Some(body) = body {
|
||||||
let model = &self.figure_model_cache.get_model(
|
let model = &self.figure_model_cache.get_model(
|
||||||
&self.col_lights,
|
&self.col_lights,
|
||||||
@ -365,7 +366,7 @@ impl Scene {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if let Some(model) = model {
|
if let Some(model) = model {
|
||||||
drawer.draw_figure(
|
figure_drawer.draw(
|
||||||
model.lod_model(0),
|
model.lod_model(0),
|
||||||
self.figure_state.bound(),
|
self.figure_state.bound(),
|
||||||
&self.col_lights.texture(model),
|
&self.col_lights.texture(model),
|
||||||
@ -374,7 +375,7 @@ impl Scene {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some((model, state)) = &self.backdrop {
|
if let Some((model, state)) = &self.backdrop {
|
||||||
drawer.draw_figure(
|
figure_drawer.draw(
|
||||||
model.lod_model(0),
|
model.lod_model(0),
|
||||||
state.bound(),
|
state.bound(),
|
||||||
&self.col_lights.texture(model),
|
&self.col_lights.texture(model),
|
||||||
|
@ -10,8 +10,8 @@ use crate::{
|
|||||||
render::{
|
render::{
|
||||||
pipelines::{self, ColLights},
|
pipelines::{self, ColLights},
|
||||||
ColLightInfo, Consts, Drawer, FirstPassDrawer, FluidVertex, FluidWaves, GlobalModel,
|
ColLightInfo, Consts, Drawer, FirstPassDrawer, FluidVertex, FluidWaves, GlobalModel,
|
||||||
Instances, LodData, Mesh, Model, RenderError, Renderer, ShadowDrawer, SpriteInstance,
|
Instances, LodData, Mesh, Model, RenderError, Renderer, SpriteInstance, SpriteLocals,
|
||||||
SpriteLocals, SpriteVertex, TerrainLocals, TerrainVertex, Texture,
|
SpriteVertex, TerrainLocals, TerrainShadowDrawer, TerrainVertex, Texture,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1264,9 +1264,7 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
|
|
||||||
pub fn render_shadows<'a>(
|
pub fn render_shadows<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
drawer: &mut ShadowDrawer<'a>,
|
drawer: &mut TerrainShadowDrawer<'_, 'a>,
|
||||||
global: &GlobalModel,
|
|
||||||
(is_daylight, light_data): super::LightData,
|
|
||||||
focus_pos: Vec3<f32>,
|
focus_pos: Vec3<f32>,
|
||||||
) {
|
) {
|
||||||
span!(_guard, "render_shadows", "Terrain::render_shadows");
|
span!(_guard, "render_shadows", "Terrain::render_shadows");
|
||||||
@ -1286,28 +1284,28 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
// NOTE: We also render shadows for dead chunks that were found to still be
|
// NOTE: We also render shadows for dead chunks that were found to still be
|
||||||
// potential shadow casters, to avoid shadows suddenly disappearing at
|
// potential shadow casters, to avoid shadows suddenly disappearing at
|
||||||
// very steep sun angles (e.g. sunrise / sunset).
|
// very steep sun angles (e.g. sunrise / sunset).
|
||||||
if is_daylight {
|
|
||||||
chunk_iter
|
chunk_iter
|
||||||
.clone()
|
|
||||||
.filter(|chunk| chunk.can_shadow_sun())
|
.filter(|chunk| chunk.can_shadow_sun())
|
||||||
.chain(self.shadow_chunks.iter().map(|(_, chunk)| chunk))
|
.chain(self.shadow_chunks.iter().map(|(_, chunk)| chunk))
|
||||||
.for_each(|chunk| drawer.draw_terrain_shadow(&chunk.opaque_model, &chunk.locals));
|
.for_each(|chunk| drawer.draw(&chunk.opaque_model, &chunk.locals));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render_point_shadows<'a>(
|
pub fn chunks_for_point_shadows(
|
||||||
&'a self,
|
&self,
|
||||||
drawer: &mut Drawer<'a>,
|
|
||||||
global: &GlobalModel,
|
|
||||||
(is_daylight, light_data): super::LightData,
|
|
||||||
focus_pos: Vec3<f32>,
|
focus_pos: Vec3<f32>,
|
||||||
) {
|
) -> impl Clone
|
||||||
|
+ Iterator<
|
||||||
|
Item = (
|
||||||
|
&Model<pipelines::terrain::Vertex>,
|
||||||
|
&pipelines::terrain::BoundLocals,
|
||||||
|
),
|
||||||
|
> {
|
||||||
let focus_chunk = Vec2::from(focus_pos).map2(TerrainChunk::RECT_SIZE, |e: f32, sz| {
|
let focus_chunk = Vec2::from(focus_pos).map2(TerrainChunk::RECT_SIZE, |e: f32, sz| {
|
||||||
(e as i32).div_euclid(sz as i32)
|
(e as i32).div_euclid(sz as i32)
|
||||||
});
|
});
|
||||||
|
|
||||||
let chunk_iter = Spiral2d::new()
|
let chunk_iter = Spiral2d::new()
|
||||||
.filter_map(|rpos| {
|
.filter_map(move |rpos| {
|
||||||
let pos = focus_chunk + rpos;
|
let pos = focus_chunk + rpos;
|
||||||
self.chunks.get(&pos)
|
self.chunks.get(&pos)
|
||||||
})
|
})
|
||||||
@ -1317,35 +1315,27 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
//
|
//
|
||||||
// NOTE: We don't bother retaining chunks unless they cast sun shadows, so we
|
// NOTE: We don't bother retaining chunks unless they cast sun shadows, so we
|
||||||
// don't use `shadow_chunks` here.
|
// don't use `shadow_chunks` here.
|
||||||
light_data.iter().take(1).for_each(|_light| {
|
|
||||||
drawer.draw_point_shadow(
|
|
||||||
&global.point_light_matrices,
|
|
||||||
chunk_iter
|
chunk_iter
|
||||||
.clone()
|
|
||||||
.filter(|chunk| chunk.can_shadow_point)
|
.filter(|chunk| chunk.can_shadow_point)
|
||||||
.map(|chunk| (&chunk.opaque_model, &chunk.locals)),
|
.map(|chunk| (&chunk.opaque_model, &chunk.locals))
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render<'a>(&'a self, drawer: &mut FirstPassDrawer<'a>, focus_pos: Vec3<f32>) {
|
pub fn render<'a>(&'a self, drawer: &mut FirstPassDrawer<'a>, focus_pos: Vec3<f32>) {
|
||||||
span!(_guard, "render", "Terrain::render");
|
span!(_guard, "render", "Terrain::render");
|
||||||
|
let mut drawer = drawer.draw_terrain(&self.col_lights);
|
||||||
|
|
||||||
let focus_chunk = Vec2::from(focus_pos).map2(TerrainChunk::RECT_SIZE, |e: f32, sz| {
|
let focus_chunk = Vec2::from(focus_pos).map2(TerrainChunk::RECT_SIZE, |e: f32, sz| {
|
||||||
(e as i32).div_euclid(sz as i32)
|
(e as i32).div_euclid(sz as i32)
|
||||||
});
|
});
|
||||||
|
|
||||||
let chunk_iter = Spiral2d::new()
|
Spiral2d::new()
|
||||||
.filter_map(|rpos| {
|
.filter_map(|rpos| {
|
||||||
let pos = focus_chunk + rpos;
|
let pos = focus_chunk + rpos;
|
||||||
self.chunks.get(&pos).map(|c| (pos, c))
|
self.chunks.get(&pos)
|
||||||
})
|
})
|
||||||
.take(self.chunks.len());
|
.take(self.chunks.len())
|
||||||
|
.filter(|chunk| chunk.visible.is_visible())
|
||||||
for (_, chunk) in chunk_iter {
|
.for_each(|chunk| drawer.draw(&chunk.opaque_model, &chunk.locals));
|
||||||
if chunk.visible.is_visible() {
|
|
||||||
drawer.draw_terrain(&chunk.opaque_model, &chunk.locals, &self.col_lights)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render_translucent<'a>(
|
pub fn render_translucent<'a>(
|
||||||
@ -1373,8 +1363,11 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
span!(guard, "Terrain sprites");
|
span!(guard, "Terrain sprites");
|
||||||
let chunk_size = V::RECT_SIZE.map(|e| e as f32);
|
let chunk_size = V::RECT_SIZE.map(|e| e as f32);
|
||||||
let chunk_mag = (chunk_size * (f32::consts::SQRT_2 * 0.5)).magnitude_squared();
|
let chunk_mag = (chunk_size * (f32::consts::SQRT_2 * 0.5)).magnitude_squared();
|
||||||
for (pos, chunk) in chunk_iter.clone() {
|
let mut sprite_drawer = drawer.draw_sprites(&self.sprite_col_lights);
|
||||||
if chunk.visible.is_visible() {
|
chunk_iter
|
||||||
|
.clone()
|
||||||
|
.filter(|(_, c)| c.visible.is_visible())
|
||||||
|
.for_each(|(pos, chunk)| {
|
||||||
let sprite_low_detail_distance = sprite_render_distance * 0.75;
|
let sprite_low_detail_distance = sprite_render_distance * 0.75;
|
||||||
let sprite_mid_detail_distance = sprite_render_distance * 0.5;
|
let sprite_mid_detail_distance = sprite_render_distance * 0.5;
|
||||||
let sprite_hid_detail_distance = sprite_render_distance * 0.35;
|
let sprite_hid_detail_distance = sprite_render_distance * 0.35;
|
||||||
@ -1396,6 +1389,8 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
chunk_center + chunk_size.x * 0.5 - chunk_size.y * 0.5,
|
chunk_center + chunk_size.x * 0.5 - chunk_size.y * 0.5,
|
||||||
));
|
));
|
||||||
if focus_dist_sqrd < sprite_render_distance.powi(2) {
|
if focus_dist_sqrd < sprite_render_distance.powi(2) {
|
||||||
|
// TODO: skip if sprite_instances is empty
|
||||||
|
let mut chunk_sprite_drawer = sprite_drawer.in_chunk(&chunk.locals);
|
||||||
for (kind, instances) in (&chunk.sprite_instances).into_iter() {
|
for (kind, instances) in (&chunk.sprite_instances).into_iter() {
|
||||||
let SpriteData { model, locals, .. } = if kind
|
let SpriteData { model, locals, .. } = if kind
|
||||||
.0
|
.0
|
||||||
@ -1417,24 +1412,17 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
&self.sprite_data[&kind][4]
|
&self.sprite_data[&kind][4]
|
||||||
};
|
};
|
||||||
|
|
||||||
drawer.draw_sprite(
|
chunk_sprite_drawer.draw(model, instances, locals);
|
||||||
model,
|
|
||||||
instances,
|
|
||||||
&chunk.locals,
|
|
||||||
locals,
|
|
||||||
&self.sprite_col_lights,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
drop(sprite_drawer);
|
||||||
drop(guard);
|
drop(guard);
|
||||||
|
|
||||||
// Translucent
|
// Translucent
|
||||||
span!(guard, "Fluid chunks");
|
span!(guard, "Fluid chunks");
|
||||||
let mut fluid_drawer = drawer.draw_fluid(&self.waves);
|
let mut fluid_drawer = drawer.draw_fluid(&self.waves);
|
||||||
chunk_iter
|
chunk_iter
|
||||||
.clone()
|
|
||||||
.filter(|(_, chunk)| chunk.visible.is_visible())
|
.filter(|(_, chunk)| chunk.visible.is_visible())
|
||||||
.filter_map(|(_, chunk)| {
|
.filter_map(|(_, chunk)| {
|
||||||
chunk
|
chunk
|
||||||
|
@ -1318,34 +1318,9 @@ impl PlayState for SessionState {
|
|||||||
particles_enabled: settings.graphics.particles_enabled,
|
particles_enabled: settings.graphics.particles_enabled,
|
||||||
is_aiming: self.is_aiming,
|
is_aiming: self.is_aiming,
|
||||||
};
|
};
|
||||||
drawer.shadow_pass().map(|mut drawer| {
|
|
||||||
self.scene.render_terrain_shadows(
|
|
||||||
&mut drawer,
|
|
||||||
client.state(),
|
|
||||||
client.entity(),
|
|
||||||
client.get_tick(),
|
|
||||||
&scene_data,
|
|
||||||
);
|
|
||||||
|
|
||||||
self.scene.render_figure_shadows(
|
|
||||||
&mut drawer,
|
|
||||||
client.state(),
|
|
||||||
client.entity(),
|
|
||||||
client.get_tick(),
|
|
||||||
&scene_data,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
self.scene.render_point_shadows(
|
|
||||||
&mut drawer,
|
|
||||||
client.state(),
|
|
||||||
client.entity(),
|
|
||||||
client.get_tick(),
|
|
||||||
&scene_data,
|
|
||||||
);
|
|
||||||
|
|
||||||
self.scene.render(
|
self.scene.render(
|
||||||
&mut drawer.first_pass(),
|
&mut drawer,
|
||||||
client.state(),
|
client.state(),
|
||||||
client.entity(),
|
client.entity(),
|
||||||
client.get_tick(),
|
client.get_tick(),
|
||||||
|
Loading…
Reference in New Issue
Block a user