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

153 lines
4.3 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 UINT_MAX 0xFFFFFFFF
#define FLOAT_MAX 3.402823466e+38
#define BLOCKSIZE 16
#define NUMTHREADS BLOCKSIZE * BLOCKSIZE
2014-02-27 09:04:12 +01:00
#define MAXLIGHTS 1024
#define TEXTURESPREAD 1/255
// -- Shared Memory ------------------------------------------------- //
2014-02-27 09:04:12 +01:00
groupshared uint iMinDepth, iMaxDepth;
groupshared uint numVisiblePointLights,
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-02-27 09:04:12 +01:00
float2 UV = DTid.xy / (float2)Diffuse.Length.xy;
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);
2014-02-27 09:04:12 +01:00
float3 ViewPos = ToVpos(DTid.xy, UV);
if(GI==0)
{
numVisiblePointLights = 0;
iMinDepth = 0x7F7FFFFF;
iMaxDepth = 0;
}
GroupMemoryBarrierWithGroupSync();
// store and load shared minDepth and maxDepth
2014-02-27 09:04:12 +01:00
float minDepth = 0.0f, maxDepth = 0.0f;
{
2014-02-27 09:04:12 +01:00
InterlockedMin( iMinDepth, asuint(ViewPos.z) );
InterlockedMax( iMaxDepth, asuint(ViewPos.z) );
GroupMemoryBarrierWithGroupSync();
2014-02-27 09:04:12 +01:00
minDepth = asfloat(iMinDepth);
maxDepth = asfloat(iMaxDepth);
}
// -- Switching to LightCulling ------------------------------------- //
//define collision volume
2014-02-27 09:04:12 +01:00
float2 tilescale = float2(Diffuse.Length.xy) * rcp(float(2 * BLOCKSIZE));
float2 tilebias = tilescale - float2(Gid.xy);
// Now work out composite projection matrix
// Relevant matrix columns for this tile frusta
float4 c1 = float4(Proj._11 * tilescale.x, 0.0f, tilebias.x, 0.0f);
float4 c2 = float4(0.0f, -Proj._22 * tilescale.y, tilebias.y, 0.0f);
float4 c4 = float4(0.0f, 0.0f, 1.0f, 1.0f);
// Derive frustum planes
float4 frustumPlanes[6];
// Sides
frustumPlanes[0] = c4 - c1;
frustumPlanes[1] = c4 + c1;
frustumPlanes[2] = c4 - c2;
frustumPlanes[3] = c4 + c2;
// Near/far
frustumPlanes[4] = float4(0.0f, 0.0f, 1.0f, -minDepth);
frustumPlanes[5] = float4(0.0f, 0.0f, -1.0f, maxDepth);
// Normalize frustum planes (near/far already normalized)
[unroll]
for (uint i = 0; i < 4; ++i)
{
frustumPlanes[i] *= rcp(length(frustumPlanes[i].xyz));
}
// culling the tile's near and far to minDepth & maxDepth ( with tolerance )
2014-02-27 09:04:12 +01:00
for(uint lightIndex = GI; lightIndex < Lights; lightIndex += NUMTHREADS)
{
PointLight pl = Points[lightIndex];
bool inFrustrum = true;
2014-02-27 10:49:22 +01:00
[unroll]
for(int i = 0; i < 6; ++i)
{
float d = dot(frustumPlanes[i], float4(pl.Pos, 1.0f));
inFrustrum = inFrustrum && (d >= -pl.Radius);
}
2014-02-27 09:04:12 +01:00
[branch]
if(inFrustrum)
{
2014-02-27 09:04:12 +01:00
uint offset;
InterlockedAdd( numVisiblePointLights, 1, offset );
visiblePointlightIndex[offset] = lightIndex;
}
2014-02-27 09:04:12 +01:00
}
GroupMemoryBarrierWithGroupSync();
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
2014-02-27 09:04:12 +01:00
for(int i = 0; i < numVisiblePointLights; ++i)
{
2014-02-27 09:04:12 +01:00
DiffSpec light = LightCalc(Points[visiblePointlightIndex[i]], ViewPos, DTid.xy);
2014-01-08 07:01:59 +01:00
Shaded.Diffuse += light.Diffuse;
Shaded.Specular += light.Specular;
}
2014-02-27 09:04:12 +01:00
Diffuse[DTid.xy] = float4(Shaded.Diffuse * DiffuseGlow[DTid.xy].xyz,1);
2014-02-10 09:35:03 +01:00
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];
2014-02-27 09:04:12 +01:00
DepthBase += DepthTexture[DTid.xy + uint2(1,0)];
DepthBase += DepthTexture[DTid.xy + uint2(0,1)];
DepthBase += DepthTexture[DTid.xy + uint2(1,1)];
2014-02-19 13:38:36 +01:00
DepthBase = DepthBase /4;
2014-02-27 09:04:12 +01:00
Ambient[DTid.xy/2] = float4(DiffBase.xyz , AmbValue);
//Ambient[DTid.xy/2] = float4(DiffBase.xyz, 1);
Ambient[DTid.xy/2 + float2(Diffuse.Length.x/2, 0)] = GUI[DTid.xy];
Ambient[DTid.xy/2 + float2(0, Diffuse.Length.y/2)] = float4(DiffBase.xyz * DiffBase.w ,DiffBase.w);
2014-02-27 10:49:22 +01:00
//Ambient[DTid.xy/2 + Diffuse.Length.xy/2] = float4(numVisiblePointLights * (1.0f/Lights), 0, 0 ,1);
Ambient[DTid.xy/2 + Diffuse.Length.xy/2] = float4(NormalSpec[DTid.xy/2].xyz ,1);
}
2014-01-08 07:01:59 +01:00
}