Evgenii Golubev 8 年前
当前提交
f85c5fe4
共有 30 个文件被更改,包括 1943 次插入662 次删除
  1. 2
      Assets/ScriptableRenderLoop/HDRenderLoop/Editor/HDRenderLoopInspector.cs
  2. 2
      Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.asset.meta
  3. 327
      Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.cs
  4. 2
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/LightDefinition.cs
  5. 2
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/SinglePass/SinglePass.cs
  6. 10
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/Resources/lightlistbuild.compute
  7. 413
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/TilePass.cs
  8. 21
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/TilePass.cs.hlsl
  9. 8
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/LayeredLit/LayeredLit.shader
  10. 16
      Assets/ScriptableRenderLoop/HDRenderLoop/Sky/Resources/SkyHDRI.shader
  11. 4
      Assets/ScriptableRenderLoop/RenderPasses/ShadowRenderPass.cs
  12. 10
      Assets/ScriptableRenderLoop/ShaderLibrary/Common.hlsl
  13. 8
      Assets/ScriptableRenderLoop/fptl/FptlLighting.cs
  14. 208
      Assets/TestScenes/HDTest/GlobalIlluminationTest.unity
  15. 259
      Assets/TestScenes/HDTest/Material/HDRenderLoopMaterials/Gray.mat
  16. 12
      Assets/TestScenes/HDTest/Material/HDRenderLoopMaterials/Layered/Layered.mat
  17. 2
      Assets/TestScenes/HDTest/Material/HDRenderLoopMaterials/Layered/Layered.mat.meta
  18. 90
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/ClusteredUtils.hlsl
  19. 9
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/ClusteredUtils.hlsl.meta
  20. 267
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/Resources/lightlistbuild-bigtile.compute
  21. 9
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/Resources/lightlistbuild-bigtile.compute.meta
  22. 553
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/Resources/lightlistbuild-clustered.compute
  23. 9
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/Resources/lightlistbuild-clustered.compute.meta
  24. 30
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/ShaderBase.hlsl
  25. 9
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/ShaderBase.hlsl.meta
  26. 9
      Assets/ScriptableRenderLoop/HDRenderLoop/Shaders.meta
  27. 185
      Assets/ScriptableRenderLoop/HDRenderLoop/Sky/SkyRenderer.cs
  28. 12
      Assets/ScriptableRenderLoop/HDRenderLoop/Sky/SkyRenderer.cs.meta
  29. 105
      Assets/ScriptableRenderLoop/HDRenderLoop/Utilities.cs
  30. 12
      Assets/ScriptableRenderLoop/HDRenderLoop/Utilities.cs.meta

2
Assets/ScriptableRenderLoop/HDRenderLoop/Editor/HDRenderLoopInspector.cs


skyParameters.skyHDRI = (Cubemap)EditorGUILayout.ObjectField("Cubemap", skyParameters.skyHDRI, typeof(Cubemap), false);
skyParameters.exposure = Mathf.Max(Mathf.Min(EditorGUILayout.FloatField(styles.skyExposure, skyParameters.exposure), 32), -32);
skyParameters.multiplier = Mathf.Max(EditorGUILayout.FloatField(styles.skyMultiplier, skyParameters.multiplier), 0);
skyParameters.rotation = Mathf.Max(Mathf.Min(EditorGUILayout.FloatField(styles.skyRotation, skyParameters.rotation), 360), 0);
skyParameters.rotation = Mathf.Max(Mathf.Min(EditorGUILayout.FloatField(styles.skyRotation, skyParameters.rotation), 360), -360);
if (EditorGUI.EndChangeCheck())
{

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


fileFormatVersion: 2
guid: 2400b74f5ce370c4481e5dc417d03703
timeCreated: 1479395301
timeCreated: 1479691644
licenseType: Pro
NativeFormatImporter:
userData:

327
Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.cs


}
#endif
public class SkyParameters
{
public Cubemap skyHDRI;
public float rotation;
public float exposure;
public float multiplier;
}
SkyRenderer m_SkyRenderer = null;
[SerializeField]
SkyParameters m_SkyParameters = new SkyParameters();

}
}
public RenderTargetIdentifier[] GetGBuffers(CommandBuffer cmd)
public RenderTargetIdentifier[] GetGBuffers()
{
var colorMRTs = new RenderTargetIdentifier[gbufferCount];
for (int index = 0; index < gbufferCount; index++)

TextureSettings m_TextureSettings = TextureSettings.Default;
// Various set of material use in render loop
Material m_SkyboxMaterial;
Material m_SkyHDRIMaterial;
int s_CameraColorBuffer;
int s_CameraDepthBuffer;
int s_VelocityBuffer;
int s_DistortionBuffer;
int m_CameraColorBuffer;
int m_CameraDepthBuffer;
int m_VelocityBuffer;
int m_DistortionBuffer;
RenderTargetIdentifier m_CameraColorBufferRT;
RenderTargetIdentifier m_CameraDepthBufferRT;
RenderTargetIdentifier m_VelocityBufferRT;
RenderTargetIdentifier m_DistortionBufferRT;
public class LightList
{

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();

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>();
}
}

// TODO: Find a way to automatically create/iterate through lightloop
SinglePass.LightLoop m_SinglePassLightLoop;
// TilePass.LightLoop m_TilePassLightLoop;
TilePass.LightLoop m_TilePassLightLoop;
// TODO: Find a way to automatically create/iterate through deferred material
Lit.RenderLoop m_LitRenderLoop;

Rebuild();
}
Material CreateEngineMaterial(string shaderPath)
public override void Rebuild()
var mat = new Material(Shader.Find(shaderPath) as Shader)
{
hideFlags = HideFlags.HideAndDontSave
};
return mat;
}
m_CameraColorBuffer = Shader.PropertyToID("_CameraColorTexture");
m_CameraDepthBuffer = Shader.PropertyToID("_CameraDepthTexture");
public override void Rebuild()
{
s_CameraColorBuffer = Shader.PropertyToID("_CameraColorTexture");
s_CameraDepthBuffer = Shader.PropertyToID("_CameraDepthTexture");
m_CameraColorBufferRT = new RenderTargetIdentifier(m_CameraColorBuffer);
m_CameraDepthBufferRT = new RenderTargetIdentifier(m_CameraDepthBuffer);
// TODO: We need to have an API to send our sky information to Enlighten. For now use a workaround through skybox/cubemap material...
m_SkyboxMaterial = CreateEngineMaterial("Skybox/Cubemap");
RenderSettings.skybox = m_SkyboxMaterial; // Setup this material as the default to be use in RenderSettings
RenderSettings.ambientIntensity = 1.0f; // fix this to 1, this parameter should not exist!
RenderSettings.ambientMode = UnityEngine.Rendering.AmbientMode.Skybox; // Force skybox for our HDRI
RenderSettings.reflectionIntensity = 1.0f;
m_SkyRenderer = new SkyRenderer();
m_SkyRenderer.Rebuild();
m_SkyHDRIMaterial = CreateEngineMaterial("Hidden/HDRenderLoop/SkyHDRI");
m_DeferredMaterial = CreateEngineMaterial("Hidden/HDRenderLoop/Deferred");
m_FinalPassMaterial = CreateEngineMaterial("Hidden/HDRenderLoop/FinalPass");
m_DebugViewMaterialGBuffer = CreateEngineMaterial("Hidden/HDRenderLoop/DebugViewMaterialGBuffer");
m_DeferredMaterial = Utilities.CreateEngineMaterial("Hidden/HDRenderLoop/Deferred");
m_FinalPassMaterial = Utilities.CreateEngineMaterial("Hidden/HDRenderLoop/FinalPass");
m_DebugViewMaterialGBuffer = Utilities.CreateEngineMaterial("Hidden/HDRenderLoop/DebugViewMaterialGBuffer");
m_ShadowPass = new ShadowRenderPass(m_ShadowSettings);

}
#pragma warning disable 162 // warning CS0162: Unreachable code detected
s_VelocityBuffer = Shader.PropertyToID("_VelocityTexture");
m_VelocityBuffer = Shader.PropertyToID("_VelocityTexture");
if (ShaderConfig.VelocityInGbuffer == 1)
{
// If velocity is in GBuffer then it is in the last RT. Assign a different name to it.

m_VelocityBufferRT = new RenderTargetIdentifier(m_VelocityBuffer);
s_DistortionBuffer = Shader.PropertyToID("_DistortionTexture");
m_DistortionBuffer = Shader.PropertyToID("_DistortionTexture");
m_DistortionBufferRT = new RenderTargetIdentifier(m_DistortionBuffer);
m_LitRenderLoop.Rebuild();

// Init various light loop
m_SinglePassLightLoop = new SinglePass.LightLoop();
m_SinglePassLightLoop.Rebuild();
// m_TilePassLightLoop = new TilePass.LightLoop();
// m_TilePassLightLoop.Rebuild();
m_TilePassLightLoop = new TilePass.LightLoop();
m_TilePassLightLoop.Rebuild();
m_lightList.directionalLights = new List<DirectionalLightData>();
m_lightList.punctualLights = new List<LightData>();
m_lightList.areaLights = new List<LightData>();
m_lightList.envLights = new List<EnvLightData>();
m_lightList.punctualShadows = new List<PunctualShadowData>();
m_lightList.directionalShadows = new List<DirectionalShadowData>();
m_lightList.directionalShadowSplitSphereSqr = new Vector4[k_MaxCascadeCount];
m_lightList.Allocate();
}
void OnDisable()

//m_TilePassLightLoop.OnDisable();
m_TilePassLightLoop.OnDisable();
if (m_SkyboxMaterial) DestroyImmediate(m_SkyboxMaterial);
if (m_SkyHDRIMaterial) DestroyImmediate(m_SkyHDRIMaterial);
if (m_DeferredMaterial) DestroyImmediate(m_DeferredMaterial);
if (m_FinalPassMaterial) DestroyImmediate(m_FinalPassMaterial);
if (m_DebugViewMaterialGBuffer) DestroyImmediate(m_DebugViewMaterialGBuffer);
Utilities.Destroy(m_DeferredMaterial);
Utilities.Destroy(m_FinalPassMaterial);
Utilities.Destroy(m_DebugViewMaterialGBuffer);
m_SkyRenderer.OnDisable();
}
void NewFrame()

int w = camera.pixelWidth;
int h = camera.pixelHeight;
cmd.GetTemporaryRT(s_CameraColorBuffer, w, h, 0, FilterMode.Point, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Linear);
cmd.GetTemporaryRT(s_CameraDepthBuffer, w, h, 24, FilterMode.Point, RenderTextureFormat.Depth);
cmd.GetTemporaryRT(m_CameraColorBuffer, w, h, 0, FilterMode.Point, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Linear);
cmd.GetTemporaryRT(m_CameraDepthBuffer, w, h, 24, FilterMode.Point, RenderTextureFormat.Depth);
cmd.SetRenderTarget(new RenderTargetIdentifier(s_CameraColorBuffer), new RenderTargetIdentifier(s_CameraDepthBuffer));
cmd.ClearRenderTarget(true, false, new Color(0, 0, 0, 0));
}
Utilities.SetRenderTarget(renderLoop, m_CameraColorBufferRT, m_CameraDepthBufferRT, ClearFlag.ClearDepth);
}
var cmd = new CommandBuffer();
cmd.name = "Clear HDR target";
cmd.SetRenderTarget(new RenderTargetIdentifier(s_CameraColorBuffer), new RenderTargetIdentifier(s_CameraDepthBuffer));
cmd.ClearRenderTarget(false, true, new Color(0, 0, 0, 0));
renderLoop.ExecuteCommandBuffer(cmd);
cmd.Dispose();
Utilities.SetRenderTarget(renderLoop, m_CameraColorBufferRT, m_CameraDepthBufferRT, ClearFlag.ClearColor, Color.black, "Clear HDR target");
var cmd = new CommandBuffer();
cmd.name = "Clear GBuffer";
// Write into the Camera Depth buffer
cmd.SetRenderTarget(m_gbufferManager.GetGBuffers(cmd), new RenderTargetIdentifier(s_CameraDepthBuffer));
// Clear everything
// TODO: Clear is not required for color as we rewrite everything, will save performance.
cmd.ClearRenderTarget(false, true, new Color(0, 0, 0, 0));
renderLoop.ExecuteCommandBuffer(cmd);
cmd.Dispose();
Utilities.SetRenderTarget(renderLoop, m_gbufferManager.GetGBuffers(), m_CameraDepthBufferRT, ClearFlag.ClearColor, Color.black, "Clear GBuffer");
void RenderOpaqueNoLightingRenderList(CullResults cull, Camera camera, RenderLoop renderLoop, string passName)
void RenderOpaqueRenderList(CullResults cull, Camera camera, RenderLoop renderLoop, string passName, RendererConfiguration rendererConfiguration = 0)
{
if (!debugParameters.displayOpaqueObjects)
return;

rendererConfiguration = 0,
rendererConfiguration = rendererConfiguration,
sorting = { sortOptions = SortOptions.SortByMaterialThenMesh }
};
settings.inputFilter.SetQueuesOpaque();

void RenderOpaqueRenderList(CullResults cull, Camera camera, RenderLoop renderLoop, string passName)
{
if (!debugParameters.displayOpaqueObjects)
return;
var settings = new DrawRendererSettings(cull, camera, new ShaderPassName(passName))
{
rendererConfiguration = RendererConfiguration.PerObjectLightProbe | RendererConfiguration.PerObjectReflectionProbes | RendererConfiguration.PerObjectLightmaps | RendererConfiguration.PerObjectLightProbeProxyVolume,
sorting = { sortOptions = SortOptions.SortByMaterialThenMesh }
};
settings.inputFilter.SetQueuesOpaque();
renderLoop.DrawRenderers(ref settings);
}
void RenderTransparentNoLightingRenderList(CullResults cull, Camera camera, RenderLoop renderLoop, string passName)
void RenderTransparentRenderList(CullResults cull, Camera camera, RenderLoop renderLoop, string passName, RendererConfiguration rendererConfiguration = 0)
{
if (!debugParameters.displayTransparentObjects)
return;

rendererConfiguration = 0,
sorting = { sortOptions = SortOptions.BackToFront }
};
settings.inputFilter.SetQueuesTransparent();
renderLoop.DrawRenderers(ref settings);
}
void RenderTransparentRenderList(CullResults cull, Camera camera, RenderLoop renderLoop, string passName)
{
if (!debugParameters.displayTransparentObjects)
return;
var settings = new DrawRendererSettings(cull, camera, new ShaderPassName(passName))
{
rendererConfiguration = RendererConfiguration.PerObjectLightProbe | RendererConfiguration.PerObjectReflectionProbes | RendererConfiguration.PerObjectLightmaps | RendererConfiguration.PerObjectLightProbeProxyVolume,
rendererConfiguration = rendererConfiguration,
sorting = { sortOptions = SortOptions.BackToFront }
};
settings.inputFilter.SetQueuesTransparent();

// TODO: Must do opaque then alpha masked for performance!
// TODO: front to back for opaque and by materal for opaque tested when we split in two
var cmd = new CommandBuffer { name = "Depth Prepass" };
cmd.SetRenderTarget(new RenderTargetIdentifier(s_CameraDepthBuffer));
renderLoop.ExecuteCommandBuffer(cmd);
cmd.Dispose();
RenderOpaqueNoLightingRenderList(cull, camera, renderLoop, "DepthOnly");
Utilities.SetRenderTarget(renderLoop, m_CameraDepthBufferRT, "Depth Prepass");
RenderOpaqueRenderList(cull, camera, renderLoop, "DepthOnly");
}
void RenderGBuffer(CullResults cull, Camera camera, RenderLoop renderLoop)

}
// setup GBuffer for rendering
var cmd = new CommandBuffer { name = "GBuffer Pass" };
cmd.SetRenderTarget(m_gbufferManager.GetGBuffers(cmd), new RenderTargetIdentifier(s_CameraDepthBuffer));
renderLoop.ExecuteCommandBuffer(cmd);
cmd.Dispose();
Utilities.SetRenderTarget(renderLoop, m_gbufferManager.GetGBuffers(), m_CameraDepthBufferRT, "GBuffer Pass");
RenderOpaqueRenderList(cull, camera, renderLoop, "GBuffer");
RenderOpaqueRenderList(cull, camera, renderLoop, "GBuffer", Utilities.kRendererConfigurationBakedLighting);
}
// This pass is use in case of forward opaque and deferred rendering. We need to render forward objects before tile lighting pass

