1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
|
use bevy::{prelude::*, render::{render_graph::{ViewNode, NodeRunError, RenderGraphContext, RenderLabel}, view::ViewTarget, renderer::RenderContext, render_resource::{PipelineCache, BindGroupEntries, RenderPassDescriptor, RenderPassColorAttachment, Operations}, extract_component::ComponentUniforms}, core_pipeline::prepass::ViewPrepassTextures, ecs::query::QueryItem};
use super::components;
use super::resources;
#[derive(RenderLabel, Clone, Eq, PartialEq, Hash, Debug)]
pub struct OutlineRenderLabel;
#[derive(Default)]
pub struct OutlineRenderNode;
impl ViewNode for OutlineRenderNode {
type ViewQuery = (
&'static ViewTarget,
&'static ViewPrepassTextures,
&'static components::OutlinePostProcessSettings,
);
fn run(
&self,
_graph: &mut RenderGraphContext,
render_context: &mut RenderContext,
(view_target, view_prepass_textures, _): QueryItem<Self::ViewQuery>,
world: &World,
) -> Result<(), NodeRunError> {
let render_pipeline = world.resource::<resources::OutlinePostProcessPipeline>();
let pipeline_cache = world.resource::<PipelineCache>();
let Some(pipeline) = pipeline_cache.get_render_pipeline(render_pipeline.pipeline_id) else {
warn!("Failed to get render pipeline from cache, skipping...");
return Ok(());
};
let uniforms = world.resource::<ComponentUniforms<components::OutlinePostProcessSettings>>();
let Some(uniform_binding) = uniforms.uniforms().binding() else {
error!("Failed to get settings uniform binding");
return Ok(());
};
let Some(normal_buffer_view) = view_prepass_textures.normal_view() else {
error!("Failed to get normal buffer view");
return Ok(());
};
let post_process = view_target.post_process_write();
let bind_group = render_context.render_device().create_bind_group(
"outline_post_process_bind_group",
&render_pipeline.layout,
&BindGroupEntries::sequential((
post_process.source,
&render_pipeline.screen_sampler,
normal_buffer_view,
&render_pipeline.normal_sampler,
uniform_binding,
)),
);
let mut render_pass = render_context.begin_tracked_render_pass(RenderPassDescriptor {
label: Some("outline_post_process_render_pass"),
color_attachments: &[Some(RenderPassColorAttachment {
view: post_process.destination,
ops: Operations::default(),
resolve_target: None,
})],
timestamp_writes: None,
depth_stencil_attachment: None,
occlusion_query_set: None,
});
render_pass.set_render_pipeline(pipeline);
render_pass.set_bind_group(0, &bind_group, &[]);
render_pass.draw(0..3, 0..1);
Ok(())
}
}
|