Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bevy_webgl2 render backend #613

Closed
wants to merge 12 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 30 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,32 @@ default = [
"x11",
]

supported_android_features = [
# cpal is not supported yet
# "bevy_audio",
"bevy_dynamic_plugin",
"bevy_gilrs",
"bevy_gltf",
"bevy_wgpu",
"bevy_winit",
"render",
"png",
"hdr",
# "mp3",
"x11",
]

web = [
"bevy_webgl2",
"bevy_gltf",
"bevy_winit",
"render",
"bevy_sprite",
"png",
"bevy_text",
"bevy_ui",
]

profiler = ["bevy_ecs/profiler", "bevy_diagnostic/profiler"]
wgpu_trace = ["bevy_wgpu/trace"]

Expand Down Expand Up @@ -81,23 +107,26 @@ bevy_sprite = { path = "crates/bevy_sprite", optional = true, version = "0.3.0"
bevy_text = { path = "crates/bevy_text", optional = true, version = "0.3.0" }
bevy_ui = { path = "crates/bevy_ui", optional = true, version = "0.3.0" }
bevy_wgpu = { path = "crates/bevy_wgpu", optional = true, version = "0.3.0" }
bevy_webgl2 = { path = "crates/bevy_webgl2", optional = true, version = "0.3.0" }
bevy_winit = { path = "crates/bevy_winit", optional = true, version = "0.3.0" }
bevy_gilrs = { path = "crates/bevy_gilrs", optional = true, version = "0.3.0" }
log = { version = "0.4", features = ["release_max_level_info"] }

[dev-dependencies]
rand = "0.7.3"
serde = { version = "1", features = ["derive"] }
log = "0.4"
ron = "0.6"
anyhow = "1.0"
env_logger = "0.8.1"
console_error_panic_hook = "0.1.6"

# bevy (Android)
[target.'cfg(target_os = "android")'.dependencies]
ndk-glue = { version = "0.2", features = ["logger"] }
android_logger = "0.9"

[target.'cfg(target_arch = "wasm32")'.dev-dependencies]
console_error_panic_hook = "0.1.6"
console_log = { version = "0.2", features = ["color"] }

[[example]]
Expand Down
13 changes: 13 additions & 0 deletions crates/bevy_ecs/src/resource/resource_query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,10 @@ impl<'a, T: Resource> FetchResource<'a> for FetchResourceRead<T> {
Res::new(resources.get_unsafe_ref::<T>(ResourceIndex::Global))
}

unsafe fn is_some(resources: &'a Resources, _system_id: Option<SystemId>) -> bool {
resources.contains::<T>()
}

fn borrow(resources: &Resources) {
resources.borrow::<T>();
}
Expand Down Expand Up @@ -276,6 +280,10 @@ impl<'a, T: Resource> FetchResource<'a> for FetchResourceWrite<T> {
ResMut::new(value, type_state.mutated())
}

unsafe fn is_some(resources: &'a Resources, _system_id: Option<SystemId>) -> bool {
resources.contains::<T>()
}

fn borrow(resources: &Resources) {
resources.borrow_mut::<T>();
}
Expand Down Expand Up @@ -322,6 +330,11 @@ impl<'a, T: Resource + FromResources> FetchResource<'a> for FetchResourceLocalMu
}
}

unsafe fn is_some(resources: &'a Resources, system_id: Option<SystemId>) -> bool {
let id = system_id.expect("Local<T> resources can only be used by systems");
resources.get_local::<T>(id).is_some()
}

fn borrow(resources: &Resources) {
resources.borrow_mut::<T>();
}
Expand Down
19 changes: 2 additions & 17 deletions crates/bevy_pbr/src/entity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use bevy_ecs::Bundle;
use bevy_render::{
draw::Draw,
mesh::Mesh,
pipeline::{DynamicBinding, PipelineSpecialization, RenderPipeline, RenderPipelines},
pipeline::{RenderPipeline, RenderPipelines},
render_graph::base::MainPass,
};
use bevy_transform::prelude::{GlobalTransform, Transform};
Expand All @@ -24,23 +24,8 @@ pub struct PbrComponents {
impl Default for PbrComponents {
fn default() -> Self {
Self {
render_pipelines: RenderPipelines::from_pipelines(vec![RenderPipeline::specialized(
render_pipelines: RenderPipelines::from_pipelines(vec![RenderPipeline::new(
FORWARD_PIPELINE_HANDLE,
PipelineSpecialization {
dynamic_bindings: vec![
// Transform
DynamicBinding {
bind_group: 2,
binding: 0,
},
// StandardMaterial_albedo
DynamicBinding {
bind_group: 3,
binding: 0,
},
],
..Default::default()
},
)]),
mesh: Default::default(),
material: Default::default(),
Expand Down
22 changes: 10 additions & 12 deletions crates/bevy_pbr/src/render_graph/forward_pipeline/forward.frag
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
#version 450

const int MAX_LIGHTS = 10;

struct Light {
Expand All @@ -8,28 +6,28 @@ struct Light {
vec4 color;
};

layout(location = 0) in vec3 v_Position;
layout(location = 1) in vec3 v_Normal;
layout(location = 2) in vec2 v_Uv;
LAYOUT(location = 0) in vec3 v_Position;
LAYOUT(location = 1) in vec3 v_Normal;
LAYOUT(location = 2) in vec2 v_Uv;

layout(location = 0) out vec4 o_Target;
LAYOUT(location = 0) out vec4 o_Target;

layout(set = 0, binding = 0) uniform Camera {
BLOCK_LAYOUT(set = 0, binding = 0) uniform Camera {
mat4 ViewProj;
};

layout(set = 1, binding = 0) uniform Lights {
BLOCK_LAYOUT(set = 1, binding = 0) uniform Lights {
uvec4 NumLights;
Light SceneLights[MAX_LIGHTS];
};

layout(set = 3, binding = 0) uniform StandardMaterial_albedo {
BLOCK_LAYOUT(set = 3, binding = 0) uniform StandardMaterial_albedo {
vec4 Albedo;
};

# ifdef STANDARDMATERIAL_ALBEDO_TEXTURE
layout(set = 3, binding = 1) uniform texture2D StandardMaterial_albedo_texture;
layout(set = 3, binding = 2) uniform sampler StandardMaterial_albedo_texture_sampler;
UNIFORM_TEXTURE(set = 3, binding = 1, StandardMaterial_albedo_texture)
UNIFORM_SAMPLER(set = 3, binding = 2, StandardMaterial_albedo_texture_sampler)
# endif

void main() {
Expand Down Expand Up @@ -57,5 +55,5 @@ void main() {
# endif

// multiply the light by material color
o_Target = output_color;
o_Target = encodeColor(output_color);
}
18 changes: 8 additions & 10 deletions crates/bevy_pbr/src/render_graph/forward_pipeline/forward.vert
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
#version 450
LAYOUT(location = 0) in vec3 Vertex_Position;
LAYOUT(location = 1) in vec3 Vertex_Normal;
LAYOUT(location = 2) in vec2 Vertex_Uv;

layout(location = 0) in vec3 Vertex_Position;
layout(location = 1) in vec3 Vertex_Normal;
layout(location = 2) in vec2 Vertex_Uv;
LAYOUT(location = 0) out vec3 v_Position;
LAYOUT(location = 1) out vec3 v_Normal;
LAYOUT(location = 2) out vec2 v_Uv;

layout(location = 0) out vec3 v_Position;
layout(location = 1) out vec3 v_Normal;
layout(location = 2) out vec2 v_Uv;

layout(set = 0, binding = 0) uniform Camera {
BLOCK_LAYOUT(set = 0, binding = 0) uniform Camera {
mat4 ViewProj;
};

layout(set = 2, binding = 0) uniform Transform {
BLOCK_LAYOUT(set = 2, binding = 0) uniform Transform {
mat4 Model;
};

Expand Down
10 changes: 6 additions & 4 deletions crates/bevy_render/src/draw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,8 @@ impl<'a> DrawContext<'a> {
&mut self,
draw: &mut Draw,
pipeline_handle: &Handle<PipelineDescriptor>,
specialization: &PipelineSpecialization,
specialization: &mut PipelineSpecialization,
render_resource_bindings: &mut [&mut RenderResourceBindings],
) -> Result<(), DrawError> {
let specialized_pipeline = if let Some(specialized_pipeline) = self
.pipeline_compiler
Expand All @@ -255,6 +256,7 @@ impl<'a> DrawContext<'a> {
&mut self.shaders,
pipeline_handle,
specialization,
render_resource_bindings,
)
};

Expand Down Expand Up @@ -355,9 +357,6 @@ impl<'a> DrawContext<'a> {
.iter()
.any(|x| x.name == VERTEX_FALLBACK_LAYOUT_NAME);
for bindings in render_resource_bindings.iter() {
if let Some(index_buffer) = bindings.index_buffer {
draw.set_index_buffer(index_buffer, 0);
}
if let Some(main_vertex_buffer) = bindings.vertex_attribute_buffer {
draw.set_vertex_buffer(0, main_vertex_buffer, 0);
}
Expand All @@ -366,6 +365,9 @@ impl<'a> DrawContext<'a> {
draw.set_vertex_buffer(1, fallback_vertex_buffer, 0);
}
}
if let Some(index_buffer) = bindings.index_buffer {
draw.set_index_buffer(index_buffer, 0);
}
}
Ok(())
}
Expand Down
17 changes: 10 additions & 7 deletions crates/bevy_render/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,19 +32,19 @@ use crate::prelude::*;
use base::{MainPass, Msaa};
use bevy_app::prelude::*;
use bevy_asset::AddAsset;
use bevy_ecs::{IntoQuerySystem, IntoThreadLocalSystem};
use bevy_ecs::{IntoQuerySystem, IntoThreadLocalSystem, Res};
use camera::{
ActiveCameras, Camera, OrthographicProjection, PerspectiveProjection, VisibleEntities,
};
use pipeline::{
DynamicBinding, IndexFormat, PipelineCompiler, PipelineDescriptor, PipelineSpecialization,
PrimitiveTopology, ShaderSpecialization,
IndexFormat, PipelineCompiler, PipelineDescriptor, PipelineSpecialization, PrimitiveTopology,
ShaderSpecialization,
};
use render_graph::{
base::{self, BaseRenderGraphBuilder, BaseRenderGraphConfig},
RenderGraph,
};
use renderer::{AssetRenderResourceBindings, RenderResourceBindings};
use renderer::{AssetRenderResourceBindings, RenderResourceBindings, RenderResourceContext};
use std::ops::Range;
#[cfg(feature = "hdr")]
use texture::HdrTextureLoader;
Expand All @@ -66,7 +66,7 @@ pub mod stage {

/// Adds core render types and systems to an App
pub struct RenderPlugin {
/// configures the "base render graph". If this is not `None`, the "base render graph" will be added
/// configures the "base render graph". If this is not `None`, the "base render graph" will be added
pub base_render_graph_config: Option<BaseRenderGraphConfig>,
}

Expand Down Expand Up @@ -112,7 +112,6 @@ impl Plugin for RenderPlugin {
.register_property::<Color>()
.register_property::<Range<f32>>()
.register_property::<ShaderSpecialization>()
.register_property::<DynamicBinding>()
.register_property::<PrimitiveTopology>()
.register_property::<IndexFormat>()
.register_properties::<PipelineSpecialization>()
Expand Down Expand Up @@ -143,7 +142,6 @@ impl Plugin for RenderPlugin {
bevy_app::stage::POST_UPDATE,
camera::visible_entities_system.system(),
)
// TODO: turn these "resource systems" into graph nodes and remove the RENDER_RESOURCE stage
.add_system_to_stage(
stage::RENDER_RESOURCE,
mesh::mesh_resource_provider_system.system(),
Expand All @@ -161,6 +159,7 @@ impl Plugin for RenderPlugin {
stage::POST_RENDER,
shader::clear_shader_defs_system.system(),
);
//.add_system_to_stage(stage::POST_RENDER, flush_render_resource_context.system());

if app.resources().get::<Msaa>().is_none() {
app.init_resource::<Msaa>();
Expand All @@ -182,3 +181,7 @@ impl Plugin for RenderPlugin {
}
}
}

fn flush_render_resource_context(render_resource_context: Res<Box<dyn RenderResourceContext>>) {
render_resource_context.flush();
}
67 changes: 2 additions & 65 deletions crates/bevy_render/src/pipeline/pipeline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,9 @@ use super::{
CompareFunction, CullMode, DepthStencilStateDescriptor, FrontFace, IndexFormat,
PrimitiveTopology, RasterizationStateDescriptor, StencilStateFaceDescriptor,
},
BindType, DynamicBinding, PipelineLayout, StencilStateDescriptor,
PipelineLayout, StencilStateDescriptor,
};
use crate::{
shader::{Shader, ShaderStages},
texture::TextureFormat,
};
use bevy_asset::Assets;
use crate::{shader::ShaderStages, texture::TextureFormat};
use bevy_type_registry::TypeUuid;

#[derive(Clone, Debug, TypeUuid)]
Expand Down Expand Up @@ -117,63 +113,4 @@ impl PipelineDescriptor {
pub fn get_layout_mut(&mut self) -> Option<&mut PipelineLayout> {
self.layout.as_mut()
}

/// Reflects the pipeline layout from its shaders.
///
/// If `bevy_conventions` is true, it will be assumed that the shader follows "bevy shader conventions". These allow
/// richer reflection, such as inferred Vertex Buffer names and inferred instancing.
///
/// If `dynamic_bindings` has values, shader uniforms will be set to "dynamic" if there is a matching binding in the list
///
/// If `vertex_buffer_descriptors` is set, the pipeline's vertex buffers
/// will inherit their layouts from global descriptors, otherwise the layout will be assumed to be complete / local.
pub fn reflect_layout(
&mut self,
shaders: &Assets<Shader>,
bevy_conventions: bool,
dynamic_bindings: &[DynamicBinding],
) {
let vertex_spirv = shaders.get(&self.shader_stages.vertex).unwrap();
let fragment_spirv = self
.shader_stages
.fragment
.as_ref()
.map(|handle| shaders.get(handle).unwrap());

let mut layouts = vec![vertex_spirv.reflect_layout(bevy_conventions).unwrap()];
if let Some(ref fragment_spirv) = fragment_spirv {
layouts.push(fragment_spirv.reflect_layout(bevy_conventions).unwrap());
}

let mut layout = PipelineLayout::from_shader_layouts(&mut layouts);

if !dynamic_bindings.is_empty() {
// set binding uniforms to dynamic if render resource bindings use dynamic
for bind_group in layout.bind_groups.iter_mut() {
let mut binding_changed = false;
for binding in bind_group.bindings.iter_mut() {
let current = DynamicBinding {
bind_group: bind_group.index,
binding: binding.index,
};

if dynamic_bindings.contains(&current) {
if let BindType::Uniform {
ref mut dynamic, ..
} = binding.bind_type
{
*dynamic = true;
binding_changed = true;
}
}
}

if binding_changed {
bind_group.update_id();
}
}
}

self.layout = Some(layout);
}
}
Loading