浏览代码

support orthographic projection in tiled lighting (fptl renderloop only atm)

support orthographic projection in tiled lighting (fptl renderloop only
atm)
/RenderPassXR_Sandbox
mmikk 7 年前
当前提交
e314c854
共有 7 个文件被更改,包括 92 次插入33 次删除
  1. 11
      Assets/ScriptableRenderPipeline/Fptl/FptlLighting.cs
  2. 10
      Assets/ScriptableRenderPipeline/Fptl/LightingConvexHullUtils.hlsl
  3. 24
      Assets/ScriptableRenderPipeline/Fptl/LightingUtils.hlsl
  4. 26
      Assets/ScriptableRenderPipeline/Fptl/lightlistbuild-bigtile.compute
  5. 26
      Assets/ScriptableRenderPipeline/Fptl/lightlistbuild-clustered.compute
  6. 17
      Assets/ScriptableRenderPipeline/Fptl/lightlistbuild.compute
  7. 11
      Assets/ScriptableRenderPipeline/Fptl/scrbound.compute

11
Assets/ScriptableRenderPipeline/Fptl/FptlLighting.cs


cmd.SetComputeBufferParam(buildPerVoxelLightListShader, s_ClearVoxelAtomicKernel, "g_LayeredSingleIdxBuffer", s_GlobalLightListAtomic);
cmd.DispatchCompute(buildPerVoxelLightListShader, s_ClearVoxelAtomicKernel, 1, 1, 1);
bool isOrthographic = camera.orthographic;
cmd.SetComputeIntParam(buildPerVoxelLightListShader, "g_isOrthographic", isOrthographic ? 1 : 0);
cmd.SetComputeIntParam(buildPerVoxelLightListShader, "g_iNrVisibLights", numLights);
cmd.SetComputeMatrixParam(buildPerVoxelLightListShader, "g_mScrProjection", projscr);
cmd.SetComputeMatrixParam(buildPerVoxelLightListShader, "g_mInvScrProjection", invProjscr);

