asny / three-d

2D/3D renderer - makes it simple to draw stuff across platforms (including web)
MIT License
1.24k stars 105 forks source link

Some kind of blend/alpha issue with some models (inside-out models) #452

Open frnsys opened 3 months ago

frnsys commented 3 months ago

Hi, thanks for this library. I'm having one small issue that I can't seem to figure out.

image

I have some models like this one where the model is shown "inside-out". I've checked then normals, tried flipping them, etc but can't get it to display correctly.

I've also checked that the alpha mode of the material is correct:

image

I'm using a headless context and loading the model like so:

        // `model` is a `CpuModel`.
        let mut model = Model::<ColorMaterial>::new(&self.context, &model).unwrap();
        model.iter_mut().for_each(|m| {
            // I've tried every Blend option
            m.material.render_states.blend = Blend::TRANSPARENCY;
            m.material.render_states.cull = Cull::None;
            m.material.is_transparent = false;
        });

Another clue is that on my RenderTarget, if I use .clear(ClearState::color_and_depth(0.0, 0.0, 0.0, 1.0, 1.0)) then I can see the model (though inside-out), but if I set the clear alpha to 0.0 then nothing renders at all.

I'm able to load other models fine, so I thought the issue was related to this specific model. But every other viewer I've tried has been able to display the model without issue.

Update: It's fine if I use DeferredPhysicalMaterial but I'm trying to have an unlit model.

model.zip

asny commented 1 month ago

It's hard to know for sure, but I have an idea. Since you're using headless context, you probably don't have a depth buffer in your render target, only a color buffer. That means the depth sorting doesn't work and what triangles render in front of others only depend on the draw order of the triangles. The deferred material create a render target with depth buffer which is why that will work.

If I'm right, all you need to do is to create a render target with both color and depth buffer to render to.