Announcement

Collapse
No announcement yet.

Dynamic shadows artifacts

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    I replaced Sobol with simple spiral sampling. With per pixel rotation matrix premultiplied to PCFUVMATRIX. It's not as good looking yet but it's saves 300 assembly lines. This makes me wonder is sobol random worth it. With unrolled loop it's easy to precalculate sampling points. Same optimization can be done to blocker search too. Need more testing.
    Code:
        PCFUVMatrix = mul(float2x2(FilterRadius, 0, 0, FilterRadius), PCFUVMatrix);
        float RandAngle = 2.0f * PI * frac(7.1721f * Settings.SvPosition.x + 11.131f * Settings.SvPosition.y + View.StateFrameIndexMod8 * 0.125f);
        PCFUVMatrix = mul(float2x2(cos(RandAngle), -sin(RandAngle), sin(RandAngle), cos(RandAngle)), PCFUVMatrix);
        UNROLL
        for (int j = 0; j < PCSS_SAMPLES; j++)
        {
            float angle = j * PI * 4.71f;
            float2 PCFSample = float2(sin(angle), cos(angle)) * sqrt(float(j+1) * (1.0f / float(PCSS_SAMPLES)));
            //float2 PCFSample = RandToCircle(SobolIndex(SobolRandom, j << 3, PCSS_SAMPLE_BITS + 3));
            float2 SampleUVOffset = mul(PCFUVMatrix, PCFSample);
            float2 SampleUV = ShadowPosition + SampleUVOffset * Settings.ShadowTileOffsetAndSize.zw;
    
            float SampleDepthBias = max(dot(DepthBiasDotFactors, SampleUVOffset), 0);        
    
            #if FEATURE_GATHER4
                float4 SampleDepth = Settings.ShadowDepthTexture.Gather(Settings.ShadowDepthTextureSampler, SampleUV);
                VisibleLightAccumulation += dot(0.25, saturate(SampleDepth * Settings.TransitionScale + (Settings.TransitionScale * SampleDepthBias + ScaledAndBiasedDepth)));
            #else
                float SampleDepth = Texture2DSampleLevel(Settings.ShadowDepthTexture, Settings.ShadowDepthTextureSampler, SampleUV, 0).r;
                VisibleLightAccumulation += saturate(SampleDepth * Settings.TransitionScale + (Settings.TransitionScale * SampleDepthBias + ScaledAndBiasedDepth));
            #endif
        }

    Comment


      Ditching Sobol reduced ShadowProjection time from 4.04ms to 2.60ms.

      Comment


        when will this be in an official build?

        Comment


          Originally posted by Kalle_H View Post
          Ditching Sobol reduced ShadowProjection time from 4.04ms to 2.60ms.
          Are the visual improvements of Sobol worh the ~1.44ms?

          Comment


            Originally posted by DamirH View Post

            Are the visual improvements of Sobol worh the ~1.44ms?
            Very unlikely. Spiral in some cases gives bit nicer self shadow. Both are quite good methods to do sampling. Sobol just isn't free.

            Comment


              Code:
                  // PCF loop.
                  float VisibleLightAccumulation = 0;
                  float ScaledAndBiasedDepth = -Settings.SceneDepth * Settings.TransitionScale + 1.f;
              
                  float RandAngle = 2.0f * PI * frac(0.625 * Settings.SvPosition.x + 0.625 * Settings.SvPosition.y + View.StateFrameIndexMod8 * 0.625f);
                  float radius = View.StateFrameIndexMod8 % 2 == 0 ? FilterRadius : -FilterRadius;
                  PCFUVMatrix = mul(mul(float2x2(radius, 0, 0, radius), float2x2(cos(RandAngle), -sin(RandAngle), sin(RandAngle), cos(RandAngle))), PCFUVMatrix);
                  UNROLL
                  for (int j = 0; j < PCSS_SAMPLES; j++)
                  {
                      float angle = j * PI * 2.0f * 0.4171;
                      float2 PCFSample = float2(sin(angle), cos(angle)) * sqrt(float(j) * (1.0f / float(PCSS_SAMPLES)));
                      //float2 PCFSample = RandToCircle(SobolIndex(SobolRandom, j << 3, PCSS_SAMPLE_BITS + 3));
                      float2 SampleUVOffset = mul(PCFUVMatrix, PCFSample);
                      float2 SampleUV = ShadowPosition + SampleUVOffset * Settings.ShadowTileOffsetAndSize.zw;
              
                      float SampleDepthBias = max(dot(DepthBiasDotFactors, SampleUVOffset), 0);        
              
                      #if FEATURE_GATHER4
                          float4 SampleDepth = Settings.ShadowDepthTexture.Gather(Settings.ShadowDepthTextureSampler, SampleUV);
                          VisibleLightAccumulation += dot(0.25, saturate(SampleDepth * Settings.TransitionScale + (Settings.TransitionScale * SampleDepthBias + ScaledAndBiasedDepth)));
                      #else
                          float SampleDepth = Texture2DSampleLevel(Settings.ShadowDepthTexture, Settings.ShadowDepthTextureSampler, SampleUV, 0).r;
                          VisibleLightAccumulation += saturate(SampleDepth * Settings.TransitionScale + (Settings.TransitionScale * SampleDepthBias + ScaledAndBiasedDepth));
                      #endif
                  }
              
                  float Visibility = VisibleLightAccumulation * (1.0f / float(PCSS_SAMPLES));
              This is the final form on spiral tapping. Every pixel is rotated peusdo randomly and samples are mirrored every other frame. Spiral offsets are precalculated and then rotated, scaled and mirrored with 2x2 matrix. So this method has no per sample overhead at all.

              Comment


                Would love to see some comparisons.

                Comment


                  Originally posted by ZacD View Post
                  Would love to see some comparisons.
                  Here you go.

                  Sobol:
                  Click image for larger version

