浏览代码

remove some code duplication for sphere vs. tile overlap

remove some code duplication for sphere vs. tile overlap
/main
mmikk 8 年前
当前提交
5802bde9
共有 4 个文件被更改,包括 38 次插入80 次删除
  1. 29
      Assets/ScriptableRenderLoop/fptl/LightingConvexHullUtils.hlsl
  2. 32
      Assets/ScriptableRenderLoop/fptl/lightlistbuild-bigtile.compute
  3. 27
      Assets/ScriptableRenderLoop/fptl/lightlistbuild-clustered.compute
  4. 30
      Assets/ScriptableRenderLoop/fptl/lightlistbuild.compute

29
Assets/ScriptableRenderLoop/fptl/LightingConvexHullUtils.hlsl


return float4(vN, -dot(vN,p0));
}
bool DoesSphereOverlapTile(float3 dir, float halfTileSizeAtZDistOne, float3 sphCen, float sphRadiusIn)
{
float3 V = dir; // ray direction down center of tile (does not need to be normalized).
#if 1
float3 maxZdir = float3(-sphCen.z*sphCen.x, -sphCen.z*sphCen.y, sphCen.x*sphCen.x + sphCen.y*sphCen.y); // cross(sphCen,cross(Zaxis,sphCen))
float len = length(maxZdir);
float scalarProj = len>0.0001 ? (maxZdir.z/len) : len; // since len>=(maxZdir.z/len) we can use len as an approximate value when len<=epsilon
float offs = scalarProj*sphRadiusIn;
#else
float offs = sphRadiusIn; // more false positives due to larger radius but works too
#endif
// enlarge sphere so it overlaps the center of the tile assuming it overlaps the tile to begin with.
#ifdef LEFT_HAND_COORDINATES
float sphRadius = sphRadiusIn + (sphCen.z+offs)*halfTileSizeAtZDistOne;
#else
float sphRadius = sphRadiusIn - (sphCen.z-offs)*halfTileSizeAtZDistOne;
#endif
float a = dot(V,V);
float CdotV = dot(sphCen,V);
float c = dot(sphCen,sphCen) - sphRadius*sphRadius;
float fDescDivFour = CdotV*CdotV - a*c;
return c<0 || (fDescDivFour>0 && CdotV>0); // if ray hits bounding sphere
}
#endif

32
Assets/ScriptableRenderLoop/fptl/lightlistbuild-bigtile.compute


}
}
#ifdef PERFORM_SPHERICAL_INTERSECTION_TESTS
void SphericalIntersectionTests(uint threadID, int iNrCoarseLights, float2 screenCoordinate)
{

#endif
float onePixDiagDist = GetOnePixDiagWorldDistAtDepthOne();
float worldDistAtDepthOne = 32*onePixDiagDist; // scale by half a tile
float halfTileSizeAtZDistOne = 32*onePixDiagDist; // scale by half a tile
int iNrVisib = 0;
const float3 center = lgtDat.center.xyz;
float fRad = lgtDat.radius;
#if 1
float3 maxZdir = float3(-center.z*center.x, -center.z*center.y, center.x*center.x + center.y*center.y); // cross(center,cross(Zaxis,center))
float len = length(maxZdir);
float scalarProj = len>0.0001 ? (maxZdir.z/len) : len; // since len>=(maxZdir.z/len) we can use len as an approximate value when len<=epsilon
float fOffs = scalarProj*fRad;
#else
float fOffs = fRad; // more false positives due to larger radius but works too
#endif
#ifdef LEFT_HAND_COORDINATES
fRad = fRad + (center.z+fOffs)*worldDistAtDepthOne;
#else
fRad = fRad - (center.z-fOffs)*worldDistAtDepthOne;
#endif
float a = dot(V,V);
float CdotV = dot(center,V);
float c = dot(center,center) - fRad*fRad;
float fDescDivFour = CdotV*CdotV - a*c;
if(!(c<0 || (fDescDivFour>0 && CdotV>0))) // if ray misses bounding sphere
if( !DoesSphereOverlapTile(V, halfTileSizeAtZDistOne, lgtDat.center.xyz, lgtDat.radius) )
lightsListLDS[l]=0xffffffff;
}

