fix: avoid norm16 for textures with linear filtering #3194
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Context
On certain hardware, combining linear texture filtering with the normalized fixed point types from EXT_texture_norm16 results in black pixels and a WebGL warning from the browser.
According to this proposed webgpu extension, there are a lot of mobile devices that don't support linear filtering for norm16 (eg Adreno 5XX, 7XX devices). This includes recent flagships like the Samsung Galaxy 24 Ultra, where I found this issue.
Unlike floats which have the OES_texture_float_linear extension, it doesn't seem possible to check using webgl if linear filtering is present for norm16 types. It would have been much better to limit the change only when it really is a problem. Not sure if I'm missing anything here, but this seems like a gap in the standard... I might open an issue there to askI asked: KhronosGroup/WebGL#3706
Also, here's two recent bugs from cornerstone that I think are a manifestation of this problem. Same error message, same black canvas (except turned gray due to window levels)
The phones mentioned there are Huawei P50, Huawei P60, Huawei Mate 9. These have Adreno/Mali GPUs, matching what the webgpu proposal said.
Results
Texture now acts as if EXT_texture_norm16 is unsupported when LINEAR filtering is chosen. It should fall back to some float type.
Changes
by defaultwhen a runtime check determines it won't workadded override API if someone wants to force itenableLinearNorm16Ext(useLinearNorm16: boolean): void
PR and Code Checklist
npm run reformat
to have correctly formatted codeTesting
Unfortunately you need a phone that has a problematic GPU. Like the previous texture filtering issue, I tested this with a modified vtk.js directly in OHIF.
If you do have a phone, I found a useful jsfiddle that reproduces the bug. It directly renders a texture with webgl: https://jsfiddle.net/sedghi/hxLegk5y/
This is how it should look, on a desktop GPU where everything is fine:
This is how it looks on a phone that has the problem:
And identical code, but replacing LINEAR with NEAREST fixes the black image: