Skip to content

Commit

Permalink
Updates.
Browse files Browse the repository at this point in the history
  • Loading branch information
tychedelia committed Oct 20, 2024
1 parent eba013d commit d8df46a
Show file tree
Hide file tree
Showing 11 changed files with 876 additions and 592 deletions.
1,235 changes: 737 additions & 498 deletions Cargo.lock

Large diffs are not rendered by default.

16 changes: 10 additions & 6 deletions bevy_nannou_draw/src/draw/indirect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ use bevy::{
};
use rayon::prelude::*;
use std::{hash::Hash, marker::PhantomData};
use crate::render::RenderShaderModelInstances;

pub struct Indirect<'a, SM>
where
Expand Down Expand Up @@ -98,6 +99,9 @@ where
#[derive(Component, ExtractComponent, Clone)]
pub struct IndirectMesh;

#[derive(Component, ExtractComponent, Clone)]
pub struct IndirectBuffer(pub Handle<ShaderStorageBuffer>);

pub struct IndirectShaderModelPlugin<SM>(PhantomData<SM>);

impl<SM> Default for IndirectShaderModelPlugin<SM>
Expand Down Expand Up @@ -140,7 +144,7 @@ impl<P: PhaseItem, SM: ShaderModel, const I: usize> RenderCommand<P>
{
type Param = (
SRes<RenderAssets<PreparedShaderModel<SM>>>,
SRes<ExtractedInstances<AssetId<SM>>>,
SRes<RenderShaderModelInstances<SM>>,
);
type ViewQuery = ();
type ItemQuery = ();
Expand All @@ -156,7 +160,7 @@ impl<P: PhaseItem, SM: ShaderModel, const I: usize> RenderCommand<P>
let models = models.into_inner();
let instances = instances.into_inner();

let Some(asset_id) = instances.get(&item.entity()) else {
let Some(asset_id) = instances.get(&item.main_entity()) else {
return RenderCommandResult::Skip;
};
let Some(model) = models.get(*asset_id) else {
Expand All @@ -176,13 +180,13 @@ impl<P: PhaseItem> RenderCommand<P> for DrawMeshIndirect {
SRes<RenderAssets<GpuShaderStorageBuffer>>,
);
type ViewQuery = ();
type ItemQuery = Read<Handle<ShaderStorageBuffer>>;
type ItemQuery = Read<IndirectBuffer>;

#[inline]
fn render<'w>(
item: &P,
_view: (),
indirect_buffer: Option<&'w Handle<ShaderStorageBuffer>>,
indirect_buffer: Option<&'w IndirectBuffer>,
(meshes, render_mesh_instances, mesh_allocator, ssbos): SystemParamItem<
'w,
'_,
Expand All @@ -192,7 +196,7 @@ impl<P: PhaseItem> RenderCommand<P> for DrawMeshIndirect {
) -> RenderCommandResult {
let mesh_allocator = mesh_allocator.into_inner();

let Some(mesh_instance) = render_mesh_instances.render_mesh_queue_data(item.entity())
let Some(mesh_instance) = render_mesh_instances.render_mesh_queue_data(item.main_entity())
else {
return RenderCommandResult::Skip;
};
Expand All @@ -202,7 +206,7 @@ impl<P: PhaseItem> RenderCommand<P> for DrawMeshIndirect {
let Some(indirect_buffer) = indirect_buffer else {
return RenderCommandResult::Skip;
};
let Some(indirect_buffer) = ssbos.into_inner().get(indirect_buffer) else {
let Some(indirect_buffer) = ssbos.into_inner().get(&indirect_buffer.0) else {
return RenderCommandResult::Skip;
};
let Some(vertex_buffer_slice) =
Expand Down
20 changes: 8 additions & 12 deletions bevy_nannou_draw/src/draw/instanced.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,26 +10,22 @@ use bevy::{
pbr::{RenderMeshInstances, SetMeshBindGroup, SetMeshViewBindGroup},
prelude::*,
render::{
extract_component::{ExtractComponent, ExtractComponentPlugin},
extract_component::ExtractComponent,
extract_instances::ExtractedInstances,
mesh::{
allocator::MeshAllocator, MeshVertexBufferLayoutRef, RenderMesh, RenderMeshBufferInfo,
},
mesh::{allocator::MeshAllocator, RenderMesh, RenderMeshBufferInfo},
render_asset::{prepare_assets, RenderAssets},
render_phase::{
AddRenderCommand, BinnedRenderPhaseType, DrawFunctions, PhaseItem, RenderCommand,
RenderCommandResult, SetItemPipeline, TrackedRenderPass, ViewBinnedRenderPhases,
AddRenderCommand, PhaseItem, RenderCommand, RenderCommandResult, SetItemPipeline,
TrackedRenderPass,
},
render_resource::*,
renderer::RenderDevice,
storage::GpuShaderStorageBuffer,
view,
view::{ExtractedView, VisibilitySystems},
Render, RenderApp, RenderSet,
},
};
use rayon::prelude::*;
use std::{hash::Hash, marker::PhantomData, ops::Range};
use crate::render::RenderShaderModelInstances;

pub struct Instanced<'a, SM>
where
Expand Down Expand Up @@ -142,7 +138,7 @@ impl<P: PhaseItem, SM: ShaderModel, const I: usize> RenderCommand<P>
{
type Param = (
SRes<RenderAssets<PreparedShaderModel<SM>>>,
SRes<ExtractedInstances<AssetId<SM>>>,
SRes<RenderShaderModelInstances<SM>>,
);
type ViewQuery = ();
type ItemQuery = ();
Expand All @@ -158,7 +154,7 @@ impl<P: PhaseItem, SM: ShaderModel, const I: usize> RenderCommand<P>
let models = models.into_inner();
let instances = instances.into_inner();

let Some(asset_id) = instances.get(&item.entity()) else {
let Some(asset_id) = instances.get(&item.main_entity()) else {
return RenderCommandResult::Skip;
};
let Some(shader_model) = models.get(*asset_id) else {
Expand Down Expand Up @@ -194,7 +190,7 @@ impl<P: PhaseItem> RenderCommand<P> for DrawMeshInstanced {
) -> RenderCommandResult {
let mesh_allocator = mesh_allocator.into_inner();

let Some(mesh_instance) = render_mesh_instances.render_mesh_queue_data(item.entity())
let Some(mesh_instance) = render_mesh_instances.render_mesh_queue_data(item.main_entity())
else {
return RenderCommandResult::Skip;
};
Expand Down
114 changes: 72 additions & 42 deletions bevy_nannou_draw/src/render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use crate::{
DrawHolder,
};
use bevy::render::storage::ShaderStorageBuffer;
use bevy::render::Extract;
use bevy::{
asset::{load_internal_asset, Asset, UntypedAssetId},
core_pipeline::core_3d::Transparent3d,
Expand Down Expand Up @@ -53,11 +54,13 @@ use bevy::{
};
use lyon::lyon_tessellation::{FillTessellator, StrokeTessellator};
use std::{any::TypeId, hash::Hash, marker::PhantomData};
use bevy::render::sync_world::{MainEntity, MainEntityHashMap, RenderEntity};
use crate::draw::indirect::IndirectBuffer;

pub const DEFAULT_NANNOU_SHADER_HANDLE: Handle<Shader> = Handle::weak_from_u128(3086880141013591);

pub trait ShaderModel:
Asset + AsBindGroup + Clone + Default + Sized + Send + Sync + 'static
Asset + AsBindGroup + Clone + Default + Sized + Send + Sync + 'static
{
/// Returns this shader model's vertex shader. If [`ShaderRef::Default`] is returned, the default mesh vertex shader
/// will be used.
Expand All @@ -83,6 +86,16 @@ pub trait ShaderModel:
}
}

impl ShaderModel for StandardMaterial {
fn vertex_shader() -> ShaderRef {
<Self as ShaderModel>::vertex_shader()
}

fn fragment_shader() -> ShaderRef {
<Self as ShaderModel>::fragment_shader()
}
}

pub struct NannouRenderPlugin;

impl Plugin for NannouRenderPlugin {
Expand All @@ -102,7 +115,7 @@ impl Plugin for NannouRenderPlugin {
ExtractComponentPlugin::<IndirectMesh>::default(),
ExtractComponentPlugin::<InstancedMesh>::default(),
ExtractComponentPlugin::<DrawIndex>::default(),
ExtractComponentPlugin::<Handle<ShaderStorageBuffer>>::default(),
ExtractComponentPlugin::<IndirectBuffer>::default(),
ExtractComponentPlugin::<InstanceRange>::default(),
ExtractResourcePlugin::<DefaultTextureHandle>::default(),
NannouShaderModelPlugin::<DefaultNannouShaderModel>::default(),
Expand Down Expand Up @@ -130,7 +143,6 @@ where
fn build(&self, app: &mut App) {
app.init_asset::<SM>()
.add_plugins((
ExtractInstancesPlugin::<AssetId<SM>>::extract_visible(),
RenderAssetPlugin::<PreparedShaderModel<SM>>::default(),
IndirectShaderModelPlugin::<SM>::default(),
InstancedShaderModelPlugin::<SM>::default(),
Expand All @@ -143,6 +155,14 @@ where
app.sub_app_mut(RenderApp)
.add_render_command::<Transparent3d, DrawShaderModel<SM>>()
.init_resource::<SpecializedMeshPipelines<ShaderModelPipeline<SM>>>()
.add_systems(
ExtractSchedule,
(
clear_shader_model_instances::<SM>,
extract_shader_models::<SM>,
)
.chain(),
)
.add_systems(
bevy::render::Render,
queue_shader_model::<SM, With<ShaderModelMesh>, DrawShaderModel<SM>>
Expand All @@ -153,6 +173,7 @@ where

fn finish(&self, app: &mut App) {
app.sub_app_mut(RenderApp)
.init_resource::<RenderShaderModelInstances<SM>>()
.init_resource::<ShaderModelPipeline<SM>>();
}
}
Expand Down Expand Up @@ -199,11 +220,11 @@ impl<SM: ShaderModel> RenderAsset for PreparedShaderModel<SM> {
/// Sets the bind group for a given [`ShaderModel`] at the configured `I` index.
pub struct SetShaderModelBindGroup<SM: ShaderModel, const I: usize>(PhantomData<SM>);
impl<P: PhaseItem, SM: ShaderModel, const I: usize> RenderCommand<P>
for SetShaderModelBindGroup<SM, I>
for SetShaderModelBindGroup<SM, I>
{
type Param = (
SRes<RenderAssets<PreparedShaderModel<SM>>>,
SRes<ExtractedInstances<AssetId<SM>>>,
SRes<RenderShaderModelInstances<SM>>,
);
type ViewQuery = ();
type ItemQuery = ();
Expand All @@ -219,7 +240,7 @@ impl<P: PhaseItem, SM: ShaderModel, const I: usize> RenderCommand<P>
let models = models.into_inner();
let model_instances = model_instances.into_inner();

let Some(shader_model_asset_id) = model_instances.get(&item.entity()) else {
let Some(shader_model_asset_id) = model_instances.get(&item.main_entity()) else {
return RenderCommandResult::Skip;
};
let Some(model) = models.get(*shader_model_asset_id) else {
Expand Down Expand Up @@ -303,6 +324,28 @@ impl From<&NannouShaderModel> for NannouBindGroupData {
}
}

fn clear_shader_model_instances<SM>(mut shader_model_instances: ResMut<RenderShaderModelInstances<SM>>)
where
SM: ShaderModel,
SM::Data: PartialEq + Eq + Hash + Clone,
{
shader_model_instances.clear();
}

fn extract_shader_models<SM>(
mut material_instances: ResMut<RenderShaderModelInstances<SM>>,
query: Extract<Query<(Entity, &ViewVisibility, &ShaderModelHandle<SM>), With<ShaderModelMesh>>>,
) where
SM: ShaderModel,
SM::Data: PartialEq + Eq + Hash + Clone,
{
for (entity, view_visibility, shader_model) in &query {
if view_visibility.get() {
material_instances.insert(entity.into(), shader_model.id());
}
}
}

#[allow(clippy::too_many_arguments)]
pub(crate) fn queue_shader_model<SM, QF, RC>(
draw_functions: Res<DrawFunctions<Transparent3d>>,
Expand All @@ -319,11 +362,11 @@ pub(crate) fn queue_shader_model<SM, QF, RC>(
extracted_instances,
): (
Res<RenderMeshInstances>,
Query<(Entity, &DrawIndex), QF>,
Query<(Entity, &MainEntity, &DrawIndex), QF>,
ResMut<ViewSortedRenderPhases<Transparent3d>>,
Query<(Entity, &ExtractedView, &Msaa)>,
Res<RenderAssets<PreparedShaderModel<SM>>>,
Res<ExtractedInstances<AssetId<SM>>>,
Res<RenderShaderModelInstances<SM>>,
),
) where
SM: ShaderModel,
Expand All @@ -340,14 +383,14 @@ pub(crate) fn queue_shader_model<SM, QF, RC>(
};

let view_key = msaa_key | MeshPipelineKey::from_hdr(view.hdr);
for (entity, draw_idx) in &nannou_meshes {
let Some(shader_model) = extracted_instances.get(&entity) else {
for (entity, main_entity, draw_idx) in &nannou_meshes {
let Some(shader_model) = extracted_instances.get(main_entity) else {
continue;
};
let Some(shader_model) = shader_models.get(*shader_model) else {
continue;
};
let Some(mesh_instance) = render_mesh_instances.render_mesh_queue_data(entity) else {
let Some(mesh_instance) = render_mesh_instances.render_mesh_queue_data(*main_entity) else {
continue;
};
let Some(mesh) = meshes.get(mesh_instance.mesh_asset_id) else {
Expand All @@ -366,7 +409,7 @@ pub(crate) fn queue_shader_model<SM, QF, RC>(
phase.add(Transparent3d {
distance: draw_idx.0 as f32,
pipeline,
entity,
entity: (entity, *main_entity),
draw_function,
batch_range: Default::default(),
extra_index: PhaseItemExtraIndex(0),
Expand Down Expand Up @@ -562,7 +605,7 @@ fn update_shader_model<SM>(
if id.type_id() == TypeId::of::<SM>() {
commands
.entity(entity)
.insert(Handle::Weak(id.typed::<SM>()));
.insert(ShaderModelHandle(Handle::Weak(id.typed::<SM>())));
}
}
}
Expand Down Expand Up @@ -650,12 +693,8 @@ fn update_draw_mesh(
InstancedMesh,
InstanceRange(range),
UntypedShaderModelId(model_id),
mesh.clone(),
Transform::default(),
GlobalTransform::default(),
Visibility::default(),
InheritedVisibility::default(),
ViewVisibility::default(),
Mesh3d(mesh.clone()),
SpatialBundle::INHERITED_IDENTITY,
NannouTransient,
NoFrustumCulling,
DrawIndex(idx),
Expand Down Expand Up @@ -685,14 +724,10 @@ fn update_draw_mesh(
last_shader_model.expect("No shader model set for instanced draw command");
commands.spawn((
IndirectMesh,
indirect_buffer,
IndirectBuffer(indirect_buffer),
UntypedShaderModelId(model_id),
mesh.clone(),
Transform::default(),
GlobalTransform::default(),
Visibility::default(),
InheritedVisibility::default(),
ViewVisibility::default(),
Mesh3d(mesh.clone()),
SpatialBundle::INHERITED_IDENTITY,
NannouTransient,
NoFrustumCulling,
DrawIndex(idx),
Expand All @@ -708,13 +743,9 @@ fn update_draw_mesh(
mesh = meshes.add(Mesh::init());
commands.spawn((
UntypedShaderModelId(model_id),
mesh.clone(),
Transform::default(),
GlobalTransform::default(),
Visibility::default(),
InheritedVisibility::default(),
ViewVisibility::default(),
ShaderModelMesh,
Mesh3d(mesh.clone()),
SpatialBundle::INHERITED_IDENTITY,
NannouTransient,
NoFrustumCulling,
DrawIndex(idx),
Expand All @@ -738,12 +769,14 @@ pub struct NannouTransient;
#[derive(Component, ExtractComponent, Clone)]
pub struct ShaderModelMesh;

#[derive(Resource)]
pub struct NannouRender {
pub mesh: Handle<Mesh>,
pub entity: Entity,
pub draw_context: DrawContext,
}
#[derive(Component, Deref, DerefMut, Clone)]
pub struct ShaderModelHandle<SM: ShaderModel>(Handle<SM>);

#[derive(Default, Resource, Deref, DerefMut)]
pub struct RenderShaderModelInstances<SM: ShaderModel>(MainEntityHashMap<AssetId<SM>>);

#[derive(Component)]
pub struct NannouCamera;

// BLEND
pub mod blend {
Expand Down Expand Up @@ -784,7 +817,4 @@ pub mod blend {
dst_factor: wgpu::BlendFactor::One,
operation: wgpu::BlendOperation::Max,
};
}

#[derive(Component)]
pub struct NannouCamera;
}
Loading

0 comments on commit d8df46a

Please sign in to comment.