Danbias/Code/OysterGraphics/Shader/Passes/Light/LightPass.hlsl

126 lines
3.5 KiB
HLSL
Raw Normal View History

#include "Defines.hlsli"
#include "LightCalc.hlsli"
#include "PosManipulation.hlsli"
2014-01-08 07:01:59 +01:00
#include "SSAO.hlsli"
//todo
//LightCulling
2014-01-08 07:01:59 +01:00
//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 )
{
2014-01-28 13:48:15 +01:00
float2 UV = DTid.xy / Pixels;
2014-01-08 07:01:59 +01:00
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();
2014-01-08 07:01:59 +01:00
float3 ViewPos = ToVpos(DTid.xy, UV);
DiffSpec Shaded;
2014-01-28 13:48:15 +01:00
Shaded.Diffuse = float3(0,0,0);
Shaded.Specular = float3(0,0,0);
2014-01-08 07:01:59 +01:00
for(int i = 0; i < Lights; ++i)
{
DiffSpec light = LightCalc(Points[i], ViewPos, DTid.xy);
2014-01-08 07:01:59 +01:00
Shaded.Diffuse += light.Diffuse;
Shaded.Specular += light.Specular;
}
2014-02-10 09:35:03 +01:00
Diffuse[DTid.xy] = float4(Shaded.Diffuse * DiffuseGlow[DTid.xy].xyz,0);
Specular[DTid.xy] = float4(Shaded.Specular, 0);
2014-01-08 07:01:59 +01:00
2014-01-22 16:31:33 +01:00
if(DTid.x & 1 && DTid.y & 1 )
2014-01-08 07:01:59 +01:00
{
2014-01-22 16:31:33 +01:00
float AmbValue = GetSSAO(ViewPos, UV, DTid.xy, GTid.xy/2);
2014-02-17 09:03:53 +01:00
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;
2014-02-19 13:38:36 +01:00
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;
2014-02-17 09:03:53 +01:00
Ambient[DTid.xy/2] = float4(DiffBase.xyz, AmbValue);
2014-02-10 01:03:10 +01:00
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);
2014-02-19 13:38:36 +01:00
Ambient[DTid.xy/2 + Pixels/2] = float4(NormalSpec[DTid.xy].xyz * float3(1,1,-1),1);
}
2014-01-08 07:01:59 +01:00
}