return;
// TODO: Use the render queue index to only send the forward opaque!
var cmd = new CommandBuffer { name = "Depth Prepass" };
cmd.SetRenderTarget(new RenderTargetIdentifier(s_CameraDepthBuffer));
renderLoop.ExecuteCommandBuffer(cmd);
cmd.Dispose();
RenderOpaqueNoLightingRenderList(cull, camera, renderLoop, "DepthOnly");
Utilities.SetRenderTarget(renderLoop, m_CameraDepthBufferRT, "Clear HDR target");
RenderOpaqueRenderList(cull, camera, renderLoop, "DepthOnly");
}
void RenderDebugViewMaterial(CullResults cull, Camera camera, RenderLoop renderLoop)

var cmd = new CommandBuffer { name = "DebugView Material Mode Pass" };
cmd.SetRenderTarget(new RenderTargetIdentifier(s_CameraColorBuffer), new RenderTargetIdentifier(s_CameraDepthBuffer));
cmd.ClearRenderTarget(true, true, new Color(0, 0, 0, 0));
renderLoop.ExecuteCommandBuffer(cmd);
cmd.Dispose();
Utilities.SetRenderTarget(renderLoop, m_CameraColorBufferRT, m_CameraDepthBufferRT, Utilities.kClearAll, Color.black, "DebugView Material Mode Pass");
Shader.SetGlobalInt("_DebugViewMaterial", (int)debugParameters.debugViewMaterial);

// m_gbufferManager.BindBuffers(m_DeferredMaterial);
// TODO: Bind depth textures
var cmd = new CommandBuffer { name = "GBuffer Debug Pass" };
cmd.Blit(null, new RenderTargetIdentifier(s_CameraColorBuffer), m_DebugViewMaterialGBuffer, 0);
cmd.Blit(null, m_CameraColorBufferRT, m_DebugViewMaterialGBuffer, 0);
renderLoop.ExecuteCommandBuffer(cmd);
cmd.Dispose();
}

// Last blit
{
var cmd = new CommandBuffer { name = "Blit DebugView Material Debug" };
cmd.Blit(new RenderTargetIdentifier(s_CameraColorBuffer), BuiltinRenderTextureType.CameraTarget);
cmd.Blit(m_CameraColorBufferRT, BuiltinRenderTextureType.CameraTarget);
renderLoop.ExecuteCommandBuffer(cmd);
cmd.Dispose();
}

// m_gbufferManager.BindBuffers(m_DeferredMaterial);
// TODO: Bind depth textures
var cmd = new CommandBuffer { name = "Deferred Ligthing Pass" };
cmd.Blit(null, new RenderTargetIdentifier(s_CameraColorBuffer), m_DeferredMaterial, 0);
cmd.Blit(null, m_CameraColorBufferRT, m_DeferredMaterial, 0);
renderLoop.ExecuteCommandBuffer(cmd);
cmd.Dispose();
}

/*
// Render sky into a cubemap - doesn't happen every frame, can be control
// TODO: do a render to texture here
// Downsample the cubemap and provide it to Enlighten
// TODO: currently workaround is to set the cubemap in a Skybox/cubemap material
//m_SkyboxMaterial.SetTexture(cubemap);
// Render the sky itself
Vector3[] vertData = new Vector3[4];
vertData[0] = new Vector3(-1.0f, -1.0f, 0.0f);
vertData[1] = new Vector3(1.0f, -1.0f, 0.0f);
vertData[2] = new Vector3(1.0f, 1.0f, 0.0f);
vertData[3] = new Vector3(-1.0f, 1.0f, 0.0f);
Vector3[] eyeVectorData = new Vector3[4];
// camera.worldToCameraMatrix, camera.projectionMatrix
// Get view vector vased on the frustrum, i.e (invert transform frustrum get position etc...)
eyeVectorData[0] =
eyeVectorData[1] =
eyeVectorData[2] =
eyeVectorData[3] =
// Write out the mesh
var triangles = new int[4];
for (int i = 0; i < 4; i++)
{
triangles[i] = i;
m_SkyRenderer.RenderSky(camera, m_SkyParameters, m_CameraColorBufferRT, m_CameraDepthBufferRT, renderLoop);
Mesh mesh = new Mesh
{
vertices = vertData,
normals = eyeVectorData,
triangles = triangles
};
m_SkyHDRIMaterial.SetTexture("_Cubemap", skyParameters.skyHDRI);
m_SkyHDRIMaterial.SetVector("_SkyParam", new Vector4(skyParameters.exposure, skyParameters.multiplier, skyParameters.rotation, 0.0f));
var cmd = new CommandBuffer { name = "Skybox" };
cmd.DrawMesh(mesh, Matrix4x4.identity, m_SkyHDRIMaterial);
renderloop.ExecuteCommandBuffer(cmd);
cmd.Dispose();
*/
}
var cmd = new CommandBuffer { name = "Forward Pass" };
cmd.SetRenderTarget(new RenderTargetIdentifier(s_CameraColorBuffer), new RenderTargetIdentifier(s_CameraDepthBuffer));
renderLoop.ExecuteCommandBuffer(cmd);
cmd.Dispose();
Utilities.SetRenderTarget(renderLoop, m_CameraColorBufferRT, m_CameraDepthBufferRT, "Forward Pass");
if (debugParameters.useForwardRenderingOnly)
{

RenderTransparentRenderList(cullResults, camera, renderLoop, "Forward");
RenderTransparentRenderList(cullResults, camera, renderLoop, "Forward", Utilities.kRendererConfigurationBakedLighting);
}
void RenderForwardUnlit(CullResults cullResults, Camera camera, RenderLoop renderLoop)

var cmd = new CommandBuffer { name = "Forward Unlit Pass" };
cmd.SetRenderTarget(new RenderTargetIdentifier(s_CameraColorBuffer), new RenderTargetIdentifier(s_CameraDepthBuffer));
renderLoop.ExecuteCommandBuffer(cmd);
cmd.Dispose();
RenderOpaqueNoLightingRenderList(cullResults, camera, renderLoop, "ForwardUnlit");
RenderTransparentNoLightingRenderList(cullResults, camera, renderLoop, "ForwardUnlit");
Utilities.SetRenderTarget(renderLoop, m_CameraColorBufferRT, m_CameraDepthBufferRT, "Forward Unlit Pass");
RenderOpaqueRenderList(cullResults, camera, renderLoop, "ForwardUnlit");
RenderTransparentRenderList(cullResults, camera, renderLoop, "ForwardUnlit");
}
void RenderVelocity(CullResults cullResults, Camera camera, RenderLoop renderLoop)

int h = camera.pixelHeight;
var cmd = new CommandBuffer { name = "Velocity Pass" };
cmd.GetTemporaryRT(s_VelocityBuffer, w, h, 0, FilterMode.Point, Builtin.RenderLoop.GetVelocityBufferFormat(), Builtin.RenderLoop.GetVelocityBufferReadWrite());
cmd.SetRenderTarget(new RenderTargetIdentifier(s_VelocityBuffer), new RenderTargetIdentifier(s_CameraDepthBuffer));
cmd.GetTemporaryRT(m_VelocityBuffer, w, h, 0, FilterMode.Point, Builtin.RenderLoop.GetVelocityBufferFormat(), Builtin.RenderLoop.GetVelocityBufferReadWrite());
cmd.SetRenderTarget(m_VelocityBufferRT, m_CameraDepthBufferRT);
RenderOpaqueNoLightingRenderList(cullResults, camera, renderLoop, "MotionVectors");
RenderOpaqueRenderList(cullResults, camera, renderLoop, "MotionVectors");
#pragma warning restore 162, 429
}

int h = camera.pixelHeight;
var cmd = new CommandBuffer { name = "Distortion Pass" };
cmd.GetTemporaryRT(s_DistortionBuffer, w, h, 0, FilterMode.Point, Builtin.RenderLoop.GetDistortionBufferFormat(), Builtin.RenderLoop.GetDistortionBufferReadWrite());
cmd.SetRenderTarget(new RenderTargetIdentifier(s_DistortionBuffer), new RenderTargetIdentifier(s_CameraDepthBuffer));
cmd.GetTemporaryRT(m_DistortionBuffer, w, h, 0, FilterMode.Point, Builtin.RenderLoop.GetDistortionBufferFormat(), Builtin.RenderLoop.GetDistortionBufferReadWrite());
cmd.SetRenderTarget(m_DistortionBufferRT, m_CameraDepthBufferRT);
RenderTransparentNoLightingRenderList(cullResults, camera, renderLoop, "DistortionVectors");
RenderTransparentRenderList(cullResults, camera, renderLoop, "DistortionVectors");
}

var cmd = new CommandBuffer { name = "FinalPass" };
// Resolve our HDR texture to CameraTarget.
cmd.Blit(new RenderTargetIdentifier(s_CameraColorBuffer), BuiltinRenderTextureType.CameraTarget, m_FinalPassMaterial, 0);
cmd.Blit(m_CameraColorBufferRT, BuiltinRenderTextureType.CameraTarget, m_FinalPassMaterial, 0);
void ConvertLightForGPU(CullResults cullResults, ref ShadowOutput shadowOutput, ref LightList lightList)
void PrepareLightsForGPU(CullResults cullResults, Camera camera, ref ShadowOutput shadowOutput, ref LightList lightList)
{
lightList.Clear();

}
lightList.directionalLights.Add(directionalLightData);
lightList.directionalCullIndices.Add(lightIndex);
continue;
}

if (additionalData.archetype == LightArchetype.Rectangle)
{
lightData.lightType = GPULightType.Rectangle;
}
else
{
lightData.lightType = GPULightType.Rectangle;
}
else
{
lightData.lightType = GPULightType.Line;
}
}

if (additionalData.archetype == LightArchetype.Punctual)
{
lightList.punctualLights.Add(lightData);
lightList.punctualCullIndices.Add(lightIndex);
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);
// build per tile light lists
m_SinglePassLightLoop.PrepareLightsForGPU(cullResults, camera, m_lightList);
m_TilePassLightLoop.PrepareLightsForGPU(cullResults, camera, m_lightList);
{ /*
{
if (camera.pixelWidth != m_WidthOnRecord || camera.pixelHeight != m_HeightOnRecord || m_TilePassLightLoop.NeedResize())
{
if (m_WidthOnRecord > 0 && m_HeightOnRecord > 0)

m_WidthOnRecord = camera.pixelWidth;
m_HeightOnRecord = camera.pixelHeight;
}
*/
}
public void PushGlobalParams(Camera camera, RenderLoop renderLoop, HDRenderLoop.LightList lightList)

Shader.SetGlobalTexture("_EnvTextures", m_CubeReflTexArray.GetTexCache());
m_SinglePassLightLoop.PushGlobalParams(camera, renderLoop, lightList);
// m_TilePassLightLoop.PushGlobalParams(camera, renderLoop, lightList);
m_TilePassLightLoop.PushGlobalParams(camera, renderLoop, lightList);
}
public override void Render(Camera[] cameras, RenderLoop renderLoop)

renderLoop.SetupCameraProperties(camera); // Need to recall SetupCameraProperties after m_ShadowPass.Render
ConvertLightForGPU(cullResults, ref shadows, ref m_lightList);
PrepareLightsForGPU(cullResults, camera, ref shadows, ref m_lightList);
m_TilePassLightLoop.BuildGPULightLists(camera, renderLoop, m_lightList, m_CameraDepthBuffer);
// build per tile light lists
//var numLights = 0; // GenerateSourceLightBuffers(camera, cullResults);
//m_tilePassLightLoop.BuildPerTileLightLists(camera, loop, numLights, projscr, invProjscr);
RenderDeferredLighting(camera, renderLoop);

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


public int IESIndex;
public int cookieIndex;
public GPULightType lightType;
public GPULightType lightType;
// Area Light specific
public Vector2 size;
public bool twoSided;

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


s_PunctualShadowList = null;
}
public void PrepareLightsForGPU(CullResults cullResults, Camera camera, HDRenderLoop.LightList lightList) {}
public void PushGlobalParams(Camera camera, RenderLoop loop, HDRenderLoop.LightList lightList)
{
s_DirectionalLights.SetData(lightList.directionalLights.ToArray());

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


#pragma kernel TileLightListGen LIGHTLISTGEN=TileLightListGen
#pragma kernel TileLightListGen_SrcBigTile LIGHTLISTGEN=TileLightListGen_SrcBigTile USE_TWO_PASS_TILED_LIGHTING
float FetchDepth(Texture2D depthTexture, uint2 pixCoord)
{
return 1 - depthTexture.Load(uint3(pixCoord.xy, 0)).x;
}
#include "../ShaderBase.hlsl"
#if !defined(SHADER_API_XBOXONE) && !defined(SHADER_API_PSSL)
#include "../SortingComputeUtils.hlsl"
#endif

while(l<iNrCoarseLights && uLgtType==SPOT_LIGHT)
{
SFiniteLightData lightData = g_vLightData[idxCoarse];
const bool bIsSpotDisc = (lightData.flags&IS_CIRCULAR_SPOT_SHAPE)!=0;
// TODO: Change by SebL
const bool bIsSpotDisc = true; // (lightData.flags&IS_CIRCULAR_SPOT_SHAPE) != 0;
// serially check 4 pixels
uint uVal = 0;

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


using UnityEngine;
using UnityEngine.Experimental.Rendering;
using UnityEngine.Rendering;
using System;
namespace UnityEngine.Experimental.ScriptableRenderLoop

public struct SFiniteLightData
{
public Vector3 lightPos;
public int flags;
public Vector3 lightAxisX;
public uint lightType;

public Vector3 lightAxisZ; // spot +Z axis
public float cotan;
public Vector3 color;
public uint lightModel; // DIRECT_LIGHT=0, REFLECTION_LIGHT=1
public float unusued;
public uint lightModel; // DIRECT_LIGHT=0, REFLECTION_LIGHT=1
public Vector3 boxInvRange;
public float unused2;

return "LIGHTLOOP_SINGLE_PASS";
}
/*
public const int MaxNumLights = HDRenderLoop.k_MaxPunctualLightsOnSCreen + HDRenderLoop.k_MaxAreaLightsOnSCreen + HDRenderLoop.k_MaxEnvLightsOnSCreen;
public const int MaxNumLights = 1024;
ComputeShader buildScreenAABBShader;
ComputeShader buildPerTileLightListShader; // FPTL
ComputeShader buildPerBigTileLightListShader;
ComputeShader buildPerVoxelLightListShader; // clustered
static ComputeShader buildScreenAABBShader;
static ComputeShader buildPerTileLightListShader; // FPTL
static ComputeShader buildPerBigTileLightListShader;
static ComputeShader buildPerVoxelLightListShader; // clustered
private static int s_GenAABBKernel;
private static int s_GenListPerTileKernel;

private static ComputeBuffer s_ConvexBoundsBuffer;
private static ComputeBuffer s_AABBBoundsBuffer;
private static ComputeBuffer s_LightList;
private static ComputeBuffer s_DirLightList;
private static ComputeBuffer s_BigTileLightList; // used for pre-pass coarse culling on 64x64 tiles
private static int s_GenListPerBigTileKernel;

public bool disableFptlWhenClustered = false; // still useful on opaques
public bool enableBigTilePrepass = true;
public bool enableBigTilePrepass = false; // SebL - TODO: I get a crash when enabling this
public bool enableDrawLightBoundsDebug = false;
public bool enableDrawTileDebug = false;
public bool enableComputeLightEvaluation = false;

// clustered light list specific buffers and data end
const int k_TileSize = 16;
*/
SFiniteLightBound[] m_boundData;
SFiniteLightData[] m_lightData;
int m_lightCount;
/*
*/
return true;
}
}

/*
ReleaseResolutionDependentBuffers();
if (s_AABBBoundsBuffer != null)

if (s_LightDataBuffer != null)
s_LightDataBuffer.Release();
if (s_DirLightList != null)
s_DirLightList.Release();
*/
/*
ClearComputeBuffers();
buildScreenAABBShader = Resources.Load<ComputeShader>("scrbound");

s_AABBBoundsBuffer = new ComputeBuffer(2 * MaxNumLights, 3 * sizeof(float));
s_ConvexBoundsBuffer = new ComputeBuffer(MaxNumLights, System.Runtime.InteropServices.Marshal.SizeOf(typeof(SFiniteLightBound)));
s_LightDataBuffer = new ComputeBuffer(MaxNumLights, System.Runtime.InteropServices.Marshal.SizeOf(typeof(SFiniteLightData)));
s_DirLightList = new ComputeBuffer(MaxNumDirLights, System.Runtime.InteropServices.Marshal.SizeOf(typeof(DirectionalLight)));
buildScreenAABBShader.SetBuffer(s_GenAABBKernel, "g_data", s_ConvexBoundsBuffer);
buildPerTileLightListShader.SetBuffer(s_GenListPerTileKernel, "g_vBoundsBuffer", s_AABBBoundsBuffer);
buildPerTileLightListShader.SetBuffer(s_GenListPerTileKernel, "g_vLightData", s_LightDataBuffer);

s_GlobalLightListAtomic = new ComputeBuffer(1, sizeof(uint));
}
if (enableBigTilePrepass)
{
s_GenListPerBigTileKernel = buildPerBigTileLightListShader.FindKernel("BigTileLightListGen");

}
*/
m_boundData = new SFiniteLightBound[MaxNumLights];
m_lightData = new SFiniteLightData[MaxNumLights];
m_lightCount = 0;
{/*
{
// TODO: do something for Resources.Load<ComputeShader> ?
s_AABBBoundsBuffer.Release();

s_DirLightList.Release();
*/
/*
public bool NeedResize()
{
return s_LightList == null || (s_BigTileLightList == null && enableBigTilePrepass) || (s_PerVoxelLightLists == null && enableClustered);

s_BigTileLightList = new ComputeBuffer(LightDefinitions.MAX_NR_BIGTILE_LIGHTS_PLUSONE * nrBigTiles, sizeof(uint));
}
}
*/
// TEMP: These functions should be implemented C++ side, for now do it in C#
private static void SetMatrixCS(CommandBuffer cmd, ComputeShader shadercs, string name, Matrix4x4 mat)
{
var data = new float[16];
for (int c = 0; c < 4; c++)
for (int r = 0; r < 4; r++)
data[4 * c + r] = mat[r, c];
cmd.SetComputeFloatParams(shadercs, name, data);
}
private static void SetMatrixArrayCS(CommandBuffer cmd, ComputeShader shadercs, string name, Matrix4x4[] matArray)
{
int numMatrices = matArray.Length;
var data = new float[numMatrices * 16];
for (int n = 0; n < numMatrices; n++)
for (int c = 0; c < 4; c++)
for (int r = 0; r < 4; r++)
data[16 * n + 4 * c + r] = matArray[n][r, c];
cmd.SetComputeFloatParams(shadercs, name, data);
}
/*
int GenerateSourceLightBuffers(Camera camera, CullResults inputs)
private static void SetVectorArrayCS(CommandBuffer cmd, ComputeShader shadercs, string name, Vector4[] vecArray)
{
int numVectors = vecArray.Length;
var data = new float[numVectors * 4];
for (int n = 0; n < numVectors; n++)
for (int i = 0; i < 4; i++)
data[4 * n + i] = vecArray[n][i];
cmd.SetComputeFloatParams(shadercs, name, data);
}
static Matrix4x4 GetFlipMatrix()
{
Matrix4x4 flip = Matrix4x4.identity;
bool isLeftHand = ((int)LightDefinitions.USE_LEFTHAND_CAMERASPACE) != 0;
if (isLeftHand) flip.SetColumn(2, new Vector4(0.0f, 0.0f, -1.0f, 0.0f));
return flip;
}
static Matrix4x4 WorldToCamera(Camera camera)
{
return GetFlipMatrix() * camera.worldToCameraMatrix;
}
static Matrix4x4 CameraProjection(Camera camera)
var probes = inputs.visibleReflectionProbes;
//ReflectionProbe[] probes = Object.FindObjectsOfType<ReflectionProbe>();
return camera.projectionMatrix * GetFlipMatrix();
}
public void PrepareLightsForGPU(CullResults cullResults, Camera camera, HDRenderLoop.LightList lightList)
{
// Use for first space screen AABB
// Use for the second pass (fine pruning)
// first pass. Figure out how much we have of each and establish offsets
foreach (var cl in inputs.visibleLights)
// TODO manage area lights
foreach (var punctualLight in lightList.punctualLights)
var volType = cl.lightType == LightType.Spot ? LightDefinitions.SPOT_LIGHT : (cl.lightType == LightType.Point ? LightDefinitions.SPHERE_LIGHT : -1);
if (volType >= 0) ++numEntries[LightDefinitions.DIRECT_LIGHT, volType];
var volType = punctualLight.lightType == GPULightType.Spot ? LightDefinitions.SPOT_LIGHT : (punctualLight.lightType == GPULightType.Point ? LightDefinitions.SPHERE_LIGHT : -1);
if (volType >= 0)
++numEntries[LightDefinitions.DIRECT_LIGHT, volType];
foreach (var rl in probes)
// TODO: manage sphere_light
foreach (var envLight in lightList.envLights)
if (rl.texture != null) ++numEntries[LightDefinitions.REFLECTION_LIGHT, volType];
++numEntries[LightDefinitions.REFLECTION_LIGHT, volType];
}
// add decals here too similar to the above

{
offsets[m, 0] = m == 0 ? 0 : (numEntries[m - 1, numVolTypes - 1] + offsets[m - 1, numVolTypes - 1]);
for (var v = 1; v < numVolTypes; v++) offsets[m, v] = numEntries[m, v - 1] + offsets[m, v - 1];
for (var v = 1; v < numVolTypes; v++)
{
offsets[m, v] = numEntries[m, v - 1] + offsets[m, v - 1];
}
var numLights = inputs.visibleLights.Length;
var numProbes = probes.Length;
var numVolumes = numLights + numProbes;
var lightData = new SFiniteLightData[numVolumes];
var boundData = new SFiniteLightBound[numVolumes];
bool isNegDeterminant = Vector3.Dot(worldToView.GetColumn(0), Vector3.Cross(worldToView.GetColumn(1), worldToView.GetColumn(2))) < 0.0f; // 3x3 Determinant.
uint shadowLightIndex = 0;
foreach (var cl in inputs.visibleLights)
for (int lightIndex = 0; lightIndex < lightList.punctualLights.Count; lightIndex++)
var range = cl.range;
LightData punctualLightData = lightList.punctualLights[lightIndex];
VisibleLight light = cullResults.visibleLights[lightList.punctualCullIndices[lightIndex]];
var lightToWorld = cl.localToWorld;
var range = light.range;
var lightToWorld = light.localToWorld;
// Fill bounds
var light = new SFiniteLightData();
var lightData = new SFiniteLightData();
int index = -1;
bound.boxAxisX.Set(1, 0, 0);
bound.boxAxisY.Set(0, 1, 0);
bound.boxAxisZ.Set(0, 0, 1);
bound.scaleXY.Set(1.0f, 1.0f);
bound.radius = range;
light.flags = 0;
light.recipRange = 1.0f / range;
light.color.Set(cl.finalColor.r, cl.finalColor.g, cl.finalColor.b);
light.sliceIndex = 0;
light.lightModel = (uint)LightDefinitions.DIRECT_LIGHT;
light.shadowLightIndex = shadowLightIndex;
shadowLightIndex++;
lightData.lightModel = (uint)LightDefinitions.DIRECT_LIGHT;
var bHasCookie = cl.light.cookie != null;
var bHasShadow = cl.light.shadows != LightShadows.None;
var idxOut = 0;
if (cl.lightType == LightType.Spot)
if (punctualLightData.lightType == GPULightType.Spot || punctualLightData.lightType == GPULightType.ProjectorPyramid)
var isCircularSpot = !bHasCookie;
if (!isCircularSpot) // square spots always have cookie
{
light.sliceIndex = m_CookieTexArray.FetchSlice(cl.light.cookie);
}
Vector3 lightDir = lightToWorld.GetColumn(2); // Z axis in world space
// represents a left hand coordinate system in world space

const float degToRad = (float)(pi / 180.0);
var sa = cl.light.spotAngle;
var sa = light.light.spotAngle;
var cs = Mathf.Cos(0.5f * sa * degToRad);
var si = Mathf.Sin(0.5f * sa * degToRad);

var squeeze = true;//sa < 0.7f * 90.0f; // arb heuristic
var fS = squeeze ? ta : si;
bound.center = worldToView.MultiplyPoint(lightPos + ((0.5f * range) * lightDir)); // use mid point of the spot as the center of the bounding volume for building screen-space AABB for tiled lighting.
light.lightAxisX = vx;
light.lightAxisY = vy;
light.lightAxisZ = vz;
// scale axis to match box or base of pyramid
bound.boxAxisX = (fS * range) * vx;

fAltDx *= range; fAltDy *= range;
var altDist = Mathf.Sqrt(fAltDy * fAltDy + (isCircularSpot ? 1.0f : 2.0f) * fAltDx * fAltDx);
var altDist = Mathf.Sqrt(fAltDy * fAltDy + (punctualLightData.lightType == GPULightType.Spot ? 1.0f : 2.0f) * fAltDx * fAltDx);
// fill up ldata
light.lightType = (uint)LightDefinitions.SPOT_LIGHT;
light.lightPos = worldToView.MultiplyPoint(lightPos);
light.radiusSq = range * range;
light.penumbra = cs;
light.cotan = cota;
light.flags |= (isCircularSpot ? LightDefinitions.IS_CIRCULAR_SPOT_SHAPE : 0);
light.flags |= (bHasCookie ? LightDefinitions.HAS_COOKIE_TEXTURE : 0);
light.flags |= (bHasShadow ? LightDefinitions.HAS_SHADOW : 0);
lightData.lightAxisX = vx;
lightData.lightAxisY = vy;
lightData.lightAxisZ = vz;
lightData.lightType = (uint)LightDefinitions.SPOT_LIGHT;
lightData.lightPos = worldToView.MultiplyPoint(lightPos);
lightData.radiusSq = range * range;
lightData.cotan = cota;
idxOut = numEntries2nd[i, j] + offsets[i, j]; ++numEntries2nd[i, j];
index = numEntries2nd[i, j] + offsets[i, j]; ++numEntries2nd[i, j];
else if (cl.lightType == LightType.Point)
else // if (punctualLightData.lightType == GPULightType.Point)
if (bHasCookie)
{
light.sliceIndex = m_CubeCookieTexArray.FetchSlice(cl.light.cookie);
}
bool isNegDeterminant = Vector3.Dot(worldToView.GetColumn(0), Vector3.Cross(worldToView.GetColumn(1), worldToView.GetColumn(2))) < 0.0f; // 3x3 Determinant.
bound.center = worldToView.MultiplyPoint(lightPos);
bound.boxAxisX.Set(range, 0, 0);

Vector3 vz = lightToView.GetColumn(2);
// fill up ldata
light.lightType = (uint)LightDefinitions.SPHERE_LIGHT;
light.lightPos = bound.center;
light.radiusSq = range * range;
light.lightAxisX = vx;
light.lightAxisY = vy;
light.lightAxisZ = vz;
light.flags |= (bHasCookie ? LightDefinitions.HAS_COOKIE_TEXTURE : 0);
light.flags |= (bHasShadow ? LightDefinitions.HAS_SHADOW : 0);
lightData.lightAxisX = vx;
lightData.lightAxisY = vy;
lightData.lightAxisZ = vz;
lightData.lightType = (uint)LightDefinitions.SPHERE_LIGHT;
lightData.lightPos = bound.center;
lightData.radiusSq = range * range;
idxOut = numEntries2nd[i, j] + offsets[i, j]; ++numEntries2nd[i, j];
}
else
{
//Assert(false);
index = numEntries2nd[i, j] + offsets[i, j]; ++numEntries2nd[i, j];
// next light
if (cl.lightType == LightType.Spot || cl.lightType == LightType.Point)
{
boundData[idxOut] = bound;
lightData[idxOut] = light;
}
m_boundData[index] = bound;
m_lightData[index] = lightData;
var numLightsOut = offsets[LightDefinitions.DIRECT_LIGHT, numVolTypes - 1] + numEntries[LightDefinitions.DIRECT_LIGHT, numVolTypes - 1];
// probe.m_BlendDistance
// Vector3f extents = 0.5*Abs(probe.m_BoxSize);
// C center of rendered refl box <-- GetComponent (Transform).GetPosition() + m_BoxOffset;
// cube map capture point: GetComponent (Transform).GetPosition()
// shader parameter min and max are C+/-(extents+blendDistance)
foreach (var rl in probes)
for (int envIndex = 0; envIndex < lightList.envLights.Count; envIndex++)
var cubemap = rl.texture;
EnvLightData envLightData = lightList.envLights[envIndex];
VisibleReflectionProbe probe = cullResults.visibleReflectionProbes[lightList.envCullIndices[envIndex]];
// always a box for now
if (cubemap == null)
continue;
var bound = new SFiniteLightBound();
var lightData = new SFiniteLightData();
var bndData = new SFiniteLightBound();
var lgtData = new SFiniteLightData();
var idxOut = 0;
lgtData.flags = 0;
var bnds = rl.bounds;
var boxOffset = rl.center; // reflection volume offset relative to cube map capture point
var blendDistance = rl.blendDistance;
float imp = rl.importance;
var bnds = probe.bounds;
var boxOffset = probe.center; // reflection volume offset relative to cube map capture point
var blendDistance = probe.blendDistance;
var mat = rl.localToWorld;
//Matrix4x4 mat = rl.transform.localToWorldMatrix;
Vector3 cubeCapturePos = mat.GetColumn(3); // cube map capture position in world space
// implicit in CalculateHDRDecodeValues() --> float ints = rl.intensity;
var boxProj = (rl.boxProjection != 0);
var decodeVals = rl.hdr;
//Vector4 decodeVals = rl.CalculateHDRDecodeValues();
var mat = probe.localToWorld;
// C is reflection volume center in world space (NOT same as cube map capture point)
var e = bnds.extents; // 0.5f * Vector3.Max(-boxSizes[p], boxSizes[p]);

//Vector3 posForShaderParam = bnds.center - boxOffset; // gives same as rl.GetComponent<Transform>().position;
var posForShaderParam = cubeCapturePos; // same as commented out line above when rot is identity
var combinedExtent = e + new Vector3(blendDistance, blendDistance, blendDistance);
var combinedExtent = e + new Vector3(blendDistance, blendDistance, blendDistance);
Vector3 vx = mat.GetColumn(0);
Vector3 vy = mat.GetColumn(1);

var Cw = worldToView.MultiplyPoint(C);
if (boxProj) lgtData.flags |= LightDefinitions.IS_BOX_PROJECTED;
bound.center = Cw;
bound.boxAxisX = combinedExtent.x * vx;
bound.boxAxisY = combinedExtent.y * vy;
bound.boxAxisZ = combinedExtent.z * vz;
bound.scaleXY.Set(1.0f, 1.0f);
bound.radius = combinedExtent.magnitude;
lgtData.lightPos = Cw;
lgtData.lightAxisX = vx;
lgtData.lightAxisY = vy;
lgtData.lightAxisZ = vz;
lgtData.localCubeCapturePoint = -boxOffset;
lgtData.probeBlendDistance = blendDistance;
lgtData.lightIntensity = decodeVals.x;
lgtData.decodeExp = decodeVals.y;
lgtData.sliceIndex = m_CubeReflTexArray.FetchSlice(cubemap);
lightData.lightPos = Cw;
lightData.lightAxisX = vx;
lightData.lightAxisY = vy;
lightData.lightAxisZ = vz;
lgtData.boxInnerDist = e;
lgtData.boxInvRange.Set(1.0f / delta.x, 1.0f / delta.y, 1.0f / delta.z);
bndData.center = Cw;
bndData.boxAxisX = combinedExtent.x * vx;
bndData.boxAxisY = combinedExtent.y * vy;
bndData.boxAxisZ = combinedExtent.z * vz;
bndData.scaleXY.Set(1.0f, 1.0f);
bndData.radius = combinedExtent.magnitude;
// fill up ldata
lgtData.lightType = (uint)LightDefinitions.BOX_LIGHT;
lgtData.lightModel = (uint)LightDefinitions.REFLECTION_LIGHT;
lightData.boxInnerDist = e;
lightData.boxInvRange.Set(1.0f / delta.x, 1.0f / delta.y, 1.0f / delta.z);
idxOut = numEntries2nd[i, j] + offsets[i, j]; ++numEntries2nd[i, j];
boundData[idxOut] = bndData;
lightData[idxOut] = lgtData;
int index = numEntries2nd[i, j] + offsets[i, j]; ++numEntries2nd[i, j];
m_boundData[index] = bound;
var numProbesOut = offsets[LightDefinitions.REFLECTION_LIGHT, numVolTypes - 1] + numEntries[LightDefinitions.REFLECTION_LIGHT, numVolTypes - 1];
// Sanity check
{
}
s_ConvexBoundsBuffer.SetData(boundData);
s_LightDataBuffer.SetData(lightData);
m_lightCount = lightList.punctualLights.Count + lightList.envLights.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 ?
}
void VoxelLightListGeneration(CommandBuffer cmd, Camera camera, Matrix4x4 projscr, Matrix4x4 invProjscr, int cameraDepthBuffer)
{
// clear atomic offset index
cmd.SetComputeBufferParam(buildPerVoxelLightListShader, s_ClearVoxelAtomicKernel, "g_LayeredSingleIdxBuffer", s_GlobalLightListAtomic);
cmd.DispatchCompute(buildPerVoxelLightListShader, s_ClearVoxelAtomicKernel, 1, 1, 1);
cmd.SetComputeIntParam(buildPerVoxelLightListShader, "g_iNrVisibLights", m_lightCount);
SetMatrixCS(cmd, buildPerVoxelLightListShader, "g_mScrProjection", projscr);
SetMatrixCS(cmd, buildPerVoxelLightListShader, "g_mInvScrProjection", invProjscr);
cmd.SetComputeIntParam(buildPerVoxelLightListShader, "g_iLog2NumClusters", k_Log2NumClusters);
//Vector4 v2_near = invProjscr * new Vector4(0.0f, 0.0f, 0.0f, 1.0f);
//Vector4 v2_far = invProjscr * new Vector4(0.0f, 0.0f, 1.0f, 1.0f);
//float nearPlane2 = -(v2_near.z/v2_near.w);
//float farPlane2 = -(v2_far.z/v2_far.w);
var nearPlane = camera.nearClipPlane;
var farPlane = camera.farClipPlane;
cmd.SetComputeFloatParam(buildPerVoxelLightListShader, "g_fNearPlane", nearPlane);
cmd.SetComputeFloatParam(buildPerVoxelLightListShader, "g_fFarPlane", farPlane);
const float C = (float)(1 << k_Log2NumClusters);
var geomSeries = (1.0 - Mathf.Pow(k_ClustLogBase, C)) / (1 - k_ClustLogBase); // geometric series: sum_k=0^{C-1} base^k
m_ClustScale = (float)(geomSeries / (farPlane - nearPlane));
cmd.SetComputeFloatParam(buildPerVoxelLightListShader, "g_fClustScale", m_ClustScale);
cmd.SetComputeFloatParam(buildPerVoxelLightListShader, "g_fClustBase", k_ClustLogBase);
return numLightsOut + numProbesOut;
}
cmd.SetComputeTextureParam(buildPerVoxelLightListShader, s_GenListPerVoxelKernel, "g_depth_tex", new RenderTargetIdentifier(cameraDepthBuffer));
cmd.SetComputeBufferParam(buildPerVoxelLightListShader, s_GenListPerVoxelKernel, "g_vLayeredLightList", s_PerVoxelLightLists);
cmd.SetComputeBufferParam(buildPerVoxelLightListShader, s_GenListPerVoxelKernel, "g_LayeredOffset", s_PerVoxelOffset);
cmd.SetComputeBufferParam(buildPerVoxelLightListShader, s_GenListPerVoxelKernel, "g_LayeredSingleIdxBuffer", s_GlobalLightListAtomic);
if (enableBigTilePrepass) cmd.SetComputeBufferParam(buildPerVoxelLightListShader, s_GenListPerVoxelKernel, "g_vBigTileLightList", s_BigTileLightList);
if (k_UseDepthBuffer)
{
cmd.SetComputeBufferParam(buildPerVoxelLightListShader, s_GenListPerVoxelKernel, "g_logBaseBuffer", s_PerTileLogBaseTweak);
}
void BuildPerTileLightLists(Camera camera, RenderLoop loop, int numLights, Matrix4x4 projscr, Matrix4x4 invProjscr)
var numTilesX = (camera.pixelWidth + 15) / 16;
var numTilesY = (camera.pixelHeight + 15) / 16;
cmd.DispatchCompute(buildPerVoxelLightListShader, s_GenListPerVoxelKernel, numTilesX, numTilesY, 1);
}
public void BuildGPULightLists(Camera camera, RenderLoop loop, HDRenderLoop.LightList lightList, int cameraDepthBuffer)
{
var w = camera.pixelWidth;
var h = camera.pixelHeight;

var numBigTilesY = (h + 63) / 64;
// camera to screen matrix (and it's inverse)
var proj = CameraProjection(camera);
var temp = new Matrix4x4();
temp.SetRow(0, new Vector4(0.5f * w, 0.0f, 0.0f, 0.5f * w));
temp.SetRow(1, new Vector4(0.0f, 0.5f * h, 0.0f, 0.5f * h));
temp.SetRow(2, new Vector4(0.0f, 0.0f, 0.5f, 0.5f));
temp.SetRow(3, new Vector4(0.0f, 0.0f, 0.0f, 1.0f));
var projscr = temp * proj;
var invProjscr = projscr.inverse;
var proj = CameraProjection(camera);
var temp = new Matrix4x4();
temp.SetRow(0, new Vector4(1.0f, 0.0f, 0.0f, 0.0f));
temp.SetRow(1, new Vector4(0.0f, 1.0f, 0.0f, 0.0f));
temp.SetRow(2, new Vector4(0.0f, 0.0f, 0.5f, 0.5f));

cmd.SetComputeIntParam(buildScreenAABBShader, "g_iNrVisibLights", numLights);
cmd.SetComputeIntParam(buildScreenAABBShader, "g_iNrVisibLights", m_lightCount);
cmd.DispatchCompute(buildScreenAABBShader, s_GenAABBKernel, (numLights + 7) / 8, 1, 1);
cmd.DispatchCompute(buildScreenAABBShader, s_GenAABBKernel, (m_lightCount + 7) / 8, 1, 1);
}
// enable coarse 2D pass on 64x64 tiles (used for both fptl and clustered).

cmd.SetComputeIntParam(buildPerBigTileLightListShader, "g_iNrVisibLights", numLights);
cmd.SetComputeIntParam(buildPerBigTileLightListShader, "g_iNrVisibLights", m_lightCount);
SetMatrixCS(cmd, buildPerBigTileLightListShader, "g_mScrProjection", projscr);
SetMatrixCS(cmd, buildPerBigTileLightListShader, "g_mInvScrProjection", invProjscr);
cmd.SetComputeFloatParam(buildPerBigTileLightListShader, "g_fNearPlane", camera.nearClipPlane);

if (usingFptl) // optimized for opaques only
{
cmd.SetComputeIntParams(buildPerTileLightListShader, "g_viDimensions", new int[2] { w, h });
cmd.SetComputeIntParam(buildPerTileLightListShader, "g_iNrVisibLights", numLights);
cmd.SetComputeIntParam(buildPerTileLightListShader, "g_iNrVisibLights", m_lightCount);
cmd.SetComputeTextureParam(buildPerTileLightListShader, s_GenListPerTileKernel, "g_depth_tex", new RenderTargetIdentifier(s_CameraDepthTexture));
cmd.SetComputeTextureParam(buildPerTileLightListShader, s_GenListPerTileKernel, "g_depth_tex", new RenderTargetIdentifier(cameraDepthBuffer));
cmd.SetComputeBufferParam(buildPerTileLightListShader, s_GenListPerTileKernel, "g_vLightList", s_LightList);
if (enableBigTilePrepass) cmd.SetComputeBufferParam(buildPerTileLightListShader, s_GenListPerTileKernel, "g_vBigTileLightList", s_BigTileLightList);
cmd.DispatchCompute(buildPerTileLightListShader, s_GenListPerTileKernel, numTilesX, numTilesY, 1);

{
VoxelLightListGeneration(cmd, camera, numLights, projscr, invProjscr);
VoxelLightListGeneration(cmd, camera, projscr, invProjscr, cameraDepthBuffer);
*/
}
}
}

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


