Use the prepass normal texture in main pass when possible (#8231)
# Objective - We support enabling a normal prepass, but the main pass never actually uses it and recomputes the normals in the main pass. This isn't ideal since it's doing redundant work. ## Solution - Use the normal texture from the prepass in the main pass ## Notes ~~I used `NORMAL_PREPASS_ENABLED` as a shader_def because `NORMAL_PREPASS` is currently used to signify that it is running in the prepass while this shader_def need to indicate the prepass is done and the normal prepass was ran before. I'm not sure if there's a better way to name this.~~
This commit is contained in:
parent
21dc3abe1b
commit
0859f675c3
@ -7,6 +7,7 @@ use bevy_app::{App, Plugin};
|
||||
use bevy_asset::{AddAsset, AssetEvent, AssetServer, Assets, Handle};
|
||||
use bevy_core_pipeline::{
|
||||
core_3d::{AlphaMask3d, Opaque3d, Transparent3d},
|
||||
prepass::NormalPrepass,
|
||||
tonemapping::{DebandDither, Tonemapping},
|
||||
};
|
||||
use bevy_derive::{Deref, DerefMut};
|
||||
@ -380,6 +381,7 @@ pub fn queue_material_meshes<M: Material>(
|
||||
Option<&Tonemapping>,
|
||||
Option<&DebandDither>,
|
||||
Option<&EnvironmentMapLight>,
|
||||
Option<&NormalPrepass>,
|
||||
&mut RenderPhase<Opaque3d>,
|
||||
&mut RenderPhase<AlphaMask3d>,
|
||||
&mut RenderPhase<Transparent3d>,
|
||||
@ -393,6 +395,7 @@ pub fn queue_material_meshes<M: Material>(
|
||||
tonemapping,
|
||||
dither,
|
||||
environment_map,
|
||||
normal_prepass,
|
||||
mut opaque_phase,
|
||||
mut alpha_mask_phase,
|
||||
mut transparent_phase,
|
||||
@ -405,6 +408,10 @@ pub fn queue_material_meshes<M: Material>(
|
||||
let mut view_key = MeshPipelineKey::from_msaa_samples(msaa.samples())
|
||||
| MeshPipelineKey::from_hdr(view.hdr);
|
||||
|
||||
if normal_prepass.is_some() {
|
||||
view_key |= MeshPipelineKey::NORMAL_PREPASS;
|
||||
}
|
||||
|
||||
let environment_map_loaded = match environment_map {
|
||||
Some(environment_map) => environment_map.is_loaded(&images),
|
||||
None => false,
|
||||
|
||||
@ -665,6 +665,10 @@ impl SpecializedMeshPipeline for MeshPipeline {
|
||||
let mut shader_defs = Vec::new();
|
||||
let mut vertex_attributes = Vec::new();
|
||||
|
||||
if key.contains(MeshPipelineKey::NORMAL_PREPASS) {
|
||||
shader_defs.push("LOAD_PREPASS_NORMALS".into());
|
||||
}
|
||||
|
||||
if layout.contains(Mesh::ATTRIBUTE_POSITION) {
|
||||
shader_defs.push("VERTEX_POSITIONS".into());
|
||||
vertex_attributes.push(Mesh::ATTRIBUTE_POSITION.at_shader_location(0));
|
||||
|
||||
@ -10,6 +10,8 @@
|
||||
#import bevy_pbr::fog
|
||||
#import bevy_pbr::pbr_functions
|
||||
|
||||
#import bevy_pbr::prepass_utils
|
||||
|
||||
struct FragmentInput {
|
||||
@builtin(front_facing) is_front: bool,
|
||||
@builtin(position) frag_coord: vec4<f32>,
|
||||
@ -69,11 +71,16 @@ fn fragment(in: FragmentInput) -> @location(0) vec4<f32> {
|
||||
#endif
|
||||
pbr_input.frag_coord = in.frag_coord;
|
||||
pbr_input.world_position = in.world_position;
|
||||
|
||||
#ifdef LOAD_PREPASS_NORMALS
|
||||
pbr_input.world_normal = prepass_normal(in.frag_coord, 0u);
|
||||
#else // LOAD_PREPASS_NORMALS
|
||||
pbr_input.world_normal = prepare_world_normal(
|
||||
in.world_normal,
|
||||
(material.flags & STANDARD_MATERIAL_FLAGS_DOUBLE_SIDED_BIT) != 0u,
|
||||
in.is_front,
|
||||
);
|
||||
#endif // LOAD_PREPASS_NORMALS
|
||||
|
||||
pbr_input.is_orthographic = view.projection[3].w == 1.0;
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user