Skip to content
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

Screen depth artifacts on mobile (iOS / Android) #3197

Closed
leonidaspir opened this issue May 26, 2021 · 15 comments · Fixed by #3420
Closed

Screen depth artifacts on mobile (iOS / Android) #3197

leonidaspir opened this issue May 26, 2021 · 15 comments · Fixed by #3420
Labels
area: graphics Graphics related issue bug

Comments

@leonidaspir
Copy link
Contributor

leonidaspir commented May 26, 2021

A simple shader that calculates depth height on a plane, using the screen to world depth difference, produces visible banding on mobile.

Here is on desktop:

Screenshot 2021-05-26 104527

Here is on Android 10, Samsung Galaxy S10:

image

Here is on an 2020 iPad, iOS 14.3:

image

The shader code is pretty simple:

varying vec2 vUv0;
varying vec3 vPositionW;

void main() { 
    
    float waterDepth = getLinearDepth(vPositionW);
    float depth = getLinearScreenDepth();

    float depthDiff = clamp(pow(abs(waterDepth - depth) * 27.5 * 0.002, 0.5), 0.0, 1.0);

    gl_FragColor = vec4( vec3(depthDiff), depthDiff);
}

Project sample: https://playcanvas.com/editor/scene/1164740

It seems like a texel size / resolution issue, though we were unable to find the exact fix by overriding the internal screen depth chunk methods.

@mvaligursky
Copy link
Contributor

maybe it needs

#define GL2

@leonidaspir
Copy link
Contributor Author

maybe it needs

#define GL2

Added that to the top of the PS shader, but still the result is the same on mobile.

@mvaligursky
Copy link
Contributor

how about
precision highp float;
I suspect it might default to lowp if not specified

@leonidaspir
Copy link
Contributor Author

Added it but still the same. We thought it may be some precision issue, we even rendered to a render target on another example and messed with the texture formats to increase precision but still the same issue.

@yaustar yaustar added area: graphics Graphics related issue bug labels Jul 1, 2021
@mvaligursky
Copy link
Contributor

I tried the example on Google Pixel 3A, Android 11, and also iPhone XR on 14.5, and cannot see any banding there.

@leonidaspir
Copy link
Contributor Author

It seems to reproduce here on the following devices:

Samsung Galaxy S10, Android 10, Chrome

image

iPad 2020, iOS 14.2, Safari

image

@leonidaspir
Copy link
Contributor Author

leonidaspir commented Aug 21, 2021

So issue seems to persist, tested on the following devices:

  • iPhone XR, iOS 14 (WebGL 2.0 enabled)
  • iPad 2020, iOS 14 (WebGL 2.0 enabled)
  • Samsung Galaxy S10, Android 11

All produce the same result, interestingly when switching to WebGL 1.0 the issue is resolved. Any idea why the same shader produces a different output?

We are about to release an open alpha of our open world game, it would be great if we could solve this. On the same device/OS/browser, WebGL 1.0:

rn_image_picker_lib_temp_ee532064-3707-4f03-a366-155108ab5dc6

WebGL 2.0:

rn_image_picker_lib_temp_bf1d57fd-1ed4-4efb-998c-75d473929b94

@willeastcott
Copy link
Contributor

Presuambly there is a bug in the GL2 code path for getLinearScreenDepth:

https://github.com/playcanvas/engine/blob/master/src/graphics/program-lib/chunks/screenDepth.frag#L36

@willeastcott
Copy link
Contributor

Although then I would expect the bug to happen on desktop too under WebGL 2.

@leonidaspir
Copy link
Contributor Author

This may be related: mrdoob/three.js#18696

@leonidaspir
Copy link
Contributor Author

leonidaspir commented Aug 21, 2021

Although then I would expect the bug to happen on desktop too under WebGL 2.

Yeah, I thought so. Initially I thought something with the screen size may be the issue but I wasn't able to reproduce on desktop emulating mobile screen sizes ( pixel ratio > 1).

@willeastcott
Copy link
Contributor

I seem to be able to fix this by overriding the screenDepth.frag chunk and editing:

uniform sampler2D uDepthMap;

to:

uniform highp sampler2D uDepthMap;

@leonidaspir
Copy link
Contributor Author

Confirmed, that indeed fixes the issue. Many thanks @willeastcott for the find!

@leonidaspir
Copy link
Contributor Author

For anyone coming across this and until the fix is added to the engine, you can do the following before using the screenDepthPS shader chunk:

// --- fix precision of depth map on mobile
pc.shaderChunks.screenDepthPS = pc.shaderChunks.screenDepthPS.replace('uniform sampler2D uDepthMap', 'uniform highp sampler2D uDepthMap');

@willeastcott
Copy link
Contributor

The fix for this is now deployed so you can remove the workaround from your application code. 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: graphics Graphics related issue bug
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants