#Making a simple custom render pipeline

11 messages · Page 1 of 1 (latest)

gray topaz
#

I would like to create a custom render pipeline (i.e. only use bevy_render, not bevy_pbr or bevy_core_pipeline). I am trying to utilize CameraRenderGraph to tell bevy to execute my plugin's subgraph, but no matter what I do it doesn't seem to execute. Can someone help me understand what I'm doing wrong?

#
use bevy::log::info;
use bevy::prelude::*;
use bevy::render::RenderApp;
use bevy::render::camera::CameraRenderGraph;
use bevy::render::render_graph::{RenderGraphExt, ViewNodeRunner};

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_plugins(MyPlugin)
        .add_systems(Startup, setup)
        .run();
}

fn setup(mut commands: Commands) {
    commands.spawn((
        Name::new("mycam"),
        Camera::default(),
        CameraRenderGraph::new(MySubGraph),
    ));
}

struct MyPlugin;

impl Plugin for MyPlugin {
    fn build(&self, app: &mut App) {
        info!("building MyPlugin"); // this prints :)
        let Some(render_app) = app.get_sub_app_mut(RenderApp) else {
            warn!("no render app"); // this does not print :)
            return; // None in headless renderers
        };
        render_app
            .add_render_sub_graph(MySubGraph)
            .add_render_graph_node::<ViewNodeRunner<MyViewNode>>(
                MySubGraph,
                MyViewNodeLabel,
            );
    }
}

#[derive(
    Debug, Clone, Eq, PartialEq, Hash, bevy::render::render_graph::RenderSubGraph,
)]
struct MySubGraph;

#[derive(Debug, Default)]
struct MyViewNode;

impl bevy::render::render_graph::ViewNode for MyViewNode {
    type ViewQuery = ();

    fn run<'w>(
        &self,
        _graph: &mut bevy::render::render_graph::RenderGraphContext,
        _render_context: &mut bevy::render::renderer::RenderContext<'w>,
        _view_query: bevy::ecs::query::QueryItem<'w, '_, Self::ViewQuery>,
        _world: &'w World,
    ) -> std::result::Result<(), bevy::render::render_graph::NodeRunError> {
        info!("running MyViewNode"); // this does not print :(

        Ok(())
    }
}

#[derive(
    Debug, Eq, PartialEq, Hash, Clone, bevy::render::render_graph::RenderLabel,
)]
struct MyViewNodeLabel;
gray topaz
#

@mystic arrow am i supposed to instantiate the node somewhere?

#

I assumed that add_render_graph_node would take care of it

mystic arrow
#

you're right that it does take a subgraph argument

#

I missed that previously

#

I guess check if you need any sort of input node or somesuch?

#

that'd be my next guess

gray topaz
#

Btw i was able to fix it

#

Here's the functional code:

gray topaz
#
use bevy::log::info;
use bevy::prelude::*;
use bevy::render::RenderApp;
use bevy::render::camera::CameraRenderGraph;
use bevy::render::render_graph::{RenderGraphExt, ViewNodeRunner};

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_plugins(MyPlugin)
        .add_systems(Startup, setup)
        .run();
}

fn setup(mut commands: Commands) {
    commands.spawn((Name::new("mycam"), Camera::default(), MyCamera));
}

/// A custom camera component. Enables MySubGraph for a [`Camera`].
#[derive(
    Component,
    Default,
    Reflect,
    Clone,
    bevy::render::extract_component::ExtractComponent,
)]
#[reflect(Component, Default, Clone)]
#[require(
    Camera,
    Projection::Orthographic(OrthographicProjection::default_2d()), // Wont work without this
    // Frustum = OrthographicProjection::default_2d().compute_frustum(&GlobalTransform::from(Transform::default())),
)]
pub struct MyCamera;

struct MyPlugin;

impl Plugin for MyPlugin {
    fn build(&self, app: &mut App) {
        info!("building MyPlugin");

        app.register_required_components_with::<MyCamera, CameraRenderGraph>(|| {
            CameraRenderGraph::new(MySubGraph)
        });

        let Some(render_app) = app.get_sub_app_mut(RenderApp) else {
            warn!("no render app");
            return; // None in headless renderers
        };

        render_app
            .add_render_sub_graph(MySubGraph)
            .add_render_graph_node::<ViewNodeRunner<MyViewNode>>(
                MySubGraph,
                MyViewNodeLabel,
            );
    }
}

#[derive(
    Debug, Clone, Eq, PartialEq, Hash, bevy::render::render_graph::RenderSubGraph,
)]
struct MySubGraph;

#[derive(Debug, Default)]
struct MyViewNode;

impl bevy::render::render_graph::ViewNode for MyViewNode {
    type ViewQuery = ();

    fn run<'w>(
        &self,
        _graph: &mut bevy::render::render_graph::RenderGraphContext,
        _render_context: &mut bevy::render::renderer::RenderContext<'w>,
        _view_query: bevy::ecs::query::QueryItem<'w, '_, Self::ViewQuery>,
        _world: &'w World,
    ) -> std::result::Result<(), bevy::render::render_graph::NodeRunError> {
        info!("running MyViewNode");

        Ok(())
    }
}

#[derive(
    Debug, Eq, PartialEq, Hash, Clone, bevy::render::render_graph::RenderLabel,
)]
struct MyViewNodeLabel;