Name:	Sobol.jpg
Views:	93
Size:	270.6 KB
ID:	1434926
                  Spiral:

                  ​​​​​​​Click image for larger version

Name:	Spiral.jpg
Views:	105
Size:	272.8 KB
ID:	1434927

                  Comment


                    Looks nearly identical! No player will know how it was before...

                    Comment


                      Indeed, if you didn't have the images side by side you wouldn't be able to tell the difference. Is the difference more obvious in other scenarios maybe?

                      Comment


                        Finally back at office. Profiled scene before and after softshadow optimizations with GTX 1080Ti. Single directional light with two cascades ShadowProjection time went from 1.51ms to 0.47ms. Non soft shadows cost would be 0.18ms.

                        Comment


                          I just hope they implement when you PR...
                          Some times it's annoying the long wait when someone PR changes to renderer just to be said "no".
                          | Savior | USQLite | FSM | Object Pool | Sound Occlusion | Property Transfer | Magic Nodes | MORE |

                          Comment


                            Originally posted by BrUnO XaVIeR View Post
                            I just hope they implement when you PR...
                            Some times it's annoying the long wait when someone PR changes to renderer just to be said "no".
                            Yes, this one as an example: https://forums.unrealengine.com/deve...-aa-sharpening
                            Nilson Lima
                            Technical Director @ Rigel Studios Ltda - twitter: @RigelStudios
                            Join us at Discord: https://discord.gg/FUwTvzr

                            UE4 Marketplace: Cloudscape Seasons
                            supporting: Community FREE Ocean plugin

                            Comment


                              Well I think this is a bigger and more advantageous change than TAA sharpening.

                              Comment


                                The PR for TAA sharpening kinda conflicts with Epic's perspective and intentions with TAA, Plus Epic was working on Temporal AA upsampling and dynamic resolution.

                                Comment

                                Working...
                                X