Skip to content

Commit

Permalink
WIP cull mode specialization
Browse files Browse the repository at this point in the history
  • Loading branch information
rparrett committed Jan 20, 2022
1 parent cb2ba19 commit ebbb63a
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 2 deletions.
20 changes: 20 additions & 0 deletions crates/bevy_pbr/src/material.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,12 @@ pub trait Material: Asset + RenderAsset {
AlphaMode::Opaque
}

/// Returns this material's [`AlphaMode`]. Defaults to [`AlphaMode::Opaque`].
#[allow(unused_variables)]
fn double_sided(material: &<Self as RenderAsset>::PreparedAsset) -> bool {
false
}

/// The dynamic uniform indices to set for the given `material`'s [`BindGroup`].
/// Defaults to an empty array / no dynamic uniform indices.
#[allow(unused_variables)]
Expand Down Expand Up @@ -98,6 +104,11 @@ impl<M: Material> SpecializedMaterial for M {
<M as Material>::alpha_mode(material)
}

#[inline]
fn double_sided(material: &<Self as RenderAsset>::PreparedAsset) -> bool {
<M as Material>::double_sided(material)
}

#[inline]
fn vertex_shader(asset_server: &AssetServer) -> Option<Handle<Shader>> {
<M as Material>::vertex_shader(asset_server)
Expand Down Expand Up @@ -158,6 +169,12 @@ pub trait SpecializedMaterial: Asset + RenderAsset {
AlphaMode::Opaque
}

/// Returns this material's [`AlphaMode`]. Defaults to [`AlphaMode::Opaque`].
#[allow(unused_variables)]
fn double_sided(material: &<Self as RenderAsset>::PreparedAsset) -> bool {
false
}

/// The dynamic uniform indices to set for the given `material`'s [`BindGroup`].
/// Defaults to an empty array / no dynamic uniform indices.
#[allow(unused_variables)]
Expand Down Expand Up @@ -326,6 +343,9 @@ pub fn queue_material_meshes<M: SpecializedMaterial>(
if let AlphaMode::Blend = alpha_mode {
mesh_key |= MeshPipelineKey::TRANSPARENT_MAIN_PASS
}
if M::double_sided(material) {
mesh_key |= MeshPipelineKey::from_cull_mode(None)
}

let specialized_key = M::key(material);
let pipeline_id = pipelines.specialize(
Expand Down
7 changes: 7 additions & 0 deletions crates/bevy_pbr/src/pbr_material.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ pub struct GpuStandardMaterial {
pub flags: StandardMaterialFlags,
pub base_color_texture: Option<Handle<Image>>,
pub alpha_mode: AlphaMode,
pub double_sided: bool,
}

impl RenderAsset for StandardMaterial {
Expand Down Expand Up @@ -320,6 +321,7 @@ impl RenderAsset for StandardMaterial {
has_normal_map,
base_color_texture: material.base_color_texture,
alpha_mode: material.alpha_mode,
double_sided: material.double_sided,
})
}
}
Expand Down Expand Up @@ -477,4 +479,9 @@ impl SpecializedMaterial for StandardMaterial {
fn alpha_mode(render_asset: &<Self as RenderAsset>::PreparedAsset) -> AlphaMode {
render_asset.alpha_mode
}

#[inline]
fn double_sided(render_asset: &<Self as RenderAsset>::PreparedAsset) -> bool {
render_asset.double_sided
}
}
25 changes: 24 additions & 1 deletion crates/bevy_pbr/src/render/mesh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,7 @@ bitflags::bitflags! {
const TRANSPARENT_MAIN_PASS = (1 << 1);
const MSAA_RESERVED_BITS = MeshPipelineKey::MSAA_MASK_BITS << MeshPipelineKey::MSAA_SHIFT_BITS;
const PRIMITIVE_TOPOLOGY_RESERVED_BITS = MeshPipelineKey::PRIMITIVE_TOPOLOGY_MASK_BITS << MeshPipelineKey::PRIMITIVE_TOPOLOGY_SHIFT_BITS;
const CULL_MODE_RESERVED_BITS = MeshPipelineKey::CULL_MODE_MASK_BITS << MeshPipelineKey::CULL_MODE_SHIFT_BITS;
}
}

Expand All @@ -380,6 +381,8 @@ impl MeshPipelineKey {
const MSAA_SHIFT_BITS: u32 = 32 - 6;
const PRIMITIVE_TOPOLOGY_MASK_BITS: u32 = 0b111;
const PRIMITIVE_TOPOLOGY_SHIFT_BITS: u32 = Self::MSAA_SHIFT_BITS - 3;
const CULL_MODE_MASK_BITS: u32 = 0b11;
const CULL_MODE_SHIFT_BITS: u32 = Self::PRIMITIVE_TOPOLOGY_SHIFT_BITS - 2;

pub fn from_msaa_samples(msaa_samples: u32) -> Self {
let msaa_bits = ((msaa_samples - 1) & Self::MSAA_MASK_BITS) << Self::MSAA_SHIFT_BITS;
Expand Down Expand Up @@ -409,6 +412,26 @@ impl MeshPipelineKey {
_ => PrimitiveTopology::default(),
}
}

pub fn from_cull_mode(cull_mode: Option<Face>) -> Self {
let cull_mode = match cull_mode {
Some(Face::Back) => 0,
Some(Face::Front) => 1,
None => 2,
};
let cull_mode_bits = (cull_mode & Self::CULL_MODE_MASK_BITS) << Self::CULL_MODE_SHIFT_BITS;
MeshPipelineKey::from_bits(cull_mode_bits).unwrap()
}

pub fn cull_mode(&self) -> Option<Face> {
let cull_mode_bits = (self.bits >> Self::CULL_MODE_SHIFT_BITS) & Self::CULL_MODE_MASK_BITS;
match cull_mode_bits {
0 => Some(Face::Back),
1 => Some(Face::Front),
2 => None,
_ => Some(Face::Back),
}
}
}

impl SpecializedPipeline for MeshPipeline {
Expand Down Expand Up @@ -519,7 +542,7 @@ impl SpecializedPipeline for MeshPipeline {
layout: Some(vec![self.view_layout.clone(), self.mesh_layout.clone()]),
primitive: PrimitiveState {
front_face: FrontFace::Ccw,
cull_mode: Some(Face::Back),
cull_mode: key.cull_mode(),
unclipped_depth: false,
polygon_mode: PolygonMode::Fill,
conservative: false,
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_render/src/mesh/mesh/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use bevy_reflect::TypeUuid;
use bevy_utils::EnumVariantMeta;
use std::{borrow::Cow, collections::BTreeMap};
use wgpu::{
util::BufferInitDescriptor, BufferUsages, IndexFormat, PrimitiveTopology, VertexFormat,
util::BufferInitDescriptor, BufferUsages, Face, IndexFormat, PrimitiveTopology, VertexFormat,
};

pub const INDEX_BUFFER_ASSET_INDEX: u64 = 0;
Expand Down

0 comments on commit ebbb63a

Please sign in to comment.