浏览代码

HDRenderLoop: Draft of refator not working

/main
sebastienlagarde 8 年前
当前提交
5882c727
共有 7 个文件被更改,包括 500 次插入407 次删除
  1. 253
      Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.cs
  2. 14
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/LightDefinition.cs
  3. 124
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/SinglePass/SinglePass.cs
  4. 361
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/TilePass.cs
  5. 2
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/TilePass.cs.hlsl
  6. 2
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/TilePassLoop.hlsl
  7. 151
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/LightLoop.cs

253
Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.cs


ShadowRenderPass m_ShadowPass;
public const int k_MaxDirectionalLightsOnSCreen = 3;
public const int k_MaxPunctualLightsOnSCreen = 512;
public const int k_MaxAreaLightsOnSCreen = 128;
public const int k_MaxEnvLightsOnSCreen = 64;
public const int k_MaxShadowOnScreen = 16;
public const int k_MaxCascadeCount = 4; //Should be not less than m_Settings.directionalLightCascadeCount;
[SerializeField]
TextureSettings m_TextureSettings = TextureSettings.Default;

RenderTargetIdentifier m_CameraDepthBufferRT;
RenderTargetIdentifier m_VelocityBufferRT;
RenderTargetIdentifier m_DistortionBufferRT;
public class LightList
{
public List<DirectionalLightData> directionalLights;
public List<DirectionalShadowData> directionalShadows;
public List<LightData> punctualLights;
public List<PunctualShadowData> punctualShadows;
public List<LightData> areaLights;
public List<EnvLightData> envLights;
public Vector4[] directionalShadowSplitSphereSqr;
// Index mapping list to go from GPU lights (above) to CPU light (in cullResult)
public List<int> directionalCullIndices;
public List<int> punctualCullIndices;
public List<int> areaCullIndices;
public List<int> envCullIndices;
public void Clear()
{
directionalLights.Clear();
directionalShadows.Clear();
punctualLights.Clear();
punctualShadows.Clear();
areaLights.Clear();
envLights.Clear();
directionalCullIndices.Clear();
punctualCullIndices.Clear();
areaCullIndices.Clear();
envCullIndices.Clear();
}
public void Allocate()
{
directionalLights = new List<DirectionalLightData>();
punctualLights = new List<LightData>();
areaLights = new List<LightData>();
envLights = new List<EnvLightData>();
punctualShadows = new List<PunctualShadowData>();
directionalShadows = new List<DirectionalShadowData>();
directionalShadowSplitSphereSqr = new Vector4[k_MaxCascadeCount];
directionalCullIndices = new List<int>();
punctualCullIndices = new List<int>();
areaCullIndices = new List<int>();
envCullIndices = new List<int>();
}
}
LightList m_lightList;
// TODO: Find a way to automatically create/iterate through lightloop
enum LightLoopType
{
SinglePass = 0,
TilePass = 1
};
SinglePass.LightLoop m_SinglePassLightLoop = new SinglePass.LightLoop();
TilePass.LightLoop m_TilePassLightLoop = new TilePass.LightLoop();
public TilePass.LightLoop tilePassLightLoop
{
get { return m_TilePassLightLoop; }
}
LightLoop m_lightLoop = new SinglePass();
TextureCacheCubemap m_CubeReflTexArray;
TextureCache2D m_CookieTexArray;
TextureCacheCubemap m_CubeCookieTexArray;
public void OnValidate()
{
// Calling direction Rebuild() here cause this warning:

}
public void ChangeLoop(LightLoopType type)
{
m_lightLoop.Cleanup();
switch (type)
{
case LightLoopType.SinglePass:
m_lightLoop = new SinglePass();
break;
case LightLoopType.TilePass:
m_lightLoop = new TilePass();
break;
}
m_lightLoop.Rebuild();
}
public override void Rebuild()

m_LitRenderLoop.Rebuild();
m_CookieTexArray = new TextureCache2D();
m_CookieTexArray.AllocTextureArray(8, m_TextureSettings.spotCookieSize, m_TextureSettings.spotCookieSize, TextureFormat.RGBA32, true);
m_CubeCookieTexArray = new TextureCacheCubemap();
m_CubeCookieTexArray.AllocTextureArray(4, m_TextureSettings.pointCookieSize, TextureFormat.RGBA32, true);
m_CubeReflTexArray = new TextureCacheCubemap();
m_CubeReflTexArray.AllocTextureArray(32, m_TextureSettings.reflectionCubemapSize, TextureFormat.BC6H, true);
m_SinglePassLightLoop.Rebuild();
tilePassLightLoop.Rebuild();
m_lightList = new LightList();
m_lightList.Allocate();
m_lightLoop.Rebuild();
m_Dirty = false;
}

public override void Cleanup()
{
m_LitRenderLoop.Cleanup();
m_SinglePassLightLoop.Cleanup();
m_TilePassLightLoop.Cleanup();
m_lightLoop.Cleanup();
if (m_CubeReflTexArray != null)
{
m_CubeReflTexArray.Release();
m_CubeReflTexArray = null;
}
if (m_CookieTexArray != null)
{
m_CookieTexArray.Release();
m_CookieTexArray = null;
}
if (m_CubeCookieTexArray != null)
{
m_CubeCookieTexArray.Release();
m_CubeCookieTexArray = null;
}
if (m_SkyRenderer != null)
{
m_SkyRenderer.Cleanup();

#endif
}
void NewFrame()
{
m_CookieTexArray.NewFrame();
m_CubeCookieTexArray.NewFrame();
m_CubeReflTexArray.NewFrame();
}
void InitAndClearBuffer(Camera camera, RenderLoop renderLoop)
{
using (new Utilities.ProfilingSample("InitAndClearBuffer", renderLoop))

// Bind material data
m_LitRenderLoop.Bind();
if (debugParameters.useSinglePassLightLoop)
{
m_SinglePassLightLoop.RenderDeferredLighting(camera, renderLoop, m_CameraColorBuffer);
}
else
{
tilePassLightLoop.RenderDeferredLighting(camera, renderLoop, m_CameraColorBufferRT);
}
m_lightLoop.RenderDeferredLighting(camera, renderLoop, m_CameraColorBuffer);
}
void RenderSky(Camera camera, RenderLoop renderLoop)

}
}
void PrepareLightsForGPU(CullResults cullResults, Camera camera, ref ShadowOutput shadowOutput, ref LightList lightList)
void PrepareLightsForGPU(CullResults cullResults, Camera camera, ref ShadowOutput shadowOutput)
lightList.Clear();
for (int lightIndex = 0, numLights = cullResults.visibleLights.Length; lightIndex < numLights; ++lightIndex)
{
var light = cullResults.visibleLights[lightIndex];

continue;
}
// Linear intensity calculation (different Unity 5.5)
var lightColorR = light.light.intensity * Mathf.GammaToLinearSpace(light.light.color.r);
var lightColorG = light.light.intensity * Mathf.GammaToLinearSpace(light.light.color.g);
var lightColorB = light.light.intensity * Mathf.GammaToLinearSpace(light.light.color.b);
if (light.lightType == LightType.Directional)
{
if (lightList.directionalLights.Count >= k_MaxDirectionalLightsOnSCreen)
continue;
var directionalLightData = new DirectionalLightData();
// Light direction for directional and is opposite to the forward direction
directionalLightData.direction = -light.light.transform.forward;
directionalLightData.up = light.light.transform.up;
directionalLightData.right = light.light.transform.right;
directionalLightData.positionWS = light.light.transform.position;
directionalLightData.color = new Vector3(lightColorR, lightColorG, lightColorB);
directionalLightData.diffuseScale = additionalData.affectDiffuse ? 1.0f : 0.0f;
directionalLightData.specularScale = additionalData.affectSpecular ? 1.0f : 0.0f;
directionalLightData.invScaleX = 1.0f / light.light.transform.localScale.x;
directionalLightData.invScaleY = 1.0f / light.light.transform.localScale.y;
directionalLightData.cosAngle = 0.0f;
directionalLightData.sinAngle = 0.0f;
directionalLightData.shadowIndex = -1;
directionalLightData.cookieIndex = -1;
if (light.light.cookie != null)
{
directionalLightData.tileCookie = (light.light.cookie.wrapMode == TextureWrapMode.Repeat);
directionalLightData.cookieIndex = m_CookieTexArray.FetchSlice(light.light.cookie);
}
bool hasDirectionalShadows = light.light.shadows != LightShadows.None && shadowOutput.GetShadowSliceCountLightIndex(lightIndex) != 0;
bool hasDirectionalNotReachMaxLimit = lightList.directionalShadows.Count == 0; // Only one cascade shadow allowed
if (hasDirectionalShadows && hasDirectionalNotReachMaxLimit) // Note < MaxShadows should be check at shadowOutput creation
{
// When we have a point light, we assumed that there is 6 consecutive PunctualShadowData
directionalLightData.shadowIndex = 0;
for (int sliceIndex = 0; sliceIndex < shadowOutput.GetShadowSliceCountLightIndex(lightIndex); ++sliceIndex)
{
DirectionalShadowData directionalShadowData = new DirectionalShadowData();
int shadowSliceIndex = shadowOutput.GetShadowSliceIndex(lightIndex, sliceIndex);
directionalShadowData.worldToShadow = shadowOutput.shadowSlices[shadowSliceIndex].shadowTransform.transpose; // Transpose for hlsl reading ?
directionalShadowData.bias = light.light.shadowBias;
lightList.directionalShadows.Add(directionalShadowData);
}
// Fill split information for shaders
for (int s = 0; s < k_MaxCascadeCount; ++s)
{
lightList.directionalShadowSplitSphereSqr[s] = shadowOutput.directionalShadowSplitSphereSqr[s];
}
}
lightList.directionalLights.Add(directionalLightData);
lightList.directionalCullIndices.Add(lightIndex);
continue;
}
// Note: LightType.Area is offline only, use for baking, no need to test it
var lightData = new LightData();

if (additionalData.archetype == LightArchetype.Punctual)
{
lightList.punctualLights.Add(lightData);
lightList.punctualCullIndices.Add(lightIndex);
}
else
{

// Area and line lights are both currently stored as area lights on the GPU.
lightList.areaLights.Add(lightData);
lightList.areaCullIndices.Add(lightIndex);
}
}

envLightData.offsetLS = probe.center; // center is misnamed, it is the offset (in local space) from center of the bounding box to the cubemap capture point
envLightData.blendDistance = blendDistance;
lightList.envLights.Add(envLightData);
lightList.envCullIndices.Add(probeIndex);
if (debugParameters.useSinglePassLightLoop)
{
m_SinglePassLightLoop.PrepareLightsForGPU(cullResults, camera, m_lightList);
}
else
{
tilePassLightLoop.PrepareLightsForGPU(cullResults, camera, m_lightList);
}
m_lightLoop.PrepareLightsForGPU(cullResults, camera);
}
void Resize(Camera camera)

// For now consider we have only one camera that go to this code, the main one.
m_SkyRenderer.Resize(m_SkyParameters); // TODO: Also a bad naming, here we just want to realloc texture if skyparameters change (usefull for lookdev)
if (camera.pixelWidth != m_WidthOnRecord || camera.pixelHeight != m_HeightOnRecord || tilePassLightLoop.NeedResize())
if (camera.pixelWidth != m_WidthOnRecord || camera.pixelHeight != m_HeightOnRecord || m_lightLoop.NeedResize())
tilePassLightLoop.ReleaseResolutionDependentBuffers();
m_lightLoop.ReleaseResolutionDependentBuffers();
tilePassLightLoop.AllocResolutionDependentBuffers(camera.pixelWidth, camera.pixelHeight);
m_lightLoop.AllocResolutionDependentBuffers(camera.pixelWidth, camera.pixelHeight);
// update recorded window resolution
m_WidthOnRecord = camera.pixelWidth;

public void PushGlobalParams(Camera camera, RenderLoop renderLoop, HDRenderLoop.LightList lightList)
{
Shader.SetGlobalTexture("_CookieTextures", m_CookieTexArray.GetTexCache());
Shader.SetGlobalTexture("_CookieCubeTextures", m_CubeCookieTexArray.GetTexCache());
Shader.SetGlobalTexture("_EnvTextures", m_CubeReflTexArray.GetTexCache());
if (m_SkyRenderer.IsSkyValid(m_SkyParameters))
{
m_SkyRenderer.SetGlobalSkyTexture();

Shader.SetGlobalInt("_EnvLightSkyEnabled", 0);
}
if (debugParameters.useSinglePassLightLoop)
{
m_SinglePassLightLoop.PushGlobalParams(camera, renderLoop, lightList);
}
else
{
tilePassLightLoop.PushGlobalParams(camera, renderLoop, lightList);
}
m_lightLoop.PushGlobalParams(camera, renderLoop, lightList);
}
public override void Render(Camera[] cameras, RenderLoop renderLoop)

}
// Do anything we need to do upon a new frame.
NewFrame();
m_lightLoop.NewFrame();
// Set Frame constant buffer
// TODO...

using (new Utilities.ProfilingSample("Build Light list", renderLoop))
{
PrepareLightsForGPU(cullResults, camera, ref shadows, ref m_lightList);
if (!debugParameters.useSinglePassLightLoop)
tilePassLightLoop.BuildGPULightLists(camera, renderLoop, m_lightList, m_CameraDepthBufferRT);
m_lightLoop.PrepareLightsForGPU(cullResults, camera, ref shadows);
m_lightLoop.BuildGPULightLists(camera, renderLoop, m_CameraDepthBufferRT);
PushGlobalParams(camera, renderLoop, m_lightList);
PushGlobalParams(camera, renderLoop);
}
RenderDeferredLighting(camera, renderLoop);

14
Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/LightDefinition.cs


// TODO: we may have to add various parameters here for shadow - was suppose to be coupled with a light loop
// A point light is 6x PunctualShadowData
[GenerateHLSL]
public struct PunctualShadowData
public struct ShadowData
{
// World to ShadowMap matrix
// Include scale and bias for shadow atlas if any

public float bias;
public float quality;
public float unused;
};
[GenerateHLSL]
public struct DirectionalShadowData
{
// World to ShadowMap matrix
// Include scale and bias for shadow atlas if any
public Matrix4x4 worldToShadow;
public float bias;
public float quality;
public Vector2 unused2;
};
[GenerateHLSL]

