Skip to content

Commit

Permalink
Fix alpha blending issue
Browse files Browse the repository at this point in the history
Signed-off-by: Torstein Grindvik <[email protected]>
  • Loading branch information
torsteingrindvik committed Jan 10, 2023
1 parent af0ca16 commit 6632b3a
Show file tree
Hide file tree
Showing 8 changed files with 25 additions and 5 deletions.
10 changes: 10 additions & 0 deletions crates/bevy_core_pipeline/src/picking/picking.wgsl
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
#define_import_path bevy_core_pipeline::picking

fn picking_alpha(a: f32) -> f32 {
// If e.g. a sprite has slightly transparent pixels, we make that opaque (by setting alpha to 1.0)
// for picking purposes.
// If we don't do this, blending will occur on the entity index value, which makes no sense.
//
// An alternative is to truncate the alpha to 0.0 unless it's 1.0, but that would shrink
// which parts of the translucent entity are pickable, which is not desirable.
return ceil(a);
}

// TODO: Describe why/what
fn entity_index_to_vec3_f32(entity_index: u32) -> vec3<f32> {
let mask_8 = 0x000000FFu;
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_pbr/src/render/pbr.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ fn fragment(in: FragmentInput) -> FragmentOutput {

out.color = output_color;
#ifdef PICKING
out.picking = vec4(entity_index_to_vec3_f32(mesh.entity_index), output_color.a);
out.picking = vec4(entity_index_to_vec3_f32(mesh.entity_index), picking_alpha(output_color.a));
#endif

return out;
Expand Down
8 changes: 7 additions & 1 deletion crates/bevy_render/src/picking/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,10 @@ impl Picking {
/// Panics if the coordinate is out of bounds.
pub fn get_entity(&self, camera: &Camera, coordinates: UVec2) -> Option<Entity> {
let guard = self.try_lock().expect("Should have been unlocked");
let resources = guard.as_ref().expect("Resources should have been prepared");
let Some(resources) = guard.as_ref() else {
// Picking resources not yet prepared.
return None
};

let slice = resources.pick_buffer.slice(..);

Expand Down Expand Up @@ -347,6 +350,9 @@ where
let start = (y * padded_width) + (x * pixel_size);
let end = start + pixel_size;

// TODO: Sometimes we're able to go out of bounds here:
// "panicked at 'range end index 7381600 out of range for slice of length 7372800'",
// we have to figure out when this can happen and why.
let view_bytes = &buffer_view[start..end];

make_data_from_viewed_bytes(view_bytes)
Expand Down
2 changes: 2 additions & 0 deletions crates/bevy_sprite/src/mesh2d/color_material.wgsl
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#import bevy_sprite::mesh2d_types
#import bevy_sprite::mesh2d_view_bindings

// TODO: Fix this one

struct ColorMaterial {
color: vec4<f32>,
// 'flags' is a bit field indicating various options. u32 is 32 bits so we have up to 32 options.
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_sprite/src/mesh2d/mesh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,7 @@ impl SpecializedMeshPipeline for Mesh2dPipeline {

targets.push(Some(ColorTargetState {
format: PICKING_TEXTURE_FORMAT,
// TODO: Check this works
// TODO: Check this works for different situations
blend,
write_mask: ColorWrites::ALL,
}));
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_sprite/src/render/sprite.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ fn fragment(in: VertexOutput) -> FragmentOutput {
out.color = color;

#ifdef PICKING
out.picking = vec4(entity_index_to_vec3_f32(entity_indices[in.vertex_index]), color.a);
out.picking = vec4(entity_index_to_vec3_f32(entity_indices[in.vertex_index]), picking_alpha(color.a));
#endif

return out;
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_ui/src/render/ui.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ fn fragment(in: VertexOutput) -> FragmentOutput {
out.color = color;

#ifdef PICKING
out.picking = vec4(entity_index_to_vec3_f32(in.entity_index), color.a);
out.picking = vec4(entity_index_to_vec3_f32(in.entity_index), picking_alpha(color.a));
#endif

return out;
Expand Down
2 changes: 2 additions & 0 deletions examples/app/picking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
//!
//! Combines parts of the 3D shapes example and the UI example.
// TODO: Update to store mouse position across frames like many_sprites.

use std::f32::consts::PI;

use bevy::{
Expand Down

0 comments on commit 6632b3a

Please sign in to comment.