Friday, September 9, 2022
HomeGame Developmentdirectx11 - Final gap artifact in display area refection with Hierarchical Z

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


After lot of efforts I’ve an virtually good shader doing SSR with HiZ. The shader is offered beneath. Some parameters are tunable and you’ll 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 will not be as excessive as anticipated for this scene however there’s some (130 FPS as an alternative of 110-120, 960×540).
Sadly there’s a final annoying drawback I used to be not in a position to clear up on this SSR HiZ shader. The issue is proven in inexperienced on the left image and on proper what I’ve with out HiZ. It’s annoying as a result of I didn’t have this drawback 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 accessible on web sites (this one was straightforward to implement and provides fantastic outcomes) I’ve decoupled the growing/reducing Mip degree components.
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. Lastly a refinement step is finished. Doing it this fashion avoids the only inc/dec mip whereas loop discovered elsewhere that I discovered not so quick enought for me on the finish. Additionally different codes are utilizing the idea of boundary cells and I had difficulties to grasp how they calculate the ray improve from these cells.

 //parameter for finer or coarser main whereas outcomes
 #outline offset0 0.02
 #outline offsetR 2
 //my preliminary decision (Mip=0)
 static const int2 Decision = {960, 540};
 //uv offset1 : crucial to make sure appropriate uv sampling. modulate the values greater 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 remaining dicotomic refinement
 #outline refinemax 3
 //parameter for eradicating vertical artifact for objects not on floor
 //primarily based on the conventional of the article
 #outline dot3falloff 0.00005

 float4 PS_PostDeferredReflex(PS_INPUTQUAD Enter) : SV_TARGET
 {
     float D = txDepth1.SampleLevel(samPoint, Enter.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, Enter.Tex, 0).a == 0)  return float4(0,0,0,0);
     //calculalate raydir in view area
     float3 PosV = float3(InvProj.x*(Enter.Tex.x*2-1),InvProj.y*(1-Enter.Tex.y*2), 1)/(InvProj.z*D+1);

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

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(Enter.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 line with longest x or y
     SSDir*=offset0;//modulate step dimension
     int Mip = 0;//you can begin at greater Mip degree however I do not see enhancements
     //additionally beginning with greater 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

main 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 = (Decision>>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 line with 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. bear 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 (purple/blue..) not lited. If femoved the highlight usually are not 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);
     }

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

- Advertisment -
Google search engine

Most Popular

Recent Comments