124
Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/SinglePass/SinglePass.cs


namespace UnityEngine.Experimental.ScriptableRenderLoop
{
namespace SinglePass
public class SinglePass : LightLoop
//-----------------------------------------------------------------------------
// structure definition
//-----------------------------------------------------------------------------
public class LightLoop
string GetKeyword()
string GetKeyword()
{
return "LIGHTLOOP_SINGLE_PASS";
}
return "LIGHTLOOP_SINGLE_PASS";
}
// Static keyword is required here else we get a "DestroyBuffer can only be call in main thread"
static ComputeBuffer s_DirectionalLights = null;
static ComputeBuffer s_PunctualLightList = null;
static ComputeBuffer s_EnvLightList = null;
static ComputeBuffer s_AreaLightList = null;
static ComputeBuffer s_PunctualShadowList = null;
static ComputeBuffer s_DirectionalShadowList = null;
Material m_DeferredMaterial = null;
public void Rebuild()
{
s_DirectionalLights = new ComputeBuffer(HDRenderLoop.k_MaxDirectionalLightsOnSCreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(DirectionalLightData)));
s_DirectionalShadowList = new ComputeBuffer(HDRenderLoop.k_MaxCascadeCount, System.Runtime.InteropServices.Marshal.SizeOf(typeof(DirectionalShadowData)));
s_PunctualLightList = new ComputeBuffer(HDRenderLoop.k_MaxPunctualLightsOnSCreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(LightData)));
s_AreaLightList = new ComputeBuffer(HDRenderLoop.k_MaxAreaLightsOnSCreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(LightData)));
s_EnvLightList = new ComputeBuffer(HDRenderLoop.k_MaxEnvLightsOnSCreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(EnvLightData)));
s_PunctualShadowList = new ComputeBuffer(HDRenderLoop.k_MaxShadowOnScreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(PunctualShadowData)));
public const int k_MaxDirectionalLightsOnSCreen = 3;
public const int k_MaxPunctualLightsOnSCreen = 512;
public const int k_MaxAreaLightsOnSCreen = 128;
public const int k_MaxEnvLightsOnSCreen = 64;
public const int k_MaxShadowOnScreen = 16;
public const int k_MaxCascadeCount = 4; //Should be not less than m_Settings.directionalLightCascadeCount;
m_DeferredMaterial = Utilities.CreateEngineMaterial("Hidden/HDRenderLoop/Deferred");
m_DeferredMaterial.EnableKeyword("LIGHTLOOP_SINGLE_PASS");
}
Material m_DeferredMaterial = null;
public void Cleanup()
{
Utilities.SafeRelease(s_DirectionalLights);
Utilities.SafeRelease(s_DirectionalShadowList);
Utilities.SafeRelease(s_PunctualLightList);
Utilities.SafeRelease(s_AreaLightList);
Utilities.SafeRelease(s_EnvLightList);
Utilities.SafeRelease(s_PunctualShadowList);
public override void Rebuild()
{
base.Rebuild();
Utilities.Destroy(m_DeferredMaterial);
}
m_DeferredMaterial = Utilities.CreateEngineMaterial("Hidden/HDRenderLoop/Deferred");
m_DeferredMaterial.EnableKeyword(GetKeyword());
}
public void PrepareLightsForGPU(CullResults cullResults, Camera camera, HDRenderLoop.LightList lightList) {}
public override void Cleanup()
{
base.Cleanup();
public void PushGlobalParams(Camera camera, RenderLoop loop, HDRenderLoop.LightList lightList)
{
s_DirectionalLights.SetData(lightList.directionalLights.ToArray());
s_DirectionalShadowList.SetData(lightList.directionalShadows.ToArray());
s_PunctualLightList.SetData(lightList.punctualLights.ToArray());
s_AreaLightList.SetData(lightList.areaLights.ToArray());
s_EnvLightList.SetData(lightList.envLights.ToArray());
s_PunctualShadowList.SetData(lightList.punctualShadows.ToArray());
Utilities.Destroy(m_DeferredMaterial);
}
Shader.SetGlobalBuffer("_DirectionalLightList", s_DirectionalLights);
Shader.SetGlobalInt("_DirectionalLightCount", lightList.directionalLights.Count);
Shader.SetGlobalBuffer("_DirectionalShadowList", s_DirectionalShadowList);
Shader.SetGlobalBuffer("_PunctualLightList", s_PunctualLightList);
Shader.SetGlobalInt("_PunctualLightCount", lightList.punctualLights.Count);
Shader.SetGlobalBuffer("_AreaLightList", s_AreaLightList);
Shader.SetGlobalInt("_AreaLightCount", lightList.areaLights.Count);
Shader.SetGlobalBuffer("_PunctualShadowList", s_PunctualShadowList);
Shader.SetGlobalBuffer("_EnvLightList", s_EnvLightList);
Shader.SetGlobalInt("_EnvLightCount", lightList.envLights.Count);
public override void PrepareLightsForGPU(CullResults cullResults, Camera camera)
{
}
Shader.SetGlobalVectorArray("_DirShadowSplitSpheres", lightList.directionalShadowSplitSphereSqr);
}
public override void PushGlobalParams(Camera camera, RenderLoop loop)
{
base.PushGlobalParams();
}
public void RenderDeferredLighting(Camera camera, RenderLoop renderLoop, RenderTargetIdentifier cameraColorBufferRT)
{
var invViewProj = Utilities.GetViewProjectionMatrix(camera).inverse;
m_DeferredMaterial.SetMatrix("_InvViewProjMatrix", invViewProj);
public override void RenderDeferredLighting(Camera camera, RenderLoop renderLoop, RenderTargetIdentifier cameraColorBufferRT)
{
var invViewProj = Utilities.GetViewProjectionMatrix(camera).inverse;
m_DeferredMaterial.SetMatrix("_InvViewProjMatrix", invViewProj);
var screenSize = Utilities.ComputeScreenSize(camera);
m_DeferredMaterial.SetVector("_ScreenSize", screenSize);
var screenSize = Utilities.ComputeScreenSize(camera);
m_DeferredMaterial.SetVector("_ScreenSize", screenSize);
m_DeferredMaterial.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
m_DeferredMaterial.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
m_DeferredMaterial.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
m_DeferredMaterial.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
// m_gbufferManager.BindBuffers(m_DeferredMaterial);
// TODO: Bind depth textures
// m_gbufferManager.BindBuffers(m_DeferredMaterial);
// TODO: Bind depth textures
using (new Utilities.ProfilingSample("SinglePass - Deferred Lighting Pass", renderLoop))
{
var cmd = new CommandBuffer { name = "" };
cmd.Blit(null, cameraColorBufferRT, m_DeferredMaterial, 0);
renderLoop.ExecuteCommandBuffer(cmd);
cmd.Dispose();
}
using (new Utilities.ProfilingSample("SinglePass - Deferred Lighting Pass", renderLoop))
{
var cmd = new CommandBuffer { name = "" };
cmd.Blit(null, cameraColorBufferRT, m_DeferredMaterial, 0);
renderLoop.ExecuteCommandBuffer(cmd);
cmd.Dispose();
}
}
}

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


