From e649d4f6e1eec4a394b969abca284682d0d5b896 Mon Sep 17 00:00:00 2001 From: Carter Anderson Date: Fri, 17 Jan 2020 00:46:40 -0800 Subject: [PATCH] initial render graph v2 work --- examples/shader_material.rs | 63 ++++++++++++++ src/render/mod.rs | 2 +- src/render/render_graph_2/mod.rs | 145 ++++++++++++++++++++++++++++++- 3 files changed, 208 insertions(+), 2 deletions(-) create mode 100644 examples/shader_material.rs diff --git a/examples/shader_material.rs b/examples/shader_material.rs new file mode 100644 index 0000000000..0e8eb518a1 --- /dev/null +++ b/examples/shader_material.rs @@ -0,0 +1,63 @@ +use bevy::{prelude::*, asset, render::{Albedo, render_graph_2::{StandardMaterial, ShaderMaterials, ShaderMaterial, ShaderValue}}}; + +fn main() { + AppBuilder::new().add_defaults().setup_world(setup).run(); +} + +fn setup(world: &mut World) { + let texture_handle = { + let mut texture_storage = world.resources.get_mut::>().unwrap(); + let texture = Texture::load(TextureType::Data(asset::create_texels(256))); + (texture_storage.add(texture)) + }; + + let mut color_shader_materials = ShaderMaterials::new(); + let color_material = StandardMaterial { + albedo: Albedo::Color(math::vec4(1.0, 0.0, 0.0, 0.0)) + }; + + color_shader_materials.add(color_material.get_selector()); + + world.insert( + (), + vec![( + color_shader_materials, + color_material, + )], + ); + + let mut texture_shader_materials = ShaderMaterials::new(); + let texture_material = StandardMaterial { + albedo: Albedo::Texture(texture_handle) + }; + + texture_shader_materials.add(texture_material.get_selector()); + + world.insert( + (), + vec![( + texture_shader_materials, + texture_material, + )], + ); + + for (entity, materials) in >::query().iter_entities(world) { + println!("entity {}", entity); + for selector in materials.materials.iter() { + let shader_material = selector(entity, world).unwrap(); + print!(" "); + for property in shader_material.iter_properties() { + println!("property: {}", property); + print!(" "); + match shader_material.get_property(property) { + Some(a) => match a { + ShaderValue::Vec4(color) => println!("color {}", color), + ShaderValue::Texture(ref handle) => println!("tex {}", handle.id), + _ => println!("other"), + }, + None => println!("none"), + } + } + } + } +} diff --git a/src/render/mod.rs b/src/render/mod.rs index 2c3731c126..8720c749c3 100644 --- a/src/render/mod.rs +++ b/src/render/mod.rs @@ -3,11 +3,11 @@ pub mod instancing; pub mod passes; pub mod render_resources; pub mod shader; +pub mod render_graph_2; mod light; mod material; mod render_graph; -mod render_graph_2; mod vertex; pub use camera::*; diff --git a/src/render/render_graph_2/mod.rs b/src/render/render_graph_2/mod.rs index 2e201da1e6..53d6b1a3fa 100644 --- a/src/render/render_graph_2/mod.rs +++ b/src/render/render_graph_2/mod.rs @@ -1,3 +1,146 @@ mod pipeline; -pub use pipeline::*; \ No newline at end of file +pub use pipeline::*; + +use crate::{asset::Texture, legion::{prelude::{Entity, World}, borrow::{Ref, RefMap}}, render::Albedo}; +use std::{collections::{HashMap, HashSet}, ops::Deref}; + +pub enum ShaderValue<'a> { + Int(u32), + Float(f32), + Vec4(crate::math::Vec4), + Texture(&'a crate::asset::Handle), +} + +type ShaderMaterialSelector = fn(Entity, &World) -> Option>; +pub struct ShaderMaterials { + // used for distinguishing + pub materials: Vec +} + +impl<'a> ShaderMaterials { + pub fn new() -> Self { + ShaderMaterials { + materials: Vec::new(), + } + } + + pub fn add(&mut self, selector: ShaderMaterialSelector) { + self.materials.push(selector); + } +} + +pub trait ShaderMaterial { + fn iter_properties(&self) -> std::slice::Iter<&'static str> ; + fn get_property(&self, name: &str) -> Option; + fn get_selector(&self) -> ShaderMaterialSelector; +} + +pub struct StandardMaterial { + pub albedo: Albedo +} + +// create this from a derive macro +const STANDARD_MATERIAL_PROPERTIES: &[&str] = &["albedo"]; +impl ShaderMaterial for StandardMaterial { + fn iter_properties(&self) -> std::slice::Iter<&'static str> { + STANDARD_MATERIAL_PROPERTIES.iter() + } + fn get_property(&self, name: &str) -> Option { + match name { + "albedo" => Some(match self.albedo { + Albedo::Color(color) => ShaderValue::Vec4(color), + Albedo::Texture(ref texture) => ShaderValue::Texture(texture) + }), + _ => None, + } + } + fn get_selector(&self) -> ShaderMaterialSelector { + |entity, world| { + world.get_component::(entity).map( + |c: Ref| { + c.map_into(|s| { + s as &dyn ShaderMaterial + }) + } + ) + } + } +} + + +// a named graphics resource provided by a resource provider +struct Resource { + resource_type: ResourceType, + name: String, +} + +// a resource type +enum ResourceType { + Texture, + Uniform, + Sampler, +} + +// impl Into for StandardMaterial + +// manages a specific named resource in a RenderGraph. [my_texture_name: TextureView]--> +// updates resources based on events like "resize" or "update" +// if there are no resources in use, dont run allocate resource provider resources on gpu +trait ResourceProvider { + fn get_resources() -> Vec; +} + +// holds on to passes, pipeline descriptions, instances +// passes: shadow, forward +struct RenderGraph; +/* +RenderGraph::build() +.AddPass("forward", Pass { + +}) +.AddPipeline(Pipeline::build() + .with_vertex_shader("pbr.vert") + .with_fragment_shader("pbr.frag") + .with_vertex_layout(Vertex::get_layout()) // maybe someday reflect this using spirv-reflect + .with_uniform_binding("camera_resource", "shader_camera") // if a uniform is not bound directly, and no uniforms are set on entity, produce an error + .with_texture_binding("some_texture", "shader_texture") // if a uniform is not bound directly, and no uniforms are set on entity, produce an error + .with_draw_target(MeshDrawTarget) + .with_draw_target(InstancedMeshDrawTarget) +) +.AddPipeline(Pipeline::build() + .with_vertex_shader("ui.vert") + .with_fragment_shader("ui.frag") + .with_vertex_layout(Vertex::get_layout()) + .with_draw_target(UiDrawTarget) +) +.AddPass("shadow", Pass { + render_target: Null + depth_target: DepthTexture (TextureView) +}) +.AddPipeline(Pipeline::build() + .with_vertex_shader("pbr.vert") + .with_fragment_shader("pbr.frag") + .with_vertex_layout(Vertex::get_layout()) + .with_draw_target(ShadowedMeshDrawTarget) + .with_draw_target(ShadowedInstancedMeshDrawTarget) +) +*/ + +// A set of draw calls. ex: get + draw meshes, get + draw instanced meshes, draw ui meshes, etc +// Mesh target +trait DrawTarget { + fn draw(device: &wgpu::Device); +} + +// a texture that is rendered to. TextureView or SwapChain +struct RenderTarget; + +// A set of pipeline bindings and draw calls with color and depth outputs +struct Pass; + +// A pipeline description (original shaders) +struct PipelineDefinition; + +// A specific instance of a pipeline definition +struct Pipeline; \ No newline at end of file