struct SFiniteLightData
{
float3 lightPos;
int flags;
float3 lightAxisX;
uint lightType;
float3 lightAxisY;

float3 color;
uint lightModel;
float unusued;
uint lightModel;
float3 boxInvRange;
float unused2;
};

{
return value.lightPos;
}
int GetFlags(SFiniteLightData value)
{
return value.flags;
}
float3 GetLightAxisX(SFiniteLightData value)
{
return value.lightAxisX;

{
return value.cotan;
}
float3 GetColor(SFiniteLightData value)
float3 GetBoxInnerDist(SFiniteLightData value)
return value.color;
return value.boxInnerDist;
}
float3 GetBoxInnerDist(SFiniteLightData value)
{
return value.boxInnerDist;
}
float GetUnusued(SFiniteLightData value)
{
return value.unusued;
}
float3 GetBoxInvRange(SFiniteLightData value)
{

8
Assets/ScriptableRenderLoop/HDRenderLoop/Material/LayeredLit/LayeredLit.shader


#pragma shader_feature _LAYER_MASK_MAP
#pragma shader_feature _LAYER_MASK_VERTEX_COLOR
#pragma shader_feature _ _LAYEREDLIT_3_LAYERS _LAYEREDLIT_4_LAYERS
//#pragma shader_feature _ _LAYER_MAPPING_UV1_0 _LAYER_MAPPING_PLANAR_0 _LAYER_MAPPING_TRIPLANAR_0
//#pragma shader_feature _ _LAYER_MAPPING_UV1_1 _LAYER_MAPPING_PLANAR_1 _LAYER_MAPPING_TRIPLANAR_1
//#pragma shader_feature _ _LAYER_MAPPING_UV1_2 _LAYER_MAPPING_PLANAR_2 _LAYER_MAPPING_TRIPLANAR_2
//#pragma shader_feature _ _LAYER_MAPPING_UV1_3 _LAYER_MAPPING_PLANAR_3 _LAYER_MAPPING_TRIPLANAR_3
#pragma shader_feature _ _LAYER_MAPPING_UV1_0 _LAYER_MAPPING_PLANAR_0 _LAYER_MAPPING_TRIPLANAR_0
#pragma shader_feature _ _LAYER_MAPPING_UV1_1 _LAYER_MAPPING_PLANAR_1 _LAYER_MAPPING_TRIPLANAR_1
#pragma shader_feature _ _LAYER_MAPPING_UV1_2 _LAYER_MAPPING_PLANAR_2 _LAYER_MAPPING_TRIPLANAR_2
#pragma shader_feature _ _LAYER_MAPPING_UV1_3 _LAYER_MAPPING_PLANAR_3 _LAYER_MAPPING_TRIPLANAR_3
//-------------------------------------------------------------------------------------
// Define

16
Assets/ScriptableRenderLoop/HDRenderLoop/Sky/Resources/SkyHDRI.shader


Pass
{
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha // We will lerp only the values that are valid
ZTest LEqual
Blend One Zero
HLSLPROGRAM
#pragma target 5.0

// TODO: implement SV_vertexID full screen quad
Varyings output;
output.positionCS = float4(input.positionCS.xy, UNITY_RAW_FAR_CLIP_VALUE
#if UNITY_REVERSED_Z
+ 0.000001
#else
- 0.000001
#endif
, 1.0);
output.eyeVector = input.eyeVector;

float3 dir = normalize(input.eyeVector);
// Rotate direction
float phi = _SkyParam.z * PI / 180.0; // Convert to radiant
float phi = DegToRad(_SkyParam.z);
sincos(phi, cosPhi, sinPhi);
float3 rotDirX = float3(cosPhi, 0, sinPhi);
float3 rotDirY = float3(sinPhi, 0, -cosPhi);
sincos(phi, sinPhi, cosPhi);
float3 rotDirX = float3(cosPhi, 0, -sinPhi);
float3 rotDirY = float3(sinPhi, 0, cosPhi);
dir = float3(dot(rotDirX, dir), dir.y, dot(rotDirY, dir));
return ClampToFloat16Max(SAMPLE_TEXTURECUBE_LOD(_Cubemap, sampler_Cubemap, dir, 0) * exp2(_SkyParam.x) * _SkyParam.y);

4
Assets/ScriptableRenderLoop/RenderPasses/ShadowRenderPass.cs


if (lightType == LightType.Spot)
{
var settings = new DrawShadowsSettings(cullResults, lightIndex);
bool needRendering = cullResults.ComputeSpotShadowsMatricesAndCullingPrimitives(lightIndex, out view, out proj, out settings.splitData);
bool needRendering = cullResults.ComputeSpotShadowMatricesAndCullingPrimitives(lightIndex, out view, out proj, out settings.splitData);
SetupShadowSplitMatrices(ref packedShadows.shadowSlices[shadowSliceIndex], proj, view);
if (needRendering)
RenderShadowSplit(ref shadowSlices[shadowSliceIndex], lightDirection, proj, view, ref loop, settings);

for (int s = 0; s < shadowSliceCount; ++s, shadowSliceIndex++)
{
var settings = new DrawShadowsSettings(cullResults, lightIndex);
bool needRendering = cullResults.ComputePointShadowsMatricesAndCullingPrimitives(lightIndex, (CubemapFace)s, 2.0f, out view, out proj, out settings.splitData);
bool needRendering = cullResults.ComputePointShadowMatricesAndCullingPrimitives(lightIndex, (CubemapFace)s, 2.0f, out view, out proj, out settings.splitData);
SetupShadowSplitMatrices(ref shadowSlices[shadowSliceIndex], proj, view);
if (needRendering)

10
Assets/ScriptableRenderLoop/ShaderLibrary/Common.hlsl


#define MERGE_NAME(X, Y) X##Y
float DegToRad(float deg)
{
return deg * PI / 180.0;
}
float RadToDeg(float rad)
{
return rad * 180.0 / PI;
}
// Acos in 14 cycles.
// Ref: https://seblagarde.wordpress.com/2014/12/01/inverse-trigonometric-functions-gpu-optimization-for-amd-gcn-architecture/
float FastACos(float inX)

8
Assets/ScriptableRenderLoop/fptl/FptlLighting.cs


cmd.SetComputeTextureParam(deferredComputeShader, kernel, "_spotCookieTextures", m_CookieTexArray.GetTexCache());
cmd.SetComputeTextureParam(deferredComputeShader, kernel, "_pointCookieTextures", m_CubeCookieTexArray.GetTexCache());
cmd.SetComputeTextureParam(deferredComputeShader, kernel, "_reflCubeTextures", m_CubeReflTexArray.GetTexCache());
cmd.SetComputeTextureParam(deferredComputeShader, kernel, "_reflRootCubeTexture", ReflectionProbe.GetDefaultTexture());
cmd.SetComputeTextureParam(deferredComputeShader, kernel, "_reflRootCubeTexture", ReflectionProbe.defaultTexture);
cmd.SetComputeTextureParam(deferredComputeShader, kernel, "g_tShadowBuffer", new RenderTargetIdentifier(m_shadowBufferID));
cmd.SetComputeTextureParam(deferredComputeShader, kernel, "unity_NHxRoughness", m_NHxRoughnessTexture);
cmd.SetComputeTextureParam(deferredComputeShader, kernel, "_LightTextureB0", m_LightAttentuationTexture);

cmd.SetComputeBufferParam(deferredComputeShader, kernel, "g_dirLightData", s_DirLightList);
var defdecode = ReflectionProbe.GetDefaultTextureHDRDecodeValues();
var defdecode = ReflectionProbe.defaultTextureHDRDecodeValues;
cmd.SetComputeFloatParam(deferredComputeShader, "_reflRootHdrDecodeMult", defdecode.x);
cmd.SetComputeFloatParam(deferredComputeShader, "_reflRootHdrDecodeExp", defdecode.y);

cmd.SetGlobalTexture("_pointCookieTextures", m_CubeCookieTexArray.GetTexCache());
cmd.SetGlobalTexture("_reflCubeTextures", m_CubeReflTexArray.GetTexCache());
var topCube = ReflectionProbe.GetDefaultTexture();
var defdecode = ReflectionProbe.GetDefaultTextureHDRDecodeValues();
var topCube = ReflectionProbe.defaultTexture;
var defdecode = ReflectionProbe.defaultTextureHDRDecodeValues;
cmd.SetGlobalTexture("_reflRootCubeTexture", topCube);
cmd.SetGlobalFloat("_reflRootHdrDecodeMult", defdecode.x);
cmd.SetGlobalFloat("_reflRootHdrDecodeExp", defdecode.y);

208
Assets/TestScenes/HDTest/GlobalIlluminationTest.unity


m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1}
m_AmbientIntensity: 1
m_AmbientMode: 0
m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0}
m_SkyboxMaterial: {fileID: 0}
m_HaloStrength: 0.5
m_FlareStrength: 1
m_FlareFadeSpeed: 3

m_DefaultReflectionResolution: 128
m_DefaultReflectionResolution: 1024
m_IndirectSpecularColor: {r: 0.11480248, g: 0.11976801, b: 0.105756685, a: 1}
m_IndirectSpecularColor: {r: 0.5456174, g: 0.39782104, b: 0.24038851, a: 1}
--- !u!157 &3
LightmapSettings:
m_ObjectHideFlags: 0

m_AlbedoBoost: 1
m_TemporalCoherenceThreshold: 1
m_EnvironmentLightingMode: 0
m_EnableBakedLightmaps: 1
m_EnableBakedLightmaps: 0
m_EnableRealtimeLightmaps: 1
m_LightmapEditorSettings:
serializedVersion: 4

m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
--- !u!65 &20738782
BoxCollider:

m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
--- !u!65 &32562345
BoxCollider:

m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
--- !u!135 &439514138
SphereCollider:

m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
--- !u!65 &841702837
BoxCollider:

m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
--- !u!64 &877242193
MeshCollider:

m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
--- !u!65 &931864777
BoxCollider:

- {fileID: 931864775}
- {fileID: 190482350}
- {fileID: 1232831964}
- {fileID: 1543726726}
m_Father: {fileID: 0}
m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}

m_Component:
- component: {fileID: 1108908832}
- component: {fileID: 1108908833}
- component: {fileID: 1108908834}
m_Layer: 0
m_Name: Spotlight
m_TagString: Untagged

m_BounceIntensity: 1
m_ShadowRadius: 0
m_ShadowAngle: 0
--- !u!114 &1108908834
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1108908831}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 7a68c43fe1f2a47cfa234b5eeaa98012, type: 3}
m_Name:
m_EditorClassIdentifier:
shadowResolution: 512
shadowDimmer: 1
affectDiffuse: 1
affectSpecular: 1
treatAsAreaLight: 0
isDoubleSided: 0
areaLightLength: 0
areaLightWidth: 0
--- !u!1 &1197900219
GameObject:
m_ObjectHideFlags: 0

