Uploaded image for project: 'Minecraft (Bedrock codebase)'
  1. Minecraft (Bedrock codebase)
  2. MCPE-173922

Flickering shadow artefacts on Android deferred pipeline

XMLWordPrintable

    • Confirmed
    • Android
    • 1093262

      Deferred pipeline sun shadows look broken on Android
      Device: Samsung Galaxy s10 SM-G9730

      Steps to Reproduce:

      1. Enable deferred pipeline on android beta version
      2. 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;
      } 

            Veka0 Veka0
            Votes:
            30 Vote for this issue
            Watchers:
            6 Start watching this issue

              Created:
              Updated:
              Resolved:
              CHK: