Home Game Development directx11 – Last gap artifact in display area refection with Hierarchical Z

directx11 – Last gap artifact in display area refection with Hierarchical Z

0
directx11 – Last gap artifact in display area refection with Hierarchical Z

[ad_1]

After lot of efforts I’ve an virtually good shader doing SSR with HiZ. The shader is supplied beneath. Some parameters are tunable and you may velocity up issues however the issue in my scene (image) are the spheres that restrict the coarsiness of the ray marching. So the advantage of HiZ just isn’t as excessive as anticipated for this scene however there’s some (130 FPS as a substitute of 110-120, 960×540).
Unfortunately there’s a final annoying downside I used to be not in a position to remedy on this SSR HiZ shader. The downside is proven in inexperienced on the left image and on proper what I’ve with out HiZ. It is annoying as a result of I didn’t have this downside with my common SSR shader whitout HiZ.
I’ve tried a thickness check like within the McGuirre methodology however it isn’t working.

 e.g : if abs ( ray.z-zbuff)< thickness.

enter image description here

So if somebody will help beneath is my shader. get pleasure from when you’re .

In distinction to different codes obtainable on web sites (this one was simple to implement and provides superb outcomes) I’ve decoupled the growing/reducing Mip degree elements.
A primary whereas advances the ray with growing Mip and raystep till ray.z>zbuff.
Then ranging from the final place the place ray.z<zbuff a second loop works with solely Mip=0. Finally a refinement step is completed. Doing it this manner avoids the one inc/dec mip whereas loop discovered elsewhere that I discovered not so quick enought for me on the finish. Also different codes are utilizing the idea of boundary cells and I had difficulties to know how they calculate the ray enhance from these cells.

 //parameter for finer or coarser major whereas outcomes
 #outline offset0 0.02
 #outline offsetR 2
 //my preliminary decision (Mip=0)
 static const int2 Resolution = {960, 540};
 //uv offset1 : crucial to make sure appropriate uv sampling. modulate the values larger than 1 to see impact
 static const float2 offset1 = {1, 1.035};
 //parameter for finer or coarser secondary whereas outcomes
 #outline offset2  1.15
 //parameter for ultimate dicotomic refinement
 #outline refinemax 3
 //parameter for eradicating vertical artifact for objects not on floor
 //primarily based on the traditional of the thing
 #outline dot3falloff 0.00005

 float4 PS_PostDeferredReflex(PS_INPUTQUAD Input) : SV_TARGET
 {
     float D = txDepth1.SampleLevel(samPoint, Input.Tex, 0).r;
     if ( D == 1 ) return float4(0,0,0,0);
     //solely the bottom mesh is alpha=1 to obtain reflections
     if ( txDiffuse1.SampleLevel(samPoint, Input.Tex, 0).a == 0)  return float4(0,0,0,0);
     //calculalate raydir in view area
     float3 PosV = float3(InvProj.x*(Input.Tex.x*2-1),InvProj.y*(1-Input.Tex.y*2), 1)/(InvProj.z*D+1);

     float3 VSDir = normalize(mirror(normalize(PosV.xyz),txNormal1.SampleLevel(samPoint, Input.Tex, 0).rgb*2-1));    
     if ( VSDir.z < 0 ) return float4(0,0,0,0);//filter off ray in the direction of digital camera

the ray dir initilization methodology in display area comes from right here

     float4 SSEnd = mul(float4(PosV + VSDir*200, 1), Proj);
     SSEnd/= SSEnd.w;
     SSEnd.xy = SSEnd.xy*float2(0.5,-0.5)+float2(0.5,0.5); 
     float3 SSray = float3(Input.Tex, D);
     float3 SSDir = normalize(SSEnd.xyz-SSray);
     float dSS;
     if ( abs(SSDir.x) < abs(SSDir.y) ) dSS = abs(SSDir.y); else dSS = abs(SSDir.x);
     SSDir/=dSS;//"normalize" SSDir in response to longest x or y
     SSDir*=offset0;//modulate step dimension
     int Mip = 0;//you can begin at larger Mip degree however I do not see enhancements
     //additionally beginning with larger Mip degree produces a lack of reflection on the backside display 
     float ZBufferVal;
     float2 CurResol;
     float3 curSSDir = SSDir*pow(2,Mip)*offsetR;//pow ineffective at Mip=0

major whereas : transfer ray with Mip-dependant growing steps till ray.z > zbuffer

     whereas (Mip<10)//my decision corresponds to 10 miplevel
     {
             //utilizing the offset1 guarantee appropriate uv sampling. take away to see what i imply
             //use Load as beneath or SampleLevel
             //CurResol = (Resolution>>Mip)*SSray.xy*offset1;
             //ZBufferVal = txDepth1.Load(int3(CurResol, Mip)).r;
             ZBufferVal = txDepth1.SampleLevel(samPoint, SSray.xy*offset1, Mip).r; //or use Load as above
             if ( ZBufferVal==0 ) ZBufferVal=1; //keep away from disappearing reflexions at backside display
             if (SSray.z > ZBufferVal) break;
             SSray += curSSDir;
             if ( Mip <10 ) 
             {
                 Mip++;
                 curSSDir*=2;
             }
    }
    if (SSray.z>=1) return float4(0,0,0,0);

secondary whereas : transfer ray from final place (z<zbuffer) now solely at degree Mip = 0 till ray.z > zbuffer

         float3 poslast = SSray;
         SSDir*=offset2;
         whereas (ZBufferVal!=0)//in any other case you need to be outbound in response to DX specs
         {
             SSray += SSDir;
             ZBufferVal = txDepth1.SampleLevel(samPoint, SSray.xy, 0).r;    
             if (SSray.z > ZBufferVal) break;
             poslast = SSray;
         }

refinement step

         float3 MinRay = poslast;
         float3 MaxRay = SSray;
         for(int j = 0; j < refinemax; j++)
         {
             poslast = (MinRay+MaxRay)*0.5f;
             ZBufferVal = txDepth1.SampleLevel(samPoint, poslast.xy, 0).r;
             if ( poslast.z > ZBufferVal) MaxRay = poslast; else MinRay = poslast;
         }

some alpha checking earlier than returning the colour. keep in mind D is the depth at begin

         float3 N = txNormal1.SampleLevel(samPoint, poslast.xy,0).rgb*2-1;
         //N.x+N.y+N.z>2.99f is for the spot lights (crimson/blue..) not lited. If femoved the highlight will not be mirrored
         float Dot3 = ( N.x+N.y+N.z>2.99f)?dot3falloff:(dot(-VSDir, N)<0)?0:dot3falloff;
         if (abs(poslast.z-ZBufferVal)<Dot3) 
             return float4(txDiffuse1.SampleLevel(samPoint, poslast.xy, 0).rgb, 1-abs(poslast.z-D)*500);
         return float4(0,0,0,0);
     }

[ad_2]

LEAVE A REPLY

Please enter your comment!
Please enter your name here