Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Transparent base_color_texture with AlphaMode::Mask should make shadow casters transparent #4372

Closed
Nathan-Fenner opened this issue Mar 31, 2022 · 3 comments
Labels
A-Rendering Drawing game state to the screen C-Enhancement A new feature

Comments

@Nathan-Fenner
Copy link
Contributor

Nathan-Fenner commented Mar 31, 2022

In the following scene, a simple mesh is constructed from a basic plane mesh:

commands
    .spawn_bundle(PbrBundle {
        mesh: meshes.add(Mesh::from(shape::Plane { size: 1.0 })),
        material: materials.add(StandardMaterial {
            base_color_texture: Some(chara_texture.clone()),
            double_sided: false,
            alpha_mode: AlphaMode::Mask(0.5),
            ..Default::default()
        }),
        transform: Transform::from_xyz(0.0, 0.5, 0.0),
        ..Default::default()
    });

image

The mesh itself is transparent ("cut out" where the alpha of the texture is more than 0.5) but the entire plane casts a shadow. This means that it casts a shadow in a different shape than the object itself.

What problem does this solve or what need does it fill?

Meshes textures with transparency using AlphaMode::Mask can cast shadows that match their shape in space.

What solution would you like?

When a StandardMaterial has AlphaMode::Mask, it should automatically cast shadows using the same mask for transparency. If this is infeasible, a built-in ShadowTextureMask{ ... } component could be an alternative solution.

What alternative(s) have you considered?

In some cases, the shape of the object could be constructed out of geometry instead of using textures, or a custom alternative shadow pass could be built. This would be a lot of work to match the probably "expected" behavior.

Additional context

It's not entirely clear how shadows should behave for transparency with AlphaMode::Blend, so that's out-of-scope for this issue. Using a separate component (even optionally) could make this clearer, by allowing different strategies for the shadow and the mesh in the standard pipeline (e.g. blend transparency in the main pipeline, while using AlphaMode::Mask(0.1) for shadows).

@Nathan-Fenner Nathan-Fenner added C-Enhancement A new feature S-Needs-Triage This issue needs to be labelled labels Mar 31, 2022
@alice-i-cecile alice-i-cecile added A-Rendering Drawing game state to the screen and removed S-Needs-Triage This issue needs to be labelled labels Mar 31, 2022
@superdump
Copy link
Contributor

I haven’t looked into any they about how this should be done but I suspect it’s as simple as having to implement opaque and alpha mask shadow phases where the alpha mask phase has a fragment shader that discards similar to the pbr shader. I haven’t yet had to implement a fragment shader that doesn’t return anything. All this has to do is check the alpha for the fragment and discard or not. I don’t know if that is a valid fragment shader.

@nicholasc
Copy link

+1 I would love to have this

@Anti-Alias
Copy link
Contributor

Second. Objects like foliage make heavy use of this and is a must-have.

@bors bors bot closed this as completed in e54103f Mar 2, 2023
Shfty pushed a commit to shfty-rust/bevy that referenced this issue Mar 19, 2023
# Objective

- Fixes bevyengine#4372.

## Solution

- Use the prepass shaders for the shadow passes.
- Move `DEPTH_CLAMP_ORTHO` from `ShadowPipelineKey` to `MeshPipelineKey` and the associated clamp operation from `depth.wgsl` to `prepass.wgsl`.
- Remove `depth.wgsl` .
- Replace `ShadowPipeline` with `ShadowSamplers`.

Instead of running the custom `ShadowPipeline` we run the `PrepassPipeline` with the `DEPTH_PREPASS` flag and additionally the `DEPTH_CLAMP_ORTHO` flag for directional lights as well as the `ALPHA_MASK` flag for materials that use `AlphaMode::Mask(_)`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Rendering Drawing game state to the screen C-Enhancement A new feature
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants