126 lines
3.5 KiB
HLSL
126 lines
3.5 KiB
HLSL
#include "Defines.hlsli"
|
|
#include "LightCalc.hlsli"
|
|
#include "PosManipulation.hlsli"
|
|
#include "SSAO.hlsli"
|
|
//todo
|
|
//LightCulling
|
|
//Calc Diff + Spec Done
|
|
//Calc Ambience Done
|
|
//Write Glow
|
|
|
|
#define EXPAND 1024.0f
|
|
#define SHRINK 1.0f/EXPAND
|
|
#define UINT_MAX 0xFFFFFFFF
|
|
#define FLOAT_MAX 3.402823466e+38
|
|
#define BLOCKSIZE 16
|
|
#define NUMTHREADS BLOCKSIZE * BLOCKSIZE
|
|
#define MAXLIGHTS 100
|
|
|
|
|
|
// -- Shared Memory ------------------------------------------------- //
|
|
|
|
groupshared uint iMinDepth = UINT_MAX,
|
|
iMaxDepth = 0;
|
|
groupshared uint numVisiblePointLights = 0,
|
|
visiblePointlightIndex[MAXLIGHTS];
|
|
|
|
// ------------------------------------------------------------------ //
|
|
|
|
[numthreads(BLOCKSIZE, BLOCKSIZE, 1)]
|
|
void main( uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint3 Gid : SV_GroupID, uint GI : SV_GroupIndex )
|
|
{
|
|
float2 UV = DTid.xy / Pixels;
|
|
UV.x = UV.x * 2 - 1;
|
|
UV.y = 1 - 2 * UV.y;
|
|
|
|
float3 posN = float3(UV, DepthTexture[DTid.xy].x);
|
|
|
|
// store and load shared minDepth and maxDepth
|
|
float minDepth = 0.0f, maxDepth = 0.0f,
|
|
depth = posN.z;
|
|
{
|
|
uint uidepth = (uint)( depth * EXPAND);
|
|
InterlockedMin( iMinDepth, uidepth );
|
|
InterlockedMax( iMaxDepth, uidepth );
|
|
|
|
GroupMemoryBarrierWithGroupSync();
|
|
minDepth = (float)( iMinDepth ) * SHRINK;
|
|
maxDepth = (float)( iMaxDepth ) * SHRINK;
|
|
}
|
|
|
|
|
|
// -- Switching to LightCulling ------------------------------------- //
|
|
|
|
//define collision volume
|
|
float2 size = BLOCKSIZE / Pixels;
|
|
FrustrumPoints tile;
|
|
tile.v0 = float3(size * Gid,minDepth);
|
|
tile.v1 = float3(tile.v0.xy+size,maxDepth);
|
|
tile.v2 = float3(tile.v1.xy, minDepth);
|
|
tile.v3 = float3(tile.v0.x,tile.v1.y,minDepth);
|
|
tile.v4 = float3(tile.v1.x, tile.v0.y, minDepth);
|
|
tile.v5 = float3(tile.v0.xy, maxDepth);
|
|
|
|
|
|
|
|
// culling the tile's near and far to minDepth & maxDepth ( with tolerance )
|
|
|
|
|
|
uint numPass = (Lights + NUMTHREADS - 1) / NUMTHREADS;
|
|
numPass = min( numPass, MAXLIGHTS / NUMTHREADS );
|
|
|
|
for( uint passI = 0; passI < numPass; ++passI )
|
|
{
|
|
uint lightIndex = (passI * NUMTHREADS) + GI;
|
|
lightIndex = min( lightIndex, Lights );
|
|
|
|
if( lightIndex < Lights )
|
|
if( intersects(tile, lightIndex) )
|
|
{
|
|
uint offset;
|
|
InterlockedAdd( numVisiblePointLights, 1, offset );
|
|
visiblePointlightIndex[offset] = lightIndex;
|
|
}
|
|
}
|
|
|
|
GroupMemoryBarrierWithGroupSync();
|
|
|
|
|
|
|
|
float3 ViewPos = ToVpos(DTid.xy, UV);
|
|
DiffSpec Shaded;
|
|
Shaded.Diffuse = float3(0,0,0);
|
|
Shaded.Specular = float3(0,0,0);
|
|
|
|
for(int i = 0; i < Lights; ++i)
|
|
{
|
|
DiffSpec light = LightCalc(Points[i], ViewPos, DTid.xy);
|
|
Shaded.Diffuse += light.Diffuse;
|
|
Shaded.Specular += light.Specular;
|
|
}
|
|
|
|
Diffuse[DTid.xy] = float4(Shaded.Diffuse * DiffuseGlow[DTid.xy].xyz,0);
|
|
Specular[DTid.xy] = float4(Shaded.Specular, 0);
|
|
|
|
|
|
if(DTid.x & 1 && DTid.y & 1 )
|
|
{
|
|
float AmbValue = GetSSAO(ViewPos, UV, DTid.xy, GTid.xy/2);
|
|
float4 DiffBase = DiffuseGlow[DTid.xy];
|
|
DiffBase += DiffuseGlow[DTid.xy + uint2(1,0)];
|
|
DiffBase += DiffuseGlow[DTid.xy + uint2(0,1)];
|
|
DiffBase += DiffuseGlow[DTid.xy + uint2(1,1)];
|
|
DiffBase = DiffBase / 4;
|
|
|
|
float4 DepthBase = DepthTexture[DTid.xy];
|
|
DepthBase = DepthTexture[DTid.xy + uint2(1,0)];
|
|
DepthBase = DepthTexture[DTid.xy + uint2(0,1)];
|
|
DepthBase = DepthTexture[DTid.xy + uint2(1,1)];
|
|
DepthBase = DepthBase /4;
|
|
Ambient[DTid.xy/2] = float4(DiffBase.xyz, AmbValue);
|
|
Ambient[DTid.xy/2 + float2(Pixels.x/2, 0)] = GUI[DTid.xy];
|
|
Ambient[DTid.xy/2 + float2(0, Pixels.y/2)] = float4(DiffBase.xyz * DiffBase.w ,DiffBase.w);
|
|
Ambient[DTid.xy/2 + Pixels/2] = float4(NormalSpec[DTid.xy].xyz * float3(1,1,-1),1);
|
|
}
|
|
|
|
} |