27
Assets/ScriptableRenderLoop/fptl/lightlistbuild-clustered.compute


#endif
float onePixDiagDist = GetOnePixDiagWorldDistAtDepthOne();
float worldDistAtDepthOne = 8*onePixDiagDist; // scale by half a tile
float halfTileSizeAtZDistOne = 8*onePixDiagDist; // scale by half a tile
int iNrVisib = 0;

const float3 center = lgtDat.center.xyz;
float fRad = lgtDat.radius;
#if 1
float3 maxZdir = float3(-center.z*center.x, -center.z*center.y, center.x*center.x + center.y*center.y); // cross(center,cross(Zaxis,center))
float len = length(maxZdir);
float scalarProj = len>0.0001 ? (maxZdir.z/len) : len; // since len>=(maxZdir.z/len) we can use len as an approximate value when len<=epsilon
float fOffs = scalarProj*fRad;
#else
float fOffs = fRad; // more false positives due to larger radius but works too
#endif
#ifdef LEFT_HAND_COORDINATES
fRad = fRad + (center.z+fOffs)*worldDistAtDepthOne;
#else
fRad = fRad - (center.z-fOffs)*worldDistAtDepthOne;
#endif
float a = dot(V,V);
float CdotV = dot(center,V);
float c = dot(center,center) - fRad*fRad;
float fDescDivFour = CdotV*CdotV - a*c;
if(!(c<0 || (fDescDivFour>0 && CdotV>0))) // if ray misses bounding sphere
if( !DoesSphereOverlapTile(V, halfTileSizeAtZDistOne, lgtDat.center.xyz, lgtDat.radius) )
coarseList[l]=0xffffffff;
}

30
Assets/ScriptableRenderLoop/fptl/lightlistbuild.compute


#include "..\common\ShaderBase.h"
#include "LightDefinitions.cs.hlsl"
#include "LightingConvexHullUtils.hlsl"
#define FINE_PRUNING_ENABLED
#define PERFORM_SPHERICAL_INTERSECTION_TESTS

#endif
float onePixDiagDist = GetOnePixDiagWorldDistAtDepthOne();
float worldDistAtDepthOne = 8*onePixDiagDist; // scale by half a tile
float halfTileSizeAtZDistOne = 8*onePixDiagDist; // scale by half a tile
int iNrVisib = 0;

const float3 center = lightData.center.xyz;
float fRad = lightData.radius;
#if 1
float3 maxZdir = float3(-center.z*center.x, -center.z*center.y, center.x*center.x + center.y*center.y); // cross(center,cross(Zaxis,center))
float len = length(maxZdir);
float scalarProj = len>0.0001 ? (maxZdir.z/len) : len; // since len>=(maxZdir.z/len) we can use len as an approximate value when len<=epsilon
float fOffs = scalarProj*fRad;
#else
float fOffs = fRad; // more false positives due to larger radius but works too
#endif
#ifdef LEFT_HAND_COORDINATES
fRad = fRad + (center.z+fOffs)*worldDistAtDepthOne;
#else
fRad = fRad - (center.z-fOffs)*worldDistAtDepthOne;
#endif
float a = dot(V,V);
float CdotV = dot(center,V);
float c = dot(center,center) - fRad*fRad;
float fDescDivFour = CdotV*CdotV - a*c;
if(c<0 || (fDescDivFour>0 && CdotV>0)) // if ray hit bounding sphere
if( DoesSphereOverlapTile(V, halfTileSizeAtZDistOne, lightData.center.xyz, lightData.radius) )
{
unsigned int uIndex;
InterlockedAdd(lightOffsSph, 1, uIndex);

正在加载...
取消
保存