Skip to content

Conversation

@iwanders
Copy link
Contributor

@iwanders iwanders commented Nov 4, 2025

Hi again! This PR introduces three changes that should hopefully ensure people use a correct material for transparent textures:

  • 078a085 modifies the documentation of is_transparent in the ColorMaterial. I propose this addition because I tried to 'fix' incorrect rendering of material by marking is transparent without modifying the render_states.blend property. This did not work, hopefully this addition helps steer future users (or future me) towards the solution.

  • 7355d51 modifies the shapes2d example to also show a textured rectangle using a transparent texture. I think this is a common use-case for 2d drawings like a hud or overlay, so to me it makes sense to have this in the example:

image
  • d8fa026 modifies the textures example to show the difference between an ColorMaterial::new_opaque and ColorMaterial::new_transparent, which again, hopefully helps people find the right material to render a transparent texture:
image
  • Commit 443e46d adds the texture that is used by both examples. It is made with b6e4d0d, no further editing, without the alpha channel it looks like this:
logo_transparent_no_alpha

Background; so over the weekend I tried create a fullscreen, transparent, click through window in X11 on which I could draw an overlay. Turns out that X11s blending alpha support is tricky, I couldn't get it right, but at a certain point I tried using opengl on my window, which worked and drawing a simple rectangle with transparency also worked. But drawing an image with transparency support required shaders and a lot of complexity in modern opengl. So I needed something to handle that: I used three_d::context::Context::from_loader_function and three_d::core::Context::from_gl_context for that to create a three_d::Context 👌 . That is called on a glfw-created window, which is made transparent, fullscreen and click-through using direct x11 calls. Then to make my texture I effectively ended up copying from here and ended up with

    let mut img: CpuTexture = todo!();
    img.data.to_linear_srgb();
    let material = ColorMaterial {
        color: Srgba::WHITE,
        texture: Some(Texture2DRef::from_cpu_texture(&context, &img)),
        is_transparent: true, // Initially I didn't even set this, of course.
        ..Default::default()
    };

Combined with this example image that led to the same dreaded overlay that I pretty much got from pure x11 calls.
Changing the texture into:

            let v: three_d::CpuMaterial = three_d::CpuMaterial {
                albedo_texture: Some(texture.texture.clone()),
                ..Default::default()
            };
            let m = three_d::ColorMaterial::new_transparent(&context, &v);

makes it much better, but it is still off, as it renders incorrectly against light backgrounds.

Modifying it finally to

            let v: three_d::CpuMaterial = three_d::CpuMaterial {
                albedo_texture: Some(texture.texture.clone()),
                ..Default::default()
            };
            let mut m = three_d::ColorMaterial::new_transparent(&context, &v);
            m.render_states = three_d::RenderStates {
                write_mask: three_d::WriteMask::COLOR,
                blend: three_d::Blend::STANDARD_TRANSPARENCY,
                ..Default::default()
            };

makes it render completely correct.

Writing this up here, I actually wonder if we should talk about that STANDARD_TRANSPARENCY in the comments in the examples. Anyways, hopefully this prevents a lot of debugging by other people in the future. Happy to accommodate any feedback etc, or remove changes if I went over-the-top 👍

This makes it clearer that a transparent material is more involved than
setting this boolean to true.
This is a screen buffer capture of a modification of the logo example.
It is modified in that the inside of the gears holds a square in addition
to the logo if just the RGB channels are viewed and the alpha channel is
ignored.
This shows why it is important to use a material is correctly
configured for drawing transparent materials.
This shows how to draw textures with transparancy on the screen.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant