Skip to content

Commit

Permalink
optimized view z functions
Browse files Browse the repository at this point in the history
  • Loading branch information
DGriffin91 committed Sep 10, 2023
1 parent e3c4c7e commit e86324d
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 31 deletions.
10 changes: 10 additions & 0 deletions crates/bevy_pbr/src/material.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use bevy_ecs::{
},
};
use bevy_render::{
camera::Projection,
extract_component::ExtractComponentPlugin,
mesh::{Mesh, MeshVertexBufferLayout},
prelude::Image,
Expand Down Expand Up @@ -390,6 +391,7 @@ pub fn queue_material_meshes<M: Material>(
Option<&ScreenSpaceAmbientOcclusionSettings>,
Option<&NormalPrepass>,
Option<&TemporalAntiAliasSettings>,
Option<&Projection>,
&mut RenderPhase<Opaque3d>,
&mut RenderPhase<AlphaMask3d>,
&mut RenderPhase<Transparent3d>,
Expand All @@ -406,6 +408,7 @@ pub fn queue_material_meshes<M: Material>(
ssao,
normal_prepass,
taa_settings,
projection,
mut opaque_phase,
mut alpha_mask_phase,
mut transparent_phase,
Expand Down Expand Up @@ -434,6 +437,13 @@ pub fn queue_material_meshes<M: Material>(
view_key |= MeshPipelineKey::ENVIRONMENT_MAP;
}

if let Some(projection) = projection {
view_key |= match projection {
Projection::Perspective(_) => MeshPipelineKey::VIEW_PROJECTION_PERSPECTIVE,
Projection::Orthographic(_) => MeshPipelineKey::VIEW_PROJECTION_ORTHOGRAPHIC,
};
}

if !view.hdr {
if let Some(tonemapping) = tonemapping {
view_key |= MeshPipelineKey::TONEMAP_IN_SHADER;
Expand Down
17 changes: 17 additions & 0 deletions crates/bevy_pbr/src/render/mesh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -751,6 +751,11 @@ bitflags::bitflags! {
const TONEMAP_METHOD_SOMEWHAT_BORING_DISPLAY_TRANSFORM = 5 << Self::TONEMAP_METHOD_SHIFT_BITS;
const TONEMAP_METHOD_TONY_MC_MAPFACE = 6 << Self::TONEMAP_METHOD_SHIFT_BITS;
const TONEMAP_METHOD_BLENDER_FILMIC = 7 << Self::TONEMAP_METHOD_SHIFT_BITS;
const VIEW_PROJECTION_RESERVED_BITS = Self::VIEW_PROJECTION_MASK_BITS << Self::VIEW_PROJECTION_SHIFT_BITS;
const VIEW_PROJECTION_NONSTANDARD = 0 << Self::VIEW_PROJECTION_SHIFT_BITS;
const VIEW_PROJECTION_PERSPECTIVE = 1 << Self::VIEW_PROJECTION_SHIFT_BITS;
const VIEW_PROJECTION_ORTHOGRAPHIC = 2 << Self::VIEW_PROJECTION_SHIFT_BITS;
const VIEW_PROJECTION_RESERVED = 3 << Self::VIEW_PROJECTION_SHIFT_BITS;
}
}

Expand All @@ -766,6 +771,9 @@ impl MeshPipelineKey {
const TONEMAP_METHOD_MASK_BITS: u32 = 0b111;
const TONEMAP_METHOD_SHIFT_BITS: u32 =
Self::BLEND_SHIFT_BITS - Self::TONEMAP_METHOD_MASK_BITS.count_ones();
const VIEW_PROJECTION_MASK_BITS: u32 = 0b11;
const VIEW_PROJECTION_SHIFT_BITS: u32 =
Self::TONEMAP_METHOD_SHIFT_BITS - Self::VIEW_PROJECTION_MASK_BITS.count_ones();

pub fn from_msaa_samples(msaa_samples: u32) -> Self {
let msaa_bits =
Expand Down Expand Up @@ -948,6 +956,15 @@ impl SpecializedMeshPipeline for MeshPipeline {
shader_defs.push("LOAD_PREPASS_NORMALS".into());
}

let view_projection = key.intersection(MeshPipelineKey::VIEW_PROJECTION_RESERVED_BITS);
if view_projection == MeshPipelineKey::VIEW_PROJECTION_NONSTANDARD {
shader_defs.push("VIEW_PROJECTION_NONSTANDARD".into());
} else if view_projection == MeshPipelineKey::VIEW_PROJECTION_PERSPECTIVE {
shader_defs.push("VIEW_PROJECTION_PERSPECTIVE".into());
} else if view_projection == MeshPipelineKey::VIEW_PROJECTION_ORTHOGRAPHIC {
shader_defs.push("VIEW_PROJECTION_ORTHOGRAPHIC".into());
}

if key.contains(MeshPipelineKey::TONEMAP_IN_SHADER) {
shader_defs.push("TONEMAP_IN_SHADER".into());

Expand Down
58 changes: 27 additions & 31 deletions crates/bevy_pbr/src/render/view_transformations.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -138,41 +138,37 @@ fn position_view_to_ndc(view_pos: vec3<f32>) -> vec3<f32> {
// DEPTH -----------
// -----------------

/// Retrieve the camera near clipping plane
fn camera_near() -> f32 {
/// Retrieve the perspective camera near clipping plane
fn perspective_camera_near() -> f32 {
return view_bindings::view.projection[3][2];
}

/// Convert ndc space depth to linear view space. Only for use with perspective projections.
fn depth_ndc_to_linear_perspective(ndc_depth: f32) -> f32 {
return camera_near() / ndc_depth;
}

/// Convert linear view space depth to ndc space. Only for use with perspective projections.
fn depth_linear_to_ndc_perspective(linear_depth: f32) -> f32 {
return camera_near() / linear_depth;
}

/// Convert ndc space depth to linear view space. Only for use with orthographic projections.
fn depth_ndc_to_linear_orthographic(ndc_depth: f32) -> f32 {
return (view_bindings::view.projection[3][2] - ndc_depth) / view_bindings::view.projection[2][2];
}

/// Convert linear view space depth to ndc space. Only for use with orthographic projections.
fn depth_linear_to_ndc_orthographic(linear_depth: f32) -> f32 {
return view_bindings::view.projection[3][2] - linear_depth * view_bindings::view.projection[2][2];
}

/// Convert ndc space depth to linear view space.
fn depth_ndc_to_linear(ndc_depth: f32) -> f32 {
/// Convert ndc depth to linear view z.
fn depth_ndc_to_view_z(ndc_depth: f32) -> f32 {
#ifdef VIEW_PROJECTION_PERSPECTIVE
return -perspective_camera_near() / ndc_depth;
#else
#ifdef VIEW_PROJECTION_ORTHOGRAPHIC
return -(view_bindings::view.projection[3][2] - ndc_depth) / view_bindings::view.projection[2][2];
#else
let view_pos = view_bindings::view.inverse_projection * vec4(0.0, 0.0, ndc_depth, 1.0);
return -view_pos.z / view_pos.w;
}

/// Convert linear view space depth to ndc space.
fn depth_linear_to_ndc(view_depth: f32) -> f32 {
let ndc_pos = view_bindings::view.projection * vec4(0.0, 0.0, view_depth, 1.0);
return -ndc_pos.z / ndc_pos.w;
return view_pos.z / view_pos.w;
#endif // VIEW_PROJECTION_ORTHOGRAPHIC
#endif // VIEW_PROJECTION_PERSPECTIVE
}

/// Convert linear view z to ndc depth.
fn view_z_to_depth_ndc(view_z: f32) -> f32 {
#ifdef VIEW_PROJECTION_PERSPECTIVE
return -perspective_camera_near() / view_z;
#else
#ifdef VIEW_PROJECTION_ORTHOGRAPHIC
return view_bindings::view.projection[3][2] + view_z * view_bindings::view.projection[2][2];
#else
let ndc_pos = view_bindings::view.projection * vec4(0.0, 0.0, view_z, 1.0);
return ndc_pos.z / ndc_pos.w;
#endif // VIEW_PROJECTION_ORTHOGRAPHIC
#endif // VIEW_PROJECTION_PERSPECTIVE
}

// -----------------
Expand Down
8 changes: 8 additions & 0 deletions crates/bevy_render/src/camera/camera.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ use bevy_window::{
use std::{borrow::Cow, ops::Range};
use wgpu::{BlendState, Extent3d, LoadOp, TextureFormat};

use super::Projection;

/// Render viewport configuration for the [`Camera`] component.
///
/// The viewport defines the area on the render target to which the camera renders its image.
Expand Down Expand Up @@ -644,6 +646,7 @@ pub fn extract_cameras(
Option<&ColorGrading>,
Option<&TemporalJitter>,
Option<&RenderLayers>,
Option<&Projection>,
)>,
>,
primary_window: Extract<Query<Entity, With<PrimaryWindow>>>,
Expand All @@ -658,6 +661,7 @@ pub fn extract_cameras(
color_grading,
temporal_jitter,
render_layers,
perspective,
) in query.iter()
{
let color_grading = *color_grading.unwrap_or(&ColorGrading::default());
Expand Down Expand Up @@ -720,6 +724,10 @@ pub fn extract_cameras(
if let Some(render_layers) = render_layers {
commands.insert(*render_layers);
}

if let Some(perspective) = perspective {
commands.insert(perspective.clone());
}
}
}
}
Expand Down

0 comments on commit e86324d

Please sign in to comment.