initial render graph v2 work

This commit is contained in:
Carter Anderson 2020-01-17 00:46:40 -08:00
parent 435357ee86
commit e649d4f6e1
3 changed files with 208 additions and 2 deletions

View file

@ -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::<AssetStorage<Texture>>().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 <Read<ShaderMaterials>>::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"),
}
}
}
}
}

View file

@ -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::*;

View file

@ -1,3 +1,146 @@
mod pipeline;
pub use pipeline::*;
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<Texture>),
}
type ShaderMaterialSelector = fn(Entity, &World) -> Option<RefMap<&dyn ShaderMaterial>>;
pub struct ShaderMaterials {
// used for distinguishing
pub materials: Vec<ShaderMaterialSelector>
}
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<ShaderValue>;
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<ShaderValue> {
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::<Self>(entity).map(
|c: Ref<StandardMaterial>| {
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<ShaderMaterial> 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<String>;
}
// 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;