// direct lights and reflection probes for now
public static int NR_LIGHT_CATEGORIES = 3;
public static int DIRECT_LIGHT_CATEGORY = 0;
public static int PUNCTUAL_LIGHT_CATEGORY = 0;
public static int REFLECTION_LIGHT_CATEGORY = 1;
public static int AREA_LIGHT_CATEGORY = 2;
}

};
[GenerateHLSL]
public struct LightShapeData
public struct LightVolumeData
{
public Vector3 lightPos;
public uint lightIndex; // Index in light tabs like LightData / EnvLightData

public class LightLoop
{
string GetKeyword()
{
return "LIGHTLOOP_TILE_PASS";
}
public const int k_MaxDirectionalLightsOnSCreen = 3;
public const int k_MaxPunctualLightsOnSCreen = 512;
public const int k_MaxAreaLightsOnSCreen = 128;
public const int k_MaxEnvLightsOnSCreen = 64;
public const int k_MaxShadowOnScreen = 16;
public const int k_MaxCascadeCount = 4; //Should be not less than m_Settings.directionalLightCascadeCount;
// Static keyword is required here else we get a "DestroyBuffer can only be call in main thread"
static ComputeBuffer s_DirectionalLights = null;
static ComputeBuffer s_PunctualLightList = null;
static ComputeBuffer s_EnvLightList = null;
static ComputeBuffer s_AreaLightList = null;
static ComputeBuffer s_PunctualShadowList = null;
static ComputeBuffer s_DirectionalShadowList = null;
TextureCacheCubemap m_CubeReflTexArray;
TextureCache2D m_CookieTexArray;
TextureCacheCubemap m_CubeCookieTexArray;
public const int MaxNumLights = 1024;
public const int MaxNumDirLights = 2;

private static int s_GenListPerTileKernel;
private static int s_GenListPerVoxelKernel;
private static int s_ClearVoxelAtomicKernel;
private static ComputeBuffer s_LightShapeDataBuffer = null;
private static ComputeBuffer s_LigthVolumeDataBuffer = null;
private static ComputeBuffer s_ConvexBoundsBuffer = null;
private static ComputeBuffer s_AABBBoundsBuffer = null;
private static ComputeBuffer s_LightList = null;

private static ComputeBuffer s_GlobalLightListAtomic = null;
// clustered light list specific buffers and data end
SFiniteLightBound[] m_boundData;
LightShapeData[] m_lightShapeData;
int m_lightCount;
bool usingFptl

}
}
// Static keyword is required here else we get a "DestroyBuffer can only be call in main thread"
static ComputeBuffer s_DirectionalLights = null;
static ComputeBuffer s_PunctualLightList = null;
static ComputeBuffer s_EnvLightList = null;
static ComputeBuffer s_AreaLightList = null;
static ComputeBuffer s_PunctualShadowList = null;
static ComputeBuffer s_DirectionalShadowList = null;
Material m_SingleDeferredMaterial = null;
const int k_TileSize = 16;

s_GenListPerTileKernel = buildPerTileLightListShader.FindKernel(enableBigTilePrepass ? "TileLightListGen_SrcBigTile" : "TileLightListGen");
s_AABBBoundsBuffer = new ComputeBuffer(2 * MaxNumLights, 3 * sizeof(float));
s_ConvexBoundsBuffer = new ComputeBuffer(MaxNumLights, System.Runtime.InteropServices.Marshal.SizeOf(typeof(SFiniteLightBound)));
s_LightShapeDataBuffer = new ComputeBuffer(MaxNumLights, System.Runtime.InteropServices.Marshal.SizeOf(typeof(LightShapeData)));
s_LigthVolumeDataBuffer = new ComputeBuffer(MaxNumLights, System.Runtime.InteropServices.Marshal.SizeOf(typeof(LigthVolumeData)));
buildPerTileLightListShader.SetBuffer(s_GenListPerTileKernel, "_LightShapeData", s_LightShapeDataBuffer);
buildPerTileLightListShader.SetBuffer(s_GenListPerTileKernel, "_LigthVolumeData", s_LigthVolumeDataBuffer);
buildPerTileLightListShader.SetBuffer(s_GenListPerTileKernel, "g_data", s_ConvexBoundsBuffer);
if (enableClustered)

s_ClearVoxelAtomicKernel = buildPerVoxelLightListShader.FindKernel("ClearAtomic");
buildPerVoxelLightListShader.SetBuffer(s_GenListPerVoxelKernel, "g_vBoundsBuffer", s_AABBBoundsBuffer);
buildPerVoxelLightListShader.SetBuffer(s_GenListPerVoxelKernel, "_LightShapeData", s_LightShapeDataBuffer);
buildPerVoxelLightListShader.SetBuffer(s_GenListPerVoxelKernel, "_LigthVolumeData", s_LigthVolumeDataBuffer);
buildPerVoxelLightListShader.SetBuffer(s_GenListPerVoxelKernel, "g_data", s_ConvexBoundsBuffer);
s_GlobalLightListAtomic = new ComputeBuffer(1, sizeof(uint));

{
s_GenListPerBigTileKernel = buildPerBigTileLightListShader.FindKernel("BigTileLightListGen");
buildPerBigTileLightListShader.SetBuffer(s_GenListPerBigTileKernel, "g_vBoundsBuffer", s_AABBBoundsBuffer);
buildPerBigTileLightListShader.SetBuffer(s_GenListPerBigTileKernel, "_LightShapeData", s_LightShapeDataBuffer);
buildPerBigTileLightListShader.SetBuffer(s_GenListPerBigTileKernel, "_LigthVolumeData", s_LigthVolumeDataBuffer);
m_boundData = new SFiniteLightBound[MaxNumLights];
m_lightShapeData = new LightShapeData[MaxNumLights];
s_DirectionalLights = new ComputeBuffer(HDRenderLoop.k_MaxDirectionalLightsOnSCreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(DirectionalLightData)));
s_DirectionalShadowList = new ComputeBuffer(HDRenderLoop.k_MaxCascadeCount, System.Runtime.InteropServices.Marshal.SizeOf(typeof(DirectionalShadowData)));
s_PunctualLightList = new ComputeBuffer(HDRenderLoop.k_MaxPunctualLightsOnSCreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(LightData)));
s_AreaLightList = new ComputeBuffer(HDRenderLoop.k_MaxAreaLightsOnSCreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(LightData)));
s_EnvLightList = new ComputeBuffer(HDRenderLoop.k_MaxEnvLightsOnSCreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(EnvLightData)));
s_PunctualShadowList = new ComputeBuffer(HDRenderLoop.k_MaxShadowOnScreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(PunctualShadowData)));
s_DirectionalLights = new ComputeBuffer(k_MaxDirectionalLightsOnSCreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(DirectionalLightData)));
s_DirectionalShadowList = new ComputeBuffer(k_MaxCascadeCount, System.Runtime.InteropServices.Marshal.SizeOf(typeof(ShadowData)));
s_PunctualLightList = new ComputeBuffer(k_MaxPunctualLightsOnSCreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(LightData)));
s_AreaLightList = new ComputeBuffer(k_MaxAreaLightsOnSCreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(LightData)));
s_EnvLightList = new ComputeBuffer(k_MaxEnvLightsOnSCreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(EnvLightData)));
s_PunctualShadowList = new ComputeBuffer(k_MaxShadowOnScreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(ShadowData)));
m_DeferredDirectMaterial = Utilities.CreateEngineMaterial("Hidden/HDRenderLoop/Deferred");
m_DeferredDirectMaterial.EnableKeyword("LIGHTLOOP_TILE_PASS");

