Deferred pipeline sun shadows look broken on Android
Device: Samsung Galaxy s10 SM-G9730
Steps to Reproduce:
Enable deferred pipeline on android beta version
Observe sun shadows
Observed Results:
Shadows have visible flickering artefacts (see attached video)
Expected Results:
Shadows will look normal
Notes:
The frame captured with graphics debugger looks completely normal, artefacts only occur during gameplay on the device itself.
I tried fixing it by editing shader code, and this is the minimum set of edits that resolved the issue on my device (both edits are necessary for it to function properly, removing either causes artefacts to appear)
bool areCascadedShadowsEnabled(float mode) {
return round(mode) == 1.0; // Instead of int(mode) == 1
}
float GetShadowAmount(ShadowParameters params, DirectionalLightParams light, vec3 worldPos, float NdL, float viewDepth) {
vec4 projPos;
float amt = 1.0;
float cloudAmt = 1.0;
bool isSun = light.isSun > 0; // This has to be computed before GetShadowCascade() is called, otherwise artefacts occur. Storing just light.isSun and comparing it with 0 after GetShadowCascade() didn't fix the issue.
int cascade = GetShadowCascade(light, worldPos, projPos);
if (cascade != -1) {
float bias = params.shadowBias[light.index] + params.shadowSlopeBias[light.index] * clamp(tan(acos(NdL)), 0.0, 1.0);
projPos.z -= bias / projPos.w;
vec2 uv = vec2(projPos.x, projPos.y) * 0.5f + 0.5f;
amt = GetFilteredShadow(params, light.index, projPos.z, cascade, uv);
if (isSun && params.cloudshadowsEnabled > 0) { // Here use computed previously variable instead of direct light.isSun > 0 comparison.
cloudAmt = GetFilteredCloudShadow(params, worldPos, NdL);
if (cloudAmt < 1.0) {
cloudAmt = max(cloudAmt, 1.0 - params.cloudshadowContribution);
amt = min(amt, cloudAmt);
}
}
float shadowRange = params.shadowParams.y;
float shadowFade = smoothstep(max(0.0, shadowRange - 8.0), shadowRange, -viewDepth);
amt = mix(amt, 1.0, shadowFade);
}
return amt;
}
Linked issues
is duplicated by 7
Attachments
Comments 4
@magwar my device supports OGLES 3 and the game is running with that version, you can tell that because of ESSL_310 in the debug text and the graphics debugger showed "#version 310 es" in shader source. Video was captured on a flat world, but I tried making new flat worlds a few more times and got the same result. This bug appears to be quite common on android devices, I've seen a few examples of it from other people, I can ask them to provide device model and/or screenshots with debug information if this helps. I should also mention that I've gotten it working 2 or 3 times out of 20 or 30 that I tried joining a world, it seemed to happen randomly and on the next join it would break again.
It is helpful to know that at least sometimes deferred mode is working for you, it gives us clues as to what can fail here.
It would be great if you got these details from other affected users, thank you.
Added new images and videos from different devices to the report. Also, I tried editing shaders and I think I found a fix for this bug, at least it completely solved it for my device. Although I'm not sure if I can post material file here or include shader code snippets. Please let me know if and how I can post this information here.
Reply from @unknown:
Yes, you can include code snippets here. Simply edit the Description and paste a short code snippet into it, and/or provide a description of your edits. (You can delete this entire comment when you do that).
It looks like overloaded graphics card not loading certain textures. After briefly searching your device model on web I did not find it on this list: OpenGL ES - Wikipedia Your device needs to support OGLES 3, according to this article. Please ensure your graphics card/device can support Deferred mode.
If it does, have you tried to use deferred mode on a new, flat world?