var cmd = CommandBufferPool.Get("Build light list" );
bool isOrthographic = camera.orthographic;
// generate screen-space AABBs (used for both fptl and clustered).
if (numLights != 0)
{

var projh = temp * proj;
var invProjh = projh.inverse;
cmd.SetComputeIntParam(buildScreenAABBShader, "g_isOrthographic", isOrthographic ? 1 : 0);
cmd.SetComputeIntParam(buildScreenAABBShader, "g_iNrVisibLights", numLights);
cmd.SetComputeMatrixParam(buildScreenAABBShader, "g_mProjection", projh);
cmd.SetComputeMatrixParam(buildScreenAABBShader, "g_mInvProjection", invProjh);

// enable coarse 2D pass on 64x64 tiles (used for both fptl and clustered).
if (enableBigTilePrepass)
{
cmd.SetComputeIntParam(buildPerBigTileLightListShader, "g_isOrthographic", isOrthographic ? 1 : 0);
cmd.SetComputeIntParams(buildPerBigTileLightListShader, "g_viDimensions", new int[2] { w, h });
cmd.SetComputeIntParam(buildPerBigTileLightListShader, "g_iNrVisibLights", numLights);
cmd.SetComputeMatrixParam(buildPerBigTileLightListShader, "g_mScrProjection", projscr);

if (usingFptl) // optimized for opaques only
{
cmd.SetComputeIntParam(buildPerTileLightListShader, "g_isOrthographic", isOrthographic ? 1 : 0);
cmd.SetComputeIntParams(buildPerTileLightListShader, "g_viDimensions", new int[2] { w, h });
cmd.SetComputeIntParam(buildPerTileLightListShader, "g_iNrVisibLights", numLights);
cmd.SetComputeMatrixParam(buildPerTileLightListShader, "g_mScrProjection", projscr);

void PushGlobalParams(Camera camera, ScriptableRenderContext loop, Matrix4x4 viewToWorld, Matrix4x4 scrProj, Matrix4x4 incScrProj, int numDirLights)
{
var cmd = CommandBufferPool.Get("Push Global Parameters");
bool isOrthographic = camera.orthographic;
cmd.SetGlobalFloat("g_isOrthographic", (float) (isOrthographic ? 1 : 0));
cmd.SetGlobalFloat("g_widthRT", (float)camera.pixelWidth);
cmd.SetGlobalFloat("g_heightRT", (float)camera.pixelHeight);

10
Assets/ScriptableRenderPipeline/Fptl/LightingConvexHullUtils.hlsl


return float4(vN, -dot(vN,p0));
}
bool DoesSphereOverlapTile(float3 dir, float halfTileSizeAtZDistOne, float3 sphCen, float sphRadiusIn)
bool DoesSphereOverlapTile(float3 dir, float halfTileSizeAtZDistOne, float3 sphCen_in, float sphRadiusIn, bool isOrthographic)
float3 V = dir; // ray direction down center of tile (does not need to be normalized).
float3 V = float3(isOrthographic ? 0.0 : dir.x, isOrthographic ? 0.0 : dir.y, dir.z); // ray direction down center of tile (does not need to be normalized).
float3 sphCen = float3(sphCen_in.x - (isOrthographic ? dir.x : 0.0), sphCen_in.y - (isOrthographic ? dir.y : 0.0), sphCen_in.z);
#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))

// enlarge sphere so it overlaps the center of the tile assuming it overlaps the tile to begin with.
#if USE_LEFTHAND_CAMERASPACE
float sphRadius = sphRadiusIn + (sphCen.z+offs)*halfTileSizeAtZDistOne;
float s = sphCen.z+offs;
float sphRadius = sphRadiusIn - (sphCen.z-offs)*halfTileSizeAtZDistOne;
float s = -(sphCen.z-offs);
float sphRadius = sphRadiusIn + (isOrthographic ? 1.0 : s)*halfTileSizeAtZDistOne;
float a = dot(V,V);
float CdotV = dot(sphCen,V);

24
Assets/ScriptableRenderPipeline/Fptl/LightingUtils.hlsl


uniform float4x4 g_mInvScrProjection;
uniform uint g_isOrthographic;
uniform uint g_widthRT;
uniform uint g_heightRT;

float fSx = g_mScrProjection[0].x;
//float fCx = g_mScrProjection[2].x;
float fCx = g_mScrProjection[0].z;
float fSy = g_mScrProjection[1].y;
//float fCy = g_mScrProjection[2].y;
float fCy = g_mScrProjection[1].z;
bool isOrthographic = g_isOrthographic!=0;
float fSx = g_mScrProjection[0].x;
float fSy = g_mScrProjection[1].y;
float fCx = isOrthographic ? g_mScrProjection[0].w : g_mScrProjection[0].z;
float fCy = isOrthographic ? g_mScrProjection[1].w : g_mScrProjection[1].z;
return fLinDepth*float3( ((v2ScrPos.x-fCx)/fSx), ((v2ScrPos.y-fCy)/fSy), 1.0 );
bool useLeftHandVersion = true;
return fLinDepth*float3( -((v2ScrPos.x+fCx)/fSx), -((v2ScrPos.y+fCy)/fSy), 1.0 );
bool useLeftHandVersion = isOrthographic;
float s = useLeftHandVersion ? 1 : (-1);
float2 p = float2( (s*v2ScrPos.x-fCx)/fSx, (s*v2ScrPos.y-fCy)/fSy);
return float3(isOrthographic ? p.xy : (fLinDepth*p.xy), fLinDepth);
}
float GetLinearZFromSVPosW(float posW)

float GetLinearDepth(float zDptBufSpace) // 0 is near 1 is far
{
// todo (simplify): m22 is zero and m23 is +1/-1 (depends on left/right hand proj)
// for perspective projection m22 is zero and m23 is +1/-1 (depends on left/right hand proj)
// however this function must also work for orthographic projection so we keep it like this.
float m22 = g_mInvScrProjection[2].z, m23 = g_mInvScrProjection[2].w;
float m32 = g_mInvScrProjection[3].z, m33 = g_mInvScrProjection[3].w;

26
Assets/ScriptableRenderPipeline/Fptl/lightlistbuild-bigtile.compute


#define MAX_NR_BIGTILE_LIGHTS (MAX_NR_BIGTILE_LIGHTS_PLUSONE-1)
uniform int g_isOrthographic;
uniform int g_iNrVisibLights;
uniform uint2 g_viDimensions;
uniform float4x4 g_mInvScrProjection;

float3 GetViewPosFromLinDepth(float2 v2ScrPos, float fLinDepth)
{
bool isOrthographic = g_isOrthographic!=0;
float fCx = g_mScrProjection[0].z;
float fCy = g_mScrProjection[1].z;
float fCx = isOrthographic ? g_mScrProjection[0].w : g_mScrProjection[0].z;
float fCy = isOrthographic ? g_mScrProjection[1].w : g_mScrProjection[1].z;
return fLinDepth*float3( ((v2ScrPos.x-fCx)/fSx), ((v2ScrPos.y-fCy)/fSy), 1.0 );
bool useLeftHandVersion = true;
return fLinDepth*float3( -((v2ScrPos.x+fCx)/fSx), -((v2ScrPos.y+fCy)/fSy), 1.0 );
bool useLeftHandVersion = isOrthographic;
float s = useLeftHandVersion ? 1 : (-1);
float2 p = float2( (s*v2ScrPos.x-fCx)/fSx, (s*v2ScrPos.y-fCy)/fSy);
return float3(isOrthographic ? p.xy : (fLinDepth*p.xy), fLinDepth);
}
float GetOnePixDiagWorldDistAtDepthOne()

{
SFiniteLightBound lgtDat = g_data[lightsListLDS[l]];
if( !DoesSphereOverlapTile(V, halfTileSizeAtZDistOne, lgtDat.center.xyz, lgtDat.radius) )
if( !DoesSphereOverlapTile(V, halfTileSizeAtZDistOne, lgtDat.center.xyz, lgtDat.radius, g_isOrthographic!=0) )
lightsListLDS[l]=0xffffffff;
}

int i=iSwizzle + (2*(iSection&0x2)); // offset by 4 at section 2
vP0 = GetTileVertex(uint2(viTilLL.x, viTilUR.y), uint2(viTilUR.x, viTilLL.y), i, fTileFarPlane);
vE0 = iSection == 0 ? vP0 : (((iSwizzle & 0x2) == 0 ? 1.0f : (-1.0f)) * ((int)(iSwizzle & 0x1) == (iSwizzle >> 1) ? float3(1, 0, 0) : float3(0, 1, 0)));
#if USE_LEFTHAND_CAMERASPACE
float3 edgeSectionZero = g_isOrthographic==0 ? vP0 : float3(0.0,0.0,1.0);
#else
float3 edgeSectionZero = g_isOrthographic==0 ? vP0 : float3(0.0,0.0,-1.0);
#endif
vE0 = iSection == 0 ? edgeSectionZero : (((iSwizzle & 0x2) == 0 ? 1.0f : (-1.0f)) * ((int)(iSwizzle & 0x1) == (iSwizzle >> 1) ? float3(1, 0, 0) : float3(0, 1, 0)));
}
void CullByExactEdgeTests(uint threadID, int iNrCoarseLights, uint2 viTilLL, uint2 viTilUR)

26
Assets/ScriptableRenderPipeline/Fptl/lightlistbuild-clustered.compute


#define PERFORM_SPHERICAL_INTERSECTION_TESTS
#define CONV_HULL_TEST_ENABLED
uniform int g_isOrthographic;
uniform int g_iNrVisibLights;
uniform float4x4 g_mInvScrProjection;
uniform float4x4 g_mScrProjection;

float3 GetViewPosFromLinDepth(float2 v2ScrPos, float fLinDepth)
{
bool isOrthographic = g_isOrthographic!=0;
float fCx = g_mScrProjection[0].z;
float fCy = g_mScrProjection[1].z;
float fCx = isOrthographic ? g_mScrProjection[0].w : g_mScrProjection[0].z;
float fCy = isOrthographic ? g_mScrProjection[1].w : g_mScrProjection[1].z;
return fLinDepth*float3( ((v2ScrPos.x-fCx)/fSx), ((v2ScrPos.y-fCy)/fSy), 1.0 );
bool useLeftHandVersion = true;
return fLinDepth*float3( -((v2ScrPos.x+fCx)/fSx), -((v2ScrPos.y+fCy)/fSy), 1.0 );
bool useLeftHandVersion = isOrthographic;
float s = useLeftHandVersion ? 1 : (-1);
float2 p = float2( (s*v2ScrPos.x-fCx)/fSx, (s*v2ScrPos.y-fCy)/fSy);
return float3(isOrthographic ? p.xy : (fLinDepth*p.xy), fLinDepth);
}
float GetOnePixDiagWorldDistAtDepthOne()

{
SFiniteLightBound lgtDat = g_data[coarseList[l]];
if( !DoesSphereOverlapTile(V, halfTileSizeAtZDistOne, lgtDat.center.xyz, lgtDat.radius) )
if( !DoesSphereOverlapTile(V, halfTileSizeAtZDistOne, lgtDat.center.xyz, lgtDat.radius, g_isOrthographic!=0) )
coarseList[l]=0xffffffff;
}

int i=iSwizzle + (2*(iSection&0x2)); // offset by 4 at section 2
vP0 = GetTileVertex(uint2(viTilLL.x, viTilUR.y), uint2(viTilUR.x, viTilLL.y), i, fTileFarPlane);
vE0 = iSection==0 ? vP0 : (((iSwizzle&0x2)==0 ? 1.0f : (-1.0f))*((iSwizzle&0x1)==(iSwizzle>>1) ? float3(1,0,0) : float3(0,1,0)));
#if USE_LEFTHAND_CAMERASPACE
float3 edgeSectionZero = g_isOrthographic==0 ? vP0 : float3(0.0,0.0,1.0);
#else
float3 edgeSectionZero = g_isOrthographic==0 ? vP0 : float3(0.0,0.0,-1.0);
#endif
vE0 = iSection==0 ? edgeSectionZero : (((iSwizzle&0x2)==0 ? 1.0f : (-1.0f))*((iSwizzle&0x1)==(iSwizzle>>1) ? float3(1,0,0) : float3(0,1,0)));
}
int CullByExactEdgeTests(uint threadID, int iNrCoarseLights, uint2 viTilLL, uint2 viTilUR, float fTileFarPlane)

17
Assets/ScriptableRenderPipeline/Fptl/lightlistbuild.compute


#define PERFORM_SPHERICAL_INTERSECTION_TESTS
uniform int g_isOrthographic;
uniform int g_iNrVisibLights;
uniform uint2 g_viDimensions;
uniform float4x4 g_mInvScrProjection;

float3 GetViewPosFromLinDepth(float2 v2ScrPos, float fLinDepth)
{
bool isOrthographic = g_isOrthographic!=0;
float fCx = g_mScrProjection[0].z;
float fCy = g_mScrProjection[1].z;
float fCx = isOrthographic ? g_mScrProjection[0].w : g_mScrProjection[0].z;
float fCy = isOrthographic ? g_mScrProjection[1].w : g_mScrProjection[1].z;
return fLinDepth*float3( ((v2ScrPos.x-fCx)/fSx), ((v2ScrPos.y-fCy)/fSy), 1.0 );
bool useLeftHandVersion = true;
return fLinDepth*float3( -((v2ScrPos.x+fCx)/fSx), -((v2ScrPos.y+fCy)/fSy), 1.0 );
bool useLeftHandVersion = isOrthographic;
float s = useLeftHandVersion ? 1 : (-1);
float2 p = float2( (s*v2ScrPos.x-fCx)/fSx, (s*v2ScrPos.y-fCy)/fSy);
return float3(isOrthographic ? p.xy : (fLinDepth*p.xy), fLinDepth);
}
float GetOnePixDiagWorldDistAtDepthOne()

{
SFiniteLightBound lightData = g_data[prunedList[l]];
if( DoesSphereOverlapTile(V, halfTileSizeAtZDistOne, lightData.center.xyz, lightData.radius) )
if( DoesSphereOverlapTile(V, halfTileSizeAtZDistOne, lightData.center.xyz, lightData.radius, g_isOrthographic!=0) )
{
unsigned int uIndex;
InterlockedAdd(lightOffsSph, 1, uIndex);

11
Assets/ScriptableRenderPipeline/Fptl/scrbound.compute


#include "ShaderBase.h"
#include "LightDefinitions.cs.hlsl"
uniform int g_isOrthographic;
uniform int g_iNrVisibLights;
uniform float4x4 g_mInvProjection;
uniform float4x4 g_mProjection;

}
else
{
//if((center.z+radius)<0.0)
if( length(center)>radius)
if(g_isOrthographic==0 && length(center)>radius)
{
float2 vMi, vMa;
bool2 bMi, bMa;

vMax.xy = bMa ? min(vMax.xy, vMa) : vMax.xy;
}
else if(g_isOrthographic!=0)
{
float2 vMi = mul(g_mProjection, float4(center.xyz-radius,1)).xy; // no division needed for ortho
float2 vMa = mul(g_mProjection, float4(center.xyz+radius,1)).xy; // no division needed for ortho
vMin.xy = max(vMin.xy, vMi);
vMax.xy = min(vMax.xy, vMa);
}
#if USE_LEFTHAND_CAMERASPACE

正在加载...
取消
保存