-
-
Notifications
You must be signed in to change notification settings - Fork 35.4k
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
Adreno 300 series GPU black texture flickering #9988
Comments
Do you get the same results with Android's Chrome Dev, Chrome Canary and Firefox? |
Same results with Chrome Dev, Canary and Firefox as well. |
@kenrussell is this a known issue? |
@mrdoob it's hard to know. As you remember we filed ~4 driver bugs with Qualcomm against the Adreno 330 last year - the GPU in the Nexus 5. We were told that that device was not going to receive the Android N update, so no graphics driver updates, and the bugs were closed as "won't fix". I don't remember exactly which of the WebGL conformance tests in https://github.com/KhronosGroup/WebGL/tree/master/sdk/tests/conformance/glsl/bugs were created for these cases. If this is a serious issue then I recommend iteratively simplifying the shader and figuring out what part of it is executing incorrectly on the Adreno 300 series GPUs. This would only be in order to figure out a workaround -- there is no point in filing a driver bug about it since the driver will never be updated. We will gladly add a reduced test case to the WebGL conformance suite if you can come up with one and if it doesn't already exist. |
@mrdoob it seems that adding a normal map to the phong material is causing the issue in my project on some meshes. The flicker still exists on the other materials, Basic and Lambert as well unlike my initial observations. I have tested with a lot of devices with the 300 series GPU just to be sure. Here is a screen without the normal map on the door. There are a couple of more issues with these devices though, even with the Fog shader which causes issues with the fog distance set as well as the device crashing when the screen locks with the browser on and you try to unlock it. |
Does this example render correctly on those devices? |
Yes so far it is rendering fine without any flicker for this link. |
@mrdoob Any chance there's a workaround for this ? |
The example I mentioned uses |
I am using MeshPhongMaterial with a normalMap for the render. How do we go about identifying the reason for the glitch ? |
Basically enabling/disabling things. Compare how is your code different from the one in the example |
At the moment, short of using a different format for loading my meshes, i cannot think of anything. Will still test and keep you updated. Currently I am using the Open3DGC for SEA3D loader for the extra compression. |
@sunag any ideas? |
@gauravrane You can send me the door in |
Hi @sunag , here is the file with the normal map included. In the project i am not adding the map directly onto the object and exporting, instead applying a custom material at runtime. I tried using this object on the Adreno 330 with only the normal map exported from the SEA3d exporter but was getting the same results. One observation though, at a certain angle of the camera the flicker seems to disappear (ideally when the object and camera are almost in a straight line) but all other angles its still present. I am using Orbitcontrols for the camera controller. |
Hi @gauravrane I fix the problem in |
@sunag @mrdoob disabling |
Hi guys, there has been no solution to this yet. Is there an alternate shader you could point me to, for use instead of phong, i'm very bad with shader programming. I am assuming that the main fix here will be changing the normal part of the shader. |
Sounds like for those GPUs Chrome will have to force-disable antialias... |
But the normal map flicker still persists. |
This is a duplicate of this bug: #9515 There is basically an issue with the physical shader somewhere. |
Seems to be kind of resolution dependent... |
Hey guys, as an update for a quick workaround i implemented normal calculation from the ShaderSkin file. It does not give accurate per pixel mapping, but it gets the job done for me. vec3 perturbNormal2Arb( vec3 eye_pos )
{
vec4 posAndU = vec4( -eye_pos, vUv.x );
vec4 posAndU_dx = dFdx( posAndU ), posAndU_dy = dFdy( posAndU );
vec3 tangent = posAndU_dx.w * posAndU_dx.xyz + posAndU_dy.w * posAndU_dy.xyz;
tangent += 0.00000001;
vec3 thenormal = normalize( vNormal );
vec3 binormal = normalize( cross( tangent, thenormal ) );
tangent = cross( thenormal, binormal );
mat3 tsb = mat3( tangent, binormal, thenormal );
vec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;
mapN.xy = normalScale * mapN.xy;
mapN = normalize(mapN);
return normalize( tsb * mapN );
} |
@mrdoob should we say that the per pixel tangent space calculation is causing the flicker and close this with the alternate solution ? Or is there another workaround expected based on observations. |
@gauravrane do you have a test link with and without your code that we can test? |
@mrdoob here are the links http://carconfigurator.in/test/brezza/r84.html - With the original r84 Also attaching some screenshots, tested on a Nexus 5 (Adreno 330, android 7.1.1) One Plus X (Adreno 330, android 6.0.1) and Moto G3 (Adreno 306, android 6.0.1) Strangely though where i am using a repeatable texture the issue does not come up with the unedited version. |
As a recap... You've replaced normalmap_pars_fragment.glsl vec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm ) {
vec3 q0 = dFdx( eye_pos.xyz );
vec3 q1 = dFdy( eye_pos.xyz );
vec2 st0 = dFdx( vUv.st );
vec2 st1 = dFdy( vUv.st );
vec3 S = normalize( q0 * st1.t - q1 * st0.t );
vec3 T = normalize( -q0 * st1.s + q1 * st0.s );
vec3 N = normalize( surf_norm );
vec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;
mapN.xy = normalScale * mapN.xy;
mat3 tsn = mat3( S, T, N );
return normalize( tsn * mapN );
} With this code from ShaderSkin.js: // normal mapping
"vec4 posAndU = vec4( -vViewPosition, vUv.x );",
"vec4 posAndU_dx = dFdx( posAndU ), posAndU_dy = dFdy( posAndU );",
"vec3 tangent = posAndU_dx.w * posAndU_dx.xyz + posAndU_dy.w * posAndU_dy.xyz;",
"vec3 normal = normalize( vNormal );",
"vec3 binormal = normalize( cross( tangent, normal ) );",
"tangent = cross( normal, binormal );", // no normalization required
"mat3 tsb = mat3( tangent, binormal, normal );",
"vec3 normalTex = texture2D( tNormal, vUv ).xyz * 2.0 - 1.0;",
"normalTex.xy *= uNormalScale;",
"normalTex = normalize( normalTex );",
"vec3 finalNormal = tsb * normalTex;",
"normal = normalize( finalNormal );", With some modifications though: vec3 perturbNormal2Arb( vec3 eye_pos )
{
vec4 posAndU = vec4( -eye_pos, vUv.x );
vec4 posAndU_dx = dFdx( posAndU ), posAndU_dy = dFdy( posAndU );
vec3 tangent = posAndU_dx.w * posAndU_dx.xyz + posAndU_dy.w * posAndU_dy.xyz;
tangent += 0.00000001;
vec3 thenormal = normalize( vNormal );
vec3 binormal = normalize( cross( tangent, thenormal ) );
tangent = cross( thenormal, binormal );
mat3 tsb = mat3( tangent, binormal, thenormal );
vec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;
mapN.xy = normalScale * mapN.xy;
mapN = normalize(mapN);
return normalize( tsb * mapN );
} However, if Correct? |
Reminds me that we have this work-around in normal_fragment.glsl // Workaround for Adreno/Nexus5 not able able to do dFdx( vViewPosition ) ...
vec3 fdx = vec3( dFdx( vViewPosition.x ), dFdx( vViewPosition.y ), dFdx( vViewPosition.z ) );
vec3 fdy = vec3( dFdy( vViewPosition.x ), dFdy( vViewPosition.y ), dFdy( vViewPosition.z ) );
vec3 normal = normalize( cross( fdx, fdy ) ); Could you try this code on those devices? vec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm ) {
vec3 q0 = vec3( dFdx( eye_pos.x ), dFdx( eye_pos.y ), dFdx( eye_pos.z ) );
vec3 q1 = vec3( dFdy( eye_pos.x ), dFdy( eye_pos.y ), dFdy( eye_pos.z ) );
vec2 st0 = vec2( dFdx( vUv.s ), dFdx( vUv.t ) );
vec2 st1 = vec2( dFdy( vUv.s ), dFdy( vUv.t ) );
vec3 S = normalize( q0 * st1.t - q1 * st0.t );
vec3 T = normalize( -q0 * st1.s + q1 * st0.s );
vec3 N = normalize( surf_norm );
vec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;
mapN.xy = normalScale * mapN.xy;
mat3 tsn = mat3( S, T, N );
return normalize( tsn * mapN );
} |
My suspicion is that Adreno has issues with So maybe we can avoid the vec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm ) {
vec3 q0 = vec3( dFdx( eye_pos.x ), dFdx( eye_pos.y ), dFdx( eye_pos.z ) );
vec3 q1 = vec3( dFdy( eye_pos.x ), dFdy( eye_pos.y ), dFdy( eye_pos.z ) );
vec2 st0 = dFdx( vUv.st );
vec2 st1 = dFdy( vUv.st );
vec3 S = normalize( q0 * st1.t - q1 * st0.t );
vec3 T = normalize( -q0 * st1.s + q1 * st0.s );
vec3 N = normalize( surf_norm );
vec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;
mapN.xy = normalScale * mapN.xy;
mat3 tsn = mat3( S, T, N );
return normalize( tsn * mapN );
} |
Does that only happen when |
@gauravrane I think you should be able to achieve the same doing something like this: texture.offset.set( 0.001, 0.001 );
texture.repeat.set( 0.998, 0.998 ); |
Done! I've also added it to bumpmap_pars_fragment.glsl |
When loading the website on an Android phone with a Adreno 300 series, get a weird black glitch in diffuse textures causing black flickering. I am using MeshPhongMaterial for the meshes with point lights.
The same is reproduced in the threejs examples from the website, which i am giving links for instead of a jsfiddle.
https://threejs.org/examples/?q=texture#webgl_materials_texture_filters
https://threejs.org/examples/?q=texture#webgl_materials_texture_manualmipmap
Screenshots -
From my application -
In my project, the floor outside which is a Plane Geometry does not have this issue. Only the mesh I have loaded using the SEA3d loader.
Strangely there was no issue when viewing the anisotropy example too.
It is a major issue because a lot of phones use Adreno 300 series GPU's.
Three.js version
Browser
OS
Hardware Requirements (graphics card, VR Device, ...)
Tested with the following android devices. Work fine on other GPU series.
Oneplus X - Adreno 330
Moto G3 - Adreno 306
Moto G2 - Adreno 305
The text was updated successfully, but these errors were encountered: