From 5a4ba5ceddb1d1f5b464994afc1d85efd3f4d605 Mon Sep 17 00:00:00 2001 From: JMS55 <47158642+JMS55@users.noreply.github.com> Date: Thu, 30 Mar 2023 14:19:08 -0400 Subject: [PATCH 01/30] WIP SkyboxPlugin --- crates/bevy_core_pipeline/src/core_3d/mod.rs | 12 +- .../src/core_3d/skybox/mod.rs | 171 ++++++++++++++++++ .../src/core_3d/skybox/node.rs | 96 ++++++++++ .../src/core_3d/skybox/skybox.wgsl | 5 + 4 files changed, 280 insertions(+), 4 deletions(-) create mode 100644 crates/bevy_core_pipeline/src/core_3d/skybox/mod.rs create mode 100644 crates/bevy_core_pipeline/src/core_3d/skybox/node.rs create mode 100644 crates/bevy_core_pipeline/src/core_3d/skybox/skybox.wgsl diff --git a/crates/bevy_core_pipeline/src/core_3d/mod.rs b/crates/bevy_core_pipeline/src/core_3d/mod.rs index 4f1f807477a26..8f4a2bc37b965 100644 --- a/crates/bevy_core_pipeline/src/core_3d/mod.rs +++ b/crates/bevy_core_pipeline/src/core_3d/mod.rs @@ -1,6 +1,7 @@ mod camera_3d; mod main_opaque_pass_3d_node; mod main_transparent_pass_3d_node; +mod skybox; pub mod graph { pub const NAME: &str = "core_3d"; @@ -12,6 +13,7 @@ pub mod graph { pub const PREPASS: &str = "prepass"; pub const START_MAIN_PASS: &str = "start_main_pass"; pub const MAIN_OPAQUE_PASS: &str = "main_opaque_pass"; + pub const SKYBOX: &str = "skybox"; pub const MAIN_TRANSPARENT_PASS: &str = "main_transparent_pass"; pub const END_MAIN_PASS: &str = "end_main_pass"; pub const BLOOM: &str = "bloom"; @@ -27,6 +29,7 @@ use std::cmp::Reverse; pub use camera_3d::*; pub use main_opaque_pass_3d_node::*; pub use main_transparent_pass_3d_node::*; +pub use skybox::*; use bevy_app::{App, Plugin}; use bevy_ecs::prelude::*; @@ -62,6 +65,7 @@ impl Plugin for Core3dPlugin { fn build(&self, app: &mut App) { app.register_type::() .register_type::() + .add_plugin(SkyboxPlugin) .add_plugin(ExtractComponentPlugin::::default()); let render_app = match app.get_sub_app_mut(RenderApp) { @@ -88,6 +92,7 @@ impl Plugin for Core3dPlugin { let prepass_node = PrepassNode::new(&mut render_app.world); let opaque_node_3d = MainOpaquePass3dNode::new(&mut render_app.world); + let skybox = SkyboxNode::new(&mut render_app.world); let transparent_node_3d = MainTransparentPass3dNode::new(&mut render_app.world); let tonemapping = TonemappingNode::new(&mut render_app.world); let upscaling = UpscalingNode::new(&mut render_app.world); @@ -97,6 +102,7 @@ impl Plugin for Core3dPlugin { draw_3d_graph.add_node(graph::node::PREPASS, prepass_node); draw_3d_graph.add_node(graph::node::START_MAIN_PASS, EmptyNode); draw_3d_graph.add_node(graph::node::MAIN_OPAQUE_PASS, opaque_node_3d); + draw_3d_graph.add_node(graph::node::SKYBOX, skybox); draw_3d_graph.add_node(graph::node::MAIN_TRANSPARENT_PASS, transparent_node_3d); draw_3d_graph.add_node(graph::node::END_MAIN_PASS, EmptyNode); draw_3d_graph.add_node(graph::node::TONEMAPPING, tonemapping); @@ -105,10 +111,8 @@ impl Plugin for Core3dPlugin { draw_3d_graph.add_node_edge(graph::node::PREPASS, graph::node::START_MAIN_PASS); draw_3d_graph.add_node_edge(graph::node::START_MAIN_PASS, graph::node::MAIN_OPAQUE_PASS); - draw_3d_graph.add_node_edge( - graph::node::MAIN_OPAQUE_PASS, - graph::node::MAIN_TRANSPARENT_PASS, - ); + draw_3d_graph.add_node_edge(graph::node::MAIN_OPAQUE_PASS, graph::node::SKYBOX); + draw_3d_graph.add_node_edge(graph::node::SKYBOX, graph::node::MAIN_TRANSPARENT_PASS); draw_3d_graph.add_node_edge( graph::node::MAIN_TRANSPARENT_PASS, graph::node::END_MAIN_PASS, diff --git a/crates/bevy_core_pipeline/src/core_3d/skybox/mod.rs b/crates/bevy_core_pipeline/src/core_3d/skybox/mod.rs new file mode 100644 index 0000000000000..12d7e946862a7 --- /dev/null +++ b/crates/bevy_core_pipeline/src/core_3d/skybox/mod.rs @@ -0,0 +1,171 @@ +mod node; + +pub use node::*; + +use bevy_app::{App, Plugin}; +use bevy_asset::{load_internal_asset, Assets, Handle, HandleUntyped}; +use bevy_ecs::{ + prelude::{Component, Entity}, + query::With, + schedule::IntoSystemConfigs, + system::{Commands, Query, Res, ResMut, Resource}, +}; +use bevy_reflect::TypeUuid; +use bevy_render::{ + prelude::{shape::Cube, Mesh}, + render_resource::{ + BindGroup, BlendState, CachedRenderPipelineId, ColorTargetState, ColorWrites, + CompareFunction, DepthBiasState, DepthStencilState, FragmentState, MultisampleState, + PipelineCache, PrimitiveState, RenderPipelineDescriptor, Shader, SpecializedRenderPipeline, + SpecializedRenderPipelines, StencilFaceState, StencilState, TextureFormat, + VertexBufferLayout, VertexState, + }, + texture::Image, + view::{Msaa, ViewTarget}, + Render, RenderApp, RenderSet, +}; + +const SKYBOX_SHADER_HANDLE: HandleUntyped = + HandleUntyped::weak_from_u64(Shader::TYPE_UUID, 55594763423201); + +pub struct SkyboxPlugin; + +impl Plugin for SkyboxPlugin { + fn build(&self, app: &mut App) { + load_internal_asset!( + app, + SKYBOX_SHADER_HANDLE, + "skybox/skybox.wgsl", + Shader::from_wgsl + ); + + let render_app = match app.get_sub_app_mut(RenderApp) { + Ok(render_app) => render_app, + Err(_) => return, + }; + + let mesh = Mesh::from(Cube::new(1.0)); + let vertex_buffer_layout = mesh.get_mesh_vertex_buffer_layout().layout().clone(); + + render_app + .insert_resource(SkyboxMesh { + handle: app.world.resource_mut::>().add(mesh), + }) + .insert_resource(SkyboxPipeline { + vertex_buffer_layout, + }) + .init_resource::>() + .add_systems( + Render, + ( + prepare_skybox_pipelines.in_set(RenderSet::Prepare), + queue_skybox_bind_groups.in_set(RenderSet::Queue), + ), + ); + } +} + +#[derive(Component)] +pub struct Skybox(pub Handle); + +// ---------------------------------------------------------------------------- + +#[derive(Resource)] +struct SkyboxMesh { + handle: Handle, +} + +#[derive(Resource)] +struct SkyboxPipeline { + vertex_buffer_layout: VertexBufferLayout, +} + +#[derive(PartialEq, Eq, Hash, Clone, Copy)] +struct SkyboxPipelineKey { + texture_format: TextureFormat, + samples: u32, +} + +impl SpecializedRenderPipeline for SkyboxPipeline { + type Key = SkyboxPipelineKey; + + fn specialize(&self, key: Self::Key) -> RenderPipelineDescriptor { + RenderPipelineDescriptor { + label: Some("skybox_pipeline".into()), + layout: vec![todo!()], + push_constant_ranges: Vec::new(), + vertex: VertexState { + shader: SKYBOX_SHADER_HANDLE.typed(), + shader_defs: Vec::new(), + entry_point: "skybox_vertex".into(), + buffers: vec![self.vertex_buffer_layout.clone()], + }, + primitive: PrimitiveState::default(), + depth_stencil: Some(DepthStencilState { + format: TextureFormat::Depth32Float, + depth_write_enabled: false, + depth_compare: CompareFunction::GreaterEqual, + stencil: StencilState { + front: StencilFaceState::IGNORE, + back: StencilFaceState::IGNORE, + read_mask: 0, + write_mask: 0, + }, + bias: DepthBiasState { + constant: 0, + slope_scale: 0.0, + clamp: 0.0, + }, + }), + multisample: MultisampleState { + count: key.samples, + mask: !0, + alpha_to_coverage_enabled: false, + }, + fragment: Some(FragmentState { + shader: SKYBOX_SHADER_HANDLE.typed(), + shader_defs: Vec::new(), + entry_point: "skybox_fragment".into(), + targets: vec![Some(ColorTargetState { + format: key.texture_format, + blend: Some(BlendState::REPLACE), + write_mask: ColorWrites::ALL, + })], + }), + } + } +} + +#[derive(Component)] +struct SkyboxPipelineId(CachedRenderPipelineId); + +fn prepare_skybox_pipelines( + mut commands: Commands, + pipeline_cache: Res, + mut pipelines: ResMut>, + pipeline: Res, + msaa: Res, + views: Query<(Entity, &ViewTarget), With>, +) { + for (entity, view_target) in &views { + let pipeline_id = pipelines.specialize( + &pipeline_cache, + &pipeline, + SkyboxPipelineKey { + texture_format: view_target.main_texture_format(), + samples: msaa.samples(), + }, + ); + + commands + .entity(entity) + .insert(SkyboxPipelineId(pipeline_id)); + } +} + +#[derive(Component)] +struct SkyboxBindGroup(BindGroup); + +fn queue_skybox_bind_groups() { + todo!() +} diff --git a/crates/bevy_core_pipeline/src/core_3d/skybox/node.rs b/crates/bevy_core_pipeline/src/core_3d/skybox/node.rs new file mode 100644 index 0000000000000..8a56db87a5147 --- /dev/null +++ b/crates/bevy_core_pipeline/src/core_3d/skybox/node.rs @@ -0,0 +1,96 @@ +use super::{SkyboxBindGroup, SkyboxMesh, SkyboxPipelineId}; +use bevy_ecs::{query::QueryState, world::World}; +use bevy_render::{ + camera::ExtractedCamera, + mesh::GpuBufferInfo, + prelude::Mesh, + render_asset::RenderAssets, + render_graph::{Node, NodeRunError, RenderGraphContext}, + render_resource::{ + LoadOp, Operations, PipelineCache, RenderPassDepthStencilAttachment, RenderPassDescriptor, + }, + renderer::RenderContext, + view::{ViewDepthTexture, ViewTarget}, +}; + +pub struct SkyboxNode { + view_query: QueryState<( + &'static SkyboxPipelineId, + &'static SkyboxBindGroup, + &'static ExtractedCamera, + &'static ViewTarget, + &'static ViewDepthTexture, + )>, +} + +impl Node for SkyboxNode { + fn run( + &self, + graph: &mut RenderGraphContext, + render_context: &mut RenderContext, + world: &World, + ) -> Result<(), NodeRunError> { + let Ok((pipeline_id, bind_group, camera, target, depth)) = self.view_query.get_manual(world, graph.view_entity()) else { + return Ok(()); + }; + let skybox_mesh = world.resource::(); + let meshes = world.resource::>(); + let pipeline_cache = world.resource::(); + let (Some(gpu_mesh), Some(pipeline)) = ( + meshes.get(&skybox_mesh.handle), + pipeline_cache.get_render_pipeline(pipeline_id.0), + ) else { return Ok(()) }; + + let mut render_pass = render_context.begin_tracked_render_pass(RenderPassDescriptor { + label: Some("skybox"), + color_attachments: &[Some(target.get_color_attachment(Operations { + load: LoadOp::Load, + store: true, + }))], + depth_stencil_attachment: Some(RenderPassDepthStencilAttachment { + view: &depth.view, + depth_ops: Some(Operations { + load: LoadOp::Load, + store: false, + }), + stencil_ops: None, + }), + }); + + render_pass.set_render_pipeline(pipeline); + render_pass.set_bind_group(0, &bind_group.0, &[todo!()]); + + if let Some(viewport) = camera.viewport.as_ref() { + render_pass.set_camera_viewport(viewport); + } + + render_pass.set_vertex_buffer(0, gpu_mesh.vertex_buffer.slice(..)); + match &gpu_mesh.buffer_info { + GpuBufferInfo::Indexed { + buffer, + index_format, + count, + } => { + render_pass.set_index_buffer(buffer.slice(..), 0, *index_format); + render_pass.draw_indexed(0..*count, 0, 0..1); + } + GpuBufferInfo::NonIndexed { vertex_count } => { + render_pass.draw(0..*vertex_count, 0..1); + } + } + + Ok(()) + } + + fn update(&mut self, world: &mut World) { + self.view_query.update_archetypes(world); + } +} + +impl SkyboxNode { + pub fn new(world: &mut World) -> Self { + Self { + view_query: QueryState::new(world), + } + } +} diff --git a/crates/bevy_core_pipeline/src/core_3d/skybox/skybox.wgsl b/crates/bevy_core_pipeline/src/core_3d/skybox/skybox.wgsl new file mode 100644 index 0000000000000..2f049379b0879 --- /dev/null +++ b/crates/bevy_core_pipeline/src/core_3d/skybox/skybox.wgsl @@ -0,0 +1,5 @@ +@vertex +fn skybox_vertex() {} + +@fragment +fn skybox_fragment() {} From 28eb2aad4dc9eff5f3cd6dfb793909b4d1cd6cac Mon Sep 17 00:00:00 2001 From: JMS55 <47158642+JMS55@users.noreply.github.com> Date: Thu, 30 Mar 2023 15:35:15 -0400 Subject: [PATCH 02/30] Shader WIP --- .../src/core_3d/skybox/skybox.wgsl | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/crates/bevy_core_pipeline/src/core_3d/skybox/skybox.wgsl b/crates/bevy_core_pipeline/src/core_3d/skybox/skybox.wgsl index 2f049379b0879..20a0614d2120b 100644 --- a/crates/bevy_core_pipeline/src/core_3d/skybox/skybox.wgsl +++ b/crates/bevy_core_pipeline/src/core_3d/skybox/skybox.wgsl @@ -1,5 +1,21 @@ +#import bevy_pbr::mesh_view_bindings +#import bevy_pbr::mesh_functions + +@group(0) @binding(0) +var skybox: texture_cube; +@group(0) @binding(1) +var skybox_sampler: sampler; +@group(0) @binding(2) +var view: View; + @vertex -fn skybox_vertex() {} +fn skybox_vertex(@location(0) position: vec3) -> @builtin(position) vec4 { + var out = mesh_position_world_to_clip(position); + out.z = out.w; + return out; +} @fragment -fn skybox_fragment() {} +fn skybox_fragment(@builtin(position) clip_position: vec4) -> @location(0) vec4 { + return textureSample(skybox, skybox_sampler, clip_position.xyz); +} From 73f7192db18e71c8c732bd9295b773419754f52e Mon Sep 17 00:00:00 2001 From: JMS55 <47158642+JMS55@users.noreply.github.com> Date: Thu, 30 Mar 2023 15:49:54 -0400 Subject: [PATCH 03/30] Hook up bind group --- .../src/core_3d/skybox/mod.rs | 102 ++++++++++++++++-- .../src/core_3d/skybox/node.rs | 10 +- 2 files changed, 96 insertions(+), 16 deletions(-) diff --git a/crates/bevy_core_pipeline/src/core_3d/skybox/mod.rs b/crates/bevy_core_pipeline/src/core_3d/skybox/mod.rs index 12d7e946862a7..e54f40fe9a92c 100644 --- a/crates/bevy_core_pipeline/src/core_3d/skybox/mod.rs +++ b/crates/bevy_core_pipeline/src/core_3d/skybox/mod.rs @@ -13,15 +13,19 @@ use bevy_ecs::{ use bevy_reflect::TypeUuid; use bevy_render::{ prelude::{shape::Cube, Mesh}, + render_asset::RenderAssets, render_resource::{ - BindGroup, BlendState, CachedRenderPipelineId, ColorTargetState, ColorWrites, - CompareFunction, DepthBiasState, DepthStencilState, FragmentState, MultisampleState, - PipelineCache, PrimitiveState, RenderPipelineDescriptor, Shader, SpecializedRenderPipeline, - SpecializedRenderPipelines, StencilFaceState, StencilState, TextureFormat, - VertexBufferLayout, VertexState, + BindGroup, BindGroupDescriptor, BindGroupEntry, BindGroupLayout, BindGroupLayoutDescriptor, + BindGroupLayoutEntry, BindingResource, BindingType, BlendState, BufferBindingType, + CachedRenderPipelineId, ColorTargetState, ColorWrites, CompareFunction, DepthBiasState, + DepthStencilState, FragmentState, MultisampleState, PipelineCache, PrimitiveState, + RenderPipelineDescriptor, SamplerBindingType, Shader, ShaderStages, ShaderType, + SpecializedRenderPipeline, SpecializedRenderPipelines, StencilFaceState, StencilState, + TextureFormat, TextureSampleType, TextureViewDimension, VertexBufferLayout, VertexState, }, + renderer::RenderDevice, texture::Image, - view::{Msaa, ViewTarget}, + view::{Msaa, ViewTarget, ViewUniform, ViewUniforms}, Render, RenderApp, RenderSet, }; @@ -51,9 +55,10 @@ impl Plugin for SkyboxPlugin { .insert_resource(SkyboxMesh { handle: app.world.resource_mut::>().add(mesh), }) - .insert_resource(SkyboxPipeline { + .insert_resource(SkyboxPipeline::new( vertex_buffer_layout, - }) + app.world.resource::(), + )) .init_resource::>() .add_systems( Render, @@ -77,9 +82,52 @@ struct SkyboxMesh { #[derive(Resource)] struct SkyboxPipeline { + bind_group_layout: BindGroupLayout, vertex_buffer_layout: VertexBufferLayout, } +impl SkyboxPipeline { + fn new(vertex_buffer_layout: VertexBufferLayout, render_device: &RenderDevice) -> Self { + let bind_group_layout = + render_device.create_bind_group_layout(&BindGroupLayoutDescriptor { + label: Some("skybox_bind_group_layout"), + entries: &[ + BindGroupLayoutEntry { + binding: 0, + visibility: ShaderStages::FRAGMENT, + ty: BindingType::Texture { + sample_type: TextureSampleType::Float { filterable: true }, + view_dimension: TextureViewDimension::Cube, + multisampled: false, + }, + count: None, + }, + BindGroupLayoutEntry { + binding: 1, + visibility: ShaderStages::FRAGMENT, + ty: BindingType::Sampler(SamplerBindingType::Filtering), + count: None, + }, + BindGroupLayoutEntry { + binding: 2, + visibility: ShaderStages::VERTEX, + ty: BindingType::Buffer { + ty: BufferBindingType::Uniform, + has_dynamic_offset: true, + min_binding_size: Some(ViewUniform::min_size()), + }, + count: None, + }, + ], + }); + + Self { + bind_group_layout, + vertex_buffer_layout, + } + } +} + #[derive(PartialEq, Eq, Hash, Clone, Copy)] struct SkyboxPipelineKey { texture_format: TextureFormat, @@ -92,7 +140,7 @@ impl SpecializedRenderPipeline for SkyboxPipeline { fn specialize(&self, key: Self::Key) -> RenderPipelineDescriptor { RenderPipelineDescriptor { label: Some("skybox_pipeline".into()), - layout: vec![todo!()], + layout: vec![self.bind_group_layout], push_constant_ranges: Vec::new(), vertex: VertexState { shader: SKYBOX_SHADER_HANDLE.typed(), @@ -166,6 +214,38 @@ fn prepare_skybox_pipelines( #[derive(Component)] struct SkyboxBindGroup(BindGroup); -fn queue_skybox_bind_groups() { - todo!() +fn queue_skybox_bind_groups( + mut commands: Commands, + pipeline: Res, + view_uniforms: Res, + images: Res>, + render_device: Res, + views: Query<(Entity, &Skybox)>, +) { + for (entity, skybox) in &views { + if let (Some(skybox), Some(view_uniforms)) = + (images.get(&skybox.0), view_uniforms.uniforms.binding()) + { + let bind_group = render_device.create_bind_group(&BindGroupDescriptor { + label: Some("skybox_bind_group"), + layout: &pipeline.bind_group_layout, + entries: &[ + BindGroupEntry { + binding: 0, + resource: BindingResource::TextureView(&skybox.texture_view), + }, + BindGroupEntry { + binding: 1, + resource: BindingResource::Sampler(&skybox.sampler), + }, + BindGroupEntry { + binding: 2, + resource: view_uniforms, + }, + ], + }); + + commands.entity(entity).insert(SkyboxBindGroup(bind_group)); + } + } } diff --git a/crates/bevy_core_pipeline/src/core_3d/skybox/node.rs b/crates/bevy_core_pipeline/src/core_3d/skybox/node.rs index 8a56db87a5147..1d560204ea9bf 100644 --- a/crates/bevy_core_pipeline/src/core_3d/skybox/node.rs +++ b/crates/bevy_core_pipeline/src/core_3d/skybox/node.rs @@ -10,13 +10,14 @@ use bevy_render::{ LoadOp, Operations, PipelineCache, RenderPassDepthStencilAttachment, RenderPassDescriptor, }, renderer::RenderContext, - view::{ViewDepthTexture, ViewTarget}, + view::{ViewDepthTexture, ViewTarget, ViewUniformOffset}, }; pub struct SkyboxNode { view_query: QueryState<( &'static SkyboxPipelineId, &'static SkyboxBindGroup, + &'static ViewUniformOffset, &'static ExtractedCamera, &'static ViewTarget, &'static ViewDepthTexture, @@ -30,9 +31,8 @@ impl Node for SkyboxNode { render_context: &mut RenderContext, world: &World, ) -> Result<(), NodeRunError> { - let Ok((pipeline_id, bind_group, camera, target, depth)) = self.view_query.get_manual(world, graph.view_entity()) else { - return Ok(()); - }; + let Ok((pipeline_id, bind_group, view_uniform_offset, camera, target, depth)) + = self.view_query.get_manual(world, graph.view_entity()) else { return Ok(()) }; let skybox_mesh = world.resource::(); let meshes = world.resource::>(); let pipeline_cache = world.resource::(); @@ -58,7 +58,7 @@ impl Node for SkyboxNode { }); render_pass.set_render_pipeline(pipeline); - render_pass.set_bind_group(0, &bind_group.0, &[todo!()]); + render_pass.set_bind_group(0, &bind_group.0, &[view_uniform_offset.offset]); if let Some(viewport) = camera.viewport.as_ref() { render_pass.set_camera_viewport(viewport); From 4559cbdc098a51d1208ce07468b6f46ee1f89b04 Mon Sep 17 00:00:00 2001 From: JMS55 <47158642+JMS55@users.noreply.github.com> Date: Thu, 30 Mar 2023 15:53:11 -0400 Subject: [PATCH 04/30] Fixes --- .../src/core_3d/skybox/mod.rs | 25 +++++++------------ 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/crates/bevy_core_pipeline/src/core_3d/skybox/mod.rs b/crates/bevy_core_pipeline/src/core_3d/skybox/mod.rs index e54f40fe9a92c..c398e7c613d18 100644 --- a/crates/bevy_core_pipeline/src/core_3d/skybox/mod.rs +++ b/crates/bevy_core_pipeline/src/core_3d/skybox/mod.rs @@ -36,29 +36,22 @@ pub struct SkyboxPlugin; impl Plugin for SkyboxPlugin { fn build(&self, app: &mut App) { - load_internal_asset!( - app, - SKYBOX_SHADER_HANDLE, - "skybox/skybox.wgsl", - Shader::from_wgsl - ); + load_internal_asset!(app, SKYBOX_SHADER_HANDLE, "skybox.wgsl", Shader::from_wgsl); + + let mesh = Mesh::from(Cube::new(1.0)); + let vertex_buffer_layout = mesh.get_mesh_vertex_buffer_layout().layout().clone(); + let handle = app.world.resource_mut::>().add(mesh); let render_app = match app.get_sub_app_mut(RenderApp) { Ok(render_app) => render_app, Err(_) => return, }; - let mesh = Mesh::from(Cube::new(1.0)); - let vertex_buffer_layout = mesh.get_mesh_vertex_buffer_layout().layout().clone(); + let render_device = render_app.world.resource::().clone(); render_app - .insert_resource(SkyboxMesh { - handle: app.world.resource_mut::>().add(mesh), - }) - .insert_resource(SkyboxPipeline::new( - vertex_buffer_layout, - app.world.resource::(), - )) + .insert_resource(SkyboxMesh { handle }) + .insert_resource(SkyboxPipeline::new(vertex_buffer_layout, &render_device)) .init_resource::>() .add_systems( Render, @@ -140,7 +133,7 @@ impl SpecializedRenderPipeline for SkyboxPipeline { fn specialize(&self, key: Self::Key) -> RenderPipelineDescriptor { RenderPipelineDescriptor { label: Some("skybox_pipeline".into()), - layout: vec![self.bind_group_layout], + layout: vec![self.bind_group_layout.clone()], push_constant_ranges: Vec::new(), vertex: VertexState { shader: SKYBOX_SHADER_HANDLE.typed(), From 14ff0c280222a1fb55f73bfad6cf5d6a7bc860a6 Mon Sep 17 00:00:00 2001 From: JMS55 <47158642+JMS55@users.noreply.github.com> Date: Thu, 30 Mar 2023 15:58:30 -0400 Subject: [PATCH 05/30] Misc refactor --- .../src/core_3d/skybox/mod.rs | 62 +++++++++---------- .../src/core_3d/skybox/node.rs | 62 ++++++++++--------- 2 files changed, 63 insertions(+), 61 deletions(-) diff --git a/crates/bevy_core_pipeline/src/core_3d/skybox/mod.rs b/crates/bevy_core_pipeline/src/core_3d/skybox/mod.rs index c398e7c613d18..5d6df66209234 100644 --- a/crates/bevy_core_pipeline/src/core_3d/skybox/mod.rs +++ b/crates/bevy_core_pipeline/src/core_3d/skybox/mod.rs @@ -81,41 +81,41 @@ struct SkyboxPipeline { impl SkyboxPipeline { fn new(vertex_buffer_layout: VertexBufferLayout, render_device: &RenderDevice) -> Self { - let bind_group_layout = - render_device.create_bind_group_layout(&BindGroupLayoutDescriptor { - label: Some("skybox_bind_group_layout"), - entries: &[ - BindGroupLayoutEntry { - binding: 0, - visibility: ShaderStages::FRAGMENT, - ty: BindingType::Texture { - sample_type: TextureSampleType::Float { filterable: true }, - view_dimension: TextureViewDimension::Cube, - multisampled: false, - }, - count: None, - }, - BindGroupLayoutEntry { - binding: 1, - visibility: ShaderStages::FRAGMENT, - ty: BindingType::Sampler(SamplerBindingType::Filtering), - count: None, + let bind_group_layout_descriptor = BindGroupLayoutDescriptor { + label: Some("skybox_bind_group_layout"), + entries: &[ + BindGroupLayoutEntry { + binding: 0, + visibility: ShaderStages::FRAGMENT, + ty: BindingType::Texture { + sample_type: TextureSampleType::Float { filterable: true }, + view_dimension: TextureViewDimension::Cube, + multisampled: false, }, - BindGroupLayoutEntry { - binding: 2, - visibility: ShaderStages::VERTEX, - ty: BindingType::Buffer { - ty: BufferBindingType::Uniform, - has_dynamic_offset: true, - min_binding_size: Some(ViewUniform::min_size()), - }, - count: None, + count: None, + }, + BindGroupLayoutEntry { + binding: 1, + visibility: ShaderStages::FRAGMENT, + ty: BindingType::Sampler(SamplerBindingType::Filtering), + count: None, + }, + BindGroupLayoutEntry { + binding: 2, + visibility: ShaderStages::VERTEX, + ty: BindingType::Buffer { + ty: BufferBindingType::Uniform, + has_dynamic_offset: true, + min_binding_size: Some(ViewUniform::min_size()), }, - ], - }); + count: None, + }, + ], + }; Self { - bind_group_layout, + bind_group_layout: render_device + .create_bind_group_layout(&bind_group_layout_descriptor), vertex_buffer_layout, } } diff --git a/crates/bevy_core_pipeline/src/core_3d/skybox/node.rs b/crates/bevy_core_pipeline/src/core_3d/skybox/node.rs index 1d560204ea9bf..33b97abde22cc 100644 --- a/crates/bevy_core_pipeline/src/core_3d/skybox/node.rs +++ b/crates/bevy_core_pipeline/src/core_3d/skybox/node.rs @@ -41,41 +41,43 @@ impl Node for SkyboxNode { pipeline_cache.get_render_pipeline(pipeline_id.0), ) else { return Ok(()) }; - let mut render_pass = render_context.begin_tracked_render_pass(RenderPassDescriptor { - label: Some("skybox"), - color_attachments: &[Some(target.get_color_attachment(Operations { - load: LoadOp::Load, - store: true, - }))], - depth_stencil_attachment: Some(RenderPassDepthStencilAttachment { - view: &depth.view, - depth_ops: Some(Operations { + { + let mut render_pass = render_context.begin_tracked_render_pass(RenderPassDescriptor { + label: Some("skybox"), + color_attachments: &[Some(target.get_color_attachment(Operations { load: LoadOp::Load, - store: false, + store: true, + }))], + depth_stencil_attachment: Some(RenderPassDepthStencilAttachment { + view: &depth.view, + depth_ops: Some(Operations { + load: LoadOp::Load, + store: false, + }), + stencil_ops: None, }), - stencil_ops: None, - }), - }); + }); - render_pass.set_render_pipeline(pipeline); - render_pass.set_bind_group(0, &bind_group.0, &[view_uniform_offset.offset]); + render_pass.set_render_pipeline(pipeline); + render_pass.set_bind_group(0, &bind_group.0, &[view_uniform_offset.offset]); - if let Some(viewport) = camera.viewport.as_ref() { - render_pass.set_camera_viewport(viewport); - } - - render_pass.set_vertex_buffer(0, gpu_mesh.vertex_buffer.slice(..)); - match &gpu_mesh.buffer_info { - GpuBufferInfo::Indexed { - buffer, - index_format, - count, - } => { - render_pass.set_index_buffer(buffer.slice(..), 0, *index_format); - render_pass.draw_indexed(0..*count, 0, 0..1); + if let Some(viewport) = camera.viewport.as_ref() { + render_pass.set_camera_viewport(viewport); } - GpuBufferInfo::NonIndexed { vertex_count } => { - render_pass.draw(0..*vertex_count, 0..1); + + render_pass.set_vertex_buffer(0, gpu_mesh.vertex_buffer.slice(..)); + match &gpu_mesh.buffer_info { + GpuBufferInfo::Indexed { + buffer, + index_format, + count, + } => { + render_pass.set_index_buffer(buffer.slice(..), 0, *index_format); + render_pass.draw_indexed(0..*count, 0, 0..1); + } + GpuBufferInfo::NonIndexed { vertex_count } => { + render_pass.draw(0..*vertex_count, 0..1); + } } } From 2279f099411aa3b411426b06af27b8d5df803568 Mon Sep 17 00:00:00 2001 From: JMS55 <47158642+JMS55@users.noreply.github.com> Date: Thu, 30 Mar 2023 16:01:09 -0400 Subject: [PATCH 06/30] Misc fix --- .../src/core_3d/skybox/mod.rs | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/crates/bevy_core_pipeline/src/core_3d/skybox/mod.rs b/crates/bevy_core_pipeline/src/core_3d/skybox/mod.rs index 5d6df66209234..f689045d966ba 100644 --- a/crates/bevy_core_pipeline/src/core_3d/skybox/mod.rs +++ b/crates/bevy_core_pipeline/src/core_3d/skybox/mod.rs @@ -24,8 +24,8 @@ use bevy_render::{ TextureFormat, TextureSampleType, TextureViewDimension, VertexBufferLayout, VertexState, }, renderer::RenderDevice, - texture::Image, - view::{Msaa, ViewTarget, ViewUniform, ViewUniforms}, + texture::{BevyDefault, Image}, + view::{ExtractedView, Msaa, ViewTarget, ViewUniform, ViewUniforms}, Render, RenderApp, RenderSet, }; @@ -123,7 +123,7 @@ impl SkyboxPipeline { #[derive(PartialEq, Eq, Hash, Clone, Copy)] struct SkyboxPipelineKey { - texture_format: TextureFormat, + hdr: bool, samples: u32, } @@ -168,7 +168,11 @@ impl SpecializedRenderPipeline for SkyboxPipeline { shader_defs: Vec::new(), entry_point: "skybox_fragment".into(), targets: vec![Some(ColorTargetState { - format: key.texture_format, + format: if key.hdr { + ViewTarget::TEXTURE_FORMAT_HDR + } else { + TextureFormat::bevy_default() + }, blend: Some(BlendState::REPLACE), write_mask: ColorWrites::ALL, })], @@ -186,14 +190,14 @@ fn prepare_skybox_pipelines( mut pipelines: ResMut>, pipeline: Res, msaa: Res, - views: Query<(Entity, &ViewTarget), With>, + views: Query<(Entity, &ExtractedView), With>, ) { - for (entity, view_target) in &views { + for (entity, view) in &views { let pipeline_id = pipelines.specialize( &pipeline_cache, &pipeline, SkyboxPipelineKey { - texture_format: view_target.main_texture_format(), + hdr: view.hdr, samples: msaa.samples(), }, ); From addf220c236b07a6fd8b9d843dbb474b24294899 Mon Sep 17 00:00:00 2001 From: JMS55 <47158642+JMS55@users.noreply.github.com> Date: Thu, 30 Mar 2023 16:03:17 -0400 Subject: [PATCH 07/30] Extract skybox --- crates/bevy_core_pipeline/src/core_3d/skybox/mod.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/crates/bevy_core_pipeline/src/core_3d/skybox/mod.rs b/crates/bevy_core_pipeline/src/core_3d/skybox/mod.rs index f689045d966ba..0d1402799467f 100644 --- a/crates/bevy_core_pipeline/src/core_3d/skybox/mod.rs +++ b/crates/bevy_core_pipeline/src/core_3d/skybox/mod.rs @@ -12,6 +12,7 @@ use bevy_ecs::{ }; use bevy_reflect::TypeUuid; use bevy_render::{ + extract_component::{ExtractComponent, ExtractComponentPlugin}, prelude::{shape::Cube, Mesh}, render_asset::RenderAssets, render_resource::{ @@ -38,6 +39,8 @@ impl Plugin for SkyboxPlugin { fn build(&self, app: &mut App) { load_internal_asset!(app, SKYBOX_SHADER_HANDLE, "skybox.wgsl", Shader::from_wgsl); + app.add_plugin(ExtractComponentPlugin::::default()); + let mesh = Mesh::from(Cube::new(1.0)); let vertex_buffer_layout = mesh.get_mesh_vertex_buffer_layout().layout().clone(); let handle = app.world.resource_mut::>().add(mesh); @@ -63,7 +66,7 @@ impl Plugin for SkyboxPlugin { } } -#[derive(Component)] +#[derive(Component, ExtractComponent, Clone)] pub struct Skybox(pub Handle); // ---------------------------------------------------------------------------- From c952cc63529c7b4a50183e48c1f166ce13a7ff82 Mon Sep 17 00:00:00 2001 From: JMS55 <47158642+JMS55@users.noreply.github.com> Date: Thu, 30 Mar 2023 16:08:56 -0400 Subject: [PATCH 08/30] Shader fixes --- .../bevy_core_pipeline/src/core_3d/skybox/mod.rs | 16 +++++++++++----- .../src/core_3d/skybox/skybox.wgsl | 5 ++--- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/crates/bevy_core_pipeline/src/core_3d/skybox/mod.rs b/crates/bevy_core_pipeline/src/core_3d/skybox/mod.rs index 0d1402799467f..86aaa9b699e44 100644 --- a/crates/bevy_core_pipeline/src/core_3d/skybox/mod.rs +++ b/crates/bevy_core_pipeline/src/core_3d/skybox/mod.rs @@ -20,9 +20,10 @@ use bevy_render::{ BindGroupLayoutEntry, BindingResource, BindingType, BlendState, BufferBindingType, CachedRenderPipelineId, ColorTargetState, ColorWrites, CompareFunction, DepthBiasState, DepthStencilState, FragmentState, MultisampleState, PipelineCache, PrimitiveState, - RenderPipelineDescriptor, SamplerBindingType, Shader, ShaderStages, ShaderType, - SpecializedRenderPipeline, SpecializedRenderPipelines, StencilFaceState, StencilState, - TextureFormat, TextureSampleType, TextureViewDimension, VertexBufferLayout, VertexState, + RenderPipelineDescriptor, SamplerBindingType, Shader, ShaderDefVal, ShaderStages, + ShaderType, SpecializedRenderPipeline, SpecializedRenderPipelines, StencilFaceState, + StencilState, TextureFormat, TextureSampleType, TextureViewDimension, VertexBufferLayout, + VertexState, }, renderer::RenderDevice, texture::{BevyDefault, Image}, @@ -134,13 +135,18 @@ impl SpecializedRenderPipeline for SkyboxPipeline { type Key = SkyboxPipelineKey; fn specialize(&self, key: Self::Key) -> RenderPipelineDescriptor { + let shader_defs = vec![ + ShaderDefVal::UInt("MAX_DIRECTIONAL_LIGHTS".to_string(), 1), + ShaderDefVal::UInt("MAX_CASCADES_PER_LIGHT".to_string(), 1), + ]; + RenderPipelineDescriptor { label: Some("skybox_pipeline".into()), layout: vec![self.bind_group_layout.clone()], push_constant_ranges: Vec::new(), vertex: VertexState { shader: SKYBOX_SHADER_HANDLE.typed(), - shader_defs: Vec::new(), + shader_defs: shader_defs.clone(), entry_point: "skybox_vertex".into(), buffers: vec![self.vertex_buffer_layout.clone()], }, @@ -168,7 +174,7 @@ impl SpecializedRenderPipeline for SkyboxPipeline { }, fragment: Some(FragmentState { shader: SKYBOX_SHADER_HANDLE.typed(), - shader_defs: Vec::new(), + shader_defs, entry_point: "skybox_fragment".into(), targets: vec![Some(ColorTargetState { format: if key.hdr { diff --git a/crates/bevy_core_pipeline/src/core_3d/skybox/skybox.wgsl b/crates/bevy_core_pipeline/src/core_3d/skybox/skybox.wgsl index 20a0614d2120b..dc8e66a143e86 100644 --- a/crates/bevy_core_pipeline/src/core_3d/skybox/skybox.wgsl +++ b/crates/bevy_core_pipeline/src/core_3d/skybox/skybox.wgsl @@ -1,5 +1,4 @@ -#import bevy_pbr::mesh_view_bindings -#import bevy_pbr::mesh_functions +#import bevy_pbr::mesh_view_types @group(0) @binding(0) var skybox: texture_cube; @@ -10,7 +9,7 @@ var view: View; @vertex fn skybox_vertex(@location(0) position: vec3) -> @builtin(position) vec4 { - var out = mesh_position_world_to_clip(position); + var out = view.view_proj * vec4(position, 1.0); out.z = out.w; return out; } From 121ce4875fbefad603bc2a39faa25c5092060684 Mon Sep 17 00:00:00 2001 From: JMS55 <47158642+JMS55@users.noreply.github.com> Date: Thu, 30 Mar 2023 16:16:09 -0400 Subject: [PATCH 09/30] Fix shader --- crates/bevy_core_pipeline/src/core_3d/skybox/skybox.wgsl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/bevy_core_pipeline/src/core_3d/skybox/skybox.wgsl b/crates/bevy_core_pipeline/src/core_3d/skybox/skybox.wgsl index dc8e66a143e86..191fe193c819a 100644 --- a/crates/bevy_core_pipeline/src/core_3d/skybox/skybox.wgsl +++ b/crates/bevy_core_pipeline/src/core_3d/skybox/skybox.wgsl @@ -9,8 +9,8 @@ var view: View; @vertex fn skybox_vertex(@location(0) position: vec3) -> @builtin(position) vec4 { - var out = view.view_proj * vec4(position, 1.0); - out.z = out.w; + var out = view.projection * vec4(position, 1.0); + out.z = 0.0; return out; } From 2ad5eaa188dddee482b9fca28c636907516630f5 Mon Sep 17 00:00:00 2001 From: JMS55 <47158642+JMS55@users.noreply.github.com> Date: Thu, 30 Mar 2023 16:46:24 -0400 Subject: [PATCH 10/30] Remove camera translation from skybox --- crates/bevy_core_pipeline/src/core_3d/skybox/skybox.wgsl | 2 +- crates/bevy_render/src/view/mod.rs | 6 ++++++ crates/bevy_render/src/view/view.wgsl | 1 + 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/crates/bevy_core_pipeline/src/core_3d/skybox/skybox.wgsl b/crates/bevy_core_pipeline/src/core_3d/skybox/skybox.wgsl index 191fe193c819a..7c64906a2afa2 100644 --- a/crates/bevy_core_pipeline/src/core_3d/skybox/skybox.wgsl +++ b/crates/bevy_core_pipeline/src/core_3d/skybox/skybox.wgsl @@ -9,7 +9,7 @@ var view: View; @vertex fn skybox_vertex(@location(0) position: vec3) -> @builtin(position) vec4 { - var out = view.projection * vec4(position, 1.0); + var out = view.no_translation_view_proj * vec4(position, 1.0); out.z = 0.0; return out; } diff --git a/crates/bevy_render/src/view/mod.rs b/crates/bevy_render/src/view/mod.rs index c602dd7628f12..7a98e8423ec61 100644 --- a/crates/bevy_render/src/view/mod.rs +++ b/crates/bevy_render/src/view/mod.rs @@ -163,6 +163,7 @@ pub struct ViewUniform { view_proj: Mat4, unjittered_view_proj: Mat4, inverse_view_proj: Mat4, + no_translation_view_proj: Mat4, view: Mat4, inverse_view: Mat4, projection: Mat4, @@ -330,6 +331,10 @@ pub fn prepare_view_uniforms( let view = camera.transform.compute_matrix(); let inverse_view = view.inverse(); + let mut no_translation_inverse_view = view; + *no_translation_inverse_view.col_mut(3) = Vec4::new(0.0, 0.0, 0.0, 1.0); + no_translation_inverse_view = no_translation_inverse_view.inverse(); + let view_uniforms = ViewUniformOffset { offset: view_uniforms.uniforms.push(ViewUniform { view_proj: camera @@ -337,6 +342,7 @@ pub fn prepare_view_uniforms( .unwrap_or_else(|| projection * inverse_view), unjittered_view_proj: unjittered_projection * inverse_view, inverse_view_proj: view * inverse_projection, + no_translation_view_proj: projection * no_translation_inverse_view, view, inverse_view, projection, diff --git a/crates/bevy_render/src/view/view.wgsl b/crates/bevy_render/src/view/view.wgsl index ce50833e66f80..594bed36070c1 100644 --- a/crates/bevy_render/src/view/view.wgsl +++ b/crates/bevy_render/src/view/view.wgsl @@ -11,6 +11,7 @@ struct View { view_proj: mat4x4, unjittered_view_proj: mat4x4, inverse_view_proj: mat4x4, + no_translation_view_proj: mat4x4, view: mat4x4, inverse_view: mat4x4, projection: mat4x4, From b23e6401b83e2a735d01653c1770dfc39cbb8906 Mon Sep 17 00:00:00 2001 From: JMS55 <47158642+JMS55@users.noreply.github.com> Date: Fri, 31 Mar 2023 00:35:20 -0400 Subject: [PATCH 11/30] Fix skybox shader --- .../src/core_3d/skybox/skybox.wgsl | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/crates/bevy_core_pipeline/src/core_3d/skybox/skybox.wgsl b/crates/bevy_core_pipeline/src/core_3d/skybox/skybox.wgsl index 7c64906a2afa2..72a9330fee985 100644 --- a/crates/bevy_core_pipeline/src/core_3d/skybox/skybox.wgsl +++ b/crates/bevy_core_pipeline/src/core_3d/skybox/skybox.wgsl @@ -7,14 +7,21 @@ var skybox_sampler: sampler; @group(0) @binding(2) var view: View; +struct VertexOutput { + @builtin(position) clip_position: vec4, + @location(0) position: vec3, +}; + @vertex -fn skybox_vertex(@location(0) position: vec3) -> @builtin(position) vec4 { - var out = view.no_translation_view_proj * vec4(position, 1.0); - out.z = 0.0; +fn skybox_vertex(@location(0) position: vec3) -> VertexOutput { + var out: VertexOutput; + out.clip_position = view.no_translation_view_proj * vec4(position, 1.0); + out.clip_position.z = 0.0; + out.position = position; return out; } @fragment -fn skybox_fragment(@builtin(position) clip_position: vec4) -> @location(0) vec4 { - return textureSample(skybox, skybox_sampler, clip_position.xyz); +fn skybox_fragment(in: VertexOutput) -> @location(0) vec4 { + return textureSample(skybox, skybox_sampler, in.position); } From 9eb67d9a3c5268e24dd127187c965ec4f4ed2ee8 Mon Sep 17 00:00:00 2001 From: JMS55 <47158642+JMS55@users.noreply.github.com> Date: Fri, 31 Mar 2023 00:53:13 -0400 Subject: [PATCH 12/30] Improve shader --- crates/bevy_core_pipeline/src/core_3d/skybox/skybox.wgsl | 3 +-- crates/bevy_render/src/view/mod.rs | 6 ------ crates/bevy_render/src/view/view.wgsl | 1 - 3 files changed, 1 insertion(+), 9 deletions(-) diff --git a/crates/bevy_core_pipeline/src/core_3d/skybox/skybox.wgsl b/crates/bevy_core_pipeline/src/core_3d/skybox/skybox.wgsl index 72a9330fee985..7aee9d5b4e471 100644 --- a/crates/bevy_core_pipeline/src/core_3d/skybox/skybox.wgsl +++ b/crates/bevy_core_pipeline/src/core_3d/skybox/skybox.wgsl @@ -15,8 +15,7 @@ struct VertexOutput { @vertex fn skybox_vertex(@location(0) position: vec3) -> VertexOutput { var out: VertexOutput; - out.clip_position = view.no_translation_view_proj * vec4(position, 1.0); - out.clip_position.z = 0.0; + out.clip_position = view.view_proj * vec4(position, 0.0); out.position = position; return out; } diff --git a/crates/bevy_render/src/view/mod.rs b/crates/bevy_render/src/view/mod.rs index 7a98e8423ec61..c602dd7628f12 100644 --- a/crates/bevy_render/src/view/mod.rs +++ b/crates/bevy_render/src/view/mod.rs @@ -163,7 +163,6 @@ pub struct ViewUniform { view_proj: Mat4, unjittered_view_proj: Mat4, inverse_view_proj: Mat4, - no_translation_view_proj: Mat4, view: Mat4, inverse_view: Mat4, projection: Mat4, @@ -331,10 +330,6 @@ pub fn prepare_view_uniforms( let view = camera.transform.compute_matrix(); let inverse_view = view.inverse(); - let mut no_translation_inverse_view = view; - *no_translation_inverse_view.col_mut(3) = Vec4::new(0.0, 0.0, 0.0, 1.0); - no_translation_inverse_view = no_translation_inverse_view.inverse(); - let view_uniforms = ViewUniformOffset { offset: view_uniforms.uniforms.push(ViewUniform { view_proj: camera @@ -342,7 +337,6 @@ pub fn prepare_view_uniforms( .unwrap_or_else(|| projection * inverse_view), unjittered_view_proj: unjittered_projection * inverse_view, inverse_view_proj: view * inverse_projection, - no_translation_view_proj: projection * no_translation_inverse_view, view, inverse_view, projection, diff --git a/crates/bevy_render/src/view/view.wgsl b/crates/bevy_render/src/view/view.wgsl index 594bed36070c1..ce50833e66f80 100644 --- a/crates/bevy_render/src/view/view.wgsl +++ b/crates/bevy_render/src/view/view.wgsl @@ -11,7 +11,6 @@ struct View { view_proj: mat4x4, unjittered_view_proj: mat4x4, inverse_view_proj: mat4x4, - no_translation_view_proj: mat4x4, view: mat4x4, inverse_view: mat4x4, projection: mat4x4, From 6286b8ffe9c08056eaf9dc86d507b7c8d0b14ffd Mon Sep 17 00:00:00 2001 From: JMS55 <47158642+JMS55@users.noreply.github.com> Date: Fri, 31 Mar 2023 00:58:07 -0400 Subject: [PATCH 13/30] Move skybox module --- crates/bevy_core_pipeline/src/core_3d/mod.rs | 3 +-- crates/bevy_core_pipeline/src/lib.rs | 1 + crates/bevy_core_pipeline/src/{core_3d => }/skybox/mod.rs | 0 crates/bevy_core_pipeline/src/{core_3d => }/skybox/node.rs | 0 crates/bevy_core_pipeline/src/{core_3d => }/skybox/skybox.wgsl | 0 5 files changed, 2 insertions(+), 2 deletions(-) rename crates/bevy_core_pipeline/src/{core_3d => }/skybox/mod.rs (100%) rename crates/bevy_core_pipeline/src/{core_3d => }/skybox/node.rs (100%) rename crates/bevy_core_pipeline/src/{core_3d => }/skybox/skybox.wgsl (100%) diff --git a/crates/bevy_core_pipeline/src/core_3d/mod.rs b/crates/bevy_core_pipeline/src/core_3d/mod.rs index 8f4a2bc37b965..231b6576c8687 100644 --- a/crates/bevy_core_pipeline/src/core_3d/mod.rs +++ b/crates/bevy_core_pipeline/src/core_3d/mod.rs @@ -1,7 +1,6 @@ mod camera_3d; mod main_opaque_pass_3d_node; mod main_transparent_pass_3d_node; -mod skybox; pub mod graph { pub const NAME: &str = "core_3d"; @@ -29,7 +28,6 @@ use std::cmp::Reverse; pub use camera_3d::*; pub use main_opaque_pass_3d_node::*; pub use main_transparent_pass_3d_node::*; -pub use skybox::*; use bevy_app::{App, Plugin}; use bevy_ecs::prelude::*; @@ -55,6 +53,7 @@ use bevy_utils::{FloatOrd, HashMap}; use crate::{ prepass::{node::PrepassNode, DepthPrepass}, + skybox::{SkyboxNode, SkyboxPlugin}, tonemapping::TonemappingNode, upscaling::UpscalingNode, }; diff --git a/crates/bevy_core_pipeline/src/lib.rs b/crates/bevy_core_pipeline/src/lib.rs index b7692a2e51e3d..383f17561f620 100644 --- a/crates/bevy_core_pipeline/src/lib.rs +++ b/crates/bevy_core_pipeline/src/lib.rs @@ -7,6 +7,7 @@ pub mod fullscreen_vertex_shader; pub mod fxaa; pub mod msaa_writeback; pub mod prepass; +pub mod skybox; mod taa; pub mod tonemapping; pub mod upscaling; diff --git a/crates/bevy_core_pipeline/src/core_3d/skybox/mod.rs b/crates/bevy_core_pipeline/src/skybox/mod.rs similarity index 100% rename from crates/bevy_core_pipeline/src/core_3d/skybox/mod.rs rename to crates/bevy_core_pipeline/src/skybox/mod.rs diff --git a/crates/bevy_core_pipeline/src/core_3d/skybox/node.rs b/crates/bevy_core_pipeline/src/skybox/node.rs similarity index 100% rename from crates/bevy_core_pipeline/src/core_3d/skybox/node.rs rename to crates/bevy_core_pipeline/src/skybox/node.rs diff --git a/crates/bevy_core_pipeline/src/core_3d/skybox/skybox.wgsl b/crates/bevy_core_pipeline/src/skybox/skybox.wgsl similarity index 100% rename from crates/bevy_core_pipeline/src/core_3d/skybox/skybox.wgsl rename to crates/bevy_core_pipeline/src/skybox/skybox.wgsl From 0b8e3d5b8ddd52e2dbd7f846c337ef045b6e10e2 Mon Sep 17 00:00:00 2001 From: JMS55 <47158642+JMS55@users.noreply.github.com> Date: Fri, 31 Mar 2023 11:12:50 -0400 Subject: [PATCH 14/30] Add doc --- crates/bevy_core_pipeline/src/skybox/mod.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/crates/bevy_core_pipeline/src/skybox/mod.rs b/crates/bevy_core_pipeline/src/skybox/mod.rs index 86aaa9b699e44..88b2ecdfad07a 100644 --- a/crates/bevy_core_pipeline/src/skybox/mod.rs +++ b/crates/bevy_core_pipeline/src/skybox/mod.rs @@ -67,6 +67,9 @@ impl Plugin for SkyboxPlugin { } } +/// Adds a skybox to a 3D camera. +/// +/// See also . #[derive(Component, ExtractComponent, Clone)] pub struct Skybox(pub Handle); From 9b29b5d7046d540030449b74652fbffae757bf00 Mon Sep 17 00:00:00 2001 From: JMS55 <47158642+JMS55@users.noreply.github.com> Date: Fri, 31 Mar 2023 11:14:50 -0400 Subject: [PATCH 15/30] Misc doc --- crates/bevy_core_pipeline/src/skybox/mod.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/crates/bevy_core_pipeline/src/skybox/mod.rs b/crates/bevy_core_pipeline/src/skybox/mod.rs index 88b2ecdfad07a..54347e9dd3fa5 100644 --- a/crates/bevy_core_pipeline/src/skybox/mod.rs +++ b/crates/bevy_core_pipeline/src/skybox/mod.rs @@ -69,6 +69,9 @@ impl Plugin for SkyboxPlugin { /// Adds a skybox to a 3D camera. /// +/// Note that this component does not (currently) affect the scene's lighting. +/// To do so, use `EnvironmentMapLight` alongside this component. +/// /// See also . #[derive(Component, ExtractComponent, Clone)] pub struct Skybox(pub Handle); From 0d57752024c321afd56cd351f3d7da509c1d9169 Mon Sep 17 00:00:00 2001 From: JMS55 <47158642+JMS55@users.noreply.github.com> Date: Fri, 31 Mar 2023 11:21:29 -0400 Subject: [PATCH 16/30] Doc tweak --- crates/bevy_core_pipeline/src/skybox/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bevy_core_pipeline/src/skybox/mod.rs b/crates/bevy_core_pipeline/src/skybox/mod.rs index 54347e9dd3fa5..9953db72cb5da 100644 --- a/crates/bevy_core_pipeline/src/skybox/mod.rs +++ b/crates/bevy_core_pipeline/src/skybox/mod.rs @@ -67,7 +67,7 @@ impl Plugin for SkyboxPlugin { } } -/// Adds a skybox to a 3D camera. +/// Adds a skybox to a 3D camera, based on a cubemap texture. /// /// Note that this component does not (currently) affect the scene's lighting. /// To do so, use `EnvironmentMapLight` alongside this component. From 9f147c1b2b403d7b8da90cadb927f934e3ffce23 Mon Sep 17 00:00:00 2001 From: JMS55 <47158642+JMS55@users.noreply.github.com> Date: Fri, 31 Mar 2023 11:34:05 -0400 Subject: [PATCH 17/30] Change visibilities --- crates/bevy_core_pipeline/src/skybox/mod.rs | 2 +- crates/bevy_core_pipeline/src/skybox/node.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/bevy_core_pipeline/src/skybox/mod.rs b/crates/bevy_core_pipeline/src/skybox/mod.rs index 9953db72cb5da..87a9c1debde88 100644 --- a/crates/bevy_core_pipeline/src/skybox/mod.rs +++ b/crates/bevy_core_pipeline/src/skybox/mod.rs @@ -34,7 +34,7 @@ use bevy_render::{ const SKYBOX_SHADER_HANDLE: HandleUntyped = HandleUntyped::weak_from_u64(Shader::TYPE_UUID, 55594763423201); -pub struct SkyboxPlugin; +pub(crate) struct SkyboxPlugin; impl Plugin for SkyboxPlugin { fn build(&self, app: &mut App) { diff --git a/crates/bevy_core_pipeline/src/skybox/node.rs b/crates/bevy_core_pipeline/src/skybox/node.rs index 33b97abde22cc..2746403a5e3e8 100644 --- a/crates/bevy_core_pipeline/src/skybox/node.rs +++ b/crates/bevy_core_pipeline/src/skybox/node.rs @@ -13,7 +13,7 @@ use bevy_render::{ view::{ViewDepthTexture, ViewTarget, ViewUniformOffset}, }; -pub struct SkyboxNode { +pub(crate) struct SkyboxNode { view_query: QueryState<( &'static SkyboxPipelineId, &'static SkyboxBindGroup, From 637a3139e703269ddcf26fd77280cab8976e0735 Mon Sep 17 00:00:00 2001 From: JMS55 <47158642+JMS55@users.noreply.github.com> Date: Fri, 31 Mar 2023 11:37:18 -0400 Subject: [PATCH 18/30] Misc --- crates/bevy_core_pipeline/src/skybox/mod.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/crates/bevy_core_pipeline/src/skybox/mod.rs b/crates/bevy_core_pipeline/src/skybox/mod.rs index 87a9c1debde88..f506e2b714c29 100644 --- a/crates/bevy_core_pipeline/src/skybox/mod.rs +++ b/crates/bevy_core_pipeline/src/skybox/mod.rs @@ -1,7 +1,5 @@ mod node; -pub use node::*; - use bevy_app::{App, Plugin}; use bevy_asset::{load_internal_asset, Assets, Handle, HandleUntyped}; use bevy_ecs::{ From 73089f7c9935c7c388db54e1428c5e2d93e91046 Mon Sep 17 00:00:00 2001 From: JMS55 <47158642+JMS55@users.noreply.github.com> Date: Fri, 31 Mar 2023 12:44:12 -0400 Subject: [PATCH 19/30] Fix imports --- crates/bevy_core_pipeline/src/core_3d/mod.rs | 2 +- crates/bevy_core_pipeline/src/skybox/mod.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/bevy_core_pipeline/src/core_3d/mod.rs b/crates/bevy_core_pipeline/src/core_3d/mod.rs index 231b6576c8687..2f9cd22344de7 100644 --- a/crates/bevy_core_pipeline/src/core_3d/mod.rs +++ b/crates/bevy_core_pipeline/src/core_3d/mod.rs @@ -53,7 +53,7 @@ use bevy_utils::{FloatOrd, HashMap}; use crate::{ prepass::{node::PrepassNode, DepthPrepass}, - skybox::{SkyboxNode, SkyboxPlugin}, + skybox::{node::SkyboxNode, SkyboxPlugin}, tonemapping::TonemappingNode, upscaling::UpscalingNode, }; diff --git a/crates/bevy_core_pipeline/src/skybox/mod.rs b/crates/bevy_core_pipeline/src/skybox/mod.rs index f506e2b714c29..793c54e550b37 100644 --- a/crates/bevy_core_pipeline/src/skybox/mod.rs +++ b/crates/bevy_core_pipeline/src/skybox/mod.rs @@ -1,4 +1,4 @@ -mod node; +pub(crate) mod node; use bevy_app::{App, Plugin}; use bevy_asset::{load_internal_asset, Assets, Handle, HandleUntyped}; From 00a62df9450d85ef71029c3042d9bdad1d70534a Mon Sep 17 00:00:00 2001 From: JMS55 <47158642+JMS55@users.noreply.github.com> Date: Fri, 31 Mar 2023 13:04:50 -0400 Subject: [PATCH 20/30] Combine SkyboxNode and MainOpaquePass3dNode --- .../src/core_3d/main_opaque_pass_3d_node.rs | 43 +++++++- crates/bevy_core_pipeline/src/core_3d/mod.rs | 10 +- crates/bevy_core_pipeline/src/lib.rs | 4 +- crates/bevy_core_pipeline/src/skybox/mod.rs | 12 +-- crates/bevy_core_pipeline/src/skybox/node.rs | 98 ------------------- 5 files changed, 53 insertions(+), 114 deletions(-) delete mode 100644 crates/bevy_core_pipeline/src/skybox/node.rs diff --git a/crates/bevy_core_pipeline/src/core_3d/main_opaque_pass_3d_node.rs b/crates/bevy_core_pipeline/src/core_3d/main_opaque_pass_3d_node.rs index b295b4bb1cc89..bfd3348ead243 100644 --- a/crates/bevy_core_pipeline/src/core_3d/main_opaque_pass_3d_node.rs +++ b/crates/bevy_core_pipeline/src/core_3d/main_opaque_pass_3d_node.rs @@ -2,15 +2,21 @@ use crate::{ clear_color::{ClearColor, ClearColorConfig}, core_3d::{Camera3d, Opaque3d}, prepass::{DepthPrepass, MotionVectorPrepass, NormalPrepass}, + skybox::{SkyboxBindGroup, SkyboxMesh, SkyboxPipelineId}, }; use bevy_ecs::prelude::*; use bevy_render::{ camera::ExtractedCamera, + mesh::GpuBufferInfo, + prelude::Mesh, + render_asset::RenderAssets, render_graph::{Node, NodeRunError, RenderGraphContext}, render_phase::RenderPhase, - render_resource::{LoadOp, Operations, RenderPassDepthStencilAttachment, RenderPassDescriptor}, + render_resource::{ + LoadOp, Operations, PipelineCache, RenderPassDepthStencilAttachment, RenderPassDescriptor, + }, renderer::RenderContext, - view::{ExtractedView, ViewDepthTexture, ViewTarget}, + view::{ExtractedView, ViewDepthTexture, ViewTarget, ViewUniformOffset}, }; #[cfg(feature = "trace")] use bevy_utils::tracing::info_span; @@ -30,6 +36,9 @@ pub struct MainOpaquePass3dNode { Option<&'static DepthPrepass>, Option<&'static NormalPrepass>, Option<&'static MotionVectorPrepass>, + Option<&'static SkyboxPipelineId>, + Option<&'static SkyboxBindGroup>, + &'static ViewUniformOffset, ), With, >, @@ -64,7 +73,10 @@ impl Node for MainOpaquePass3dNode { depth, depth_prepass, normal_prepass, - motion_vector_prepass + motion_vector_prepass, + skybox_pipeline, + skybox_bind_group, + view_uniform_offset, )) = self.query.get_manual(world, view_entity) else { // No window return Ok(()); @@ -75,6 +87,7 @@ impl Node for MainOpaquePass3dNode { #[cfg(feature = "trace")] let _main_opaque_pass_3d_span = info_span!("main_opaque_pass_3d").entered(); + // Setup render pass let mut render_pass = render_context.begin_tracked_render_pass(RenderPassDescriptor { label: Some("main_opaque_pass_3d"), // NOTE: The opaque pass loads the color @@ -115,12 +128,36 @@ impl Node for MainOpaquePass3dNode { render_pass.set_camera_viewport(viewport); } + // Opaque draws opaque_phase.render(&mut render_pass, world, view_entity); + // Alpha draws if !alpha_mask_phase.items.is_empty() { alpha_mask_phase.render(&mut render_pass, world, view_entity); } + // Skybox draw + if let (Some(skybox_pipeline), Some(skybox_bind_group)) = + (skybox_pipeline, skybox_bind_group) + { + let skybox_mesh = world.resource::(); + let meshes = world.resource::>(); + let pipeline_cache = world.resource::(); + + if let (Some(skybox_pipeline), Some(skybox_gpu_mesh)) = ( + pipeline_cache.get_render_pipeline(skybox_pipeline.0), + meshes.get(&skybox_mesh.handle), + ) { + let GpuBufferInfo::Indexed { buffer, index_format, count } = &skybox_gpu_mesh.buffer_info else { unreachable!() }; + + render_pass.set_render_pipeline(skybox_pipeline); + render_pass.set_bind_group(0, &skybox_bind_group.0, &[view_uniform_offset.offset]); + render_pass.set_vertex_buffer(0, skybox_gpu_mesh.vertex_buffer.slice(..)); + render_pass.set_index_buffer(buffer.slice(..), 0, *index_format); + render_pass.draw_indexed(0..*count, 0, 0..1); + } + } + Ok(()) } } diff --git a/crates/bevy_core_pipeline/src/core_3d/mod.rs b/crates/bevy_core_pipeline/src/core_3d/mod.rs index 2f9cd22344de7..4f9e6ae49639e 100644 --- a/crates/bevy_core_pipeline/src/core_3d/mod.rs +++ b/crates/bevy_core_pipeline/src/core_3d/mod.rs @@ -53,7 +53,7 @@ use bevy_utils::{FloatOrd, HashMap}; use crate::{ prepass::{node::PrepassNode, DepthPrepass}, - skybox::{node::SkyboxNode, SkyboxPlugin}, + skybox::SkyboxPlugin, tonemapping::TonemappingNode, upscaling::UpscalingNode, }; @@ -91,7 +91,6 @@ impl Plugin for Core3dPlugin { let prepass_node = PrepassNode::new(&mut render_app.world); let opaque_node_3d = MainOpaquePass3dNode::new(&mut render_app.world); - let skybox = SkyboxNode::new(&mut render_app.world); let transparent_node_3d = MainTransparentPass3dNode::new(&mut render_app.world); let tonemapping = TonemappingNode::new(&mut render_app.world); let upscaling = UpscalingNode::new(&mut render_app.world); @@ -101,7 +100,6 @@ impl Plugin for Core3dPlugin { draw_3d_graph.add_node(graph::node::PREPASS, prepass_node); draw_3d_graph.add_node(graph::node::START_MAIN_PASS, EmptyNode); draw_3d_graph.add_node(graph::node::MAIN_OPAQUE_PASS, opaque_node_3d); - draw_3d_graph.add_node(graph::node::SKYBOX, skybox); draw_3d_graph.add_node(graph::node::MAIN_TRANSPARENT_PASS, transparent_node_3d); draw_3d_graph.add_node(graph::node::END_MAIN_PASS, EmptyNode); draw_3d_graph.add_node(graph::node::TONEMAPPING, tonemapping); @@ -110,8 +108,10 @@ impl Plugin for Core3dPlugin { draw_3d_graph.add_node_edge(graph::node::PREPASS, graph::node::START_MAIN_PASS); draw_3d_graph.add_node_edge(graph::node::START_MAIN_PASS, graph::node::MAIN_OPAQUE_PASS); - draw_3d_graph.add_node_edge(graph::node::MAIN_OPAQUE_PASS, graph::node::SKYBOX); - draw_3d_graph.add_node_edge(graph::node::SKYBOX, graph::node::MAIN_TRANSPARENT_PASS); + draw_3d_graph.add_node_edge( + graph::node::MAIN_OPAQUE_PASS, + graph::node::MAIN_TRANSPARENT_PASS, + ); draw_3d_graph.add_node_edge( graph::node::MAIN_TRANSPARENT_PASS, graph::node::END_MAIN_PASS, diff --git a/crates/bevy_core_pipeline/src/lib.rs b/crates/bevy_core_pipeline/src/lib.rs index 383f17561f620..cc96506c1de4e 100644 --- a/crates/bevy_core_pipeline/src/lib.rs +++ b/crates/bevy_core_pipeline/src/lib.rs @@ -7,11 +7,13 @@ pub mod fullscreen_vertex_shader; pub mod fxaa; pub mod msaa_writeback; pub mod prepass; -pub mod skybox; +mod skybox; mod taa; pub mod tonemapping; pub mod upscaling; +pub use skybox::Skybox; + /// Experimental features that are not yet finished. Please report any issues you encounter! pub mod experimental { pub mod taa { diff --git a/crates/bevy_core_pipeline/src/skybox/mod.rs b/crates/bevy_core_pipeline/src/skybox/mod.rs index 793c54e550b37..5a4bf03c97711 100644 --- a/crates/bevy_core_pipeline/src/skybox/mod.rs +++ b/crates/bevy_core_pipeline/src/skybox/mod.rs @@ -1,5 +1,3 @@ -pub(crate) mod node; - use bevy_app::{App, Plugin}; use bevy_asset::{load_internal_asset, Assets, Handle, HandleUntyped}; use bevy_ecs::{ @@ -32,7 +30,7 @@ use bevy_render::{ const SKYBOX_SHADER_HANDLE: HandleUntyped = HandleUntyped::weak_from_u64(Shader::TYPE_UUID, 55594763423201); -pub(crate) struct SkyboxPlugin; +pub struct SkyboxPlugin; impl Plugin for SkyboxPlugin { fn build(&self, app: &mut App) { @@ -77,8 +75,8 @@ pub struct Skybox(pub Handle); // ---------------------------------------------------------------------------- #[derive(Resource)] -struct SkyboxMesh { - handle: Handle, +pub struct SkyboxMesh { + pub handle: Handle, } #[derive(Resource)] @@ -195,7 +193,7 @@ impl SpecializedRenderPipeline for SkyboxPipeline { } #[derive(Component)] -struct SkyboxPipelineId(CachedRenderPipelineId); +pub struct SkyboxPipelineId(pub CachedRenderPipelineId); fn prepare_skybox_pipelines( mut commands: Commands, @@ -222,7 +220,7 @@ fn prepare_skybox_pipelines( } #[derive(Component)] -struct SkyboxBindGroup(BindGroup); +pub struct SkyboxBindGroup(pub BindGroup); fn queue_skybox_bind_groups( mut commands: Commands, diff --git a/crates/bevy_core_pipeline/src/skybox/node.rs b/crates/bevy_core_pipeline/src/skybox/node.rs deleted file mode 100644 index 2746403a5e3e8..0000000000000 --- a/crates/bevy_core_pipeline/src/skybox/node.rs +++ /dev/null @@ -1,98 +0,0 @@ -use super::{SkyboxBindGroup, SkyboxMesh, SkyboxPipelineId}; -use bevy_ecs::{query::QueryState, world::World}; -use bevy_render::{ - camera::ExtractedCamera, - mesh::GpuBufferInfo, - prelude::Mesh, - render_asset::RenderAssets, - render_graph::{Node, NodeRunError, RenderGraphContext}, - render_resource::{ - LoadOp, Operations, PipelineCache, RenderPassDepthStencilAttachment, RenderPassDescriptor, - }, - renderer::RenderContext, - view::{ViewDepthTexture, ViewTarget, ViewUniformOffset}, -}; - -pub(crate) struct SkyboxNode { - view_query: QueryState<( - &'static SkyboxPipelineId, - &'static SkyboxBindGroup, - &'static ViewUniformOffset, - &'static ExtractedCamera, - &'static ViewTarget, - &'static ViewDepthTexture, - )>, -} - -impl Node for SkyboxNode { - fn run( - &self, - graph: &mut RenderGraphContext, - render_context: &mut RenderContext, - world: &World, - ) -> Result<(), NodeRunError> { - let Ok((pipeline_id, bind_group, view_uniform_offset, camera, target, depth)) - = self.view_query.get_manual(world, graph.view_entity()) else { return Ok(()) }; - let skybox_mesh = world.resource::(); - let meshes = world.resource::>(); - let pipeline_cache = world.resource::(); - let (Some(gpu_mesh), Some(pipeline)) = ( - meshes.get(&skybox_mesh.handle), - pipeline_cache.get_render_pipeline(pipeline_id.0), - ) else { return Ok(()) }; - - { - let mut render_pass = render_context.begin_tracked_render_pass(RenderPassDescriptor { - label: Some("skybox"), - color_attachments: &[Some(target.get_color_attachment(Operations { - load: LoadOp::Load, - store: true, - }))], - depth_stencil_attachment: Some(RenderPassDepthStencilAttachment { - view: &depth.view, - depth_ops: Some(Operations { - load: LoadOp::Load, - store: false, - }), - stencil_ops: None, - }), - }); - - render_pass.set_render_pipeline(pipeline); - render_pass.set_bind_group(0, &bind_group.0, &[view_uniform_offset.offset]); - - if let Some(viewport) = camera.viewport.as_ref() { - render_pass.set_camera_viewport(viewport); - } - - render_pass.set_vertex_buffer(0, gpu_mesh.vertex_buffer.slice(..)); - match &gpu_mesh.buffer_info { - GpuBufferInfo::Indexed { - buffer, - index_format, - count, - } => { - render_pass.set_index_buffer(buffer.slice(..), 0, *index_format); - render_pass.draw_indexed(0..*count, 0, 0..1); - } - GpuBufferInfo::NonIndexed { vertex_count } => { - render_pass.draw(0..*vertex_count, 0..1); - } - } - } - - Ok(()) - } - - fn update(&mut self, world: &mut World) { - self.view_query.update_archetypes(world); - } -} - -impl SkyboxNode { - pub fn new(world: &mut World) -> Self { - Self { - view_query: QueryState::new(world), - } - } -} From 34a8ee991a2cc92495476e5d34354b06c84ba18a Mon Sep 17 00:00:00 2001 From: JMS55 <47158642+JMS55@users.noreply.github.com> Date: Fri, 31 Mar 2023 13:06:06 -0400 Subject: [PATCH 21/30] Misc removal --- crates/bevy_core_pipeline/src/core_3d/mod.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/crates/bevy_core_pipeline/src/core_3d/mod.rs b/crates/bevy_core_pipeline/src/core_3d/mod.rs index 4f9e6ae49639e..0a4e5d3834085 100644 --- a/crates/bevy_core_pipeline/src/core_3d/mod.rs +++ b/crates/bevy_core_pipeline/src/core_3d/mod.rs @@ -12,7 +12,6 @@ pub mod graph { pub const PREPASS: &str = "prepass"; pub const START_MAIN_PASS: &str = "start_main_pass"; pub const MAIN_OPAQUE_PASS: &str = "main_opaque_pass"; - pub const SKYBOX: &str = "skybox"; pub const MAIN_TRANSPARENT_PASS: &str = "main_transparent_pass"; pub const END_MAIN_PASS: &str = "end_main_pass"; pub const BLOOM: &str = "bloom"; From 6e1bfee50ac9cb93c6d9aa9a137f96d1e6b9aa0b Mon Sep 17 00:00:00 2001 From: Robert Swain Date: Fri, 31 Mar 2023 19:38:32 +0200 Subject: [PATCH 22/30] Use the view type shader import --- crates/bevy_core_pipeline/src/skybox/mod.rs | 9 ++------- crates/bevy_core_pipeline/src/skybox/skybox.wgsl | 2 +- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/crates/bevy_core_pipeline/src/skybox/mod.rs b/crates/bevy_core_pipeline/src/skybox/mod.rs index 5a4bf03c97711..8f1c20b9fb478 100644 --- a/crates/bevy_core_pipeline/src/skybox/mod.rs +++ b/crates/bevy_core_pipeline/src/skybox/mod.rs @@ -137,18 +137,13 @@ impl SpecializedRenderPipeline for SkyboxPipeline { type Key = SkyboxPipelineKey; fn specialize(&self, key: Self::Key) -> RenderPipelineDescriptor { - let shader_defs = vec![ - ShaderDefVal::UInt("MAX_DIRECTIONAL_LIGHTS".to_string(), 1), - ShaderDefVal::UInt("MAX_CASCADES_PER_LIGHT".to_string(), 1), - ]; - RenderPipelineDescriptor { label: Some("skybox_pipeline".into()), layout: vec![self.bind_group_layout.clone()], push_constant_ranges: Vec::new(), vertex: VertexState { shader: SKYBOX_SHADER_HANDLE.typed(), - shader_defs: shader_defs.clone(), + shader_defs: Vec::new(), entry_point: "skybox_vertex".into(), buffers: vec![self.vertex_buffer_layout.clone()], }, @@ -176,7 +171,7 @@ impl SpecializedRenderPipeline for SkyboxPipeline { }, fragment: Some(FragmentState { shader: SKYBOX_SHADER_HANDLE.typed(), - shader_defs, + shader_defs: Vec::new(), entry_point: "skybox_fragment".into(), targets: vec![Some(ColorTargetState { format: if key.hdr { diff --git a/crates/bevy_core_pipeline/src/skybox/skybox.wgsl b/crates/bevy_core_pipeline/src/skybox/skybox.wgsl index 7aee9d5b4e471..7ed8b45e12dac 100644 --- a/crates/bevy_core_pipeline/src/skybox/skybox.wgsl +++ b/crates/bevy_core_pipeline/src/skybox/skybox.wgsl @@ -1,4 +1,4 @@ -#import bevy_pbr::mesh_view_types +#import bevy_render::view @group(0) @binding(0) var skybox: texture_cube; From ec9f0c295432ac25e59504c6dec24631ec045374 Mon Sep 17 00:00:00 2001 From: Robert Swain Date: Fri, 31 Mar 2023 20:04:00 +0200 Subject: [PATCH 23/30] Use a fullscreen triangle to render the skybox No Mesh is needed. --- .../src/core_3d/main_opaque_pass_3d_node.rs | 20 +++------ crates/bevy_core_pipeline/src/skybox/mod.rs | 30 ++++--------- .../bevy_core_pipeline/src/skybox/skybox.wgsl | 43 ++++++++++++++++--- 3 files changed, 49 insertions(+), 44 deletions(-) diff --git a/crates/bevy_core_pipeline/src/core_3d/main_opaque_pass_3d_node.rs b/crates/bevy_core_pipeline/src/core_3d/main_opaque_pass_3d_node.rs index bfd3348ead243..c1d7344cfd713 100644 --- a/crates/bevy_core_pipeline/src/core_3d/main_opaque_pass_3d_node.rs +++ b/crates/bevy_core_pipeline/src/core_3d/main_opaque_pass_3d_node.rs @@ -2,7 +2,7 @@ use crate::{ clear_color::{ClearColor, ClearColorConfig}, core_3d::{Camera3d, Opaque3d}, prepass::{DepthPrepass, MotionVectorPrepass, NormalPrepass}, - skybox::{SkyboxBindGroup, SkyboxMesh, SkyboxPipelineId}, + skybox::{SkyboxBindGroup, SkyboxPipelineId}, }; use bevy_ecs::prelude::*; use bevy_render::{ @@ -136,25 +136,15 @@ impl Node for MainOpaquePass3dNode { alpha_mask_phase.render(&mut render_pass, world, view_entity); } - // Skybox draw + // Draw the skybox using a fullscreen triangle if let (Some(skybox_pipeline), Some(skybox_bind_group)) = (skybox_pipeline, skybox_bind_group) { - let skybox_mesh = world.resource::(); - let meshes = world.resource::>(); let pipeline_cache = world.resource::(); - - if let (Some(skybox_pipeline), Some(skybox_gpu_mesh)) = ( - pipeline_cache.get_render_pipeline(skybox_pipeline.0), - meshes.get(&skybox_mesh.handle), - ) { - let GpuBufferInfo::Indexed { buffer, index_format, count } = &skybox_gpu_mesh.buffer_info else { unreachable!() }; - - render_pass.set_render_pipeline(skybox_pipeline); + if let Some(pipeline) = pipeline_cache.get_render_pipeline(skybox_pipeline.0) { + render_pass.set_render_pipeline(pipeline); render_pass.set_bind_group(0, &skybox_bind_group.0, &[view_uniform_offset.offset]); - render_pass.set_vertex_buffer(0, skybox_gpu_mesh.vertex_buffer.slice(..)); - render_pass.set_index_buffer(buffer.slice(..), 0, *index_format); - render_pass.draw_indexed(0..*count, 0, 0..1); + render_pass.draw(0..3, 0..1); } } diff --git a/crates/bevy_core_pipeline/src/skybox/mod.rs b/crates/bevy_core_pipeline/src/skybox/mod.rs index 8f1c20b9fb478..8785a2eaf67b3 100644 --- a/crates/bevy_core_pipeline/src/skybox/mod.rs +++ b/crates/bevy_core_pipeline/src/skybox/mod.rs @@ -1,5 +1,5 @@ use bevy_app::{App, Plugin}; -use bevy_asset::{load_internal_asset, Assets, Handle, HandleUntyped}; +use bevy_asset::{load_internal_asset, Handle, HandleUntyped}; use bevy_ecs::{ prelude::{Component, Entity}, query::With, @@ -9,17 +9,15 @@ use bevy_ecs::{ use bevy_reflect::TypeUuid; use bevy_render::{ extract_component::{ExtractComponent, ExtractComponentPlugin}, - prelude::{shape::Cube, Mesh}, render_asset::RenderAssets, render_resource::{ BindGroup, BindGroupDescriptor, BindGroupEntry, BindGroupLayout, BindGroupLayoutDescriptor, BindGroupLayoutEntry, BindingResource, BindingType, BlendState, BufferBindingType, CachedRenderPipelineId, ColorTargetState, ColorWrites, CompareFunction, DepthBiasState, DepthStencilState, FragmentState, MultisampleState, PipelineCache, PrimitiveState, - RenderPipelineDescriptor, SamplerBindingType, Shader, ShaderDefVal, ShaderStages, - ShaderType, SpecializedRenderPipeline, SpecializedRenderPipelines, StencilFaceState, - StencilState, TextureFormat, TextureSampleType, TextureViewDimension, VertexBufferLayout, - VertexState, + RenderPipelineDescriptor, SamplerBindingType, Shader, ShaderStages, ShaderType, + SpecializedRenderPipeline, SpecializedRenderPipelines, StencilFaceState, StencilState, + TextureFormat, TextureSampleType, TextureViewDimension, VertexState, }, renderer::RenderDevice, texture::{BevyDefault, Image}, @@ -38,10 +36,6 @@ impl Plugin for SkyboxPlugin { app.add_plugin(ExtractComponentPlugin::::default()); - let mesh = Mesh::from(Cube::new(1.0)); - let vertex_buffer_layout = mesh.get_mesh_vertex_buffer_layout().layout().clone(); - let handle = app.world.resource_mut::>().add(mesh); - let render_app = match app.get_sub_app_mut(RenderApp) { Ok(render_app) => render_app, Err(_) => return, @@ -50,8 +44,7 @@ impl Plugin for SkyboxPlugin { let render_device = render_app.world.resource::().clone(); render_app - .insert_resource(SkyboxMesh { handle }) - .insert_resource(SkyboxPipeline::new(vertex_buffer_layout, &render_device)) + .insert_resource(SkyboxPipeline::new(&render_device)) .init_resource::>() .add_systems( Render, @@ -74,19 +67,13 @@ pub struct Skybox(pub Handle); // ---------------------------------------------------------------------------- -#[derive(Resource)] -pub struct SkyboxMesh { - pub handle: Handle, -} - #[derive(Resource)] struct SkyboxPipeline { bind_group_layout: BindGroupLayout, - vertex_buffer_layout: VertexBufferLayout, } impl SkyboxPipeline { - fn new(vertex_buffer_layout: VertexBufferLayout, render_device: &RenderDevice) -> Self { + fn new(render_device: &RenderDevice) -> Self { let bind_group_layout_descriptor = BindGroupLayoutDescriptor { label: Some("skybox_bind_group_layout"), entries: &[ @@ -108,7 +95,7 @@ impl SkyboxPipeline { }, BindGroupLayoutEntry { binding: 2, - visibility: ShaderStages::VERTEX, + visibility: ShaderStages::VERTEX_FRAGMENT, ty: BindingType::Buffer { ty: BufferBindingType::Uniform, has_dynamic_offset: true, @@ -122,7 +109,6 @@ impl SkyboxPipeline { Self { bind_group_layout: render_device .create_bind_group_layout(&bind_group_layout_descriptor), - vertex_buffer_layout, } } } @@ -145,7 +131,7 @@ impl SpecializedRenderPipeline for SkyboxPipeline { shader: SKYBOX_SHADER_HANDLE.typed(), shader_defs: Vec::new(), entry_point: "skybox_vertex".into(), - buffers: vec![self.vertex_buffer_layout.clone()], + buffers: Vec::new(), }, primitive: PrimitiveState::default(), depth_stencil: Some(DepthStencilState { diff --git a/crates/bevy_core_pipeline/src/skybox/skybox.wgsl b/crates/bevy_core_pipeline/src/skybox/skybox.wgsl index 7ed8b45e12dac..7dcfa73fb425a 100644 --- a/crates/bevy_core_pipeline/src/skybox/skybox.wgsl +++ b/crates/bevy_core_pipeline/src/skybox/skybox.wgsl @@ -9,18 +9,47 @@ var view: View; struct VertexOutput { @builtin(position) clip_position: vec4, - @location(0) position: vec3, + @location(0) world_position: vec3, }; +// 0 -> 0, 0, .25, .5 -> -1, -1, 0, 1 +// 1 -> 1, 0, .. -> 3, -1, .. +// 2 -> 0, 1, .. -> -1, 3, .. + +// 3 | 2. +// 2 | : `. +// 1 | x-----x. +// 0 | | s | `. +// -1 | 0-----x.....1 +// +--------------- +// -1 0 1 2 3 +// +// The axes are clip-space x and y. The region marked s is the visible region. +// The digits in the corners of the right-angled triangle are the vertex +// indices. @vertex -fn skybox_vertex(@location(0) position: vec3) -> VertexOutput { - var out: VertexOutput; - out.clip_position = view.view_proj * vec4(position, 0.0); - out.position = position; - return out; +fn skybox_vertex(@builtin(vertex_index) vertex_index: u32) -> VertexOutput { + // See the explanation above for how this works. + let clip_position = vec4( + f32(vertex_index & 1u), + f32((vertex_index >> 1u) & 1u), + 0.25, + 0.5 + ) * 4.0 - vec4(1.0); + // Use the position on the near clipping plane to avoid -inf world position + // because the far plane of an infinite reverse projection is at infinity. + // NOTE: The clip position has a w component equal to 1.0 so we don't need + // to apply a perspective divide to it before inverse-projecting it. + let world_position_homogeneous = view.inverse_view_proj * vec4(clip_position.xy, 1.0, 1.0); + let world_position = world_position_homogeneous.xyz / world_position_homogeneous.w; + + return VertexOutput(clip_position, world_position); } @fragment fn skybox_fragment(in: VertexOutput) -> @location(0) vec4 { - return textureSample(skybox, skybox_sampler, in.position); + // The skybox cubemap is sampled along the direction from the camera world + // position, to the fragment world position on the near clipping plane + let ray_direction = in.world_position - view.world_position; + return textureSample(skybox, skybox_sampler, ray_direction * vec3(1.0, 1.0, -1.0)); } From d00802d60e7139f525d05a914863bf67732f6e58 Mon Sep 17 00:00:00 2001 From: Robert Swain Date: Fri, 31 Mar 2023 20:04:22 +0200 Subject: [PATCH 24/30] Add documentation to how the fullscreen shader works --- .../fullscreen_vertex_shader/fullscreen.wgsl | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/crates/bevy_core_pipeline/src/fullscreen_vertex_shader/fullscreen.wgsl b/crates/bevy_core_pipeline/src/fullscreen_vertex_shader/fullscreen.wgsl index bc328269ab48c..04c3c494438ab 100644 --- a/crates/bevy_core_pipeline/src/fullscreen_vertex_shader/fullscreen.wgsl +++ b/crates/bevy_core_pipeline/src/fullscreen_vertex_shader/fullscreen.wgsl @@ -7,8 +7,26 @@ struct FullscreenVertexOutput { uv: vec2, }; +// This vertex shader produces the following, when drawn using indices 0..3: +// +// 1 | 0-----x.....2 +// 0 | | s | . ´ +// -1 | x_____x´ +// -2 | : .´ +// -3 | 1´ +// +--------------- +// -1 0 1 2 3 +// +// The axes are clip-space x and y. The region marked s is the visible region. +// The digits in the corners of the right-angled triangle are the vertex +// indices. +// +// The top-left has UV 0,0, the bottom-left has 0,2, and the top-right has 2,0. +// This means that the UV gets interpolated to 1,1 at the bottom-right corner +// of the clip-space rectangle that is at 1,-1 in clip space. @vertex fn fullscreen_vertex_shader(@builtin(vertex_index) vertex_index: u32) -> FullscreenVertexOutput { + // See the explanation above for how this works let uv = vec2(f32(vertex_index >> 1u), f32(vertex_index & 1u)) * 2.0; let clip_position = vec4(uv * vec2(2.0, -2.0) + vec2(-1.0, 1.0), 0.0, 1.0); From bbbb7080f8e258061d82ca166677722901bde18d Mon Sep 17 00:00:00 2001 From: Robert Swain Date: Fri, 31 Mar 2023 20:05:34 +0200 Subject: [PATCH 25/30] Update the skybox example to use the new Skybox component --- examples/3d/skybox.rs | 131 +++--------------------------------------- 1 file changed, 7 insertions(+), 124 deletions(-) diff --git a/examples/3d/skybox.rs b/examples/3d/skybox.rs index 50df20539fb1f..860db09d43569 100644 --- a/examples/3d/skybox.rs +++ b/examples/3d/skybox.rs @@ -4,22 +4,13 @@ use std::f32::consts::PI; use bevy::{ asset::LoadState, + core_pipeline::skybox::Skybox, input::mouse::MouseMotion, - pbr::{MaterialPipeline, MaterialPipelineKey}, prelude::*, - reflect::TypeUuid, render::{ - mesh::MeshVertexBufferLayout, - render_asset::RenderAssets, - render_resource::{ - AsBindGroup, AsBindGroupError, BindGroupDescriptor, BindGroupEntry, BindGroupLayout, - BindGroupLayoutDescriptor, BindGroupLayoutEntry, BindingResource, BindingType, - OwnedBindingResource, PreparedBindGroup, RenderPipelineDescriptor, SamplerBindingType, - ShaderRef, ShaderStages, SpecializedMeshPipelineError, TextureSampleType, - TextureViewDescriptor, TextureViewDimension, - }, + render_resource::{TextureViewDescriptor, TextureViewDimension}, renderer::RenderDevice, - texture::{CompressedImageFormats, FallbackImage}, + texture::CompressedImageFormats, }, }; @@ -45,7 +36,6 @@ const CUBEMAPS: &[(&str, CompressedImageFormats)] = &[ fn main() { App::new() .add_plugins(DefaultPlugins) - .add_plugin(MaterialPlugin::::default()) .add_systems(Startup, setup) .add_systems( Update, @@ -86,6 +76,7 @@ fn setup(mut commands: Commands, asset_server: Res) { ..default() }, CameraController::default(), + Skybox(skybox_handle.clone()), )); // ambient light @@ -145,13 +136,10 @@ fn cycle_cubemap_asset( } fn asset_loaded( - mut commands: Commands, asset_server: Res, mut images: ResMut>, - mut meshes: ResMut>, - mut cubemap_materials: ResMut>, mut cubemap: ResMut, - cubes: Query<&Handle>, + mut skyboxes: Query<&mut Skybox>, ) { if !cubemap.is_loaded && asset_server.get_load_state(cubemap.image_handle.clone_weak()) == LoadState::Loaded @@ -170,22 +158,8 @@ fn asset_loaded( }); } - // spawn cube - let mut updated = false; - for handle in cubes.iter() { - if let Some(material) = cubemap_materials.get_mut(handle) { - updated = true; - material.base_color_texture = Some(cubemap.image_handle.clone_weak()); - } - } - if !updated { - commands.spawn(MaterialMeshBundle:: { - mesh: meshes.add(Mesh::from(shape::Cube { size: 10000.0 })), - material: cubemap_materials.add(CubemapMaterial { - base_color_texture: Some(cubemap.image_handle.clone_weak()), - }), - ..default() - }); + for mut skybox in &mut skyboxes { + skybox.0 = cubemap.image_handle.clone(); } cubemap.is_loaded = true; @@ -201,97 +175,6 @@ fn animate_light_direction( } } -#[derive(Debug, Clone, TypeUuid)] -#[uuid = "9509a0f8-3c05-48ee-a13e-a93226c7f488"] -struct CubemapMaterial { - base_color_texture: Option>, -} - -impl Material for CubemapMaterial { - fn fragment_shader() -> ShaderRef { - "shaders/cubemap_unlit.wgsl".into() - } - - fn specialize( - _pipeline: &MaterialPipeline, - descriptor: &mut RenderPipelineDescriptor, - _layout: &MeshVertexBufferLayout, - _key: MaterialPipelineKey, - ) -> Result<(), SpecializedMeshPipelineError> { - descriptor.primitive.cull_mode = None; - Ok(()) - } -} - -impl AsBindGroup for CubemapMaterial { - type Data = (); - - fn as_bind_group( - &self, - layout: &BindGroupLayout, - render_device: &RenderDevice, - images: &RenderAssets, - _fallback_image: &FallbackImage, - ) -> Result, AsBindGroupError> { - let base_color_texture = self - .base_color_texture - .as_ref() - .ok_or(AsBindGroupError::RetryNextUpdate)?; - let image = images - .get(base_color_texture) - .ok_or(AsBindGroupError::RetryNextUpdate)?; - let bind_group = render_device.create_bind_group(&BindGroupDescriptor { - entries: &[ - BindGroupEntry { - binding: 0, - resource: BindingResource::TextureView(&image.texture_view), - }, - BindGroupEntry { - binding: 1, - resource: BindingResource::Sampler(&image.sampler), - }, - ], - label: Some("cubemap_texture_material_bind_group"), - layout, - }); - - Ok(PreparedBindGroup { - bind_group, - bindings: vec![ - OwnedBindingResource::TextureView(image.texture_view.clone()), - OwnedBindingResource::Sampler(image.sampler.clone()), - ], - data: (), - }) - } - - fn bind_group_layout(render_device: &RenderDevice) -> BindGroupLayout { - render_device.create_bind_group_layout(&BindGroupLayoutDescriptor { - entries: &[ - // Cubemap Base Color Texture - BindGroupLayoutEntry { - binding: 0, - visibility: ShaderStages::FRAGMENT, - ty: BindingType::Texture { - multisampled: false, - sample_type: TextureSampleType::Float { filterable: true }, - view_dimension: TextureViewDimension::Cube, - }, - count: None, - }, - // Cubemap Base Color Texture Sampler - BindGroupLayoutEntry { - binding: 1, - visibility: ShaderStages::FRAGMENT, - ty: BindingType::Sampler(SamplerBindingType::Filtering), - count: None, - }, - ], - label: None, - }) - } -} - #[derive(Component)] pub struct CameraController { pub enabled: bool, From 144f88ba16483c8be9e4bcbbf2ad63af919227d7 Mon Sep 17 00:00:00 2001 From: Robert Swain Date: Fri, 31 Mar 2023 20:15:39 +0200 Subject: [PATCH 26/30] Cleanup after rebase --- .../bevy_core_pipeline/src/core_3d/main_opaque_pass_3d_node.rs | 3 --- examples/3d/skybox.rs | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/crates/bevy_core_pipeline/src/core_3d/main_opaque_pass_3d_node.rs b/crates/bevy_core_pipeline/src/core_3d/main_opaque_pass_3d_node.rs index c1d7344cfd713..21dc970a393c5 100644 --- a/crates/bevy_core_pipeline/src/core_3d/main_opaque_pass_3d_node.rs +++ b/crates/bevy_core_pipeline/src/core_3d/main_opaque_pass_3d_node.rs @@ -7,9 +7,6 @@ use crate::{ use bevy_ecs::prelude::*; use bevy_render::{ camera::ExtractedCamera, - mesh::GpuBufferInfo, - prelude::Mesh, - render_asset::RenderAssets, render_graph::{Node, NodeRunError, RenderGraphContext}, render_phase::RenderPhase, render_resource::{ diff --git a/examples/3d/skybox.rs b/examples/3d/skybox.rs index 860db09d43569..0291eca9af571 100644 --- a/examples/3d/skybox.rs +++ b/examples/3d/skybox.rs @@ -4,7 +4,7 @@ use std::f32::consts::PI; use bevy::{ asset::LoadState, - core_pipeline::skybox::Skybox, + core_pipeline::Skybox, input::mouse::MouseMotion, prelude::*, render::{ From be50268690af92860fba7008599eadbd9954914e Mon Sep 17 00:00:00 2001 From: Robert Swain Date: Fri, 31 Mar 2023 20:21:35 +0200 Subject: [PATCH 27/30] Remove debug notes --- crates/bevy_core_pipeline/src/skybox/skybox.wgsl | 4 ---- 1 file changed, 4 deletions(-) diff --git a/crates/bevy_core_pipeline/src/skybox/skybox.wgsl b/crates/bevy_core_pipeline/src/skybox/skybox.wgsl index 7dcfa73fb425a..bedab66418daa 100644 --- a/crates/bevy_core_pipeline/src/skybox/skybox.wgsl +++ b/crates/bevy_core_pipeline/src/skybox/skybox.wgsl @@ -12,10 +12,6 @@ struct VertexOutput { @location(0) world_position: vec3, }; -// 0 -> 0, 0, .25, .5 -> -1, -1, 0, 1 -// 1 -> 1, 0, .. -> 3, -1, .. -// 2 -> 0, 1, .. -> -1, 3, .. - // 3 | 2. // 2 | : `. // 1 | x-----x. From 0d9216c1d9fe5a08ca475aaee3ab4db45450bc66 Mon Sep 17 00:00:00 2001 From: JMS55 <47158642+JMS55@users.noreply.github.com> Date: Sat, 1 Apr 2023 20:10:55 -0400 Subject: [PATCH 28/30] Update crates/bevy_core_pipeline/src/skybox/skybox.wgsl Co-authored-by: robtfm <50659922+robtfm@users.noreply.github.com> --- crates/bevy_core_pipeline/src/skybox/skybox.wgsl | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/bevy_core_pipeline/src/skybox/skybox.wgsl b/crates/bevy_core_pipeline/src/skybox/skybox.wgsl index bedab66418daa..963de3d192ac9 100644 --- a/crates/bevy_core_pipeline/src/skybox/skybox.wgsl +++ b/crates/bevy_core_pipeline/src/skybox/skybox.wgsl @@ -47,5 +47,6 @@ fn skybox_fragment(in: VertexOutput) -> @location(0) vec4 { // The skybox cubemap is sampled along the direction from the camera world // position, to the fragment world position on the near clipping plane let ray_direction = in.world_position - view.world_position; + // cube maps are left-handed so we negate the z coordinate return textureSample(skybox, skybox_sampler, ray_direction * vec3(1.0, 1.0, -1.0)); } From b0c1a1525e63bc9d7852b9af41d417174bbff759 Mon Sep 17 00:00:00 2001 From: JMS55 <47158642+JMS55@users.noreply.github.com> Date: Sun, 2 Apr 2023 00:20:27 -0400 Subject: [PATCH 29/30] Flip environment map light sampling --- crates/bevy_pbr/src/environment_map/environment_map.wgsl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/bevy_pbr/src/environment_map/environment_map.wgsl b/crates/bevy_pbr/src/environment_map/environment_map.wgsl index 1c225645a812c..80062dd69b250 100644 --- a/crates/bevy_pbr/src/environment_map/environment_map.wgsl +++ b/crates/bevy_pbr/src/environment_map/environment_map.wgsl @@ -21,8 +21,8 @@ fn environment_map_light( // Technically we could use textureNumLevels(environment_map_specular) - 1 here, but we use a uniform // because textureNumLevels() does not work on WebGL2 let radiance_level = perceptual_roughness * f32(lights.environment_map_smallest_specular_mip_level); - let irradiance = textureSample(environment_map_diffuse, environment_map_sampler, N).rgb; - let radiance = textureSampleLevel(environment_map_specular, environment_map_sampler, R, radiance_level).rgb; + let irradiance = textureSample(environment_map_diffuse, environment_map_sampler, vec3(N.xy, -N.z)).rgb; + let radiance = textureSampleLevel(environment_map_specular, environment_map_sampler, vec3(R.xy, -R.z), radiance_level).rgb; // Multiscattering approximation: https://www.jcgt.org/published/0008/01/03/paper.pdf // Useful reference: https://bruop.github.io/ibl From 36f49395c1a1566d9340ec248b70f6c7a57f2c3c Mon Sep 17 00:00:00 2001 From: JMS55 <47158642+JMS55@users.noreply.github.com> Date: Sun, 2 Apr 2023 00:20:51 -0400 Subject: [PATCH 30/30] Remove separator --- crates/bevy_core_pipeline/src/skybox/mod.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/crates/bevy_core_pipeline/src/skybox/mod.rs b/crates/bevy_core_pipeline/src/skybox/mod.rs index 8785a2eaf67b3..6d805e0478cb5 100644 --- a/crates/bevy_core_pipeline/src/skybox/mod.rs +++ b/crates/bevy_core_pipeline/src/skybox/mod.rs @@ -65,8 +65,6 @@ impl Plugin for SkyboxPlugin { #[derive(Component, ExtractComponent, Clone)] pub struct Skybox(pub Handle); -// ---------------------------------------------------------------------------- - #[derive(Resource)] struct SkyboxPipeline { bind_group_layout: BindGroupLayout,