Meshlet prep (#11442)
# Objective - Prep for https://github.com/bevyengine/bevy/pull/10164 - Make deferred_lighting_pass_id a ColorAttachment - Correctly extract shadow view frusta so that the view uniforms get populated - Make some needed things public - Misc formatting
This commit is contained in:
parent
2165793ff0
commit
a796d53a05
@ -805,7 +805,7 @@ pub fn prepare_prepass_textures(
|
|||||||
.clone()
|
.clone()
|
||||||
});
|
});
|
||||||
|
|
||||||
let deferred_lighting_pass_id_texture = deferred_prepass.then(|| {
|
let cached_deferred_lighting_pass_id_texture = deferred_prepass.then(|| {
|
||||||
deferred_lighting_id_textures
|
deferred_lighting_id_textures
|
||||||
.entry(camera.target.clone())
|
.entry(camera.target.clone())
|
||||||
.or_insert_with(|| {
|
.or_insert_with(|| {
|
||||||
@ -836,7 +836,8 @@ pub fn prepare_prepass_textures(
|
|||||||
motion_vectors: cached_motion_vectors_texture
|
motion_vectors: cached_motion_vectors_texture
|
||||||
.map(|t| ColorAttachment::new(t, None, Color::BLACK)),
|
.map(|t| ColorAttachment::new(t, None, Color::BLACK)),
|
||||||
deferred: cached_deferred_texture.map(|t| ColorAttachment::new(t, None, Color::BLACK)),
|
deferred: cached_deferred_texture.map(|t| ColorAttachment::new(t, None, Color::BLACK)),
|
||||||
deferred_lighting_pass_id: deferred_lighting_pass_id_texture,
|
deferred_lighting_pass_id: cached_deferred_lighting_pass_id_texture
|
||||||
|
.map(|t| ColorAttachment::new(t, None, Color::BLACK)),
|
||||||
size,
|
size,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -94,7 +94,7 @@ impl ViewNode for CopyDeferredLightingIdNode {
|
|||||||
let bind_group = render_context.render_device().create_bind_group(
|
let bind_group = render_context.render_device().create_bind_group(
|
||||||
"copy_deferred_lighting_id_bind_group",
|
"copy_deferred_lighting_id_bind_group",
|
||||||
©_deferred_lighting_id_pipeline.layout,
|
©_deferred_lighting_id_pipeline.layout,
|
||||||
&BindGroupEntries::single(&deferred_lighting_pass_id_texture.default_view),
|
&BindGroupEntries::single(&deferred_lighting_pass_id_texture.texture.default_view),
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut render_pass = render_context.begin_tracked_render_pass(RenderPassDescriptor {
|
let mut render_pass = render_context.begin_tracked_render_pass(RenderPassDescriptor {
|
||||||
|
@ -5,10 +5,9 @@ use bevy_render::render_graph::ViewNode;
|
|||||||
use bevy_render::render_resource::StoreOp;
|
use bevy_render::render_resource::StoreOp;
|
||||||
use bevy_render::{
|
use bevy_render::{
|
||||||
camera::ExtractedCamera,
|
camera::ExtractedCamera,
|
||||||
prelude::Color,
|
|
||||||
render_graph::{NodeRunError, RenderGraphContext},
|
render_graph::{NodeRunError, RenderGraphContext},
|
||||||
render_phase::RenderPhase,
|
render_phase::RenderPhase,
|
||||||
render_resource::{LoadOp, Operations, RenderPassColorAttachment, RenderPassDescriptor},
|
render_resource::RenderPassDescriptor,
|
||||||
renderer::RenderContext,
|
renderer::RenderContext,
|
||||||
view::ViewDepthTexture,
|
view::ViewDepthTexture,
|
||||||
};
|
};
|
||||||
@ -83,11 +82,11 @@ impl ViewNode for DeferredGBufferPrepassNode {
|
|||||||
.map(|deferred_texture| {
|
.map(|deferred_texture| {
|
||||||
#[cfg(all(feature = "webgl", target_arch = "wasm32"))]
|
#[cfg(all(feature = "webgl", target_arch = "wasm32"))]
|
||||||
{
|
{
|
||||||
RenderPassColorAttachment {
|
bevy_render::render_resource::RenderPassColorAttachment {
|
||||||
view: &deferred_texture.texture.default_view,
|
view: &deferred_texture.texture.default_view,
|
||||||
resolve_target: None,
|
resolve_target: None,
|
||||||
ops: Operations {
|
ops: bevy_render::render_resource::Operations {
|
||||||
load: LoadOp::Load,
|
load: bevy_render::render_resource::LoadOp::Load,
|
||||||
store: StoreOp::Store,
|
store: StoreOp::Store,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -101,14 +100,7 @@ impl ViewNode for DeferredGBufferPrepassNode {
|
|||||||
view_prepass_textures
|
view_prepass_textures
|
||||||
.deferred_lighting_pass_id
|
.deferred_lighting_pass_id
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|deferred_lighting_pass_id| RenderPassColorAttachment {
|
.map(|deferred_lighting_pass_id| deferred_lighting_pass_id.get_attachment()),
|
||||||
view: &deferred_lighting_pass_id.default_view,
|
|
||||||
resolve_target: None,
|
|
||||||
ops: Operations {
|
|
||||||
load: LoadOp::Clear(Color::BLACK.into()),
|
|
||||||
store: StoreOp::Store,
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if color_attachments.iter().all(Option::is_none) {
|
if color_attachments.iter().all(Option::is_none) {
|
||||||
|
@ -34,7 +34,7 @@ use bevy_reflect::Reflect;
|
|||||||
use bevy_render::{
|
use bevy_render::{
|
||||||
render_phase::{CachedRenderPipelinePhaseItem, DrawFunctionId, PhaseItem},
|
render_phase::{CachedRenderPipelinePhaseItem, DrawFunctionId, PhaseItem},
|
||||||
render_resource::{CachedRenderPipelineId, Extent3d, TextureFormat, TextureView},
|
render_resource::{CachedRenderPipelineId, Extent3d, TextureFormat, TextureView},
|
||||||
texture::{CachedTexture, ColorAttachment},
|
texture::ColorAttachment,
|
||||||
};
|
};
|
||||||
use bevy_utils::{nonmax::NonMaxU32, FloatOrd};
|
use bevy_utils::{nonmax::NonMaxU32, FloatOrd};
|
||||||
|
|
||||||
@ -78,7 +78,7 @@ pub struct ViewPrepassTextures {
|
|||||||
pub deferred: Option<ColorAttachment>,
|
pub deferred: Option<ColorAttachment>,
|
||||||
/// A texture that specifies the deferred lighting pass id for a material.
|
/// A texture that specifies the deferred lighting pass id for a material.
|
||||||
/// Exists only if [`DeferredPrepass`] is added to the `ViewTarget`
|
/// Exists only if [`DeferredPrepass`] is added to the `ViewTarget`
|
||||||
pub deferred_lighting_pass_id: Option<CachedTexture>,
|
pub deferred_lighting_pass_id: Option<ColorAttachment>,
|
||||||
/// The size of the textures.
|
/// The size of the textures.
|
||||||
pub size: Extent3d,
|
pub size: Extent3d,
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
// Creates the deferred gbuffer from a PbrInput.
|
// Creates the deferred gbuffer from a PbrInput.
|
||||||
fn deferred_gbuffer_from_pbr_input(in: PbrInput) -> vec4<u32> {
|
fn deferred_gbuffer_from_pbr_input(in: PbrInput) -> vec4<u32> {
|
||||||
// Only monochrome occlusion supported. May not be worth including at all.
|
// Only monochrome occlusion supported. May not be worth including at all.
|
||||||
// Some models have baked occlusion, GLTF only supports monochrome.
|
// Some models have baked occlusion, GLTF only supports monochrome.
|
||||||
// Real time occlusion is applied in the deferred lighting pass.
|
// Real time occlusion is applied in the deferred lighting pass.
|
||||||
// Deriving luminance via Rec. 709. coefficients
|
// Deriving luminance via Rec. 709. coefficients
|
||||||
// https://en.wikipedia.org/wiki/Rec._709
|
// https://en.wikipedia.org/wiki/Rec._709
|
||||||
@ -27,7 +27,7 @@ fn deferred_gbuffer_from_pbr_input(in: PbrInput) -> vec4<u32> {
|
|||||||
var props = deferred_types::pack_unorm3x4_plus_unorm_20_(vec4(
|
var props = deferred_types::pack_unorm3x4_plus_unorm_20_(vec4(
|
||||||
in.material.reflectance,
|
in.material.reflectance,
|
||||||
in.material.metallic,
|
in.material.metallic,
|
||||||
diffuse_occlusion,
|
diffuse_occlusion,
|
||||||
in.frag_coord.z));
|
in.frag_coord.z));
|
||||||
#else
|
#else
|
||||||
var props = deferred_types::pack_unorm4x8_(vec4(
|
var props = deferred_types::pack_unorm4x8_(vec4(
|
||||||
@ -79,7 +79,7 @@ fn pbr_input_from_deferred_gbuffer(frag_coord: vec4<f32>, gbuffer: vec4<u32>) ->
|
|||||||
#ifdef WEBGL2 // More crunched for webgl so we can also fit depth.
|
#ifdef WEBGL2 // More crunched for webgl so we can also fit depth.
|
||||||
let props = deferred_types::unpack_unorm3x4_plus_unorm_20_(gbuffer.b);
|
let props = deferred_types::unpack_unorm3x4_plus_unorm_20_(gbuffer.b);
|
||||||
// Bias to 0.5 since that's the value for almost all materials.
|
// Bias to 0.5 since that's the value for almost all materials.
|
||||||
pbr.material.reflectance = saturate(props.r - 0.03333333333);
|
pbr.material.reflectance = saturate(props.r - 0.03333333333);
|
||||||
#else
|
#else
|
||||||
let props = deferred_types::unpack_unorm4x8_(gbuffer.b);
|
let props = deferred_types::unpack_unorm4x8_(gbuffer.b);
|
||||||
pbr.material.reflectance = props.r;
|
pbr.material.reflectance = props.r;
|
||||||
@ -92,9 +92,9 @@ fn pbr_input_from_deferred_gbuffer(frag_coord: vec4<f32>, gbuffer: vec4<u32>) ->
|
|||||||
let world_position = vec4(position_ndc_to_world(frag_coord_to_ndc(frag_coord)), 1.0);
|
let world_position = vec4(position_ndc_to_world(frag_coord_to_ndc(frag_coord)), 1.0);
|
||||||
let is_orthographic = view.projection[3].w == 1.0;
|
let is_orthographic = view.projection[3].w == 1.0;
|
||||||
let V = pbr_functions::calculate_view(world_position, is_orthographic);
|
let V = pbr_functions::calculate_view(world_position, is_orthographic);
|
||||||
|
|
||||||
pbr.frag_coord = frag_coord;
|
pbr.frag_coord = frag_coord;
|
||||||
pbr.world_normal = N;
|
pbr.world_normal = N;
|
||||||
pbr.world_position = world_position;
|
pbr.world_position = world_position;
|
||||||
pbr.N = N;
|
pbr.N = N;
|
||||||
pbr.V = V;
|
pbr.V = V;
|
||||||
|
@ -639,8 +639,8 @@ pub fn prepare_previous_view_projection_uniforms(
|
|||||||
|
|
||||||
#[derive(Default, Resource)]
|
#[derive(Default, Resource)]
|
||||||
pub struct PrepassViewBindGroup {
|
pub struct PrepassViewBindGroup {
|
||||||
motion_vectors: Option<BindGroup>,
|
pub motion_vectors: Option<BindGroup>,
|
||||||
no_motion_vectors: Option<BindGroup>,
|
pub no_motion_vectors: Option<BindGroup>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn prepare_prepass_view_bind_group<M: Material>(
|
pub fn prepare_prepass_view_bind_group<M: Material>(
|
||||||
|
@ -149,7 +149,7 @@ fn fragment(in: VertexOutput) -> FragmentOutput {
|
|||||||
#ifdef DEFERRED_PREPASS
|
#ifdef DEFERRED_PREPASS
|
||||||
// There isn't any material info available for this default prepass shader so we are just writing
|
// There isn't any material info available for this default prepass shader so we are just writing
|
||||||
// emissive magenta out to the deferred gbuffer to be rendered by the first deferred lighting pass layer.
|
// emissive magenta out to the deferred gbuffer to be rendered by the first deferred lighting pass layer.
|
||||||
// The is here so if the default prepass fragment is used for deferred magenta will be rendered, and also
|
// This is here so if the default prepass fragment is used for deferred magenta will be rendered, and also
|
||||||
// as an example to show that a user could write to the deferred gbuffer if they were to start from this shader.
|
// as an example to show that a user could write to the deferred gbuffer if they were to start from this shader.
|
||||||
out.deferred = vec4(0u, bevy_pbr::rgb9e5::vec3_to_rgb9e5_(vec3(1.0, 0.0, 1.0)), 0u, 0u);
|
out.deferred = vec4(0u, bevy_pbr::rgb9e5::vec3_to_rgb9e5_(vec3(1.0, 0.0, 1.0)), 0u, 0u);
|
||||||
out.deferred_lighting_pass_id = 1u;
|
out.deferred_lighting_pass_id = 1u;
|
||||||
|
@ -5,6 +5,7 @@ use bevy_render::{
|
|||||||
camera::Camera,
|
camera::Camera,
|
||||||
color::Color,
|
color::Color,
|
||||||
mesh::Mesh,
|
mesh::Mesh,
|
||||||
|
primitives::{CascadesFrusta, CubemapFrusta, Frustum},
|
||||||
render_asset::RenderAssets,
|
render_asset::RenderAssets,
|
||||||
render_graph::{Node, NodeRunError, RenderGraphContext},
|
render_graph::{Node, NodeRunError, RenderGraphContext},
|
||||||
render_phase::*,
|
render_phase::*,
|
||||||
@ -48,6 +49,7 @@ pub struct ExtractedDirectionalLight {
|
|||||||
shadow_normal_bias: f32,
|
shadow_normal_bias: f32,
|
||||||
cascade_shadow_config: CascadeShadowConfig,
|
cascade_shadow_config: CascadeShadowConfig,
|
||||||
cascades: EntityHashMap<Entity, Vec<Cascade>>,
|
cascades: EntityHashMap<Entity, Vec<Cascade>>,
|
||||||
|
frusta: EntityHashMap<Entity, Vec<Frustum>>,
|
||||||
render_layers: RenderLayers,
|
render_layers: RenderLayers,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -296,6 +298,7 @@ pub fn extract_lights(
|
|||||||
&CubemapVisibleEntities,
|
&CubemapVisibleEntities,
|
||||||
&GlobalTransform,
|
&GlobalTransform,
|
||||||
&ViewVisibility,
|
&ViewVisibility,
|
||||||
|
&CubemapFrusta,
|
||||||
)>,
|
)>,
|
||||||
>,
|
>,
|
||||||
spot_lights: Extract<
|
spot_lights: Extract<
|
||||||
@ -304,6 +307,7 @@ pub fn extract_lights(
|
|||||||
&VisibleEntities,
|
&VisibleEntities,
|
||||||
&GlobalTransform,
|
&GlobalTransform,
|
||||||
&ViewVisibility,
|
&ViewVisibility,
|
||||||
|
&Frustum,
|
||||||
)>,
|
)>,
|
||||||
>,
|
>,
|
||||||
directional_lights: Extract<
|
directional_lights: Extract<
|
||||||
@ -314,6 +318,7 @@ pub fn extract_lights(
|
|||||||
&CascadesVisibleEntities,
|
&CascadesVisibleEntities,
|
||||||
&Cascades,
|
&Cascades,
|
||||||
&CascadeShadowConfig,
|
&CascadeShadowConfig,
|
||||||
|
&CascadesFrusta,
|
||||||
&GlobalTransform,
|
&GlobalTransform,
|
||||||
&ViewVisibility,
|
&ViewVisibility,
|
||||||
Option<&RenderLayers>,
|
Option<&RenderLayers>,
|
||||||
@ -343,7 +348,7 @@ pub fn extract_lights(
|
|||||||
|
|
||||||
let mut point_lights_values = Vec::with_capacity(*previous_point_lights_len);
|
let mut point_lights_values = Vec::with_capacity(*previous_point_lights_len);
|
||||||
for entity in global_point_lights.iter().copied() {
|
for entity in global_point_lights.iter().copied() {
|
||||||
let Ok((point_light, cubemap_visible_entities, transform, view_visibility)) =
|
let Ok((point_light, cubemap_visible_entities, transform, view_visibility, frusta)) =
|
||||||
point_lights.get(entity)
|
point_lights.get(entity)
|
||||||
else {
|
else {
|
||||||
continue;
|
continue;
|
||||||
@ -373,7 +378,11 @@ pub fn extract_lights(
|
|||||||
};
|
};
|
||||||
point_lights_values.push((
|
point_lights_values.push((
|
||||||
entity,
|
entity,
|
||||||
(extracted_point_light, render_cubemap_visible_entities),
|
(
|
||||||
|
extracted_point_light,
|
||||||
|
render_cubemap_visible_entities,
|
||||||
|
(*frusta).clone(),
|
||||||
|
),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
*previous_point_lights_len = point_lights_values.len();
|
*previous_point_lights_len = point_lights_values.len();
|
||||||
@ -381,7 +390,7 @@ pub fn extract_lights(
|
|||||||
|
|
||||||
let mut spot_lights_values = Vec::with_capacity(*previous_spot_lights_len);
|
let mut spot_lights_values = Vec::with_capacity(*previous_spot_lights_len);
|
||||||
for entity in global_point_lights.iter().copied() {
|
for entity in global_point_lights.iter().copied() {
|
||||||
if let Ok((spot_light, visible_entities, transform, view_visibility)) =
|
if let Ok((spot_light, visible_entities, transform, view_visibility, frustum)) =
|
||||||
spot_lights.get(entity)
|
spot_lights.get(entity)
|
||||||
{
|
{
|
||||||
if !view_visibility.get() {
|
if !view_visibility.get() {
|
||||||
@ -417,6 +426,7 @@ pub fn extract_lights(
|
|||||||
spot_light_angles: Some((spot_light.inner_angle, spot_light.outer_angle)),
|
spot_light_angles: Some((spot_light.inner_angle, spot_light.outer_angle)),
|
||||||
},
|
},
|
||||||
render_visible_entities,
|
render_visible_entities,
|
||||||
|
*frustum,
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@ -430,6 +440,7 @@ pub fn extract_lights(
|
|||||||
visible_entities,
|
visible_entities,
|
||||||
cascades,
|
cascades,
|
||||||
cascade_config,
|
cascade_config,
|
||||||
|
frusta,
|
||||||
transform,
|
transform,
|
||||||
view_visibility,
|
view_visibility,
|
||||||
maybe_layers,
|
maybe_layers,
|
||||||
@ -452,6 +463,7 @@ pub fn extract_lights(
|
|||||||
shadow_normal_bias: directional_light.shadow_normal_bias * std::f32::consts::SQRT_2,
|
shadow_normal_bias: directional_light.shadow_normal_bias * std::f32::consts::SQRT_2,
|
||||||
cascade_shadow_config: cascade_config.clone(),
|
cascade_shadow_config: cascade_config.clone(),
|
||||||
cascades: cascades.cascades.clone(),
|
cascades: cascades.cascades.clone(),
|
||||||
|
frusta: frusta.frusta.clone(),
|
||||||
render_layers: maybe_layers.copied().unwrap_or_default(),
|
render_layers: maybe_layers.copied().unwrap_or_default(),
|
||||||
},
|
},
|
||||||
render_visible_entities,
|
render_visible_entities,
|
||||||
@ -656,7 +668,11 @@ pub fn prepare_lights(
|
|||||||
directional_light_shadow_map: Res<DirectionalLightShadowMap>,
|
directional_light_shadow_map: Res<DirectionalLightShadowMap>,
|
||||||
mut max_directional_lights_warning_emitted: Local<bool>,
|
mut max_directional_lights_warning_emitted: Local<bool>,
|
||||||
mut max_cascades_per_light_warning_emitted: Local<bool>,
|
mut max_cascades_per_light_warning_emitted: Local<bool>,
|
||||||
point_lights: Query<(Entity, &ExtractedPointLight)>,
|
point_lights: Query<(
|
||||||
|
Entity,
|
||||||
|
&ExtractedPointLight,
|
||||||
|
AnyOf<(&CubemapFrusta, &Frustum)>,
|
||||||
|
)>,
|
||||||
directional_lights: Query<(Entity, &ExtractedDirectionalLight)>,
|
directional_lights: Query<(Entity, &ExtractedDirectionalLight)>,
|
||||||
) {
|
) {
|
||||||
let views_iter = views.iter();
|
let views_iter = views.iter();
|
||||||
@ -733,7 +749,7 @@ pub fn prepare_lights(
|
|||||||
|
|
||||||
let spot_light_shadow_maps_count = point_lights
|
let spot_light_shadow_maps_count = point_lights
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|(_, light)| light.shadows_enabled && light.spot_light_angles.is_some())
|
.filter(|(_, light, _)| light.shadows_enabled && light.spot_light_angles.is_some())
|
||||||
.count()
|
.count()
|
||||||
.min(max_texture_array_layers - directional_shadow_enabled_count * MAX_CASCADES_PER_LIGHT);
|
.min(max_texture_array_layers - directional_shadow_enabled_count * MAX_CASCADES_PER_LIGHT);
|
||||||
|
|
||||||
@ -742,7 +758,7 @@ pub fn prepare_lights(
|
|||||||
// - then those with shadows enabled first, so that the index can be used to render at most `point_light_shadow_maps_count`
|
// - then those with shadows enabled first, so that the index can be used to render at most `point_light_shadow_maps_count`
|
||||||
// point light shadows and `spot_light_shadow_maps_count` spot light shadow maps,
|
// point light shadows and `spot_light_shadow_maps_count` spot light shadow maps,
|
||||||
// - then by entity as a stable key to ensure that a consistent set of lights are chosen if the light count limit is exceeded.
|
// - then by entity as a stable key to ensure that a consistent set of lights are chosen if the light count limit is exceeded.
|
||||||
point_lights.sort_by(|(entity_1, light_1), (entity_2, light_2)| {
|
point_lights.sort_by(|(entity_1, light_1, _), (entity_2, light_2, _)| {
|
||||||
point_light_order(
|
point_light_order(
|
||||||
(
|
(
|
||||||
entity_1,
|
entity_1,
|
||||||
@ -775,7 +791,7 @@ pub fn prepare_lights(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut gpu_point_lights = Vec::new();
|
let mut gpu_point_lights = Vec::new();
|
||||||
for (index, &(entity, light)) in point_lights.iter().enumerate() {
|
for (index, &(entity, light, _)) in point_lights.iter().enumerate() {
|
||||||
let mut flags = PointLightFlags::NONE;
|
let mut flags = PointLightFlags::NONE;
|
||||||
|
|
||||||
// Lights are sorted, shadow enabled lights are first
|
// Lights are sorted, shadow enabled lights are first
|
||||||
@ -952,11 +968,11 @@ pub fn prepare_lights(
|
|||||||
};
|
};
|
||||||
|
|
||||||
// TODO: this should select lights based on relevance to the view instead of the first ones that show up in a query
|
// TODO: this should select lights based on relevance to the view instead of the first ones that show up in a query
|
||||||
for &(light_entity, light) in point_lights
|
for &(light_entity, light, (point_light_frusta, _)) in point_lights
|
||||||
.iter()
|
.iter()
|
||||||
// Lights are sorted, shadow enabled lights are first
|
// Lights are sorted, shadow enabled lights are first
|
||||||
.take(point_light_shadow_maps_count)
|
.take(point_light_shadow_maps_count)
|
||||||
.filter(|(_, light)| light.shadows_enabled)
|
.filter(|(_, light, _)| light.shadows_enabled)
|
||||||
{
|
{
|
||||||
let light_index = *global_light_meta
|
let light_index = *global_light_meta
|
||||||
.entity_to_index
|
.entity_to_index
|
||||||
@ -967,7 +983,11 @@ pub fn prepare_lights(
|
|||||||
// and ignore rotation because we want the shadow map projections to align with the axes
|
// and ignore rotation because we want the shadow map projections to align with the axes
|
||||||
let view_translation = GlobalTransform::from_translation(light.transform.translation());
|
let view_translation = GlobalTransform::from_translation(light.transform.translation());
|
||||||
|
|
||||||
for (face_index, view_rotation) in cube_face_rotations.iter().enumerate() {
|
for (face_index, (view_rotation, frustum)) in cube_face_rotations
|
||||||
|
.iter()
|
||||||
|
.zip(&point_light_frusta.unwrap().frusta)
|
||||||
|
.enumerate()
|
||||||
|
{
|
||||||
let depth_texture_view =
|
let depth_texture_view =
|
||||||
point_light_depth_texture
|
point_light_depth_texture
|
||||||
.texture
|
.texture
|
||||||
@ -1005,6 +1025,7 @@ pub fn prepare_lights(
|
|||||||
hdr: false,
|
hdr: false,
|
||||||
color_grading: Default::default(),
|
color_grading: Default::default(),
|
||||||
},
|
},
|
||||||
|
*frustum,
|
||||||
RenderPhase::<Shadow>::default(),
|
RenderPhase::<Shadow>::default(),
|
||||||
LightEntity::Point {
|
LightEntity::Point {
|
||||||
light_entity,
|
light_entity,
|
||||||
@ -1017,7 +1038,7 @@ pub fn prepare_lights(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// spot lights
|
// spot lights
|
||||||
for (light_index, &(light_entity, light)) in point_lights
|
for (light_index, &(light_entity, light, (_, spot_light_frustum))) in point_lights
|
||||||
.iter()
|
.iter()
|
||||||
.skip(point_light_count)
|
.skip(point_light_count)
|
||||||
.take(spot_light_shadow_maps_count)
|
.take(spot_light_shadow_maps_count)
|
||||||
@ -1063,6 +1084,7 @@ pub fn prepare_lights(
|
|||||||
hdr: false,
|
hdr: false,
|
||||||
color_grading: Default::default(),
|
color_grading: Default::default(),
|
||||||
},
|
},
|
||||||
|
*spot_light_frustum.unwrap(),
|
||||||
RenderPhase::<Shadow>::default(),
|
RenderPhase::<Shadow>::default(),
|
||||||
LightEntity::Spot { light_entity },
|
LightEntity::Spot { light_entity },
|
||||||
))
|
))
|
||||||
@ -1078,12 +1100,20 @@ pub fn prepare_lights(
|
|||||||
.enumerate()
|
.enumerate()
|
||||||
.take(directional_shadow_enabled_count)
|
.take(directional_shadow_enabled_count)
|
||||||
{
|
{
|
||||||
for (cascade_index, (cascade, bound)) in light
|
let cascades = light
|
||||||
.cascades
|
.cascades
|
||||||
.get(&entity)
|
.get(&entity)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.iter()
|
.iter()
|
||||||
.take(MAX_CASCADES_PER_LIGHT)
|
.take(MAX_CASCADES_PER_LIGHT);
|
||||||
|
let frusta = light
|
||||||
|
.frusta
|
||||||
|
.get(&entity)
|
||||||
|
.unwrap()
|
||||||
|
.iter()
|
||||||
|
.take(MAX_CASCADES_PER_LIGHT);
|
||||||
|
for (cascade_index, ((cascade, frusta), bound)) in cascades
|
||||||
|
.zip(frusta)
|
||||||
.zip(&light.cascade_shadow_config.bounds)
|
.zip(&light.cascade_shadow_config.bounds)
|
||||||
.enumerate()
|
.enumerate()
|
||||||
{
|
{
|
||||||
@ -1129,6 +1159,7 @@ pub fn prepare_lights(
|
|||||||
hdr: false,
|
hdr: false,
|
||||||
color_grading: Default::default(),
|
color_grading: Default::default(),
|
||||||
},
|
},
|
||||||
|
*frusta,
|
||||||
RenderPhase::<Shadow>::default(),
|
RenderPhase::<Shadow>::default(),
|
||||||
LightEntity::Directional {
|
LightEntity::Directional {
|
||||||
light_entity,
|
light_entity,
|
||||||
|
@ -678,6 +678,13 @@ pub struct InnerMeshVertexBufferLayout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl InnerMeshVertexBufferLayout {
|
impl InnerMeshVertexBufferLayout {
|
||||||
|
pub fn new(attribute_ids: Vec<MeshVertexAttributeId>, layout: VertexBufferLayout) -> Self {
|
||||||
|
Self {
|
||||||
|
attribute_ids,
|
||||||
|
layout,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn contains(&self, attribute_id: impl Into<MeshVertexAttributeId>) -> bool {
|
pub fn contains(&self, attribute_id: impl Into<MeshVertexAttributeId>) -> bool {
|
||||||
self.attribute_ids.contains(&attribute_id.into())
|
self.attribute_ids.contains(&attribute_id.into())
|
||||||
|
@ -303,7 +303,7 @@ impl Frustum {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Component, Debug, Default, Reflect)]
|
#[derive(Component, Clone, Debug, Default, Reflect)]
|
||||||
#[reflect(Component)]
|
#[reflect(Component)]
|
||||||
pub struct CubemapFrusta {
|
pub struct CubemapFrusta {
|
||||||
#[reflect(ignore)]
|
#[reflect(ignore)]
|
||||||
|
@ -32,7 +32,7 @@ pub use uniform_buffer::*;
|
|||||||
|
|
||||||
// TODO: decide where re-exports should go
|
// TODO: decide where re-exports should go
|
||||||
pub use wgpu::{
|
pub use wgpu::{
|
||||||
util::{BufferInitDescriptor, DrawIndexedIndirect},
|
util::{BufferInitDescriptor, DrawIndexedIndirect, DrawIndirect},
|
||||||
AdapterInfo as WgpuAdapterInfo, AddressMode, BindGroupDescriptor, BindGroupEntry,
|
AdapterInfo as WgpuAdapterInfo, AddressMode, BindGroupDescriptor, BindGroupEntry,
|
||||||
BindGroupLayoutDescriptor, BindGroupLayoutEntry, BindingResource, BindingType, BlendComponent,
|
BindGroupLayoutDescriptor, BindGroupLayoutEntry, BindingResource, BindingType, BlendComponent,
|
||||||
BlendFactor, BlendOperation, BlendState, BufferAddress, BufferAsyncError, BufferBinding,
|
BlendFactor, BlendOperation, BlendState, BufferAddress, BufferAsyncError, BufferBinding,
|
||||||
|
@ -457,7 +457,7 @@ struct MainTargetTextures {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
fn prepare_view_targets(
|
pub fn prepare_view_targets(
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
windows: Res<ExtractedWindows>,
|
windows: Res<ExtractedWindows>,
|
||||||
images: Res<RenderAssets<Image>>,
|
images: Res<RenderAssets<Image>>,
|
||||||
|
@ -17,7 +17,6 @@ fn main() {
|
|||||||
DefaultPlugins,
|
DefaultPlugins,
|
||||||
FrameTimeDiagnosticsPlugin,
|
FrameTimeDiagnosticsPlugin,
|
||||||
LogDiagnosticsPlugin::default(),
|
LogDiagnosticsPlugin::default(),
|
||||||
bevy_internal::core_pipeline::experimental::taa::TemporalAntiAliasPlugin,
|
|
||||||
))
|
))
|
||||||
.add_systems(Startup, setup)
|
.add_systems(Startup, setup)
|
||||||
.add_systems(Update, (light_sway, movement))
|
.add_systems(Update, (light_sway, movement))
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
//! Update a scene from a glTF file, either by spawning the scene as a child of another entity,
|
//! Update a scene from a glTF file, either by spawning the scene as a child of another entity,
|
||||||
//! or by accessing the entities of the scene.
|
//! or by accessing the entities of the scene.
|
||||||
|
|
||||||
use bevy::prelude::*;
|
use bevy::{pbr::DirectionalLightShadowMap, prelude::*};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
App::new()
|
App::new()
|
||||||
.insert_resource(bevy_internal::pbr::DirectionalLightShadowMap { size: 4096 })
|
.insert_resource(DirectionalLightShadowMap { size: 4096 })
|
||||||
.add_plugins(DefaultPlugins)
|
.add_plugins(DefaultPlugins)
|
||||||
.add_systems(Startup, setup)
|
.add_systems(Startup, setup)
|
||||||
.add_systems(Update, move_scene_entities)
|
.add_systems(Update, move_scene_entities)
|
||||||
|
Loading…
Reference in New Issue
Block a user