Repository: bevyengine/bevy
File: crates/bevy_pbr/src/prepass/mod.rs (Rust)

Code before:
            &self.properties,
        )?;

        // This is a bit risky because it's possible to change something that would
        // break the prepass but be fine in the main pass.
        // Since this api is pretty low-level it doesn't matter that much, but it is a potential issue.
        if let Some(specialize) = self.properties.user_specialize {
            specialize(
                &self.pipeline.material_pipeline,
                &mut descriptor,
                layout,
                key,
            )?;
        }

        Ok(descriptor)
    }
}

fn is_depth_only_opaque_prepass(mesh_key: MeshPipelineKey) -> bool {
    mesh_key.contains(MeshPipelineKey::DEPTH_PREPASS)
        && !mesh_key.contains(MeshPipelineKey::NORMAL_PREPASS)
        && !mesh_key.contains(MeshPipelineKey::MOTION_VECTOR_PREPASS)
        && !mesh_key.contains(MeshPipelineKey::DEFERRED_PREPASS)
        && !mesh_key.contains(MeshPipelineKey::MAY_DISCARD)
        && !mesh_key.contains(MeshPipelineKey::PREPASS_READS_MATERIAL)
}

impl PrepassPipeline {
    fn specialize(
        &self,
        mesh_key: MeshPipelineKey,
        shader_defs: Vec<ShaderDefVal>,
        layout: &MeshVertexBufferLayoutRef,
        material_properties: &MaterialProperties,
    ) -> Result<RenderPipelineDescriptor, SpecializedMeshPipelineError> {
        let mut shader_defs = shader_defs;
        let mut bind_group_layouts = vec![
            if mesh_key.contains(MeshPipelineKey::MOTION_VECTOR_PREPASS) {
                self.view_layout_motion_vectors.clone()
            } else {
                self.view_layout_no_motion_vectors.clone()
            },
            self.empty_layout.clone(),
        ];
        let mut vertex_attributes = Vec::new();

        // Let the shader code know that it's running in a prepass pipeline.
        // (PBR code will use this to detect that it's running in deferred mode,
        // since that's the only time it gets called from a prepass pipeline.)
        shader_defs.push("PREPASS_PIPELINE".into());

Review comment (suggestion):
might be nicer to add a `const ALL_PREPASS_BITS` and then do `mesh_key.intersect(MeshPipelineKey::ALL_PREPASS_BITS) == MeshPipelineKey::DEPTH_PREPASS`

Code after:
            &self.properties,
        )?;

        // This is a bit risky because it's possible to change something that would
        // break the prepass but be fine in the main pass.
        // Since this api is pretty low-level it doesn't matter that much, but it is a potential issue.
        if let Some(specialize) = self.properties.user_specialize {
            specialize(
                &self.pipeline.material_pipeline,
                &mut descriptor,
                layout,
                key,
            )?;
        }

        Ok(descriptor)
    }
}

fn is_depth_only_opaque_prepass(mesh_key: MeshPipelineKey) -> bool {
    mesh_key.intersection(MeshPipelineKey::ALL_PREPASS_BITS) == MeshPipelineKey::DEPTH_PREPASS
}

impl PrepassPipeline {
    fn specialize(
        &self,
        mesh_key: MeshPipelineKey,
        shader_defs: Vec<ShaderDefVal>,
        layout: &MeshVertexBufferLayoutRef,
        material_properties: &MaterialProperties,
    ) -> Result<RenderPipelineDescriptor, SpecializedMeshPipelineError> {
        let mut shader_defs = shader_defs;
        let mut bind_group_layouts = vec![
            if mesh_key.contains(MeshPipelineKey::MOTION_VECTOR_PREPASS) {
                self.view_layout_motion_vectors.clone()
            } else {
                self.view_layout_no_motion_vectors.clone()
            },
            self.empty_layout.clone(),
        ];
        let mut vertex_attributes = Vec::new();

        // Let the shader code know that it's running in a prepass pipeline.
        // (PBR code will use this to detect that it's running in deferred mode,
        // since that's the only time it gets called from a prepass pipeline.)
        shader_defs.push("PREPASS_PIPELINE".into());

        shader_defs.push(ShaderDefVal::UInt(
            "MATERIAL_BIND_GROUP".into(),
            crate::MATERIAL_BIND_GROUP_INDEX as u32,
        ));