m_DeferredAllMaterial.EnableKeyword("LIGHTLOOP_TILE_ALL");
m_DebugViewTilesMaterial = Utilities.CreateEngineMaterial("Hidden/HDRenderLoop/DebugViewTiles");
m_SingleDeferredMaterial = Utilities.CreateEngineMaterial("Hidden/HDRenderLoop/Deferred");
m_DeferredAllMaterial.EnableKeyword("LIGHTLOOP_SINGLE_PASS");
}
public void Cleanup()

Utilities.SafeRelease(s_AABBBoundsBuffer);
Utilities.SafeRelease(s_ConvexBoundsBuffer);
Utilities.SafeRelease(s_LightShapeDataBuffer);
Utilities.SafeRelease(s_LigthVolumeDataBuffer);
// enableClustered
Utilities.SafeRelease(s_GlobalLightListAtomic);

Utilities.Destroy(m_DeferredIndirectMaterial);
Utilities.Destroy(m_DeferredAllMaterial);
Utilities.Destroy(m_DebugViewTilesMaterial);
Utilities.Destroy(m_SingleDeferredMaterial);
}
public bool NeedResize()

return camera.projectionMatrix * GetFlipMatrix();
}
public Vector3 GetLightColor(VisibleLight light)
{
// Linear intensity calculation (different from legacy Unity - match LinearLighting new option in 5.6)
var lightColorR = light.light.intensity * Mathf.GammaToLinearSpace(light.light.color.r);
var lightColorG = light.light.intensity * Mathf.GammaToLinearSpace(light.light.color.g);
var lightColorB = light.light.intensity * Mathf.GammaToLinearSpace(light.light.color.b);
return new Vector3(lightColorR, lightColorG, lightColorB);
}
var numCategories = (int)LightDefinitions.NR_LIGHT_CATEGORIES;
var numVolTypes = (int)LightDefinitions.MAX_VOLUME_TYPES;
// 1. Count the number of lights and type of volume required
int directionalLightcount = 0;
int punctualLightcount = 0;
int areaLightCount = 0;
int envLightCount = 0;
int numCategories = (int)LightDefinitions.NR_LIGHT_CATEGORIES;
int numVolTypes = (int)LightDefinitions.MAX_VOLUME_TYPES;
// Use for first space screen AABB
var numEntries = new int[numCategories, numVolTypes];
var offsets = new int[numCategories, numVolTypes];

foreach (var punctualLight in lightList.punctualLights)
var lightIsUse = new bool[cullResults.visibleLights.Length];
var probeIsUse = new bool[cullResults.reflectionProbe.Length];
for (int lightIndex = 0, numLights = cullResults.visibleLights.Length; lightIndex < numLights; ++lightIndex)
var volType = punctualLight.lightType == GPULightType.Spot ? LightDefinitions.SPOT_VOLUME : (punctualLight.lightType == GPULightType.Point ? LightDefinitions.SPHERE_VOLUME : -1);
if (volType >= 0)
++numEntries[LightDefinitions.DIRECT_LIGHT_CATEGORY, volType];
}
lightIsUse[lightIndex] = false;
var light = cullResults.visibleLights[lightIndex];
// We only process light with additional data
var additionalData = light.light.GetComponent<AdditionalLightData>();
if (additionalData == null)
{
Debug.LogWarning("Light entity detected without additional data, will not be taken into account " + light.light.name);
continue;
}
if (additionalData.archetype == LightArchetype.Punctual)
{
switch (light.lightType)
{
case LightType.Point:
if (punctualLightcount >= k_MaxPunctualLightsOnSCreen)
continue;
++numEntries[LightDefinitions.PUNCTUAL_LIGHT_CATEGORY, LightDefinitions.SPHERE_VOLUME];
++punctualLightcount;
lightIsUse[lightIndex] = true;
break;
// TODO: manage sphere_light
foreach (var envLight in lightList.envLights)
{
var volType = LightDefinitions.BOX_VOLUME; // always a box for now
++numEntries[LightDefinitions.REFLECTION_LIGHT_CATEGORY, volType];
case LightType.Spot:
if (punctualLightcount >= k_MaxPunctualLightsOnSCreen)
continue;
++numEntries[LightDefinitions.PUNCTUAL_LIGHT_CATEGORY, LightDefinitions.SPOT_VOLUME];
++punctualLightcount;
lightIsUse[lightIndex] = true;
break;
case LightType.Directional:
if (directionalLightcount >= k_MaxDirectionalLightsOnSCreen)
continue;
// No need to add volume, always visible
++directionalLightcount;
lightIsUse[lightIndex] = true;
break;
}
}
else
{
switch (additionalData.archetype)
{
case LightArchetype.Rectangle:
case LightArchetype.Line:
if (lightList.areaLights.Count >= k_MaxAreaLightsOnSCreen)
continue;
++numEntries[LightDefinitions.AREA_LIGHT_CATEGORY, LightDefinitions.BOX_VOLUME];
++areaLightCount;
lightIsUse[lightIndex] = true;
break;
}
}
foreach (var areaLight in lightList.areaLights)
for (int probeIndex = 0, numProbes = cullResults.visibleReflectionProbes.Length; probeIndex < numProbes; probeIndex++)
var volType = LightDefinitions.BOX_VOLUME;
++numEntries[LightDefinitions.AREA_LIGHT_CATEGORY, volType];
}
var probe = cullResults.visibleReflectionProbes[probeIndex];
if (lightList.envLights.Count >= k_MaxEnvLightsOnSCreen)
continue;
// add decals here too similar to the above
// TODO Handle sphere shape
++numEntries[LightDefinitions.REFLECTION_LIGHT_CATEGORY, LightDefinitions.BOX_VOLUME];
++envLightCount;
probeIsUse[probeIndex] = true;
}
// TODO: Can add volume decal in the future
// establish offsets
for (int category = 0; category < numCategories; category++)

}
}
// 2. Allocate light list
// TODO: don't allocate 0!
var directionalLights = new DirectionalLightData[directionalLightcount];
var punctualLights = new LightData[punctualLightcount];
var areaLights = new LightData[areaLightCount];
var directionalShadows = new ShadowData[k_MaxCascadeCount];
// k_MaxShadowOnScreen is share between punctual and area shadows, here we just maximise allocation
var punctualShadows = new ShadowData[k_MaxShadowOnScreen];
var areaShadows = new ShadowData[k_MaxShadowOnScreen];
var directionalShadowSplitSphereSqr = new Vector4[k_MaxCascadeCount];
int volumeCount = punctualLightcount + areaLightCount + envLightCount;
var boundData = new SFiniteLightData[volumeCount];
var lightVolumeData = new LightVolumeData[volumeCount];
// 3. Go thought all lights, convert them to GPU format.
// Create simultaneously data for culling (LigthVolumeData and rendering
int directionalLightIndex = 0;
for (int lightIndex = 0; lightIndex < lightList.punctualLights.Count; lightIndex++)
for (int lightIndex = 0, numLights = cullResults.visibleLights.Length; lightIndex < numLights; ++lightIndex)
LightData punctualLightData = lightList.punctualLights[lightIndex];
VisibleLight light = cullResults.visibleLights[lightList.punctualCullIndices[lightIndex]];
if (!lightIsUse[lightIndex])
continue;
var light = cullResults.visibleLights[lightIndex];
var additionalData = light.light.GetComponent<AdditionalLightData>();
if (light.lightType == LightType.Directional)
{
var directionalLightData = new DirectionalLightData();
// Light direction for directional and is opposite to the forward direction
directionalLightData.direction = -light.light.transform.forward;
directionalLightData.up = light.light.transform.up;
directionalLightData.right = light.light.transform.right;
directionalLightData.positionWS = light.light.transform.position;
directionalLightData.color = GetLightColor(light);
directionalLightData.diffuseScale = additionalData.affectDiffuse ? 1.0f : 0.0f;
directionalLightData.specularScale = additionalData.affectSpecular ? 1.0f : 0.0f;
directionalLightData.invScaleX = 1.0f / light.light.transform.localScale.x;
directionalLightData.invScaleY = 1.0f / light.light.transform.localScale.y;
directionalLightData.cosAngle = 0.0f;
directionalLightData.sinAngle = 0.0f;
directionalLightData.shadowIndex = -1;
directionalLightData.cookieIndex = -1;
if (light.light.cookie != null)
{
directionalLightData.tileCookie = (light.light.cookie.wrapMode == TextureWrapMode.Repeat);
directionalLightData.cookieIndex = m_CookieTexArray.FetchSlice(light.light.cookie);
}
bool hasDirectionalShadows = light.light.shadows != LightShadows.None && shadowOutput.GetShadowSliceCountLightIndex(lightIndex) != 0;
bool hasDirectionalNotReachMaxLimit = lightList.directionalShadows.Count == 0; // Only one cascade shadow allowed
if (hasDirectionalShadows && hasDirectionalNotReachMaxLimit) // Note < MaxShadows should be check at shadowOutput creation
{
// When we have a point light, we assumed that there is 6 consecutive PunctualShadowData
directionalLightData.shadowIndex = 0;
for (int sliceIndex = 0; sliceIndex < shadowOutput.GetShadowSliceCountLightIndex(lightIndex); ++sliceIndex)
{
ShadowData directionalShadowData = new ShadowData();
int shadowSliceIndex = shadowOutput.GetShadowSliceIndex(lightIndex, sliceIndex);
directionalShadowData.worldToShadow = shadowOutput.shadowSlices[shadowSliceIndex].shadowTransform.transpose; // Transpose for hlsl reading ?
directionalShadowData.bias = light.light.shadowBias;
lightList.directionalShadows.Add(directionalShadowData);
}
// Fill split information for shaders
for (int s = 0; s < k_MaxCascadeCount; ++s)
{
lightList.directionalShadowSplitSphereSqr[s] = shadowOutput.directionalShadowSplitSphereSqr[s];
}
}
directionalLights[directionalLightIndex++];
continue;
}
// Note: LightType.Area is offline only, use for baking, no need to test it
var lightData = new LightData();
var range = light.range;
var lightToWorld = light.localToWorld;

