Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma pack_matrix( row_major )
- #include "../LogDepth.fx"
- #define SM4
- cbuffer MainBuf
- {
- float4x4 ViewProj;
- float2 VPDims;
- float CamFar;
- float NumBounds;
- };
- struct BBox
- {
- float3 InstPos;
- float3 Extent;
- };
- StructuredBuffer<BBox> Buffer0;
- // Is Visible 1 (Visible) 0 (Culled)
- RWStructuredBuffer<float> BufferOut;
- Texture2D<float> HizMap,Hiz0;// : register(t1);
- SamplerState HizMapSampler;// : register(s0);
- //#define TEX_WIDTH 200
- //#define TEX_HEIGHT 150
- //#define CAM_MAX 1000
- //CAN BE GET AUTOMATICLY, GET DIMENSIONS!
- //but still need to try with array somehow!
- //new version of alghorytm :D lol
- void ToNDC(inout float2 v)
- {
- v.x*=0.5f;
- v.y*=-0.5f;
- v.x+=0.5f;
- v.y+=0.5f;
- }
- static const float LODS[10] = {512,256,128,64,32,16,8,4,2,1};
- [numthreads(1, 1, 1)]
- void CSMain( uint3 GroupId : SV_GroupID,
- uint3 DispatchThreadId : SV_DispatchThreadID,
- uint GroupIndex : SV_GroupIndex)
- {
- // Calculate the actual index this thread in this group will be reading from.
- //int index = GroupIndex + (GroupId.x * NUM_THREADS_X);
- int index = DispatchThreadId.x;
- // Bounding sphere center (XYZ) and radius (W), world space
- BBox EntBox = Buffer0[index];
- float3 InstPos=EntBox.InstPos;
- float3 Extent=EntBox.Extent;
- float4 BoundingBox[8];
- BoundingBox[0] = float4( InstPos + float3( Extent.x, Extent.y, Extent.z), 1.0 );
- BoundingBox[1] = float4( InstPos + float3(-Extent.x, Extent.y, Extent.z), 1.0 );
- BoundingBox[2] = float4( InstPos + float3( Extent.x,-Extent.y, Extent.z), 1.0 );
- BoundingBox[3] = float4( InstPos + float3(-Extent.x,-Extent.y, Extent.z), 1.0 );
- BoundingBox[4] = float4( InstPos + float3( Extent.x, Extent.y,-Extent.z), 1.0 );
- BoundingBox[5] = float4( InstPos + float3(-Extent.x, Extent.y,-Extent.z), 1.0 );
- BoundingBox[6] = float4( InstPos + float3( Extent.x,-Extent.y,-Extent.z), 1.0 );
- BoundingBox[7] = float4( InstPos + float3(-Extent.x,-Extent.y,-Extent.z), 1.0 );
- /* check how the bounding box resides regarding to the view frustum */
- int outOfBound[6] = { 0, 0, 0, 0, 0, 0 };
- int i;
- for (i=0; i<8; i++)
- {
- BoundingBox[i]=mul(BoundingBox[i],ViewProj);
- if ( BoundingBox[i].x > BoundingBox[i].w ) outOfBound[0]++;
- if ( BoundingBox[i].x < -BoundingBox[i].w ) outOfBound[1]++;
- if ( BoundingBox[i].y > BoundingBox[i].w ) outOfBound[2]++;
- if ( BoundingBox[i].y < -BoundingBox[i].w ) outOfBound[3]++;
- if ( BoundingBox[i].z > BoundingBox[i].w ) outOfBound[4]++;
- if ( BoundingBox[i].z < -BoundingBox[i].w ) outOfBound[5]++;
- }
- int inFrustum = 1;
- for (i=0; i<6; i++)
- if ( outOfBound[i] == 8 ) inFrustum = 0;
- // float test=BufferOut[NumBounds];
- [branch]
- if(inFrustum==1)
- {
- /* perform perspective division for the bounding box */
- [unroll(8)]for (int i=0; i<8; i++)
- {
- BoundingBox[i].xy /= BoundingBox[i].w;
- BoundingBox[i].z/=CamFar;
- }
- float InstanceDepth = min( min( min( BoundingBox[0].z, BoundingBox[1].z ),
- min( BoundingBox[2].z, BoundingBox[3].z ) ),
- min( min( BoundingBox[4].z, BoundingBox[5].z ),
- min( BoundingBox[6].z, BoundingBox[7].z ) ) );
- //fast check goes here somehow :D
- [branch]
- if(InstanceDepth>HizMap.Load( int3(0,0,9) ))
- {
- BufferOut[index]=-2;
- }
- else
- {
- float2 BoundingRect[2];
- BoundingRect[0].x = min( min( min( BoundingBox[0].x, BoundingBox[1].x ),
- min( BoundingBox[2].x, BoundingBox[3].x ) ),
- min( min( BoundingBox[4].x, BoundingBox[5].x ),
- min( BoundingBox[6].x, BoundingBox[7].x ) ) );
- BoundingRect[0].y = min( min( min( BoundingBox[0].y, BoundingBox[1].y ),
- min( BoundingBox[2].y, BoundingBox[3].y ) ),
- min( min( BoundingBox[4].y, BoundingBox[5].y ),
- min( BoundingBox[6].y, BoundingBox[7].y ) ) );
- BoundingRect[1].x = max( max( max( BoundingBox[0].x, BoundingBox[1].x ),
- max( BoundingBox[2].x, BoundingBox[3].x ) ),
- max( max( BoundingBox[4].x, BoundingBox[5].x ),
- max( BoundingBox[6].x, BoundingBox[7].x ) ) );
- BoundingRect[1].y = max( max( max( BoundingBox[0].y, BoundingBox[1].y ),
- max( BoundingBox[2].y, BoundingBox[3].y ) ),
- max( max( BoundingBox[4].y, BoundingBox[5].y ),
- max( BoundingBox[6].y, BoundingBox[7].y ) ) );
- //convert bounding rect to ndc
- [unroll(2)]for(i=0;i<2;i++)
- {
- ToNDC(BoundingRect[i]);
- BoundingRect[i]=clamp(BoundingRect[i],0,1);
- }
- float2 fBoundSize;
- fBoundSize.x=BoundingRect[1].x-BoundingRect[0].x;
- fBoundSize.y=BoundingRect[1].y-BoundingRect[0].y;
- #define MAXX 512
- #define MAXY 512
- fBoundSize.x*=MAXX;
- fBoundSize.y*=MAXY;
- int fLOD = 7;//(int)ceil(log2( max(fBoundSize.x,fBoundSize.y)*0.25f ));
- fLOD=min(fLOD,8);
- fLOD=max(fLOD,1);
- float2 TexSize=float2(LODS[fLOD],LODS[fLOD]);
- //convert to texture space(here's catch we must multiply by size array
- [unroll(2)]for(int i=0;i<2;i++)
- {
- //float2 &brect=BoundingRect[i];
- //brect.x*=curVp.Width;
- //brect.y*=curVp.Height;
- BoundingRect[i]*=TexSize;
- }
- int2 SSMin,SSMax;
- SSMin.x=round( min(BoundingRect[0].x,BoundingRect[1].x) );
- SSMin.y=round( min(BoundingRect[0].y,BoundingRect[1].y) );
- SSMax.x=round( max(BoundingRect[0].x,BoundingRect[1].x) );
- SSMax.y=round( max(BoundingRect[0].y,BoundingRect[1].y) );
- float2 BoundSize;
- BoundSize.x=SSMax.x-SSMin.x;
- BoundSize.y=SSMax.y-SSMin.y;
- //[branch]
- if((BoundSize.x>MAXX/2) || (BoundSize.y>MAXY/2))//many pixels[something extra big]
- {
- BufferOut[index]=2;
- }
- else if((BoundSize.x<=0) || (BoundSize.y<=0))//bad case
- {
- BufferOut[index]=3;
- }
- else
- {
- int x,y;
- int incX=1;
- int incY=1;
- bool AllBad=false;
- for(y=SSMin.y;y<SSMax.y && !AllBad;y+=incY)
- {
- for(x=SSMin.x;x<SSMax.x && !AllBad;x+=incX)
- {
- if(InstanceDepth<HizMap.Load(uint3(x,y,fLOD)))
- {
- AllBad=true;
- break;
- }
- }
- }
- BufferOut[index]=AllBad?1:0;
- }
- }//fast cull brace
- }
- else
- {
- BufferOut[index]=-1;
- }
- }
- technique10 Render
- {
- pass P0
- {
- SetVertexShader( 0 );
- SetGeometryShader( 0 );
- SetPixelShader( 0 );
- SetComputeShader( CompileShader( cs_4_0, CSMain() ) );
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement