|
|
|
|
|
|
|
|
|
|
#pragma kernel ScreenBoundsAABB |
|
|
|
|
|
|
|
#include "..\common\ShaderBase.h" |
|
|
|
#include "ShaderBase.h" |
|
|
|
#include "LightDefinitions.cs.hlsl" |
|
|
|
|
|
|
|
uniform int g_iNrVisibLights; |
|
|
|
|
|
|
void ScreenBoundsAABB(uint threadID : SV_GroupIndex, uint3 u3GroupID : SV_GroupID) |
|
|
|
{ |
|
|
|
uint groupID = u3GroupID.x; |
|
|
|
|
|
|
|
|
|
|
|
//uint vindex = groupID * NR_THREADS + threadID; |
|
|
|
unsigned int g = groupID; |
|
|
|
unsigned int t = threadID; |
|
|
|
|
|
|
const int sideIndex = (int) (t%8); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const float3 boxX = lgtDat.boxAxisX.xyz; |
|
|
|
const float3 boxY = lgtDat.boxAxisY.xyz; |
|
|
|
const float3 boxZ = -lgtDat.boxAxisZ.xyz; // flip axis (so it points away from the light direction for a spot-light) |
|
|
|
|
|
|
const unsigned int uFlag3 = GetClip(vP3); |
|
|
|
|
|
|
|
const float4 vPnts[] = {vP0, vP1, vP2, vP3}; |
|
|
|
|
|
|
|
|
|
|
|
// screen-space AABB of one quad (assuming no intersection) |
|
|
|
float3 vMin, vMax; |
|
|
|
for(int k=0; k<4; k++) |
|
|
|
|
|
|
fW = fS * (fWabs<FLT_EPSILON ? FLT_EPSILON : fWabs); |
|
|
|
float3 vP = float3(vPnts[k].x/fW, vPnts[k].y/fW, vPnts[k].z/fW); |
|
|
|
if(k==0) { vMin=vP; vMax=vP; } |
|
|
|
|
|
|
|
|
|
|
|
vMax = max(vMax, vP); vMin = min(vMin, vP); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
float3 vFaceMi = float3(posX[subLigt*MAX_PNTS*2 + sideIndex + 0], posY[subLigt*MAX_PNTS*2 + sideIndex + 0], posZ[subLigt*MAX_PNTS*2 + sideIndex + 0]); |
|
|
|
float3 vFaceMa = float3(posX[subLigt*MAX_PNTS*2 + sideIndex + 6], posY[subLigt*MAX_PNTS*2 + sideIndex + 6], posZ[subLigt*MAX_PNTS*2 + sideIndex + 6]); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vMax = max(vMax, vP); vMin = min(vMin, vP); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
else // :( need true clipping |
|
|
|
{ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 4 vertices to a quad of the convex hull in post projection space |
|
|
|
const float4 vP0 = mul(g_mProjection, float4(q0, 1)); |
|
|
|
const float4 vP1 = mul(g_mProjection, float4(q1, 1)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int iSrcIndex = 0; |
|
|
|
|
|
|
|
int offs = iSrcIndex*MAX_PNTS+subLigt*MAX_PNTS*2; |
|
|
|
|
|
|
for(int k=0; k<iNrSrcVerts; k++) |
|
|
|
{ |
|
|
|
float4 vCur = float4(posX[offs_src+k], posY[offs_src+k], posZ[offs_src+k], posW[offs_src+k]); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
////////////////////// look for camera frustum verts that need to be included. That is frustum vertices inside the convex hull for the light |
|
|
|
|
|
|
float3 vVertPSpace = float3((i&1)!=0 ? 1 : (-1), (i&2)!=0 ? 1 : (-1), (i&4)!=0 ? 1 : 0); |
|
|
|
|
|
|
|
|
|
|
|
float4 v4ViewSpace = mul(g_mInvProjection, float4(vVertPSpace,1)); |
|
|
|
float3 vViewSpace = float3(v4ViewSpace.x/v4ViewSpace.w, v4ViewSpace.y/v4ViewSpace.w, v4ViewSpace.z/v4ViewSpace.w); |
|
|
|
|
|
|
|
|
|
|
float3 vP = float3((i&1)!=0 ? 1 : (-1), (i&2)!=0 ? 1 : (-1), (i&4)!=0 ? 1 : 0); |
|
|
|
|
|
|
|
if(!bSetBoundYet) { vMin=vP; vMax=vP; bSetBoundYet=true; } |
|
|
|
|
|
|
|
|
|
|
|
vMax = max(vMax, vP); vMin = min(vMin, vP); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// determine AABB bound in [-1;1]x[-1;1] screen space using bounding sphere. |
|
|
|
// Use the result to make our already established AABB from the convex hull |
|
|
|
// potentially tighter. |
|
|
|
|
|
|
float2 vMi, vMa; |
|
|
|
bool2 bMi, bMa; |
|
|
|
CalcBound(bMi, bMa, vMi, vMa, g_mInvProjection, center, radius); |
|
|
|
|
|
|
|
|
|
|
|
vMin.xy = bMi ? max(vMin.xy, vMi) : vMin.xy; |
|
|
|
vMax.xy = bMa ? min(vMax.xy, vMa) : vMax.xy; |
|
|
|
} |
|
|
|
|
|
|
// to see if the light is occluded: vMin.z*VIEWPORT_SCALE_Z > MipTexelMaxDepth |
|
|
|
//g_vBoundsBuffer[lgtIndex+0] = float3(0.5*vMin.x+0.5, -0.5*vMax.y+0.5, vMin.z*VIEWPORT_SCALE_Z); |
|
|
|
//g_vBoundsBuffer[lgtIndex+g_iNrVisibLights] = float3(0.5*vMax.x+0.5, -0.5*vMin.y+0.5, vMax.z*VIEWPORT_SCALE_Z); |
|
|
|
|
|
|
|
|
|
|
|
// changed for unity |
|
|
|
g_vBoundsBuffer[lgtIndex+0] = float3(0.5*vMin.x+0.5, 0.5*vMin.y+0.5, vMin.z*VIEWPORT_SCALE_Z); |
|
|
|
g_vBoundsBuffer[lgtIndex+(int) g_iNrVisibLights] = float3(0.5*vMax.x+0.5, 0.5*vMax.y+0.5, vMax.z*VIEWPORT_SCALE_Z); |
|
|
|
|
|
|
++nrVertsDst; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if(bIsCurVisib) |
|
|
|
{ |
|
|
|
//assert(nrVertsDst<MAX_PNTS); |
|
|
|
|
|
|
const int index = ((uint) p)/2; |
|
|
|
float x1 = index==0 ? vVisib.x : (index==1 ? vVisib.y : vVisib.z); |
|
|
|
float x0 = index==0 ? vInvisib.x : (index==1 ? vInvisib.y : vInvisib.z); |
|
|
|
|
|
|
|
|
|
|
|
//fS*((vVisib.w-vInvisib.w)*t + vInvisib.w) = (x1-x0)*t + x0; |
|
|
|
|
|
|
|
const float fT = (fS*vInvisib.w-x0)/((x1-x0) - fS*(vVisib.w-vInvisib.w)); |
|
|
|
|
|
|
float4 planeY0 = TransformPlaneToPostSpace(InvProjection, float4(0, planeY.x, planeY.y, 0)); |
|
|
|
float4 planeY1 = TransformPlaneToPostSpace(InvProjection, float4(0, planeY.z, planeY.w, 0)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// convert planes to the forms (1,0,0,D) and (0,1,0,D) |
|
|
|
// 2D bound is given by -D components |
|
|
|
float2 A = -float2(planeX0.w / planeX0.x, planeY0.w / planeY0.y); |
|
|
|