var bound = new SFiniteLightBound();
var lightShapeData = new LightShapeData();
var ligthVolumeData = new LigthVolumeData();
lightShapeData.lightCategory = (uint)LightDefinitions.DIRECT_LIGHT_CATEGORY;
lightShapeData.lightIndex = (uint)lightIndex;
ligthVolumeData.lightCategory = (uint)LightDefinitions.PUNCTUAL_LIGHT_CATEGORY;
ligthVolumeData.lightIndex = (uint)lightIndex;
if (punctualLightData.lightType == GPULightType.Spot || punctualLightData.lightType == GPULightType.ProjectorPyramid)
{

bound.scaleXY = squeeze ? new Vector2(0.01f, 0.01f) : new Vector2(1.0f, 1.0f);
lightShapeData.lightAxisX = vx;
lightShapeData.lightAxisY = vy;
lightShapeData.lightAxisZ = vz;
lightShapeData.lightVolume = (uint)LightDefinitions.SPOT_VOLUME;
lightShapeData.lightPos = worldToView.MultiplyPoint(lightPos);
lightShapeData.radiusSq = range * range;
lightShapeData.cotan = cota;
ligthVolumeData.lightAxisX = vx;
ligthVolumeData.lightAxisY = vy;
ligthVolumeData.lightAxisZ = vz;
ligthVolumeData.lightVolume = (uint)LightDefinitions.SPOT_VOLUME;
ligthVolumeData.lightPos = worldToView.MultiplyPoint(lightPos);
ligthVolumeData.radiusSq = range * range;
ligthVolumeData.cotan = cota;
int i = LightDefinitions.DIRECT_LIGHT_CATEGORY, j = LightDefinitions.SPOT_VOLUME;
int i = LightDefinitions.PUNCTUAL_LIGHT_CATEGORY, j = LightDefinitions.SPOT_VOLUME;
index = numEntries2nd[i, j] + offsets[i, j]; ++numEntries2nd[i, j];
}
else // if (punctualLightData.lightType == GPULightType.Point)

Vector3 vz = lightToView.GetColumn(2);
// fill up ldata
lightShapeData.lightAxisX = vx;
lightShapeData.lightAxisY = vy;
lightShapeData.lightAxisZ = vz;
lightShapeData.lightVolume = (uint)LightDefinitions.SPHERE_VOLUME;
lightShapeData.lightPos = bound.center;
lightShapeData.radiusSq = range * range;
ligthVolumeData.lightAxisX = vx;
ligthVolumeData.lightAxisY = vy;
ligthVolumeData.lightAxisZ = vz;
ligthVolumeData.lightVolume = (uint)LightDefinitions.SPHERE_VOLUME;
ligthVolumeData.lightPos = bound.center;
ligthVolumeData.radiusSq = range * range;
int i = LightDefinitions.DIRECT_LIGHT_CATEGORY, j = LightDefinitions.SPHERE_VOLUME;
int i = LightDefinitions.PUNCTUAL_LIGHT_CATEGORY, j = LightDefinitions.SPHERE_VOLUME;
m_lightShapeData[index] = lightShapeData;
m_ligthVolumeData[index] = ligthVolumeData;
}
for (int envIndex = 0; envIndex < lightList.envLights.Count; envIndex++)

