-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
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
Transparency doesnt work when on webgl adreno devices #10066
Comments
I just tested this on 8a523de with the transparency_3d example Transparency was broken on Adreno 660 and 619 but was working as it should on Adreno 730 |
After further testing I can say for certain that Qualcomm Adreno 600 series (and likely 500 series as well) is unable to use the last 16 bits of the 32bit bitflags which causes transparency to not work as that is where the alpha mode bits were stored. I tested by moving the bits to all be inside the first 16 bits which make transparency function as intended. If we look at the commit that introduced this bug 603cb43 we can see that in that commit the flags were moved inside the last 16 bits. I was planning on splitting out the Alpha bits from the #[repr(transparent)]
pub struct StandardMaterialFlags: u32 {
const BASE_COLOR_TEXTURE = 1 << 0;
const EMISSIVE_TEXTURE = 1 << 1;
const METALLIC_ROUGHNESS_TEXTURE = 1 << 2;
const OCCLUSION_TEXTURE = 1 << 3;
const DOUBLE_SIDED = 1 << 4;
const UNLIT = 1 << 5;
const TWO_COMPONENT_NORMAL_MAP = 1 << 6;
const FLIP_NORMAL_MAP_Y = 1 << 7;
const FOG_ENABLED = 1 << 8;
const DEPTH_MAP = 1 << 9; // Used for parallax mapping
const SPECULAR_TRANSMISSION_TEXTURE = 1 << 10;
const THICKNESS_TEXTURE = 1 << 11;
const DIFFUSE_TRANSMISSION_TEXTURE = 1 << 12;
const ATTENUATION_ENABLED = 1 << 13;
const NONE = 0;
const UNINITIALIZED = 0xFFFF;
}
#[repr(transparent)]
pub struct StandardMaterialAlphaModeFlags: u32 {
const ALPHA_MODE_OPAQUE = 0;
const ALPHA_MODE_MASK = 1 << 1;
const ALPHA_MODE_BLEND = 1 << 2;
const ALPHA_MODE_PREMULTIPLIED = 1 << 3;
const ALPHA_MODE_ADD = 1 << 4;
const ALPHA_MODE_MULTIPLY = 1 << 5;
const UNINITIALIZED = 0xFFFF;
} and in the pub alpha_mode_flags: u32, Just to reiterate, my two reasons for doing it like this are:
Is this an acceptable solution that could be merged? |
@alice-i-cecile @mockersf |
I'm in favor of fixing this, but I definitely don't have the rendering expertise to comment further. Let me ask around. |
This sounds like it might be this issue: KhronosGroup/WebGL#3351 |
Specifically, GLSL loads and stores to structs seemingly truncate precision to mediump on adreno 600s, for both ints and floats. |
IMO, splitting the actual Also a minor naming-related issue, but if we name the split struct What if we used a main...coreh:bevy:split-u32-flags ☝️ Can you confirm if this fixes it for the Adreno 600 series GPUs? If it works and other people are okay with the suggestion, I can also open a PR with it |
Splitting it in two does fix the transparency issue. I opened a Pull Request (#11525) with the fix but if you prefer fixing it with |
Bevy version
bevy 0.11.3, 0.10.x, and looking at the code, most likely on main as well
Relevant system information
Most adreno devices tested, currently dont have one on hand. But I assume someone can verify. I guess this might also affect android devices
What you did
The blend_modes example shows this quite well on Adreno devices on webgl, using this wasm-web-runner branch
cargo install --git https://github.com/heisencoder/wasm-server-runner.git --branch feature/support-gzip wasm-server-runner
to host the example from another computer. Opaque flags are ignored and all balls are either entirerly invisible, or fully visible, no translucency
Investigation
Looking at the unity docs, there are references to some types being 16bit in quite a few of the mobile GPU shader hardware. And when @gnargfu investigated, he found that this commit solves it. (basically moves the bitflags to the lower 16 bits in the flags field, used to branch in the shader code, so their position in the flag field of the struct doesnt matter)
Probably, a lot of the crashes related to mobile devices, are in fact due to shader code being introduced, that assumes that all values are high precision.
Quote from unity docs
The text was updated successfully, but these errors were encountered: