浏览代码

HDRenderLoop: Version that compile and display something

/main
Sebastien Lagarde 8 年前
当前提交
546401a2
共有 12 个文件被更改,包括 337 次插入65 次删除
  1. 2
      Assets/ScriptableRenderLoop/HDRenderLoop/Debug/Resources/DebugViewTiles.shader
  2. 1
      Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.asset
  3. 2
      Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.asset.meta
  4. 10
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/Lighting.hlsl
  5. 5
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/Resources/lightlistbuild-bigtile.compute
  6. 17
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/Resources/lightlistbuild-clustered.compute
  7. 42
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/Resources/lightlistbuild.compute
  8. 17
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/TilePass.cs
  9. 174
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/TilePass.hlsl
  10. 123
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/TilePassLoop.hlsl
  11. 9
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/SinglePass.meta

2
Assets/ScriptableRenderLoop/HDRenderLoop/Debug/Resources/DebugViewTiles.shader


#endif
int n = 0;
for(int category = 0; category < NR_LIGHT_CATEGORIES; category++)
for(int category = 0; category < LIGHTCATEGORY_COUNT; category++)
{
uint mask = 1u << category;
uint start;

1
Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.asset


spotCookieSize: 128
pointCookieSize: 512
reflectionCubemapSize: 128
m_Dirty: 0

2
Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.asset.meta


fileFormatVersion: 2
guid: 2400b74f5ce370c4481e5dc417d03703
timeCreated: 1480436907
timeCreated: 1481084818
licenseType: Pro
NativeFormatImporter:
userData:

10
Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/Lighting.hlsl


#define HAS_LIGHTLOOP // Allow to not define LightLoop related function in Material.hlsl
#include "Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/LightDefinition.cs.hlsl"
#ifdef LIGHTLOOP_SINGLE_PASS
#include "Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/SinglePass/SinglePass.hlsl"
#elif defined(LIGHTLOOP_TILE_PASS)
#if defined(LIGHTLOOP_SINGLE_PASS) || defined(LIGHTLOOP_TILE_PASS)
#include "Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/TilePass.hlsl"
#endif

// LightLoop use evaluation BSDF function for light type define in Material.hlsl
#ifdef LIGHTLOOP_SINGLE_PASS
#include "Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/SinglePass/SinglePassLoop.hlsl"
#elif defined(LIGHTLOOP_TILE_PASS)
#if defined(LIGHTLOOP_SINGLE_PASS) || defined(LIGHTLOOP_TILE_PASS)
#include "Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/TilePassLoop.hlsl"
#endif

5
Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/Resources/lightlistbuild-bigtile.compute


uniform float4x4 g_mScrProjection;
uniform float g_fNearPlane;
uniform float g_fFarPlane;
uniform int _EnvLightIndexShift;
StructuredBuffer<LightShapeData> _LightShapeData : register(t2);
StructuredBuffer<LightVolumeData> _LightVolumeData : register(t2);
StructuredBuffer<SFiniteLightBound> g_data : register( t3 );

for(int l=0; l<iNrCoarseLights; l++)
{
const uint idxCoarse = lightsListLDS[l];
[branch]if (idxCoarse<(uint)g_iNrVisibLights && _LightShapeData[idxCoarse].lightVolume != SPHERE_VOLUME) // don't bother doing edge tests for sphere lights since these have camera aligned bboxes.
[branch]if (idxCoarse<(uint)g_iNrVisibLights && _LightVolumeData[idxCoarse].lightVolume != LIGHTVOLUMETYPE_SPHERE) // don't bother doing edge tests for sphere lights since these have camera aligned bboxes.
{
SFiniteLightBound lgtDat = g_data[idxCoarse];

17
Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/Resources/lightlistbuild-clustered.compute


uniform int g_iNrVisibLights;
uniform float4x4 g_mInvScrProjection;
uniform float4x4 g_mScrProjection;
uniform int _EnvLightIndexShift;
uniform float g_fClustScale;
uniform float g_fClustBase;

Texture2D g_depth_tex : register( t0 );
#endif
StructuredBuffer<float3> g_vBoundsBuffer : register( t1 );
StructuredBuffer<LightShapeData> _LightShapeData : register(t2);
StructuredBuffer<LightVolumeData> _LightVolumeData : register(t2);
StructuredBuffer<SFiniteLightBound> g_data : register( t3 );
#ifdef USE_TWO_PASS_TILED_LIGHTING

InterlockedAdd(g_LayeredSingleIdxBuffer[0], (uint) iSpaceAvail, start); // alloc list memory
}
int categoryListCount[NR_LIGHT_CATEGORIES]={0,0,0}; // direct light count and reflection lights
// All our cull data are in the same list, but at render time envLights are separated so we need to shit the index
// to make it work correctly
int shiftIndex[LIGHTCATEGORY_COUNT] = {0, 0, _EnvLightIndexShift}; // 3 for now, will throw an error if we change LIGHTCATEGORY_COUNT
int categoryListCount[LIGHTCATEGORY_COUNT]={0,0,0}; // direct light count and reflection lights
uint offs = start;
for(int ll=0; ll<iNrCoarseLights; ll+=4)
{

{
if(offs<(start+iSpaceAvail) && i<nrClusters && CheckIntersection(l, i, viTilLL.xy, viTilUR.xy, suggestedBase) )
{
uint lightCategory = _LightShapeData[coarseList[l]].lightCategory;
uint lightCategory = _LightVolumeData[coarseList[l]].lightCategory;
g_vLayeredLightList[offs++] = _LightShapeData[coarseList[l]].lightIndex; // reflection lights will be last since we sorted
g_vLayeredLightList[offs++] = coarseList[l] - shiftIndex[lightCategory]; // reflection lights will be last since we sorted
}
}

uint localOffs=0;
offs = i*nrTilesX*nrTilesY + tileIDX.y*nrTilesX + tileIDX.x;
for(int category=0; category<NR_LIGHT_CATEGORIES; category++)
for(int category=0; category<LIGHTCATEGORY_COUNT; category++)
{
int numLights = min(categoryListCount[category],31); // only allow 5 bits
if(i<nrClusters)

GroupMemoryBarrierWithGroupSync();
#endif
const int idxCoarse = coarseList[l];
[branch]if (_LightShapeData[idxCoarse].lightVolume != SPHERE_VOLUME) // don't bother doing edge tests for sphere lights since these have camera aligned bboxes.
[branch]if (_LightVolumeData[idxCoarse].lightVolume != LIGHTVOLUMETYPE_SPHERE) // don't bother doing edge tests for sphere lights since these have camera aligned bboxes.
{
SFiniteLightBound lgtDat = g_data[idxCoarse];

42
Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/Resources/lightlistbuild.compute


uniform uint2 g_viDimensions;
uniform float4x4 g_mInvScrProjection;
uniform float4x4 g_mScrProjection;
uniform int _EnvLightIndexShift;
StructuredBuffer<LightShapeData> _LightShapeData : register(t2);
StructuredBuffer<LightVolumeData> _LightVolumeData : register(t2);
StructuredBuffer<SFiniteLightBound> g_data : register( t3 );
#ifdef USE_TWO_PASS_TILED_LIGHTING

#endif
groupshared int ldsNrLightsFinal;
groupshared int ldsCategoryListCount[NR_LIGHT_CATEGORIES]; // since NR_LIGHT_CATEGORIES is 3
groupshared int ldsCategoryListCount[LIGHTCATEGORY_COUNT]; // since LIGHTCATEGORY_COUNT is 3
#ifdef PERFORM_SPHERICAL_INTERSECTION_TESTS
groupshared uint lightOffsSph;

#endif
//
if(t<NR_LIGHT_CATEGORIES) ldsCategoryListCount[t]=0;
if(t<LIGHTCATEGORY_COUNT) ldsCategoryListCount[t]=0;
#if !defined(SHADER_API_XBOXONE) && !defined(SHADER_API_PSSL)
GroupMemoryBarrierWithGroupSync();

int nrLightsCombinedList = min(ldsNrLightsFinal,MAX_NR_COARSE_ENTRIES);
for(int i=t; i<nrLightsCombinedList; i+=NR_THREADS)
{
InterlockedAdd(ldsCategoryListCount[_LightShapeData[prunedList[i]].lightCategory], 1);
InterlockedAdd(ldsCategoryListCount[_LightVolumeData[prunedList[i]].lightCategory], 1);
}

int localOffs=0;
int offs = tileIDX.y*nrTilesX + tileIDX.x;
for(int category=0; category<NR_LIGHT_CATEGORIES; category++)
// All our cull data are in the same list, but at render time envLights are separated so we need to shit the index
// to make it work correctly
int shiftIndex[LIGHTCATEGORY_COUNT] = {0, 0, _EnvLightIndexShift}; // 3 for now, will throw an error if we change LIGHTCATEGORY_COUNT
for(int category=0; category<LIGHTCATEGORY_COUNT; category++)
{
int nrLightsFinal = ldsCategoryListCount[category];
int nrLightsFinalClamped = nrLightsFinal<MAX_NR_PRUNED_ENTRIES ? nrLightsFinal : MAX_NR_PRUNED_ENTRIES;

for(int l=(int) t; l<(int) nrDWords; l += NR_THREADS)
{
// We remap the prunedList index to the original LightData / EnvLightData indices
uint uLow = l==0 ? nrLightsFinalClamped : _LightShapeData[prunedList[2*l-1+localOffs]].lightIndex;
uint uHigh = _LightShapeData[prunedList[2 * l + 0 + localOffs]].lightIndex;
uint uLow = l==0 ? nrLightsFinalClamped : prunedList[2*l-1+localOffs] - shiftIndex[category];
uint uHigh = prunedList[2 * l + 0 + localOffs] - shiftIndex[category];
g_vLightList[16*offs + l] = (uLow&0xffff) | (uHigh<<16);
}

{
// fetch light
int idxCoarse = l<iNrCoarseLights ? coarseList[l] : 0;
uint uLightVolume = l<iNrCoarseLights ? _LightShapeData[idxCoarse].lightVolume : 0;
uint uLightVolume = l<iNrCoarseLights ? _LightVolumeData[idxCoarse].lightVolume : 0;
while(l<iNrCoarseLights && uLightVolume==SPOT_VOLUME)
while(l<iNrCoarseLights && uLightVolume==LIGHTVOLUMETYPE_CONE)
LightShapeData lightData = _LightShapeData[idxCoarse];
LightVolumeData lightData = _LightVolumeData[idxCoarse];
// TODO: Change by SebL
const bool bIsSpotDisc = true; // (lightData.flags&IS_CIRCULAR_SPOT_SHAPE) != 0;

uLightsFlags[l<32 ? 0 : 1] |= (uVal<<(l&31));
++l; idxCoarse = l<iNrCoarseLights ? coarseList[l] : 0;
uLightVolume = l<iNrCoarseLights ? _LightShapeData[idxCoarse].lightVolume : 0;
uLightVolume = l<iNrCoarseLights ? _LightVolumeData[idxCoarse].lightVolume : 0;
while(l<iNrCoarseLights && uLightVolume==SPHERE_VOLUME)
while(l<iNrCoarseLights && uLightVolume==LIGHTVOLUMETYPE_SPHERE)
LightShapeData lightData = _LightShapeData[idxCoarse];
LightVolumeData lightData = _LightVolumeData[idxCoarse];
// serially check 4 pixels
uint uVal = 0;

uLightsFlags[l<32 ? 0 : 1] |= (uVal<<(l&31));
++l; idxCoarse = l<iNrCoarseLights ? coarseList[l] : 0;
uLightVolume = l<iNrCoarseLights ? _LightShapeData[idxCoarse].lightVolume : 0;
uLightVolume = l<iNrCoarseLights ? _LightVolumeData[idxCoarse].lightVolume : 0;
while(l<iNrCoarseLights && uLightVolume==BOX_VOLUME)
while(l<iNrCoarseLights && uLightVolume==LIGHTVOLUMETYPE_BOX)
LightShapeData lightData = _LightShapeData[idxCoarse];
LightVolumeData lightData = _LightVolumeData[idxCoarse];
// serially check 4 pixels
uint uVal = 0;

uLightsFlags[l<32 ? 0 : 1] |= (uVal<<(l&31));
++l; idxCoarse = l<iNrCoarseLights ? coarseList[l] : 0;
uLightVolume = l<iNrCoarseLights ? _LightShapeData[idxCoarse].lightVolume : 0;
uLightVolume = l<iNrCoarseLights ? _LightVolumeData[idxCoarse].lightVolume : 0;
if(uLightVolume >=MAX_VOLUME_TYPES) ++l;
if(uLightVolume >=LIGHTVOLUMETYPE_COUNT) ++l;
}
InterlockedOr(ldsDoesLightIntersect[0], uLightsFlags[0]);

17
Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/TilePass.cs


public override void Rebuild(TextureSettings textureSettings)
{
m_lightList = new LightList();
m_lightList.Allocate();
s_DirectionalLightDatas = new ComputeBuffer(k_MaxDirectionalLightsOnSCreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(DirectionalLightData)));
s_LightDatas = new ComputeBuffer(k_MaxPunctualLightsOnSCreen + k_MaxAreaLightsOnSCreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(LightData)));

continue;
// TODO: Support LightVolumeType.Sphere, currently in UI there is no way to specify a sphere influence volume
LightVolumeType lightVolumeType = LightVolumeType.Box;
LightVolumeType lightVolumeType = probe.boxProjection != 0 ? LightVolumeType.Box : LightVolumeType.Box;
++envLightCount;
// 16 bit lightVolume, 16 bit index

cmd.SetComputeBufferParam(buildPerVoxelLightListShader, s_ClearVoxelAtomicKernel, "g_LayeredSingleIdxBuffer", s_GlobalLightListAtomic);
cmd.DispatchCompute(buildPerVoxelLightListShader, s_ClearVoxelAtomicKernel, 1, 1, 1);
cmd.SetComputeIntParam(buildPerVoxelLightListShader, "_EnvLightIndexShift", m_lightList.lights.Count);
cmd.SetComputeIntParam(buildPerVoxelLightListShader, "g_iNrVisibLights", m_lightCount);
Utilities.SetMatrixCS(cmd, buildPerVoxelLightListShader, "g_mScrProjection", projscr);
Utilities.SetMatrixCS(cmd, buildPerVoxelLightListShader, "g_mInvScrProjection", invProjscr);

if (enableBigTilePrepass)
{
cmd.SetComputeIntParams(buildPerBigTileLightListShader, "g_viDimensions", new int[2] { w, h });
cmd.SetComputeIntParam(buildPerBigTileLightListShader, "_EnvLightIndexShift", m_lightList.lights.Count);
cmd.SetComputeIntParam(buildPerBigTileLightListShader, "g_iNrVisibLights", m_lightCount);
Utilities.SetMatrixCS(cmd, buildPerBigTileLightListShader, "g_mScrProjection", projscr);
Utilities.SetMatrixCS(cmd, buildPerBigTileLightListShader, "g_mInvScrProjection", invProjscr);

if (usingFptl) // optimized for opaques only
{
cmd.SetComputeIntParams(buildPerTileLightListShader, "g_viDimensions", new int[2] { w, h });
cmd.SetComputeIntParam(buildPerTileLightListShader, "_EnvLightIndexShift", m_lightList.lights.Count);
cmd.SetComputeIntParam(buildPerTileLightListShader, "g_iNrVisibLights", m_lightCount);
Utilities.SetMatrixCS(cmd, buildPerTileLightListShader, "g_mScrProjection", projscr);
Utilities.SetMatrixCS(cmd, buildPerTileLightListShader, "g_mInvScrProjection", invProjscr);

s_ConvexBoundsBuffer.SetData(m_lightList.bounds.ToArray());
s_LigthVolumeDataBuffer.SetData(m_lightList.lightVolumes.ToArray());
Shader.SetGlobalBuffer("_DirectionalLightList", s_DirectionalLightDatas);
Shader.SetGlobalBuffer("_DirectionalLightDatas", s_DirectionalLightDatas);
Shader.SetGlobalBuffer("_PunctualLightList", s_LightDatas);
Shader.SetGlobalBuffer("_LightDatas", s_LightDatas);
Shader.SetGlobalBuffer("_AreaLightList", s_LightDatas);
Shader.SetGlobalBuffer("_EnvLightList", s_EnvLightDatas);
Shader.SetGlobalBuffer("_ShadowList", s_shadowDatas);
Shader.SetGlobalBuffer("_EnvLightDatas", s_EnvLightDatas);
Shader.SetGlobalInt("_EnvLightCount", m_lightList.envLights.Count);
Shader.SetGlobalBuffer("_ShadowDatas", s_shadowDatas);
Shader.SetGlobalVectorArray("_DirShadowSplitSpheres", m_lightList.directionalShadowSplitSphereSqr);
var cmd = new CommandBuffer { name = "Push Global Parameters" };

var projscr = temp * proj;
var invProjscr = projscr.inverse;
cmd.SetComputeIntParam(deferredComputeShader, "_EnvLightIndexShift", m_lightList.lights.Count);
cmd.SetComputeIntParam(deferredComputeShader, "g_iNrVisibLights", numLights);
SetMatrixCS(cmd, deferredComputeShader, "g_mScrProjection", projscr);
SetMatrixCS(cmd, deferredComputeShader, "g_mInvScrProjection", invProjscr);

174
Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/TilePass.hlsl


Buffer<float> g_logBaseBuffer;
//#endif
// TODO: Need to correctly define the shadow framework, WIP
#include "../SinglePass/SinglePass.hlsl"
StructuredBuffer<DirectionalLightData> _DirectionalLightDatas;
StructuredBuffer<LightData> _LightDatas;
StructuredBuffer<EnvLightData> _EnvLightDatas;
StructuredBuffer<ShadowData> _ShadowDatas;
// Use texture atlas for shadow map
//TEXTURE2D(_ShadowAtlas);
//SAMPLER2D_SHADOW(sampler_ShadowAtlas);
//SAMPLER2D(sampler_ManualShadowAtlas); // TODO: settings sampler individually is not supported in shader yet...
TEXTURE2D(g_tShadowBuffer) // TODO: No choice, the name is hardcoded in ShadowrenderPass.cs for now. Need to change this!
SAMPLER2D_SHADOW(samplerg_tShadowBuffer);
// Use texture array for IES
TEXTURE2D_ARRAY(_IESArray);
SAMPLER2D(sampler_IESArray);
// Used by directional and spot lights
TEXTURE2D_ARRAY(_CookieTextures);
SAMPLER2D(sampler_CookieTextures);
// Used by point lights
TEXTURECUBE_ARRAY(_CookieCubeTextures);
SAMPLERCUBE(sampler_CookieCubeTextures);
// Use texture array for reflection
TEXTURECUBE_ARRAY(_EnvTextures);
SAMPLERCUBE(sampler_EnvTextures);
TEXTURECUBE(_SkyTexture);
SAMPLERCUBE(sampler_SkyTexture); // NOTE: Sampler could be share here with _EnvTextures. Don't know if the shader compiler will complain...
CBUFFER_START(UnityPerLightLoop)
uint _DirectionalLightCount;
uint _PunctualLightCount;
uint _AreaLightCount;
uint _EnvLightCount;
float4 _DirShadowSplitSpheres[4]; // TODO: share this max between C# and hlsl
int _EnvLightSkyEnabled; // TODO: make it a bool
CBUFFER_END
struct LightLoopContext
{
int sampleShadow;
int sampleReflection;
};
//-----------------------------------------------------------------------------
// Shadow sampling function
// ----------------------------------------------------------------------------
float GetPunctualShadowAttenuation(LightLoopContext lightLoopContext, float3 positionWS, int index, float3 L, float2 unPositionSS)
{
int faceIndex = 0;
if (_ShadowDatas[index].lightType == GPULIGHTTYPE_POINT)
{
GetCubeFaceID(L, faceIndex);
}
ShadowData shadowData = _ShadowDatas[index + faceIndex];
// Note: scale and bias of shadow atlas are included in ShadowTransform but could be apply here.
float4 positionTXS = mul(float4(positionWS, 1.0), shadowData.worldToShadow);
positionTXS.xyz /= positionTXS.w;
// positionTXS.z -= shadowData.bias; // Apply a linear bias
positionTXS.z -= 0.001;
#if UNITY_REVERSED_Z
positionTXS.z = 1.0 - positionTXS.z;
#endif
// float3 shadowPosDX = ddx_fine(positionTXS);
// float3 shadowPosDY = ddy_fine(positionTXS);
return SAMPLE_TEXTURE2D_SHADOW(g_tShadowBuffer, samplerg_tShadowBuffer, positionTXS);
}
// Gets the cascade weights based on the world position of the fragment and the positions of the split spheres for each cascade.
// Returns an invalid split index if past shadowDistance (ie 4 is invalid for cascade)
uint GetSplitSphereIndexForDirshadows(float3 positionWS, float4 dirShadowSplitSpheres[4])
{
float3 fromCenter0 = positionWS.xyz - dirShadowSplitSpheres[0].xyz;
float3 fromCenter1 = positionWS.xyz - dirShadowSplitSpheres[1].xyz;
float3 fromCenter2 = positionWS.xyz - dirShadowSplitSpheres[2].xyz;
float3 fromCenter3 = positionWS.xyz - dirShadowSplitSpheres[3].xyz;
float4 distances2 = float4(dot(fromCenter0, fromCenter0), dot(fromCenter1, fromCenter1), dot(fromCenter2, fromCenter2), dot(fromCenter3, fromCenter3));
float4 dirShadowSplitSphereSqRadii;
dirShadowSplitSphereSqRadii.x = dirShadowSplitSpheres[0].w;
dirShadowSplitSphereSqRadii.y = dirShadowSplitSpheres[1].w;
dirShadowSplitSphereSqRadii.z = dirShadowSplitSpheres[2].w;
dirShadowSplitSphereSqRadii.w = dirShadowSplitSpheres[3].w;
float4 weights = float4(distances2 < dirShadowSplitSphereSqRadii);
weights.yzw = saturate(weights.yzw - weights.xyz);
return uint(4.0 - dot(weights, float4(4.0, 3.0, 2.0, 1.0)));
}
float GetDirectionalShadowAttenuation(LightLoopContext lightLoopContext, float3 positionWS, int index, float3 L, float2 unPositionSS)
{
// Note Index is 0 for now, but else we need to provide the correct index in _DirShadowSplitSpheres and _ShadowDatas
uint shadowSplitIndex = GetSplitSphereIndexForDirshadows(positionWS, _DirShadowSplitSpheres);
ShadowData shadowData = _ShadowDatas[shadowSplitIndex];
// Note: scale and bias of shadow atlas are included in ShadowTransform but could be apply here.
float4 positionTXS = mul(float4(positionWS, 1.0), shadowData.worldToShadow);
positionTXS.xyz /= positionTXS.w;
// positionTXS.z -= shadowData.bias; // Apply a linear bias
positionTXS.z -= 0.003;
#if UNITY_REVERSED_Z
positionTXS.z = 1.0 - positionTXS.z;
#endif
// float3 shadowPosDX = ddx_fine(positionTXS);
// float3 shadowPosDY = ddy_fine(positionTXS);
return SAMPLE_TEXTURE2D_SHADOW(g_tShadowBuffer, samplerg_tShadowBuffer, positionTXS);
}
//-----------------------------------------------------------------------------
// Cookie sampling functions
// ----------------------------------------------------------------------------
// Used by directional and spot lights.
// Returns the color in the RGB components, and the transparency (lack of occlusion) in A.
float4 SampleCookie2D(LightLoopContext lightLoopContext, float2 coord, int index)
{
return SAMPLE_TEXTURE2D_ARRAY_LOD(_CookieTextures, sampler_CookieTextures, coord, index, 0);
}
// Used by point lights.
// Returns the color in the RGB components, and the transparency (lack of occlusion) in A.
float4 SampleCookieCube(LightLoopContext lightLoopContext, float3 coord, int index)
{
return SAMPLE_TEXTURECUBE_ARRAY_LOD(_CookieCubeTextures, sampler_CookieCubeTextures, coord, index, 0);
}
//-----------------------------------------------------------------------------
// IES sampling function
// ----------------------------------------------------------------------------
// sphericalTexCoord is theta and phi spherical coordinate
float4 SampleIES(LightLoopContext lightLoopContext, int index, float2 sphericalTexCoord, float lod)
{
return SAMPLE_TEXTURE2D_ARRAY_LOD(_IESArray, sampler_IESArray, sphericalTexCoord, index, 0);
}
//-----------------------------------------------------------------------------
// Reflection proble / Sky sampling function
// ----------------------------------------------------------------------------
#define SINGLE_PASS_CONTEXT_SAMPLE_REFLECTION_PROBES 0
#define SINGLE_PASS_CONTEXT_SAMPLE_SKY 1
// Note: index is whatever the lighting architecture want, it can contain information like in which texture to sample (in case we have a compressed BC6H texture and an uncompressed for real time reflection ?)
// EnvIndex can also be use to fetch in another array of struct (to atlas information etc...).
float4 SampleEnv(LightLoopContext lightLoopContext, int index, float3 texCoord, float lod)
{
// This code will be inlined as lightLoopContext is hardcoded in the light loop
if (lightLoopContext.sampleReflection == SINGLE_PASS_CONTEXT_SAMPLE_REFLECTION_PROBES)
{
return SAMPLE_TEXTURECUBE_ARRAY_LOD(_EnvTextures, sampler_EnvTextures, texCoord, index, lod);
}
else // SINGLE_PASS_SAMPLE_SKY
{
return SAMPLE_TEXTURECUBE_LOD(_SkyTexture, sampler_SkyTexture, texCoord, lod);
}
}

123
Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/TilePassLoop.hlsl


// LightLoop
// ----------------------------------------------------------------------------
#ifdef LIGHTLOOP_TILE_PASS
// Calculate the offset in global light index light for current light category
int GetTileOffset(Coordinate coord, uint lightCategory)
{

{
float3 localDiffuseLighting, localSpecularLighting;
EvaluateBSDF_Directional( context, V, positionWS, prelightData, _DirectionalLightList[i], bsdfData,
EvaluateBSDF_Directional( context, V, positionWS, prelightData, _DirectionalLightDatas[i], bsdfData,
localDiffuseLighting, localSpecularLighting);
diffuseLighting += localDiffuseLighting;

#ifdef PROCESS_PUNCTUAL_LIGHT
// TODO: Convert the for loop below to a while on each type as we know we are sorted!
GetCountAndStart(coord, PUNCTUAL_LIGHT_CATEGORY, linearDepth, punctualLightStart, punctualLightCount);
GetCountAndStart(coord, LIGHTCATEGORY_PUNCTUAL, linearDepth, punctualLightStart, punctualLightCount);
EvaluateBSDF_Punctual( context, V, positionWS, prelightData, _PunctualLightList[FetchIndex(punctualLightStart, i)], bsdfData,
EvaluateBSDF_Punctual( context, V, positionWS, prelightData, _LightDatas[FetchIndex(punctualLightStart, i)], bsdfData,
localDiffuseLighting, localSpecularLighting);
diffuseLighting += localDiffuseLighting;

#ifdef PROCESS_AREA_LIGHT
// TODO: Area lights are where the sorting is important (Morten approach with while loop)
// TODO: Convert the for loop below to a while on each type as we know we are sorted!
GetCountAndStart(coord, AREA_LIGHT_CATEGORY, linearDepth, areaLightStart, areaLightCount);
GetCountAndStart(coord, LIGHTCATEGORY_AREA, linearDepth, areaLightStart, areaLightCount);
if(_AreaLightList[i].lightType == GPULIGHTTYPE_LINE)
uint areaIndex = FetchIndex(areaLightStart, i);
if(_LightDatas[areaIndex].lightType == GPULIGHTTYPE_LINE)
EvaluateBSDF_Line(context, V, positionWS, prelightData, _AreaLightList[FetchIndex(areaLightStart, i)], bsdfData,
localDiffuseLighting, localSpecularLighting);
EvaluateBSDF_Line( context, V, positionWS, prelightData, _LightDatas[areaIndex], bsdfData,
localDiffuseLighting, localSpecularLighting);
EvaluateBSDF_Area(context, V, positionWS, prelightData, _AreaLightList[FetchIndex(areaLightStart, i)], bsdfData,
localDiffuseLighting, localSpecularLighting);
EvaluateBSDF_Area( context, V, positionWS, prelightData, _LightDatas[areaIndex], bsdfData,
localDiffuseLighting, localSpecularLighting);
}

#ifdef PROCESS_ENV_LIGHT
uint envLightStart;
uint envLightCount;
GetCountAndStart(coord, REFLECTION_LIGHT_CATEGORY, linearDepth, envLightStart, envLightCount);
GetCountAndStart(coord, LIGHTCATEGORY_ENV, linearDepth, envLightStart, envLightCount);
float3 iblDiffuseLighting = float3(0.0, 0.0, 0.0);
float3 iblSpecularLighting = float3(0.0, 0.0, 0.0);

float3 localDiffuseLighting, localSpecularLighting;
float2 weight;
context.sampleReflection = SINGLE_PASS_CONTEXT_SAMPLE_REFLECTION_PROBES;
EvaluateBSDF_Env(context, V, positionWS, prelightData, _EnvLightList[FetchIndex(envLightStart, i)], bsdfData, localDiffuseLighting, localSpecularLighting, weight);
EvaluateBSDF_Env(context, V, positionWS, prelightData, _EnvLightDatas[FetchIndex(envLightStart, i)], bsdfData, localDiffuseLighting, localSpecularLighting, weight);
iblDiffuseLighting = lerp(iblDiffuseLighting, localDiffuseLighting, weight.x); // Should be remove by the compiler if it is smart as all is constant 0
iblSpecularLighting = lerp(iblSpecularLighting, localSpecularLighting, weight.y);
}

diffuseLighting += bakeDiffuseLighting;
#endif
}
#else // LIGHTLOOP_SINGLE_PASS
// bakeDiffuseLighting is part of the prototype so a user is able to implement a "base pass" with GI and multipass direct light (aka old unity rendering path)
void LightLoop( float3 V, float3 positionWS, Coordinate coord, PreLightData prelightData, BSDFData bsdfData, float3 bakeDiffuseLighting,
out float3 diffuseLighting,
out float3 specularLighting)
{
LightLoopContext context;
ZERO_INITIALIZE(LightLoopContext, context);
diffuseLighting = float3(0.0, 0.0, 0.0);
specularLighting = float3(0.0, 0.0, 0.0);
uint i = 0; // Declare once to avoid the D3D11 compiler warning.
for (i = 0; i < _DirectionalLightCount; ++i)
{
float3 localDiffuseLighting, localSpecularLighting;
EvaluateBSDF_Directional( context, V, positionWS, prelightData, _DirectionalLightDatas[i], bsdfData,
localDiffuseLighting, localSpecularLighting);
diffuseLighting += localDiffuseLighting;
specularLighting += localSpecularLighting;
}
for (i = 0; i < _PunctualLightCount; ++i)
{
float3 localDiffuseLighting, localSpecularLighting;
EvaluateBSDF_Punctual( context, V, positionWS, prelightData, _LightDatas[i], bsdfData,
localDiffuseLighting, localSpecularLighting);
diffuseLighting += localDiffuseLighting;
specularLighting += localSpecularLighting;
}
// Area are store with punctual, just offset the index
for (i = _PunctualLightCount; i < _AreaLightCount + _PunctualLightCount; ++i)
{
float3 localDiffuseLighting, localSpecularLighting;
if (_LightDatas[i].lightType == GPULIGHTTYPE_LINE)
{
EvaluateBSDF_Line( context, V, positionWS, prelightData, _LightDatas[i], bsdfData,
localDiffuseLighting, localSpecularLighting);
}
else
{
EvaluateBSDF_Area( context, V, positionWS, prelightData, _LightDatas[i], bsdfData,
localDiffuseLighting, localSpecularLighting);
}
diffuseLighting += localDiffuseLighting;
specularLighting += localSpecularLighting;
}
// TODO: Check the reflection hierarchy, for the current system (matching legacy unity) we must sort from bigger solid angle to lower (lower override bigger). So begging by sky
// TODO: Change the way it is done by reversing the order, from smaller solid angle to bigger, so we can early out when the weight is 1.
float3 iblDiffuseLighting = float3(0.0, 0.0, 0.0);
float3 iblSpecularLighting = float3(0.0, 0.0, 0.0);
// Only apply sky IBL if the sky texture is available.
if (_EnvLightSkyEnabled)
{
float3 localDiffuseLighting, localSpecularLighting;
float2 weight;
// The sky is a single cubemap texture separate from the reflection probe texture array (different resolution and compression)
context.sampleReflection = SINGLE_PASS_CONTEXT_SAMPLE_SKY;
EnvLightData envLightSky = InitSkyEnvLightData(0); // The sky data are generated on the fly so the compiler can optimize the code
EvaluateBSDF_Env(context, V, positionWS, prelightData, envLightSky, bsdfData, localDiffuseLighting, localSpecularLighting, weight);
iblDiffuseLighting = lerp(iblDiffuseLighting, localDiffuseLighting, weight.x); // Should be remove by the compiler if it is smart as all is constant 0
iblSpecularLighting = lerp(iblSpecularLighting, localSpecularLighting, weight.y);
}
for (i = 0; i < _EnvLightCount; ++i)
{
float3 localDiffuseLighting, localSpecularLighting;
float2 weight;
context.sampleReflection = SINGLE_PASS_CONTEXT_SAMPLE_REFLECTION_PROBES;
EvaluateBSDF_Env(context, V, positionWS, prelightData, _EnvLightDatas[i], bsdfData, localDiffuseLighting, localSpecularLighting, weight);
iblDiffuseLighting = lerp(iblDiffuseLighting, localDiffuseLighting, weight.x); // Should be remove by the compiler if it is smart as all is constant 0
iblSpecularLighting = lerp(iblSpecularLighting, localSpecularLighting, weight.y);
}
diffuseLighting += iblDiffuseLighting;
specularLighting += iblSpecularLighting;
// Add indirect diffuse + emissive (if any)
diffuseLighting += bakeDiffuseLighting;
}
#endif

9
Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/SinglePass.meta


fileFormatVersion: 2
guid: dfb6e7f2aee22e147834de3e01b7c03c
folderAsset: yes
timeCreated: 1477266406
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
正在加载...
取消
保存