bound.scaleXY.Set(1.0f, 1.0f);
bound.radius = combinedExtent.magnitude;
var lightShapeData = new LightShapeData();
lightShapeData.lightVolume = (uint)LightDefinitions.BOX_VOLUME;
lightShapeData.lightCategory = (uint)LightDefinitions.REFLECTION_LIGHT_CATEGORY;
lightShapeData.lightIndex = (uint)envIndex;
var ligthVolumeData = new LigthVolumeData();
ligthVolumeData.lightVolume = (uint)LightDefinitions.BOX_VOLUME;
ligthVolumeData.lightCategory = (uint)LightDefinitions.REFLECTION_LIGHT_CATEGORY;
ligthVolumeData.lightIndex = (uint)envIndex;
lightShapeData.lightPos = Cw;
lightShapeData.lightAxisX = vx;
lightShapeData.lightAxisY = vy;
lightShapeData.lightAxisZ = vz;
ligthVolumeData.lightPos = Cw;
ligthVolumeData.lightAxisX = vx;
ligthVolumeData.lightAxisY = vy;
ligthVolumeData.lightAxisZ = vz;
lightShapeData.boxInnerDist = e;
lightShapeData.boxInvRange.Set(1.0f / delta.x, 1.0f / delta.y, 1.0f / delta.z);
ligthVolumeData.boxInnerDist = e;
ligthVolumeData.boxInvRange.Set(1.0f / delta.x, 1.0f / delta.y, 1.0f / delta.z);
m_lightShapeData[index] = lightShapeData;
m_ligthVolumeData[index] = ligthVolumeData;
}
for (int areaLightIndex = 0; areaLightIndex < lightList.areaLights.Count; areaLightIndex++)

// Fill bounds
var bound = new SFiniteLightBound();
var lightShapeData = new LightShapeData();
var ligthVolumeData = new LigthVolumeData();
lightShapeData.lightVolume = (uint)LightDefinitions.BOX_VOLUME;
lightShapeData.lightCategory = (uint)LightDefinitions.AREA_LIGHT_CATEGORY;
lightShapeData.lightIndex = (uint)areaLightIndex;
ligthVolumeData.lightVolume = (uint)LightDefinitions.BOX_VOLUME;
ligthVolumeData.lightCategory = (uint)LightDefinitions.AREA_LIGHT_CATEGORY;
ligthVolumeData.lightIndex = (uint)areaLightIndex;
if (areaLightData.lightType == GPULightType.Rectangle)

bound.scaleXY.Set(1.0f, 1.0f);
bound.radius = dimensions.magnitude;
lightShapeData.lightPos = centerVS;
lightShapeData.lightAxisX = xAxisVS;
lightShapeData.lightAxisY = yAxisVS;
lightShapeData.lightAxisZ = zAxisVS;
lightShapeData.boxInnerDist = dimensions;
lightShapeData.boxInvRange.Set(1e5f, 1e5f, 1e5f);
ligthVolumeData.lightPos = centerVS;
ligthVolumeData.lightAxisX = xAxisVS;
ligthVolumeData.lightAxisY = yAxisVS;
ligthVolumeData.lightAxisZ = zAxisVS;
ligthVolumeData.boxInnerDist = dimensions;
ligthVolumeData.boxInvRange.Set(1e5f, 1e5f, 1e5f);
}
else if (areaLightData.lightType == GPULightType.Line)
{

bound.scaleXY.Set(1.0f, 1.0f);
bound.radius = dimensions.magnitude;
lightShapeData.lightPos = centerVS;
lightShapeData.lightAxisX = xAxisVS;
lightShapeData.lightAxisY = yAxisVS;
lightShapeData.lightAxisZ = zAxisVS;
lightShapeData.boxInnerDist = new Vector3(areaLightData.size.x * 0.5f, 0.01f, 0.01f);
lightShapeData.boxInvRange.Set(1.0f / radius, 1.0f / radius, 1.0f / radius);
ligthVolumeData.lightPos = centerVS;
ligthVolumeData.lightAxisX = xAxisVS;
ligthVolumeData.lightAxisY = yAxisVS;
ligthVolumeData.lightAxisZ = zAxisVS;
ligthVolumeData.boxInnerDist = new Vector3(areaLightData.size.x * 0.5f, 0.01f, 0.01f);
ligthVolumeData.boxInvRange.Set(1.0f / radius, 1.0f / radius, 1.0f / radius);
}
else
{

int index = numEntries2nd[i, j] + offsets[i, j]; ++numEntries2nd[i, j];
m_boundData[index] = bound;
m_lightShapeData[index] = lightShapeData;
m_ligthVolumeData[index] = ligthVolumeData;
}
// Sanity check

m_lightCount = lightList.punctualLights.Count + lightList.envLights.Count + lightList.areaLights.Count;
s_ConvexBoundsBuffer.SetData(m_boundData); // TODO: check with Vlad what is happening here, do we copy 1024 element always ? Could we setup the size we want to copy ?
s_LightShapeDataBuffer.SetData(m_lightShapeData);
s_LigthVolumeDataBuffer.SetData(m_ligthVolumeData);
}
void VoxelLightListGeneration(CommandBuffer cmd, Camera camera, Matrix4x4 projscr, Matrix4x4 invProjscr, RenderTargetIdentifier cameraDepthBufferRT)

cmd.SetComputeTextureParam(deferredComputeShader, kernel, "_LightTextureB0", m_LightAttentuationTexture);
cmd.SetComputeBufferParam(deferredComputeShader, kernel, "g_vLightListGlobal", bUseClusteredForDeferred ? s_PerVoxelLightLists : s_LightList);
cmd.SetComputeBufferParam(deferredComputeShader, kernel, "_LightShapeData", s_LightShapeDataBuffer);
cmd.SetComputeBufferParam(deferredComputeShader, kernel, "_LigthVolumeData", s_LigthVolumeDataBuffer);
cmd.SetComputeBufferParam(deferredComputeShader, kernel, "g_dirLightData", s_DirLightList);
var defdecode = ReflectionProbe.GetDefaultTextureHDRDecodeValues();

2
Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/TilePass.cs.hlsl


#define BOX_VOLUME (2)
#define DIRECTIONAL_VOLUME (3)
#define NR_LIGHT_CATEGORIES (3)
#define DIRECT_LIGHT_CATEGORY (0)
#define PUNCTUAL_LIGHT_CATEGORY (0)
#define REFLECTION_LIGHT_CATEGORY (1)
#define AREA_LIGHT_CATEGORY (2)

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


