mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Separated volumetrics and transparents into independent passes to fix UB
This commit is contained in:
@ -284,9 +284,9 @@ impl PlayState for CharSelectionState {
|
|||||||
.render(&mut first_pass, client.get_tick(), humanoid_body, loadout);
|
.render(&mut first_pass, client.get_tick(), humanoid_body, loadout);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clouds
|
if let Some(mut volumetric_pass) = drawer.volumetric_pass() {
|
||||||
if let Some(mut second_pass) = drawer.second_pass() {
|
// Clouds
|
||||||
second_pass.draw_clouds();
|
volumetric_pass.draw_clouds();
|
||||||
}
|
}
|
||||||
// Bloom (does nothing if bloom is disabled)
|
// Bloom (does nothing if bloom is disabled)
|
||||||
drawer.run_bloom_passes();
|
drawer.run_bloom_passes();
|
||||||
|
@ -50,9 +50,9 @@ pub use self::{
|
|||||||
renderer::{
|
renderer::{
|
||||||
drawer::{
|
drawer::{
|
||||||
DebugDrawer, DebugShadowDrawer, Drawer, FigureDrawer, FigureShadowDrawer,
|
DebugDrawer, DebugShadowDrawer, Drawer, FigureDrawer, FigureShadowDrawer,
|
||||||
FirstPassDrawer, ParticleDrawer, PreparedUiDrawer, SecondPassDrawer, ShadowPassDrawer,
|
FirstPassDrawer, ParticleDrawer, PreparedUiDrawer, ShadowPassDrawer, SpriteDrawer,
|
||||||
SpriteDrawer, TerrainDrawer, TerrainShadowDrawer, ThirdPassDrawer, TrailDrawer,
|
TerrainDrawer, TerrainShadowDrawer, ThirdPassDrawer, TrailDrawer,
|
||||||
UiDrawer,
|
TransparentPassDrawer, UiDrawer, VolumetricPassDrawer,
|
||||||
},
|
},
|
||||||
ColLightInfo, Renderer,
|
ColLightInfo, Renderer,
|
||||||
},
|
},
|
||||||
|
@ -177,22 +177,7 @@ impl CloudsPipeline {
|
|||||||
polygon_mode: wgpu::PolygonMode::Fill,
|
polygon_mode: wgpu::PolygonMode::Fill,
|
||||||
conservative: false,
|
conservative: false,
|
||||||
},
|
},
|
||||||
depth_stencil: Some(wgpu::DepthStencilState {
|
depth_stencil: None,
|
||||||
format: wgpu::TextureFormat::Depth32Float,
|
|
||||||
depth_write_enabled: false,
|
|
||||||
depth_compare: wgpu::CompareFunction::Always,
|
|
||||||
stencil: wgpu::StencilState {
|
|
||||||
front: wgpu::StencilFaceState::IGNORE,
|
|
||||||
back: wgpu::StencilFaceState::IGNORE,
|
|
||||||
read_mask: !0,
|
|
||||||
write_mask: 0,
|
|
||||||
},
|
|
||||||
bias: wgpu::DepthBiasState {
|
|
||||||
constant: 0,
|
|
||||||
slope_scale: 0.0,
|
|
||||||
clamp: 0.0,
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
multisample: wgpu::MultisampleState {
|
multisample: wgpu::MultisampleState {
|
||||||
count: samples,
|
count: samples,
|
||||||
mask: !0,
|
mask: !0,
|
||||||
|
@ -252,16 +252,16 @@ impl<'frame> Drawer<'frame> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns None if the clouds pipeline is not available
|
/// Returns None if the volumetrics pipeline is not available
|
||||||
pub fn second_pass(&mut self) -> Option<SecondPassDrawer> {
|
pub fn volumetric_pass(&mut self) -> Option<VolumetricPassDrawer> {
|
||||||
let pipelines = &self.borrow.pipelines.all()?;
|
let pipelines = &self.borrow.pipelines.all()?;
|
||||||
let shadow = self.borrow.shadow?;
|
let shadow = self.borrow.shadow?;
|
||||||
|
|
||||||
let encoder = self.encoder.as_mut().unwrap();
|
let encoder = self.encoder.as_mut().unwrap();
|
||||||
let device = self.borrow.device;
|
let device = self.borrow.device;
|
||||||
let mut render_pass =
|
let mut render_pass =
|
||||||
encoder.scoped_render_pass("second_pass", device, &wgpu::RenderPassDescriptor {
|
encoder.scoped_render_pass("volumetric_pass", device, &wgpu::RenderPassDescriptor {
|
||||||
label: Some("second pass (clouds)"),
|
label: Some("volumetric pass (clouds)"),
|
||||||
color_attachments: &[wgpu::RenderPassColorAttachment {
|
color_attachments: &[wgpu::RenderPassColorAttachment {
|
||||||
view: &self.borrow.views.tgt_color_pp,
|
view: &self.borrow.views.tgt_color_pp,
|
||||||
resolve_target: None,
|
resolve_target: None,
|
||||||
@ -270,9 +270,43 @@ impl<'frame> Drawer<'frame> {
|
|||||||
store: true,
|
store: true,
|
||||||
},
|
},
|
||||||
}],
|
}],
|
||||||
|
depth_stencil_attachment: None,
|
||||||
|
});
|
||||||
|
|
||||||
|
render_pass.set_bind_group(0, &self.globals.bind_group, &[]);
|
||||||
|
render_pass.set_bind_group(1, &shadow.bind.bind_group, &[]);
|
||||||
|
|
||||||
|
Some(VolumetricPassDrawer {
|
||||||
|
render_pass,
|
||||||
|
borrow: &self.borrow,
|
||||||
|
clouds_pipeline: &pipelines.clouds,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns None if the trail pipeline is not available
|
||||||
|
pub fn transparent_pass(&mut self) -> Option<TransparentPassDrawer> {
|
||||||
|
let pipelines = &self.borrow.pipelines.all()?;
|
||||||
|
let shadow = self.borrow.shadow?;
|
||||||
|
|
||||||
|
let encoder = self.encoder.as_mut().unwrap();
|
||||||
|
let device = self.borrow.device;
|
||||||
|
let mut render_pass =
|
||||||
|
encoder.scoped_render_pass("transparent_pass", device, &wgpu::RenderPassDescriptor {
|
||||||
|
label: Some("transparent pass (trails)"),
|
||||||
|
color_attachments: &[wgpu::RenderPassColorAttachment {
|
||||||
|
view: &self.borrow.views.tgt_color_pp,
|
||||||
|
resolve_target: None,
|
||||||
|
ops: wgpu::Operations {
|
||||||
|
load: wgpu::LoadOp::Load,
|
||||||
|
store: true,
|
||||||
|
},
|
||||||
|
}],
|
||||||
depth_stencil_attachment: Some(wgpu::RenderPassDepthStencilAttachment {
|
depth_stencil_attachment: Some(wgpu::RenderPassDepthStencilAttachment {
|
||||||
view: &self.borrow.views.tgt_depth,
|
view: &self.borrow.views.tgt_depth,
|
||||||
depth_ops: None,
|
depth_ops: Some(wgpu::Operations {
|
||||||
|
load: wgpu::LoadOp::Load,
|
||||||
|
store: false,
|
||||||
|
}),
|
||||||
stencil_ops: None,
|
stencil_ops: None,
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
@ -280,10 +314,9 @@ impl<'frame> Drawer<'frame> {
|
|||||||
render_pass.set_bind_group(0, &self.globals.bind_group, &[]);
|
render_pass.set_bind_group(0, &self.globals.bind_group, &[]);
|
||||||
render_pass.set_bind_group(1, &shadow.bind.bind_group, &[]);
|
render_pass.set_bind_group(1, &shadow.bind.bind_group, &[]);
|
||||||
|
|
||||||
Some(SecondPassDrawer {
|
Some(TransparentPassDrawer {
|
||||||
render_pass,
|
render_pass,
|
||||||
borrow: &self.borrow,
|
borrow: &self.borrow,
|
||||||
clouds_pipeline: &pipelines.clouds,
|
|
||||||
trail_pipeline: &pipelines.trail,
|
trail_pipeline: &pipelines.trail,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -1043,16 +1076,15 @@ impl<'pass_ref, 'pass: 'pass_ref> FluidDrawer<'pass_ref, 'pass> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Second pass: clouds
|
// Second pass: volumetrics
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub struct SecondPassDrawer<'pass> {
|
pub struct VolumetricPassDrawer<'pass> {
|
||||||
render_pass: OwningScope<'pass, wgpu::RenderPass<'pass>>,
|
render_pass: OwningScope<'pass, wgpu::RenderPass<'pass>>,
|
||||||
borrow: &'pass RendererBorrow<'pass>,
|
borrow: &'pass RendererBorrow<'pass>,
|
||||||
clouds_pipeline: &'pass clouds::CloudsPipeline,
|
clouds_pipeline: &'pass clouds::CloudsPipeline,
|
||||||
trail_pipeline: &'pass trail::TrailPipeline,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'pass> SecondPassDrawer<'pass> {
|
impl<'pass> VolumetricPassDrawer<'pass> {
|
||||||
pub fn draw_clouds(&mut self) {
|
pub fn draw_clouds(&mut self) {
|
||||||
self.render_pass
|
self.render_pass
|
||||||
.set_pipeline(&self.clouds_pipeline.pipeline);
|
.set_pipeline(&self.clouds_pipeline.pipeline);
|
||||||
@ -1060,7 +1092,17 @@ impl<'pass> SecondPassDrawer<'pass> {
|
|||||||
.set_bind_group(2, &self.borrow.locals.clouds_bind.bind_group, &[]);
|
.set_bind_group(2, &self.borrow.locals.clouds_bind.bind_group, &[]);
|
||||||
self.render_pass.draw(0..3, 0..1);
|
self.render_pass.draw(0..3, 0..1);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Third pass: transparents
|
||||||
|
#[must_use]
|
||||||
|
pub struct TransparentPassDrawer<'pass> {
|
||||||
|
render_pass: OwningScope<'pass, wgpu::RenderPass<'pass>>,
|
||||||
|
borrow: &'pass RendererBorrow<'pass>,
|
||||||
|
trail_pipeline: &'pass trail::TrailPipeline,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'pass> TransparentPassDrawer<'pass> {
|
||||||
pub fn draw_trails(&mut self) -> Option<TrailDrawer<'_, 'pass>> {
|
pub fn draw_trails(&mut self) -> Option<TrailDrawer<'_, 'pass>> {
|
||||||
let shadow = &self.borrow.shadow?;
|
let shadow = &self.borrow.shadow?;
|
||||||
|
|
||||||
|
@ -1836,20 +1836,18 @@ impl PlayState for SessionState {
|
|||||||
&scene_data,
|
&scene_data,
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Some(mut second_pass) = drawer.second_pass() {
|
if let Some(mut volumetric_pass) = drawer.volumetric_pass() {
|
||||||
// Clouds
|
// Clouds
|
||||||
{
|
prof_span!("clouds");
|
||||||
prof_span!("clouds");
|
volumetric_pass.draw_clouds();
|
||||||
second_pass.draw_clouds();
|
}
|
||||||
}
|
if let Some(mut transparent_pass) = drawer.transparent_pass() {
|
||||||
// Trails
|
// Trails
|
||||||
{
|
prof_span!("trails");
|
||||||
prof_span!("trails");
|
if let Some(mut trail_drawer) = transparent_pass.draw_trails() {
|
||||||
if let Some(mut trail_drawer) = second_pass.draw_trails() {
|
self.scene
|
||||||
self.scene
|
.trail_mgr()
|
||||||
.trail_mgr()
|
.render(&mut trail_drawer, &scene_data);
|
||||||
.render(&mut trail_drawer, &scene_data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Bloom (call does nothing if bloom is off)
|
// Bloom (call does nothing if bloom is off)
|
||||||
|
Reference in New Issue
Block a user