m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
--- !u!64 &1197900222
MeshCollider:

m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
--- !u!135 &1232831966
SphereCollider:

- {fileID: 1845946151}
- {fileID: 1910068097}
- {fileID: 1686135373}
- {fileID: 1736468425}
m_Father: {fileID: 0}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}

m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
--- !u!135 &1315831391
SphereCollider:

m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
--- !u!65 &1330031311
BoxCollider:

m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1330031308}
m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
--- !u!1 &1543726725
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 5
m_Component:
- component: {fileID: 1543726726}
- component: {fileID: 1543726729}
- component: {fileID: 1543726728}
- component: {fileID: 1543726727}
m_Layer: 0
m_Name: Sphere_Skybox
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &1543726726
Transform:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1543726725}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: -6.33, y: 0.428, z: -5.0499997}
m_LocalScale: {x: 1.6119599, y: 1.6119599, z: 1.6119599}
m_Children: []
m_Father: {fileID: 1027688891}
m_RootOrder: 10
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!23 &1543726727
MeshRenderer:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1543726725}
m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_MotionVectors: 1
m_LightProbeUsage: 0
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 6abcdf01974b58c45af2b04a9c0fdd13, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0
m_StaticBatchRoot: {fileID: 0}
m_ProbeAnchor: {fileID: 0}
m_LightProbeVolumeOverride: {fileID: 0}
m_ScaleInLightmap: 1
m_PreserveUVs: 1
m_IgnoreNormalsForChartDetection: 0
m_ImportantGI: 0
m_SelectedEditorRenderState: 3
m_MinimumChartSize: 4
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
--- !u!135 &1543726728
SphereCollider:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1543726725}
m_Material: {fileID: 0}
m_IsTrigger: 0
m_Enabled: 1
serializedVersion: 2
m_Radius: 0.5
m_Center: {x: 0, y: 0, z: 0}
--- !u!33 &1543726729
MeshFilter:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1543726725}
m_Mesh: {fileID: 10207, guid: 0000000000000000e000000000000000, type: 0}
--- !u!1 &1617519335
GameObject:
m_ObjectHideFlags: 0

m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
--- !u!135 &1617519338
SphereCollider:

m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
--- !u!135 &1664670956
SphereCollider:

m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
--- !u!135 &1686135375
SphereCollider:

m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1686135372}
m_Mesh: {fileID: 10207, guid: 0000000000000000e000000000000000, type: 0}
--- !u!1 &1736468424
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 5
m_Component:
- component: {fileID: 1736468425}
- component: {fileID: 1736468428}
- component: {fileID: 1736468427}
- component: {fileID: 1736468426}
m_Layer: 0
m_Name: Sphere_Skybox
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &1736468425
Transform:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1736468424}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: -5.815, y: 0.47800002, z: 0.013999939}
m_LocalScale: {x: 1.6119577, y: 1.6119568, z: 1.6119568}
m_Children: []
m_Father: {fileID: 1271727142}
m_RootOrder: 10
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!23 &1736468426
MeshRenderer:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1736468424}
m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_MotionVectors: 1
m_LightProbeUsage: 0
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: 1971c044ea2fd954382f35c444500b9d, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0
m_StaticBatchRoot: {fileID: 0}
m_ProbeAnchor: {fileID: 0}
m_LightProbeVolumeOverride: {fileID: 0}
m_ScaleInLightmap: 1
m_PreserveUVs: 1
m_IgnoreNormalsForChartDetection: 0
m_ImportantGI: 0
m_SelectedEditorRenderState: 3
m_MinimumChartSize: 4
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
--- !u!135 &1736468427
SphereCollider:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1736468424}
m_Material: {fileID: 0}
m_IsTrigger: 0
m_Enabled: 1
serializedVersion: 2
m_Radius: 0.5
m_Center: {x: 0, y: 0, z: 0}
--- !u!33 &1736468428
MeshFilter:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1736468424}
m_Mesh: {fileID: 10207, guid: 0000000000000000e000000000000000, type: 0}
--- !u!1 &1845946150
GameObject:
m_ObjectHideFlags: 0

m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
--- !u!65 &1845946153
BoxCollider:

259
Assets/TestScenes/HDTest/Material/HDRenderLoopMaterials/Gray.mat


m_CustomRenderQueue: -1
stringTagMap: {}
m_SavedProperties:
serializedVersion: 2
serializedVersion: 3
- first:
name: _AmbientOcclusionMap
second:
- _AmbientOcclusionMap:
- first:
name: _BaseColorMap
second:
- _AnisotropyMap:
- first:
name: _BumpMap
second:
- _BaseColorMap:
- first:
name: _DetailAlbedoMap
second:
- _BumpMap:
- first:
name: _DetailMask
second:
- _DetailAlbedoMap:
- first:
name: _DetailNormalMap
second:
- _DetailMask:
- first:
name: _DiffuseLightingMap
second:
- _DetailNormalMap:
- first:
name: _EmissionMap
second:
- _DiffuseLightingMap:
- first:
name: _EmissiveColorMap
second:
- _EmissionMap:
- first:
name: _HeightMap
second:
- _EmissiveColorMap:
- first:
name: _MainTex
second:
- _HeightMap:
- first:
name: _MaskMap
second:
- _MainTex:
- first:
name: _MetallicGlossMap
second:
- _MaskMap:
- first:
name: _MettalicMap
second:
- _MetallicGlossMap:
- first:
name: _NormalMap
second:
- _MettalicMap:
- first:
name: _OcclusionMap
second:
- _NormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _OcclusionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ParallaxMap:
- first:
name: _ParallaxMap
second:
- _SmoothnessMap:
- first:
name: _SmoothnessMap
second:
- _SpecularOcclusionMap:
- first:
name: _SpecularOcclusionMap
second:
- _SubSurfaceRadiusMap:
- first:
name: _SubSurfaceRadiusMap
second:
- _TangentMap:
- first:
name: _AlphaCutoff
second: 0.5
- first:
name: _AlphaCutoffEnable
second: 0
- first:
name: _BlendMode
second: 0
- first:
name: _BumpScale
second: 1
- first:
name: _CullMode
second: 2
- first:
name: _Cutoff
second: 0.5
- first:
name: _DetailNormalMapScale
second: 1
- first:
name: _DistortionDepthTest
second: 0
- first:
name: _DistortionOnly
second: 0
- first:
name: _DoubleSided
second: 1
- first:
name: _DoubleSidedLigthing
second: 1
- first:
name: _DoubleSidedMode
second: 0
- first:
name: _DstBlend
second: 0
- first:
name: _EmissiveColorMode
second: 1
- first:
name: _EmissiveIntensity
second: 0
- first:
name: _GlossMapScale
second: 1
- first:
name: _Glossiness
second: 0.5
- first:
name: _GlossyReflections
second: 1
- first:
name: _HeightBias
second: 0
- first:
name: _HeightMapMode
second: 0
- first:
name: _HeightScale
second: 1
- first:
name: _MaterialID
second: 0
- first:
name: _MaterialId
second: 0
- first:
name: _Metalic
second: 0
- first:
name: _Metallic
second: 0
- first:
name: _Mettalic
second: 0
- first:
name: _Mode
second: 0
- first:
name: _NormalMapSpace
second: 0
- first:
name: _OcclusionStrength
second: 1
- first:
name: _Parallax
second: 0.02
- first:
name: _Smoothness
second: 0.5
- first:
name: _SmoothnessTextureChannel
second: 0
- first:
name: _SpecularHighlights
second: 1
- first:
name: _SrcBlend
second: 1
- first:
name: _SubSurfaceRadius
second: 0
- first:
name: _SurfaceType
second: 0
- first:
name: _UVSec
second: 0
- first:
name: _ZWrite
second: 1
- _AlphaCutoff: 0.5
- _AlphaCutoffEnable: 0
- _Anisotropy: 0
- _BlendMode: 0
- _BumpScale: 1
- _CullMode: 2
- _Cutoff: 0.5
- _DetailNormalMapScale: 1
- _DistortionDepthTest: 0
- _DistortionOnly: 0
- _DoubleSided: 1
- _DoubleSidedLigthing: 1
- _DoubleSidedMode: 0
- _DstBlend: 0
- _EmissiveColorMode: 1
- _EmissiveIntensity: 0
- _GlossMapScale: 1
- _Glossiness: 0.5
- _GlossyReflections: 1
- _HeightBias: 0
- _HeightMapMode: 0
- _HeightScale: 1
- _MaterialID: 0
- _MaterialId: 0
- _Metalic: 0
- _Metallic: 0
- _Mettalic: 0
- _Mode: 0
- _NormalMapSpace: 0
- _OcclusionStrength: 1
- _Parallax: 0.02
- _Smoothness: 0.5
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SrcBlend: 1
- _SubSurfaceRadius: 0
- _SurfaceType: 0
- _UVSec: 0
- _ZWrite: 1
- first:
name: _BaseColor
second: {r: 0.5019608, g: 0.5019608, b: 0.5019608, a: 1}
- first:
name: _Color
second: {r: 0.5019608, g: 0.5019608, b: 0.5019608, a: 1}
- first:
name: _EmissionColor
second: {r: 0, g: 0, b: 0, a: 1}
- first:
name: _EmissiveColor
second: {r: 0, g: 0, b: 0, a: 1}
- _BaseColor: {r: 0.5019608, g: 0.5019608, b: 0.5019608, a: 1}
- _Color: {r: 0.5019608, g: 0.5019608, b: 0.5019608, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _EmissiveColor: {r: 0, g: 0, b: 0, a: 1}

12
Assets/TestScenes/HDTest/Material/HDRenderLoopMaterials/Layered/Layered.mat


m_Shader: {fileID: 4800000, guid: 81d02e8644315b742b154842a3a2f98c, type: 3}
m_ShaderKeywords: _ALPHACUTOFFENABLE_OFF _DISTORTIONDEPTHTEST_OFF _DISTORTIONONLY_OFF
_EMISSION _LAYEREDLIT_4_LAYER _LAYEREDLIT_4_LAYERS _LAYERMASKMAP _LAYER_MAPPING_PLANAR0
_LAYER_MAPPING_PLANAR_0 _LAYER_MAPPING_PLANAR_1 _LAYER_MAPPING_UV1_2 _LAYER_MASK_VERTEX_COLOR
_MASKMAP _NORMALMAP _NORMALMAP_TANGENT_SPACE
_LAYER_MAPPING_PLANAR_0 _LAYER_MAPPING_PLANAR_1 _LAYER_MAPPING_PLANAR_2 _LAYER_MAPPING_PLANAR_3
_LAYER_MASK_VERTEX_COLOR _MASKMAP _NORMALMAP _NORMALMAP_TANGENT_SPACE
m_LightmapFlags: 1
m_CustomRenderQueue: -1
stringTagMap: {}

- _LayerCount: 4
- _LayerMapping0: 2
- _LayerMapping1: 2
- _LayerMapping2: 1
- _LayerMapping3: 0
- _LayerMapping2: 2
- _LayerMapping3: 2
- _LayerSize2: 1
- _LayerSize3: 1
- _LayerSize2: 2
- _LayerSize3: 2
- _LayerTiling0: 10
- _LayerTiling1: 10
- _LayerTiling2: 1

2
Assets/TestScenes/HDTest/Material/HDRenderLoopMaterials/Layered/Layered.mat.meta


fileFormatVersion: 2
guid: 6e7fa39a7d1b15c4184c9f51d86eba22
timeCreated: 1479298680
timeCreated: 1479379836
licenseType: Pro
NativeFormatImporter:
userData: '{"GUIDArray":["01fa3be727161d249a81ad7065c15459","3acf8f156d29e494e8cd196462d1a17c","62b3c923bc540b94a803550e9927936a","c569253e641dc934db7c3595b31890da"]}'

90
Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/ClusteredUtils.hlsl


#ifndef __CLUSTEREDUTILS_H__
#define __CLUSTEREDUTILS_H__
#ifndef FLT_EPSILON
#define FLT_EPSILON 1.192092896e-07f
#endif
float GetScaleFromBase(float base)
{
const float C = (float)(1 << g_iLog2NumClusters);
const float geomSeries = (1.0 - pow(base, C)) / (1 - base); // geometric series: sum_k=0^{C-1} base^k
return geomSeries / (g_fFarPlane - g_fNearPlane);
}
int SnapToClusterIdxFlex(float z_in, float suggestedBase, bool logBasePerTile)
{
#if USE_LEFTHAND_CAMERASPACE
float z = z_in;
#else
float z = -z_in;
#endif
float userscale = g_fClustScale;
if (logBasePerTile)
userscale = GetScaleFromBase(suggestedBase);
// using the inverse of the geometric series
const float dist = max(0, z - g_fNearPlane);
return (int)clamp(log2(dist * userscale * (suggestedBase - 1.0f) + 1) / log2(suggestedBase), 0.0, (float)((1 << g_iLog2NumClusters) - 1));
}
int SnapToClusterIdx(float z_in, float suggestedBase)
{
#ifdef ENABLE_DEPTH_TEXTURE_BACKPLANE
bool logBasePerTile = true; // resolved compile time
#else
bool logBasePerTile = false;
#endif
return SnapToClusterIdxFlex(z_in, suggestedBase, logBasePerTile);
}
float ClusterIdxToZFlex(int k, float suggestedBase, bool logBasePerTile)
{
float res;
float userscale = g_fClustScale;
if (logBasePerTile)
userscale = GetScaleFromBase(suggestedBase);
float dist = (pow(suggestedBase, (float)k) - 1.0) / (userscale * (suggestedBase - 1.0f));
res = dist + g_fNearPlane;
#if USE_LEFTHAND_CAMERASPACE
return res;
#else
return -res;
#endif
}
float ClusterIdxToZ(int k, float suggestedBase)
{
#ifdef ENABLE_DEPTH_TEXTURE_BACKPLANE
bool logBasePerTile = true; // resolved compile time
#else
bool logBasePerTile = false;
#endif
return ClusterIdxToZFlex(k, suggestedBase, logBasePerTile);
}
// generate a log-base value such that half of the clusters are consumed from near plane to max. opaque depth of tile.
float SuggestLogBase50(float tileFarPlane)
{
const float C = (float)(1 << g_iLog2NumClusters);
float normDist = clamp((tileFarPlane - g_fNearPlane) / (g_fFarPlane - g_fNearPlane), FLT_EPSILON, 1.0);
float suggested_base = pow((1.0 + sqrt(max(0.0, 1.0 - 4.0 * normDist * (1.0 - normDist)))) / (2.0 * normDist), 2.0 / C); //
return max(g_fClustBase, suggested_base);
}
// generate a log-base value such that (approximately) a quarter of the clusters are consumed from near plane to max. opaque depth of tile.
float SuggestLogBase25(float tileFarPlane)
{
const float C = (float)(1 << g_iLog2NumClusters);
float normDist = clamp((tileFarPlane - g_fNearPlane) / (g_fFarPlane - g_fNearPlane), FLT_EPSILON, 1.0);
float suggested_base = pow((1 / 2.3) * max(0.0, (0.8 / normDist) - 1), 4.0 / (C * 2)); // approximate inverse of d*x^4 + (-x) + (1-d) = 0 - d is normalized distance
return max(g_fClustBase, suggested_base);
}
#endif

9
Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/ClusteredUtils.hlsl.meta


fileFormatVersion: 2
guid: 54f8006db9236c148af831b7fcaadc0c
timeCreated: 1479691314
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

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


#pragma kernel BigTileLightListGen
#include "../TilePass.cs.hlsl"
#include "../LightingConvexHullUtils.hlsl"
#if !defined(SHADER_API_XBOXONE) && !defined(SHADER_API_PSSL)
#include "../SortingComputeUtils.hlsl"
#endif
#define EXACT_EDGE_TESTS
#define PERFORM_SPHERICAL_INTERSECTION_TESTS
#define MAX_NR_BIGTILE_LIGHTS (MAX_NR_BIGTILE_LIGHTS_PLUSONE-1)
uniform int g_iNrVisibLights;
uniform uint2 g_viDimensions;
uniform float4x4 g_mInvScrProjection;
uniform float4x4 g_mScrProjection;
uniform float g_fNearPlane;
uniform float g_fFarPlane;
StructuredBuffer<float3> g_vBoundsBuffer : register( t1 );
StructuredBuffer<SFiniteLightData> g_vLightData : register( t2 );
StructuredBuffer<SFiniteLightBound> g_data : register( t3 );
#define NR_THREADS 64
// output buffer
RWBuffer<uint> g_vLightList : register( u0 );
// 2kB (room for roughly 30 wavefronts)
groupshared unsigned int lightsListLDS[MAX_NR_BIGTILE_LIGHTS_PLUSONE];
groupshared uint lightOffs;
float GetLinearDepth(float zDptBufSpace) // 0 is near 1 is far
{
float3 vP = float3(0.0f,0.0f,zDptBufSpace);
float4 v4Pres = mul(g_mInvScrProjection, float4(vP,1.0));
return v4Pres.z / v4Pres.w;
}
float3 GetViewPosFromLinDepth(float2 v2ScrPos, float fLinDepth)
{
float fSx = g_mScrProjection[0].x;
float fCx = g_mScrProjection[0].z;
float fSy = g_mScrProjection[1].y;
float fCy = g_mScrProjection[1].z;
#if USE_LEFTHAND_CAMERASPACE
return fLinDepth*float3( ((v2ScrPos.x-fCx)/fSx), ((v2ScrPos.y-fCy)/fSy), 1.0 );
#else
return fLinDepth*float3( -((v2ScrPos.x+fCx)/fSx), -((v2ScrPos.y+fCy)/fSy), 1.0 );
#endif
}
float GetOnePixDiagWorldDistAtDepthOne()
{
float fSx = g_mScrProjection[0].x;
float fSy = g_mScrProjection[1].y;
return length( float2(1.0/fSx,1.0/fSy) );
}
#ifdef PERFORM_SPHERICAL_INTERSECTION_TESTS
void SphericalIntersectionTests(uint threadID, int iNrCoarseLights, float2 screenCoordinate);
#endif
#ifdef EXACT_EDGE_TESTS
void CullByExactEdgeTests(uint threadID, int iNrCoarseLights, uint2 viTilLL, uint2 viTilUR);
#endif
[numthreads(NR_THREADS, 1, 1)]
void BigTileLightListGen(uint threadID : SV_GroupIndex, uint3 u3GroupID : SV_GroupID)
{
uint2 tileIDX = u3GroupID.xy;
uint t=threadID;
uint iWidth = g_viDimensions.x;
uint iHeight = g_viDimensions.y;
uint nrBigTilesX = (iWidth+63)/64;
uint nrBigTilesY = (iHeight+63)/64;
if(t==0) lightOffs = 0;
#if !defined(SHADER_API_XBOXONE) && !defined(SHADER_API_PSSL)
GroupMemoryBarrierWithGroupSync();
#endif
uint2 viTilLL = 64*tileIDX;
uint2 viTilUR = min( viTilLL+uint2(64,64), uint2(iWidth, iHeight) ); // not width and height minus 1 since viTilUR represents the end of the tile corner.
float2 vTileLL = float2(viTilLL.x/(float) iWidth, viTilLL.y/(float) iHeight);
float2 vTileUR = float2(viTilUR.x/(float) iWidth, viTilUR.y/(float) iHeight);
// build coarse list using AABB
for(int l=(int) t; l<(int) g_iNrVisibLights; l += NR_THREADS)
{
const float2 vMi = g_vBoundsBuffer[l].xy;
const float2 vMa = g_vBoundsBuffer[l+g_iNrVisibLights].xy;
if( all(vMa>vTileLL) && all(vMi<vTileUR))
{
unsigned int uInc = 1;
unsigned int uIndex;
InterlockedAdd(lightOffs, uInc, uIndex);
if(uIndex<MAX_NR_BIGTILE_LIGHTS) lightsListLDS[uIndex] = l; // add to light list
}
}
#if !defined(SHADER_API_XBOXONE) && !defined(SHADER_API_PSSL)
GroupMemoryBarrierWithGroupSync();
#endif
int iNrCoarseLights = min(lightOffs,MAX_NR_BIGTILE_LIGHTS);
#ifdef PERFORM_SPHERICAL_INTERSECTION_TESTS
SphericalIntersectionTests( t, iNrCoarseLights, float2(min(viTilLL.xy+uint2(64/2,64/2), uint2(iWidth-1, iHeight-1))) );
#endif
#ifdef EXACT_EDGE_TESTS
CullByExactEdgeTests(t, iNrCoarseLights, viTilLL.xy, viTilUR.xy);
#endif
// sort lights
SORTLIST(lightsListLDS, iNrCoarseLights, MAX_NR_BIGTILE_LIGHTS_PLUSONE, t, NR_THREADS);
lightOffs = 0;
GroupMemoryBarrierWithGroupSync();
for(int i=t; i<iNrCoarseLights; i+=NR_THREADS) if(lightsListLDS[i]<g_iNrVisibLights) InterlockedAdd(lightOffs, 1);
GroupMemoryBarrierWithGroupSync();
iNrCoarseLights = lightOffs;
int offs = tileIDX.y*nrBigTilesX + tileIDX.x;
for(int i=t; i<(iNrCoarseLights+1); i+=NR_THREADS)
g_vLightList[MAX_NR_BIGTILE_LIGHTS_PLUSONE*offs + i] = t==0 ? iNrCoarseLights : lightsListLDS[i-1];
}
#ifdef PERFORM_SPHERICAL_INTERSECTION_TESTS
void SphericalIntersectionTests(uint threadID, int iNrCoarseLights, float2 screenCoordinate)
{
#if USE_LEFTHAND_CAMERASPACE
float3 V = GetViewPosFromLinDepth( screenCoordinate, 1.0);
#else
float3 V = GetViewPosFromLinDepth( screenCoordinate, -1.0);
#endif
float onePixDiagDist = GetOnePixDiagWorldDistAtDepthOne();
float halfTileSizeAtZDistOne = 32*onePixDiagDist; // scale by half a tile
for(int l=threadID; l<iNrCoarseLights; l+=NR_THREADS)
{
SFiniteLightBound lgtDat = g_data[lightsListLDS[l]];
if( !DoesSphereOverlapTile(V, halfTileSizeAtZDistOne, lgtDat.center.xyz, lgtDat.radius) )
lightsListLDS[l]=0xffffffff;
}
#if !defined(SHADER_API_XBOXONE) && !defined(SHADER_API_PSSL)
GroupMemoryBarrierWithGroupSync();
#endif
}
#endif
#ifdef EXACT_EDGE_TESTS
float3 GetTileVertex(uint2 viTilLL, uint2 viTilUR, int i, float fTileFarPlane)
{
float x = (i&1)==0 ? viTilLL.x : viTilUR.x;
float y = (i&2)==0 ? viTilLL.y : viTilUR.y;
float z = (i&4)==0 ? g_fNearPlane : fTileFarPlane;
#if !USE_LEFTHAND_CAMERASPACE
z = -z;
#endif
return GetViewPosFromLinDepth( float2(x, y), z);
}
void GetFrustEdge(out float3 vP0, out float3 vE0, const int e0, uint2 viTilLL, uint2 viTilUR, float fTileFarPlane)
{
int iSection = e0>>2; // section 0 is side edges, section 1 is near edges and section 2 is far edges
int iSwizzle = e0&0x3;
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)));
}
void CullByExactEdgeTests(uint threadID, int iNrCoarseLights, uint2 viTilLL, uint2 viTilUR)
{
const bool bOnlyNeedFrustumSideEdges = true;
const int nrFrustEdges = bOnlyNeedFrustumSideEdges ? 4 : 8; // max 8 since we never need to test 4 far edges of frustum since they are identical vectors to near edges and plane is placed at vP0 on light hull.
const int totNrEdgePairs = 12*nrFrustEdges;
for(int l=0; l<iNrCoarseLights; l++)
{
const int idxCoarse = lightsListLDS[l];
[branch]if(idxCoarse<(uint) g_iNrVisibLights && g_vLightData[idxCoarse].lightType!=SPHERE_LIGHT) // don't bother doing edge tests for sphere lights since these have camera aligned bboxes.
{
SFiniteLightBound lgtDat = g_data[idxCoarse];
const float3 boxX = lgtDat.boxAxisX.xyz;
const float3 boxY = lgtDat.boxAxisY.xyz;
const float3 boxZ = -lgtDat.boxAxisZ.xyz; // flip axis (so it points away from the light direction for a spot-light)
const float3 center = lgtDat.center.xyz;
const float2 scaleXY = lgtDat.scaleXY;
for(int i=threadID; i<totNrEdgePairs; i+=NR_THREADS)
{
int e0 = (int) (((uint)i)/((uint) nrFrustEdges)); // should become a shift right
int e1 = i - e0*nrFrustEdges;
int idx_cur=0, idx_twin=0;
float3 vP0, vE0;
GetHullEdge(idx_cur, idx_twin, vP0, vE0, e0, boxX, boxY, boxZ, center, scaleXY);
float3 vP1, vE1;
GetFrustEdge(vP1, vE1, e1, viTilLL, viTilUR, g_fFarPlane);
// potential separation plane
float3 vN = cross(vE0, vE1);
int positive=0, negative=0;
for(int k=1; k<8; k++) // only need to test 7 verts (technically just 6).
{
int j = (idx_cur+k)&0x7;
float3 vPh = GetHullVertex(boxX, boxY, boxZ, center, scaleXY, j);
float fSignDist = idx_twin==j ? 0.0 : dot(vN, vPh-vP0);
if(fSignDist>0) ++positive; else if(fSignDist<0) ++negative;
}
int resh = (positive>0 && negative>0) ? 0 : (positive>0 ? 1 : (negative>0 ? (-1) : 0));
positive=0; negative=0;
for(int j=0; j<8; j++)
{
float3 vPf = GetTileVertex(viTilLL, viTilUR, j, g_fFarPlane);
float fSignDist = dot(vN, vPf-vP0);
if(fSignDist>0) ++positive; else if(fSignDist<0) ++negative;
}
int resf = (positive>0 && negative>0) ? 0 : (positive>0 ? 1 : (negative>0 ? (-1) : 0));
bool bFoundSepPlane = (resh*resf)<0;
if(bFoundSepPlane) lightsListLDS[l]=0xffffffff;
}
}
}
#if !defined(SHADER_API_XBOXONE) && !defined(SHADER_API_PSSL)
GroupMemoryBarrierWithGroupSync();
#endif
}
#endif

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


fileFormatVersion: 2
guid: 5ee1f9d6e09abe045b2f5e0b784b9072
timeCreated: 1479689024
licenseType: Pro
ComputeShaderImporter:
currentAPIMask: 4
userData:
assetBundleName:
assetBundleVariant:

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