#ifdef PROCESS_PUNCTUAL_LIGHT
uint punctualLightStart;
uint punctualLightCount;
GetCountAndStart(coord, DIRECT_LIGHT_CATEGORY, linearDepth, punctualLightStart, punctualLightCount);
GetCountAndStart(coord, PUNCTUAL_LIGHT_CATEGORY, linearDepth, punctualLightStart, punctualLightCount);
for (i = 0; i < punctualLightCount; ++i)
{
float3 localDiffuseLighting, localSpecularLighting;

151
Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/LightLoop.cs


using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Experimental.Rendering;
using System;
namespace UnityEngine.Experimental.ScriptableRenderLoop
{
public class LightLoop
{
public virtual string GetKeyword()
{
return "";
}
public virtual void Rebuild()
{
m_lightList = new LightList();
s_DirectionalLights = new ComputeBuffer(HDRenderLoop.k_MaxDirectionalLightsOnSCreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(DirectionalLightData)));
s_DirectionalShadowList = new ComputeBuffer(HDRenderLoop.k_MaxCascadeCount, System.Runtime.InteropServices.Marshal.SizeOf(typeof(DirectionalShadowData)));
s_PunctualLightList = new ComputeBuffer(HDRenderLoop.k_MaxPunctualLightsOnSCreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(LightData)));
s_AreaLightList = new ComputeBuffer(HDRenderLoop.k_MaxAreaLightsOnSCreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(LightData)));
s_EnvLightList = new ComputeBuffer(HDRenderLoop.k_MaxEnvLightsOnSCreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(EnvLightData)));
s_PunctualShadowList = new ComputeBuffer(HDRenderLoop.k_MaxShadowOnScreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(PunctualShadowData)));
m_CookieTexArray = new TextureCache2D();
m_CookieTexArray.AllocTextureArray(8, m_TextureSettings.spotCookieSize, m_TextureSettings.spotCookieSize, TextureFormat.RGBA32, true);
m_CubeCookieTexArray = new TextureCacheCubemap();
m_CubeCookieTexArray.AllocTextureArray(4, m_TextureSettings.pointCookieSize, TextureFormat.RGBA32, true);
m_CubeReflTexArray = new TextureCacheCubemap();
m_CubeReflTexArray.AllocTextureArray(32, m_TextureSettings.reflectionCubemapSize, TextureFormat.BC6H, true);
}
public virtual void Cleanup()
{
Utilities.SafeRelease(s_DirectionalLights);
Utilities.SafeRelease(s_DirectionalShadowList);
Utilities.SafeRelease(s_PunctualLightList);
Utilities.SafeRelease(s_AreaLightList);
Utilities.SafeRelease(s_EnvLightList);
Utilities.SafeRelease(s_PunctualShadowList);
if (m_CubeReflTexArray != null)
{
m_CubeReflTexArray.Release();
m_CubeReflTexArray = null;
}
if (m_CookieTexArray != null)
{
m_CookieTexArray.Release();
m_CookieTexArray = null;
}
if (m_CubeCookieTexArray != null)
{
m_CubeCookieTexArray.Release();
m_CubeCookieTexArray = null;
}
}
virtual void NewFrame()
{
m_CookieTexArray.NewFrame();
m_CubeCookieTexArray.NewFrame();
m_CubeReflTexArray.NewFrame();
}
public ShadowData GetShadowData(VisibleLight light, AdditionalLightData additionalData, int lightIndex, ref ShadowOutput shadowOutput)
{
bool hasDirectionalShadows = light.light.shadows != LightShadows.None && shadowOutput.GetShadowSliceCountLightIndex(lightIndex) != 0;
if (hasDirectionalShadows)
{
for (int sliceIndex = 0; sliceIndex < shadowOutput.GetShadowSliceCountLightIndex(lightIndex); ++sliceIndex)
{
ShadowData shadowData = new ShadowData();
int shadowSliceIndex = shadowOutput.GetShadowSliceIndex(lightIndex, sliceIndex);
shadowData.worldToShadow = shadowOutput.shadowSlices[shadowSliceIndex].shadowTransform.transpose; // Transpose for hlsl reading ?
shadowData.lightType = lightData.lightType;
shadowData.bias = light.light.shadowBias;
m_lightList.directionalShadows.Add(shadowData);
}
}
}
public DirectionalLightData GetDirectionalLightData(VisibleLight light, AdditionalLightData additionalData)
{
Debug.Assert(light.lightType == LightType.Directional);
var directionalLightData = new DirectionalLightData();
// Light direction for directional and is opposite to the forward direction
directionalLightData.direction = -light.light.transform.forward;
// up and right are use for cookie
directionalLightData.up = light.light.transform.up;
directionalLightData.right = light.light.transform.right;
directionalLightData.positionWS = light.light.transform.position;
directionalLightData.color = GetLightColor(light);
directionalLightData.diffuseScale = additionalData.affectDiffuse ? 1.0f : 0.0f;
directionalLightData.specularScale = additionalData.affectSpecular ? 1.0f : 0.0f;
directionalLightData.invScaleX = 1.0f / light.light.transform.localScale.x;
directionalLightData.invScaleY = 1.0f / light.light.transform.localScale.y;
directionalLightData.cosAngle = 0.0f;
directionalLightData.sinAngle = 0.0f;
directionalLightData.shadowIndex = -1;
directionalLightData.cookieIndex = -1;
if (light.light.cookie != null)
{
directionalLightData.tileCookie = (light.light.cookie.wrapMode == TextureWrapMode.Repeat);
directionalLightData.cookieIndex = m_CookieTexArray.FetchSlice(light.light.cookie);
}
directionalLightData.shadowIndex = 0;
}
public virtual void PrepareLightsForGPU(CullResults cullResults, Camera camera) { }
public virtual void PushGlobalParams(Camera camera, RenderLoop loop)
{
Shader.SetGlobalTexture("_CookieTextures", m_CookieTexArray.GetTexCache());
Shader.SetGlobalTexture("_CookieCubeTextures", m_CubeCookieTexArray.GetTexCache());
Shader.SetGlobalTexture("_EnvTextures", m_CubeReflTexArray.GetTexCache());
s_DirectionalLights.SetData(m_lightList.directionalLights.ToArray());
s_DirectionalShadowList.SetData(m_lightList.directionalShadows.ToArray());
s_PunctualLightList.SetData(m_lightList.punctualLights.ToArray());
s_AreaLightList.SetData(m_lightList.areaLights.ToArray());
s_EnvLightList.SetData(m_lightList.envLights.ToArray());
s_PunctualShadowList.SetData(m_lightList.punctualShadows.ToArray());
Shader.SetGlobalBuffer("_DirectionalLightList", s_DirectionalLights);
Shader.SetGlobalInt("_DirectionalLightCount", m_lightList.directionalLights.Count);
Shader.SetGlobalBuffer("_DirectionalShadowList", s_DirectionalShadowList);
Shader.SetGlobalBuffer("_PunctualLightList", s_PunctualLightList);
Shader.SetGlobalInt("_PunctualLightCount", m_lightList.punctualLights.Count);
Shader.SetGlobalBuffer("_AreaLightList", s_AreaLightList);
Shader.SetGlobalInt("_AreaLightCount", m_lightList.areaLights.Count);
Shader.SetGlobalBuffer("_PunctualShadowList", s_PunctualShadowList);
Shader.SetGlobalBuffer("_EnvLightList", s_EnvLightList);
Shader.SetGlobalInt("_EnvLightCount", m_lightList.envLights.Count);
Shader.SetGlobalVectorArray("_DirShadowSplitSpheres", m_lightList.directionalShadowSplitSphereSqr);
}
public virtual void RenderDeferredLighting(Camera camera, RenderLoop renderLoop, RenderTargetIdentifier cameraColorBufferRT) {}
}
}
正在加载...
取消
保存