#pragma kernel TileLightListGen_NoDepthRT LIGHTLISTGEN=TileLightListGen_NoDepthRT
#pragma kernel TileLightListGen_DepthRT LIGHTLISTGEN=TileLightListGen_DepthRT ENABLE_DEPTH_TEXTURE_BACKPLANE
#pragma kernel TileLightListGen_DepthRT_MSAA LIGHTLISTGEN=TileLightListGen_DepthRT_MSAA ENABLE_DEPTH_TEXTURE_BACKPLANE MSAA_ENABLED
#pragma kernel TileLightListGen_NoDepthRT_SrcBigTile LIGHTLISTGEN=TileLightListGen_NoDepthRT_SrcBigTile USE_TWO_PASS_TILED_LIGHTING
#pragma kernel TileLightListGen_DepthRT_SrcBigTile LIGHTLISTGEN=TileLightListGen_DepthRT_SrcBigTile ENABLE_DEPTH_TEXTURE_BACKPLANE USE_TWO_PASS_TILED_LIGHTING
#pragma kernel TileLightListGen_DepthRT_MSAA_SrcBigTile LIGHTLISTGEN=TileLightListGen_DepthRT_MSAA_SrcBigTile ENABLE_DEPTH_TEXTURE_BACKPLANE MSAA_ENABLED USE_TWO_PASS_TILED_LIGHTING
#pragma kernel ClearAtomic
#include "../ShaderBase.hlsl"
#include "../TilePass.cs.hlsl"
#include "../LightingConvexHullUtils.hlsl"
#if !defined(SHADER_API_XBOXONE) && !defined(SHADER_API_PSSL)
#include "../SortingComputeUtils.hlsl"
#endif
//#define EXACT_EDGE_TESTS
#define PERFORM_SPHERICAL_INTERSECTION_TESTS
#define CONV_HULL_TEST_ENABLED
uniform int g_iNrVisibLights;
uniform float4x4 g_mInvScrProjection;
uniform float4x4 g_mScrProjection;
uniform float g_fClustScale;
uniform float g_fClustBase;
uniform float g_fNearPlane;
uniform float g_fFarPlane;
uniform int g_iLog2NumClusters; // numClusters = (1<<g_iLog2NumClusters)
#include "../ClusteredUtils.hlsl"
#ifdef MSAA_ENABLED
Texture2DMS<float> g_depth_tex : register( t0 );
#else
Texture2D g_depth_tex : register( t0 );
#endif
StructuredBuffer<float3> g_vBoundsBuffer : register( t1 );
StructuredBuffer<SFiniteLightData> g_vLightData : register( t2 );
StructuredBuffer<SFiniteLightBound> g_data : register( t3 );
#ifdef USE_TWO_PASS_TILED_LIGHTING
Buffer<uint> g_vBigTileLightList : register( t4 );
#endif
#define NR_THREADS 64
// output buffer
RWBuffer<uint> g_vLayeredLightList : register( u0 );
RWBuffer<uint> g_LayeredOffset : register( u1 );
RWBuffer<uint> g_LayeredSingleIdxBuffer : register( u2 );
#ifdef ENABLE_DEPTH_TEXTURE_BACKPLANE
RWBuffer<float> g_logBaseBuffer : register( u3 );
#endif
#define MAX_NR_COARSE_ENTRIES 128
groupshared unsigned int coarseList[MAX_NR_COARSE_ENTRIES];
groupshared unsigned int clusterIdxs[MAX_NR_COARSE_ENTRIES/2];
groupshared float4 lightPlanes[4*6];
groupshared uint lightOffs;
#ifdef ENABLE_DEPTH_TEXTURE_BACKPLANE
groupshared int ldsZMax;
#endif
#ifdef EXACT_EDGE_TESTS
groupshared uint ldsIsLightInvisible;
groupshared uint lightOffs2;
#endif
#ifdef PERFORM_SPHERICAL_INTERSECTION_TESTS
groupshared uint lightOffsSph;
#endif
float GetLinearDepth(float zDptBufSpace) // 0 is near 1 is far
{
float3 vP = float3(0.0f,0.0f,zDptBufSpace);
float4 v4Pres = mul(g_mInvScrProjection, float4(vP,1.0));
return v4Pres.z / v4Pres.w;
}
float3 GetViewPosFromLinDepth(float2 v2ScrPos, float fLinDepth)
{
float fSx = g_mScrProjection[0].x;
float fCx = g_mScrProjection[0].z;
float fSy = g_mScrProjection[1].y;
float fCy = g_mScrProjection[1].z;
#if USE_LEFTHAND_CAMERASPACE
return fLinDepth*float3( ((v2ScrPos.x-fCx)/fSx), ((v2ScrPos.y-fCy)/fSy), 1.0 );
#else
return fLinDepth*float3( -((v2ScrPos.x+fCx)/fSx), -((v2ScrPos.y+fCy)/fSy), 1.0 );
#endif
}
float GetOnePixDiagWorldDistAtDepthOne()
{
float fSx = g_mScrProjection[0].x;
float fSy = g_mScrProjection[1].y;
return length( float2(1.0/fSx,1.0/fSy) );
}
#ifdef EXACT_EDGE_TESTS
int CullByExactEdgeTests(uint threadID, int iNrCoarseLights, uint2 viTilLL, uint2 viTilUR, float fTileFarPlane);
#endif
#ifdef PERFORM_SPHERICAL_INTERSECTION_TESTS
int SphericalIntersectionTests(uint threadID, int iNrCoarseLights, float2 screenCoordinate);
#endif
// returns 1 for intersection and 0 for none
float4 FetchPlane(int l, int p);
bool CheckIntersection(int l, int k, uint2 viTilLL, uint2 viTilUR, float suggestedBase)
{
unsigned int val = (clusterIdxs[l>>1]>>(16*(l&1)))&0xffff;
bool bIsHit = ((val>>0)&0xff)<=((uint) k) && ((uint) k)<=((val>>8)&0xff);
if(bIsHit)
{
#ifdef CONV_HULL_TEST_ENABLED
float depthAtNearZ = ClusterIdxToZ(k, suggestedBase);
float depthAtFarZ = ClusterIdxToZ(k+1, suggestedBase);
for(int p=0; p<6; p++)
{
float4 plane = lightPlanes[6*(l&3)+p];
bool bAllInvisib = true;
for(int i=0; i<8; i++)
{
float x = (i&1)==0 ? viTilLL.x : viTilUR.x;
float y = (i&2)==0 ? viTilLL.y : viTilUR.y;
float z = (i&4)==0 ? depthAtNearZ : depthAtFarZ;
float3 vP = GetViewPosFromLinDepth( float2(x, y), z);
bAllInvisib = bAllInvisib && dot(plane, float4(vP,1.0))>0;
}
if(bAllInvisib) bIsHit = false;
}
#endif
}
return bIsHit;
}
bool CheckIntersectionBasic(int l, int k)
{
unsigned int val = (clusterIdxs[l>>1]>>(16*(l&1)))&0xffff;
return ((val>>0)&0xff)<=((uint) k) && ((uint) k)<=((val>>8)&0xff);
}
[numthreads(NR_THREADS, 1, 1)]
void LIGHTLISTGEN(uint threadID : SV_GroupIndex, uint3 u3GroupID : SV_GroupID)
{
uint2 tileIDX = u3GroupID.xy;
uint t=threadID;
uint iWidth;
uint iHeight;
#ifdef MSAA_ENABLED
uint iNumSamplesMSAA;
g_depth_tex.GetDimensions(iWidth, iHeight, iNumSamplesMSAA);
#else
g_depth_tex.GetDimensions(iWidth, iHeight);
#endif
uint nrTilesX = (iWidth+15)/16;
uint nrTilesY = (iHeight+15)/16;
uint2 viTilLL = 16*tileIDX;
uint2 viTilUR = min( viTilLL+uint2(16,16), uint2(iWidth, iHeight) ); // not width and height minus 1 since viTilUR represents the end of the tile corner.
if(t==0)
{
lightOffs = 0;
#ifdef ENABLE_DEPTH_TEXTURE_BACKPLANE
ldsZMax = 0;
#endif
}
#if !defined(SHADER_API_XBOXONE) && !defined(SHADER_API_PSSL)
GroupMemoryBarrierWithGroupSync();
#endif
float dpt_ma=1.0;
#ifdef ENABLE_DEPTH_TEXTURE_BACKPLANE
// establish min and max depth first
dpt_ma=0.0;
for(int idx=t; idx<256; idx+=NR_THREADS)
{
uint2 uPixCrd = min( uint2(viTilLL.x+(idx&0xf), viTilLL.y+(idx>>4)), uint2(iWidth-1, iHeight-1) );
#ifdef MSAA_ENABLED
for(int i=0; i<iNumSamplesMSAA; i++)
{
const float fDpth = FetchDepthMSAA(g_depth_tex, uPixCrd, i);
#else
const float fDpth = FetchDepth(g_depth_tex, uPixCrd);
#endif
if(fDpth<VIEWPORT_SCALE_Z) // if not skydome
{
dpt_ma = max(fDpth, dpt_ma);
}
#ifdef MSAA_ENABLED
}
#endif
}
InterlockedMax(ldsZMax, asuint(dpt_ma) );
#if !defined(SHADER_API_XBOXONE) && !defined(SHADER_API_PSSL)
GroupMemoryBarrierWithGroupSync();
#endif
dpt_ma = asfloat(ldsZMax);
#endif
float3 vTileLL = float3(viTilLL.x/(float) iWidth, viTilLL.y/(float) iHeight, 0.0);
float3 vTileUR = float3(viTilUR.x/(float) iWidth, viTilUR.y/(float) iHeight, 1.0);
// build coarse list using AABB
#ifdef USE_TWO_PASS_TILED_LIGHTING
int NrBigTilesX = (nrTilesX+3)>>2;
const int bigTileIdx = (tileIDX.y>>2)*NrBigTilesX + (tileIDX.x>>2); // map the idx to 64x64 tiles
int nrBigTileLights = g_vBigTileLightList[MAX_NR_BIGTILE_LIGHTS_PLUSONE*bigTileIdx+0];
for(int l0=(int) t; l0<(int) nrBigTileLights; l0 += NR_THREADS)
{
int l = g_vBigTileLightList[MAX_NR_BIGTILE_LIGHTS_PLUSONE*bigTileIdx+l0+1];
#else
for(int l=(int) t; l<(int) g_iNrVisibLights; l += NR_THREADS)
{
#endif
const float3 vMi = g_vBoundsBuffer[l];
const float3 vMa = g_vBoundsBuffer[l+g_iNrVisibLights];
if( all(vMa.xy>vTileLL.xy) && all(vMi.xy<vTileUR.xy))
{
unsigned int uInc = 1;
unsigned int uIndex;
InterlockedAdd(lightOffs, uInc, uIndex);
if(uIndex<MAX_NR_COARSE_ENTRIES) coarseList[uIndex] = l; // add to light list
}
}
#if !defined(SHADER_API_XBOXONE) && !defined(SHADER_API_PSSL)
GroupMemoryBarrierWithGroupSync();
#endif
int iNrCoarseLights = min(lightOffs,MAX_NR_COARSE_ENTRIES);
#ifdef PERFORM_SPHERICAL_INTERSECTION_TESTS
iNrCoarseLights = SphericalIntersectionTests( t, iNrCoarseLights, float2(min(viTilLL.xy+uint2(16/2,16/2), uint2(iWidth-1, iHeight-1))) );
#endif
#ifdef ENABLE_DEPTH_TEXTURE_BACKPLANE
#if USE_LEFTHAND_CAMERASPACE
float fTileFarPlane = GetLinearDepth(dpt_ma);
#else
float fTileFarPlane = -GetLinearDepth(dpt_ma);
#endif
float suggestedBase = SuggestLogBase50(fTileFarPlane);
#else
float fTileFarPlane = g_fFarPlane;
float suggestedBase = g_fClustBase;
#endif
#ifdef EXACT_EDGE_TESTS
iNrCoarseLights = CullByExactEdgeTests(t, iNrCoarseLights, viTilLL.xy, viTilUR.xy, fTileFarPlane);
#endif
// sort lights (gives a more efficient execution in both deferred and tiled forward lighting).
#if !defined(SHADER_API_XBOXONE) && !defined(SHADER_API_PSSL)
SORTLIST(coarseList, iNrCoarseLights, MAX_NR_COARSE_ENTRIES, t, NR_THREADS);
#endif
//////////// cell specific code
{
for(int l=(int) t; l<((iNrCoarseLights+1)>>1); l += NR_THREADS)
{
const int l0 = coarseList[2*l+0], l1 = coarseList[min(2*l+1,iNrCoarseLights)];
const unsigned int clustIdxMi0 = (const unsigned int) min(255,SnapToClusterIdx(GetLinearDepth(g_vBoundsBuffer[l0].z), suggestedBase));
const unsigned int clustIdxMa0 = (const unsigned int) min(255,SnapToClusterIdx(GetLinearDepth(g_vBoundsBuffer[l0+g_iNrVisibLights].z), suggestedBase));
const unsigned int clustIdxMi1 = (const unsigned int) min(255,SnapToClusterIdx(GetLinearDepth(g_vBoundsBuffer[l1].z), suggestedBase));
const unsigned int clustIdxMa1 = (const unsigned int) min(255,SnapToClusterIdx(GetLinearDepth(g_vBoundsBuffer[l1+g_iNrVisibLights].z), suggestedBase));
clusterIdxs[l] = (clustIdxMa1<<24) | (clustIdxMi1<<16) | (clustIdxMa0<<8) | (clustIdxMi0<<0);
}
}
#if !defined(SHADER_API_XBOXONE) && !defined(SHADER_API_PSSL)
GroupMemoryBarrierWithGroupSync();
#endif
int nrClusters = (1<<g_iLog2NumClusters);
//////////////////////////////////////////////////////////
uint start = 0;
int i=(int) t;
int iSpaceAvail = 0;
int iSum = 0;
if(i<nrClusters)
{
for(int l=0; l<iNrCoarseLights; l++)
{
iSum += (CheckIntersectionBasic(l, i) ? 1 : 0);
}
iSpaceAvail = min(iSum,MAX_NR_COARSE_ENTRIES); // combined storage for both direct lights and reflection
InterlockedAdd(g_LayeredSingleIdxBuffer[0], (uint) iSpaceAvail, start); // alloc list memory
}
int modelListCount[NR_LIGHT_MODELS]={0,0}; // direct light count and reflection lights
uint offs = start;
for(int ll=0; ll<iNrCoarseLights; ll+=4)
{
int p = i>>2;
int m = i&3;
if(i<24) lightPlanes[6*m+p] = FetchPlane(min(iNrCoarseLights-1,ll+m), p);
#if !defined(SHADER_API_XBOXONE) && !defined(SHADER_API_PSSL)
GroupMemoryBarrierWithGroupSync();
#endif
for(int l=ll; l<min(iNrCoarseLights,(ll+4)); l++)
{
if(offs<(start+iSpaceAvail) && i<nrClusters && CheckIntersection(l, i, viTilLL.xy, viTilUR.xy, suggestedBase) )
{
uint lightModel = g_vLightData[ coarseList[l] ].lightModel;
++modelListCount[ lightModel==REFLECTION_LIGHT ? 1 : 0];
g_vLayeredLightList[offs++] = coarseList[l]; // reflection lights will be last since we sorted
}
}
#if !defined(SHADER_API_XBOXONE) && !defined(SHADER_API_PSSL)
GroupMemoryBarrierWithGroupSync();
#endif
}
uint localOffs=0;
offs = i*nrTilesX*nrTilesY + tileIDX.y*nrTilesX + tileIDX.x;
for(int m=0; m<NR_LIGHT_MODELS; m++)
{
int numLights = min(modelListCount[m],31); // only allow 5 bits
if(i<nrClusters)
{
g_LayeredOffset[offs] = (start+localOffs) | (((uint) numLights)<<27);
offs += (nrClusters*nrTilesX*nrTilesY);
localOffs += modelListCount[m]; // use unclamped count for localOffs
}
}
#ifdef ENABLE_DEPTH_TEXTURE_BACKPLANE
g_logBaseBuffer[tileIDX.y*nrTilesX + tileIDX.x] = suggestedBase;
#endif
}
float4 FetchPlane(int l, int p)
{
SFiniteLightBound lgtDat = g_data[coarseList[l]];
const float3 boxX = lgtDat.boxAxisX.xyz;
const float3 boxY = lgtDat.boxAxisY.xyz;
const float3 boxZ = -lgtDat.boxAxisZ.xyz; // flip axis (so it points away from the light direction for a spot-light)
const float3 center = lgtDat.center.xyz;
const float radius = lgtDat.radius;
const float2 scaleXY = lgtDat.scaleXY;
return GetPlaneEq(boxX, boxY, boxZ, center, scaleXY, p);
}
#ifdef PERFORM_SPHERICAL_INTERSECTION_TESTS
int SphericalIntersectionTests(uint threadID, int iNrCoarseLights, float2 screenCoordinate)
{
#if USE_LEFTHAND_CAMERASPACE
float3 V = GetViewPosFromLinDepth( screenCoordinate, 1.0);
#else
float3 V = GetViewPosFromLinDepth( screenCoordinate, -1.0);
#endif
float onePixDiagDist = GetOnePixDiagWorldDistAtDepthOne();
float halfTileSizeAtZDistOne = 8*onePixDiagDist; // scale by half a tile
for(int l=threadID; l<iNrCoarseLights; l+=NR_THREADS)
{
SFiniteLightBound lgtDat = g_data[coarseList[l]];
if( !DoesSphereOverlapTile(V, halfTileSizeAtZDistOne, lgtDat.center.xyz, lgtDat.radius) )
coarseList[l]=0xffffffff;
}
#if !defined(SHADER_API_XBOXONE) && !defined(SHADER_API_PSSL)
GroupMemoryBarrierWithGroupSync();
#endif
// to greedy to double buffer coarseList lds on this so serializing removal of gaps.
if(threadID==0)
{
int offs = 0;
for(int l=0; l<iNrCoarseLights; l++)
{ if(coarseList[l]!=0xffffffff) coarseList[offs++] = coarseList[l]; }
lightOffsSph = offs;
}
#if !defined(SHADER_API_XBOXONE) && !defined(SHADER_API_PSSL)
GroupMemoryBarrierWithGroupSync();
#endif
return lightOffsSph;
}
#endif
#ifdef EXACT_EDGE_TESTS
float3 GetTileVertex(uint2 viTilLL, uint2 viTilUR, int i, float fTileFarPlane)
{
float x = (i&1)==0 ? viTilLL.x : viTilUR.x;
float y = (i&2)==0 ? viTilLL.y : viTilUR.y;
float z = (i&4)==0 ? g_fNearPlane : fTileFarPlane;
#if !USE_LEFTHAND_CAMERASPACE
z = -z;
#endif
return GetViewPosFromLinDepth( float2(x, y), z);
}
void GetFrustEdge(out float3 vP0, out float3 vE0, const int e0, uint2 viTilLL, uint2 viTilUR, float fTileFarPlane)
{
int iSection = e0>>2; // section 0 is side edges, section 1 is near edges and section 2 is far edges
int iSwizzle = e0&0x3;
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)));
}
int CullByExactEdgeTests(uint threadID, int iNrCoarseLights, uint2 viTilLL, uint2 viTilUR, float fTileFarPlane)
{
if(threadID==0) lightOffs2 = 0;
const bool bOnlyNeedFrustumSideEdges = true;
const int nrFrustEdges = bOnlyNeedFrustumSideEdges ? 4 : 8; // max 8 since we never need to test 4 far edges of frustum since they are identical vectors to near edges and plane is placed at vP0 on light hull.
const int totNrEdgePairs = 12*nrFrustEdges;
for(int l=0; l<iNrCoarseLights; l++)
{
if(threadID==0) ldsIsLightInvisible=0;
#if !defined(SHADER_API_XBOXONE) && !defined(SHADER_API_PSSL)
GroupMemoryBarrierWithGroupSync();
#endif
const int idxCoarse = coarseList[l];
[branch]if(g_vLightData[idxCoarse].lightType!=SPHERE_LIGHT) // don't bother doing edge tests for sphere lights since these have camera aligned bboxes.
{
SFiniteLightBound lgtDat = g_data[idxCoarse];
const float3 boxX = lgtDat.boxAxisX.xyz;
const float3 boxY = lgtDat.boxAxisY.xyz;
const float3 boxZ = -lgtDat.boxAxisZ.xyz; // flip axis (so it points away from the light direction for a spot-light)
const float3 center = lgtDat.center.xyz;
const float2 scaleXY = lgtDat.scaleXY;
for(int i=threadID; i<totNrEdgePairs; i+=NR_THREADS)
{
int e0 = (int) (((uint)i)/((uint) nrFrustEdges)); // should become a shift right
int e1 = i - e0*nrFrustEdges;
int idx_cur=0, idx_twin=0;
float3 vP0, vE0;
GetHullEdge(idx_cur, idx_twin, vP0, vE0, e0, boxX, boxY, boxZ, center, scaleXY);
float3 vP1, vE1;
GetFrustEdge(vP1, vE1, e1, viTilLL, viTilUR, fTileFarPlane);
// potential separation plane
float3 vN = cross(vE0, vE1);
int positive=0, negative=0;
for(int k=1; k<8; k++) // only need to test 7 verts (technically just 6).
{
int j = (idx_cur+k)&0x7;
float3 vPh = GetHullVertex(boxX, boxY, boxZ, center, scaleXY, j);
float fSignDist = idx_twin==j ? 0.0 : dot(vN, vPh-vP0);
if(fSignDist>0) ++positive; else if(fSignDist<0) ++negative;
}
int resh = (positive>0 && negative>0) ? 0 : (positive>0 ? 1 : (negative>0 ? (-1) : 0));
positive=0; negative=0;
for(int j=0; j<8; j++)
{
float3 vPf = GetTileVertex(viTilLL, viTilUR, j, fTileFarPlane);
float fSignDist = dot(vN, vPf-vP0);
if(fSignDist>0) ++positive; else if(fSignDist<0) ++negative;
}
int resf = (positive>0 && negative>0) ? 0 : (positive>0 ? 1 : (negative>0 ? (-1) : 0));
bool bFoundSepPlane = (resh*resf)<0;
if(bFoundSepPlane) InterlockedOr(ldsIsLightInvisible, 1);
}
}
#if !defined(SHADER_API_XBOXONE) && !defined(SHADER_API_PSSL)
GroupMemoryBarrierWithGroupSync();
#endif
if(threadID==0 && ldsIsLightInvisible==0)
{
coarseList[lightOffs2++] = coarseList[l];
}
}
#if !defined(SHADER_API_XBOXONE) && !defined(SHADER_API_PSSL)
GroupMemoryBarrierWithGroupSync();
#endif
return lightOffs2;
}
#endif
[numthreads(1, 1, 1)]
void ClearAtomic(uint threadID : SV_GroupIndex, uint3 u3GroupID : SV_GroupID)
{
g_LayeredSingleIdxBuffer[0]=0;
}

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


fileFormatVersion: 2
guid: 0bb1b7e0ddcd5c44baf3ddc7456eb196
timeCreated: 1479689584
licenseType: Pro
ComputeShaderImporter:
currentAPIMask: 4
userData:
assetBundleName:
assetBundleVariant:

30
Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/ShaderBase.hlsl


#ifndef __SHADERBASE_H__
#define __SHADERBASE_H__
#ifdef SHADER_API_PSSL
#ifndef Texture2DMS
#define Texture2DMS MS_Texture2D
#endif
#ifndef SampleCmpLevelZero
#define SampleCmpLevelZero SampleCmpLOD0
#endif
#ifndef firstbithigh
#define firstbithigh FirstSetBit_Hi
#endif
#endif
float FetchDepth(Texture2D depthTexture, uint2 pixCoord)
{
return 1 - depthTexture.Load(uint3(pixCoord.xy, 0)).x;
}
float FetchDepthMSAA(Texture2DMS<float> depthTexture, uint2 pixCoord, uint sampleIdx)
{
return 1 - depthTexture.Load(uint3(pixCoord.xy, 0), sampleIdx).x;
}
#endif

9
Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/ShaderBase.hlsl.meta


fileFormatVersion: 2
guid: 3c90176b54c922b4e9cf65c9ec9cb750
timeCreated: 1479691479
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

9
Assets/ScriptableRenderLoop/HDRenderLoop/Shaders.meta


fileFormatVersion: 2
guid: fafbb144d7f66074785b7727293d89c5
folderAsset: yes
timeCreated: 1474297943
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

185
Assets/ScriptableRenderLoop/HDRenderLoop/Sky/SkyRenderer.cs


using UnityEngine.Rendering;
using UnityEngine.Experimental.Rendering;
using System.Collections.Generic;
using System;
namespace UnityEngine.Experimental.ScriptableRenderLoop
{
[Serializable]
public class SkyParameters
{
public Cubemap skyHDRI;
public float rotation = 0.0f;
public float exposure = 0.0f;
public float multiplier = 1.0f;
}
public class SkyRenderer
{
const int kSkyCubemapSize = 256;
RenderTexture m_SkyboxCubemapRT = null;
Material m_StandardSkyboxMaterial = null; // This is the Unity standard skybox material. Used to pass the correct cubemap to Enlighten.
Material m_SkyHDRIMaterial = null; // Renders a cubemap into a render texture (can be cube or 2D)
GameObject[] m_CubemapFaceCamera = new GameObject[6];
Mesh BuildSkyMesh(Camera camera, bool forceUVBottom)
{
Vector4 vertData0 = new Vector4(-1.0f, -1.0f, 1.0f, 1.0f);
Vector4 vertData1 = new Vector4(1.0f, -1.0f, 1.0f, 1.0f);
Vector4 vertData2 = new Vector4(1.0f, 1.0f, 1.0f, 1.0f);
Vector4 vertData3 = new Vector4(-1.0f, 1.0f, 1.0f, 1.0f);
Vector3[] vertData = new Vector3[4];
vertData[0] = new Vector3(vertData0.x, vertData0.y, vertData0.z);
vertData[1] = new Vector3(vertData1.x, vertData1.y, vertData1.z);
vertData[2] = new Vector3(vertData2.x, vertData2.y, vertData2.z);
vertData[3] = new Vector3(vertData3.x, vertData3.y, vertData3.z);
// Get view vector vased on the frustrum, i.e (invert transform frustrum get position etc...)
Vector3[] eyeVectorData = new Vector3[4];
Matrix4x4 transformMatrix = camera.cameraToWorldMatrix * camera.projectionMatrix.inverse;
Vector4 posWorldSpace0 = transformMatrix * vertData0;
Vector4 posWorldSpace1 = transformMatrix * vertData1;
Vector4 posWorldSpace2 = transformMatrix * vertData2;
Vector4 posWorldSpace3 = transformMatrix * vertData3;
Vector3 temp = camera.GetComponent<Transform>().position;
Vector4 cameraPosition = new Vector4(temp.x, temp.y, temp.z, 0.0f);
Vector4 direction0 = (posWorldSpace0 / posWorldSpace0.w - cameraPosition);
Vector4 direction1 = (posWorldSpace1 / posWorldSpace1.w - cameraPosition);
Vector4 direction2 = (posWorldSpace2 / posWorldSpace2.w - cameraPosition);
Vector4 direction3 = (posWorldSpace3 / posWorldSpace3.w - cameraPosition);
if (SystemInfo.graphicsUVStartsAtTop && !forceUVBottom)
{
eyeVectorData[3] = new Vector3(direction0.x, direction0.y, direction0.z).normalized;
eyeVectorData[2] = new Vector3(direction1.x, direction1.y, direction1.z).normalized;
eyeVectorData[1] = new Vector3(direction2.x, direction2.y, direction2.z).normalized;
eyeVectorData[0] = new Vector3(direction3.x, direction3.y, direction3.z).normalized;
}
else
{
eyeVectorData[0] = new Vector3(direction0.x, direction0.y, direction0.z).normalized;
eyeVectorData[1] = new Vector3(direction1.x, direction1.y, direction1.z).normalized;
eyeVectorData[2] = new Vector3(direction2.x, direction2.y, direction2.z).normalized;
eyeVectorData[3] = new Vector3(direction3.x, direction3.y, direction3.z).normalized;
}
// Write out the mesh
var triangles = new int[6] { 0, 1, 2, 2, 3, 0 };
return new Mesh
{
vertices = vertData,
normals = eyeVectorData,
triangles = triangles
};
}
public void Rebuild()
{
// TODO: We need to have an API to send our sky information to Enlighten. For now use a workaround through skybox/cubemap material...
m_StandardSkyboxMaterial = Utilities.CreateEngineMaterial("Skybox/Cubemap");
m_SkyHDRIMaterial = Utilities.CreateEngineMaterial("Hidden/HDRenderLoop/SkyHDRI");
m_SkyboxCubemapRT = new RenderTexture(kSkyCubemapSize, kSkyCubemapSize, 1, RenderTextureFormat.ARGBHalf);
m_SkyboxCubemapRT.dimension = TextureDimension.Cube;
m_SkyboxCubemapRT.useMipMap = true;
m_SkyboxCubemapRT.autoGenerateMips = true;
m_SkyboxCubemapRT.Create();
Matrix4x4 cubeProj = Matrix4x4.Perspective(90.0f, 1.0f, 0.1f, 1.0f);
Vector3[] lookAtList = {
new Vector3(1.0f, 0.0f, 0.0f),
new Vector3(-1.0f, 0.0f, 0.0f),
new Vector3(0.0f, 1.0f, 0.0f),
new Vector3(0.0f, -1.0f, 0.0f),
new Vector3(0.0f, 0.0f, 1.0f),
new Vector3(0.0f, 0.0f, -1.0f),
};
Vector3[] UpVectorList = {
new Vector3(0.0f, 1.0f, 0.0f),
new Vector3(0.0f, 1.0f, 0.0f),
new Vector3(0.0f, 0.0f, -1.0f),
new Vector3(0.0f, 0.0f, 1.0f),
new Vector3(0.0f, 1.0f, 0.0f),
new Vector3(0.0f, 1.0f, 0.0f),
};
for (int i = 0; i < 6; ++i)
{
m_CubemapFaceCamera[i] = new GameObject();
m_CubemapFaceCamera[i].hideFlags = HideFlags.HideAndDontSave;
Camera camera = m_CubemapFaceCamera[i].AddComponent<Camera>();
camera.projectionMatrix = cubeProj;
Transform transform = camera.GetComponent<Transform>();
transform.LookAt(lookAtList[i], UpVectorList[i]);
}
}
public void OnDisable()
{
Utilities.Destroy(m_StandardSkyboxMaterial);
Utilities.Destroy(m_SkyHDRIMaterial);
Utilities.Destroy(m_SkyboxCubemapRT);
for(int i = 0 ; i < 6 ; ++i)
{
Utilities.Destroy(m_CubemapFaceCamera[i]);
}
}
private void RenderSky(Camera camera, SkyParameters skyParameters, bool forceUVBottom, RenderLoop renderLoop)
{
Mesh skyMesh = BuildSkyMesh(camera, forceUVBottom);
m_SkyHDRIMaterial.SetTexture("_Cubemap", skyParameters.skyHDRI);
m_SkyHDRIMaterial.SetVector("_SkyParam", new Vector4(skyParameters.exposure, skyParameters.multiplier, skyParameters.rotation, 0.0f));
var cmd = new CommandBuffer { name = "Skybox" };
cmd.DrawMesh(skyMesh, Matrix4x4.identity, m_SkyHDRIMaterial);
renderLoop.ExecuteCommandBuffer(cmd);
cmd.Dispose();
}
public void RenderSky(Camera camera, SkyParameters skyParameters, RenderTargetIdentifier colorBuffer, RenderTargetIdentifier depthBuffer, RenderLoop renderLoop)
{
// Render sky into a cubemap - doesn't happen every frame, can be control
for (int i = 0; i < 6; ++i)
{
Utilities.SetRenderTarget(renderLoop, m_SkyboxCubemapRT, "", 0, (CubemapFace)i);
Camera faceCamera = m_CubemapFaceCamera[i].GetComponent<Camera>();
RenderSky(faceCamera, skyParameters, true, renderLoop);
}
m_StandardSkyboxMaterial.SetTexture("_Tex", m_SkyboxCubemapRT);
RenderSettings.skybox = m_StandardSkyboxMaterial; // Setup this material as the default to be use in RenderSettings
RenderSettings.ambientIntensity = 1.0f; // fix this to 1, this parameter should not exist!
RenderSettings.ambientMode = UnityEngine.Rendering.AmbientMode.Skybox; // Force skybox for our HDRI
RenderSettings.reflectionIntensity = 1.0f;
DynamicGI.UpdateEnvironment();
// TODO: do a render to texture here
// Downsample the cubemap and provide it to Enlighten
// TODO: currently workaround is to set the cubemap in a Skybox/cubemap material
//m_SkyboxMaterial.SetTexture(cubemap);
// Render the sky itself
Utilities.SetRenderTarget(renderLoop, colorBuffer, depthBuffer, "Sky Pass");
RenderSky(camera, skyParameters, false, renderLoop);
}
}
}

12
Assets/ScriptableRenderLoop/HDRenderLoop/Sky/SkyRenderer.cs.meta


fileFormatVersion: 2
guid: cf8a015aab8d3b643aa3ef3816f85447
timeCreated: 1479314393
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

105
Assets/ScriptableRenderLoop/HDRenderLoop/Utilities.cs


using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Experimental.Rendering;
using UnityObject = UnityEngine.Object;
namespace UnityEngine.Experimental.ScriptableRenderLoop
{
[Flags]
public enum ClearFlag
{
ClearNone = 0,
ClearColor = 1,
ClearDepth = 2
}
public class Utilities
{
public const RendererConfiguration kRendererConfigurationBakedLighting = RendererConfiguration.PerObjectLightProbe | RendererConfiguration.PerObjectReflectionProbes | RendererConfiguration.PerObjectLightmaps | RendererConfiguration.PerObjectLightProbeProxyVolume;
// Render Target Management.
public const ClearFlag kClearAll = ClearFlag.ClearDepth | ClearFlag.ClearColor;
public static void SetRenderTarget(RenderLoop renderLoop, RenderTargetIdentifier buffer, string name = "", int miplevel = 0, CubemapFace cubemapFace = CubemapFace.Unknown)
{
var cmd = new CommandBuffer();
cmd.name = name;
cmd.SetRenderTarget(buffer, miplevel, cubemapFace);
renderLoop.ExecuteCommandBuffer(cmd);
cmd.Dispose();
}
public static void SetRenderTarget(RenderLoop renderLoop, RenderTargetIdentifier colorBuffer, RenderTargetIdentifier depthBuffer, string name = "", int miplevel = 0, CubemapFace cubemapFace = CubemapFace.Unknown)
{
SetRenderTarget(renderLoop, colorBuffer, depthBuffer, ClearFlag.ClearNone, new Color(0.0f, 0.0f, 0.0f, 0.0f), name, miplevel, cubemapFace);
}
public static void SetRenderTarget(RenderLoop renderLoop, RenderTargetIdentifier colorBuffer, RenderTargetIdentifier depthBuffer, ClearFlag clearFlag, string name = "", int miplevel = 0, CubemapFace cubemapFace = CubemapFace.Unknown)
{
SetRenderTarget(renderLoop, colorBuffer, depthBuffer, clearFlag, new Color(0.0f, 0.0f, 0.0f, 0.0f), name, miplevel, cubemapFace);
}
public static void SetRenderTarget(RenderLoop renderLoop, RenderTargetIdentifier colorBuffer, RenderTargetIdentifier depthBuffer, ClearFlag clearFlag, Color clearColor, string name = "", int miplevel = 0, CubemapFace cubemapFace = CubemapFace.Unknown)
{
var cmd = new CommandBuffer();
cmd.name = name;
cmd.SetRenderTarget(colorBuffer, depthBuffer, miplevel, cubemapFace);
if (clearFlag != ClearFlag.ClearNone)
cmd.ClearRenderTarget((clearFlag & ClearFlag.ClearDepth) != 0, (clearFlag & ClearFlag.ClearColor) != 0, clearColor);
renderLoop.ExecuteCommandBuffer(cmd);
cmd.Dispose();
}
public static void SetRenderTarget(RenderLoop renderLoop, RenderTargetIdentifier[] colorBuffers, RenderTargetIdentifier depthBuffer, string name = "")
{
SetRenderTarget(renderLoop, colorBuffers, depthBuffer, ClearFlag.ClearNone, Color.black, name);
}
public static void SetRenderTarget(RenderLoop renderLoop, RenderTargetIdentifier[] colorBuffers, RenderTargetIdentifier depthBuffer, ClearFlag clearFlag = ClearFlag.ClearNone, string name = "")
{
SetRenderTarget(renderLoop, colorBuffers, depthBuffer, clearFlag, Color.black, name);
}
public static void SetRenderTarget(RenderLoop renderLoop, RenderTargetIdentifier[] colorBuffers, RenderTargetIdentifier depthBuffer, ClearFlag clearFlag, Color clearColor, string name = "")
{
var cmd = new CommandBuffer();
cmd.name = name;
cmd.SetRenderTarget(colorBuffers, depthBuffer);
if (clearFlag != ClearFlag.ClearNone)
cmd.ClearRenderTarget((clearFlag & ClearFlag.ClearDepth) != 0, (clearFlag & ClearFlag.ClearColor) != 0, clearColor);
renderLoop.ExecuteCommandBuffer(cmd);
cmd.Dispose();
}
// Miscellanous
public static Material CreateEngineMaterial(string shaderPath)
{
var mat = new Material(Shader.Find(shaderPath))
{
hideFlags = HideFlags.HideAndDontSave
};
return mat;
}
public static void Destroy(UnityObject obj)
{
if (obj != null)
{
#if UNITY_EDITOR
if (Application.isPlaying)
UnityObject.Destroy(obj);
else
UnityObject.DestroyImmediate(obj);
#else
UnityObject.Destroy(obj);
#endif
}
}
}
}

12
Assets/ScriptableRenderLoop/HDRenderLoop/Utilities.cs.meta


fileFormatVersion: 2
guid: b91b03c2b2270d648a49e0fb6880ca3f
timeCreated: 1479315130
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
正在加载...
取消
保存