浏览代码

Removed the old shadow system.

Removed the temporary namespace ShadowExp.
/main
uygar 7 年前
当前提交
c0b6dcd6
共有 17 个文件被更改,包括 129 次插入759 次删除
  1. 12
      Assets/ScriptableRenderPipeline/AdditionalLightData.cs
  2. 39
      Assets/ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipeline.cs
  3. 16
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/LightDefinition.cs
  4. 40
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/LightDefinition.cs.hlsl
  5. 8
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/LightLoop.cs
  6. 263
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.cs
  7. 120
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.hlsl
  8. 13
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePassLoop.hlsl
  9. 16
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.hlsl
  10. 10
      Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/Shadow.hlsl
  11. 6
      Assets/ScriptableRenderPipeline/common/Shadow/Shadow.cs
  12. 13
      Assets/ScriptableRenderPipeline/common/Shadow/ShadowBase.cs
  13. 28
      Assets/ScriptableRenderPipeline/common/Shadow/ShadowBase.cs.hlsl
  14. 10
      Assets/ScriptableRenderPipeline/common/Shadow/ShadowUtilities.cs
  15. 159
      Assets/ScriptableRenderPipeline/fptl/FptlLighting.cs
  16. 135
      Assets/ScriptableRenderPipeline/fptl/LightingTemplate.hlsl

12
Assets/ScriptableRenderPipeline/AdditionalLightData.cs


using UnityEngine;
using System.Collections;
namespace UnityEngine.Experimental.Rendering
namespace UnityEngine.Experimental.Rendering
{
public enum LightArchetype { Punctual, Area, Projector };

[UnityEditor.CanEditMultipleObjects]
public class AdditionalLightDataEditor : UnityEditor.Editor
{
static ShadowExp.ShadowRegistry m_ShadowRegistry;
static ShadowRegistry m_ShadowRegistry;
#pragma warning disable 414 // CS0414 The private field '...' is assigned but its value is never used
public static void SetRegistry( ShadowExp.ShadowRegistry registry ) { m_ShadowRegistry = registry; }
#pragma warning restore 414
public static void SetRegistry( ShadowRegistry registry ) { m_ShadowRegistry = registry; }
void OnEnable()
{

39
Assets/ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipeline.cs


//#define SHADOWS_OLD
using UnityEngine.Rendering;
using System;
using System.Linq;

int m_CurrentWidth;
int m_CurrentHeight;
#if SHADOWS_OLD
ShadowRenderPass m_ShadowPass;
ShadowOutput m_ShadowsResult = new ShadowOutput();
public int GetCurrentShadowCount() { return m_ShadowsResult.shadowLights == null ? 0 : m_ShadowsResult.shadowLights.Length; }
#else
#endif
readonly SkyManager m_SkyManager = new SkyManager();
private readonly BaseLightLoop m_LightLoop;

InitializeDebugMaterials();
#if SHADOWS_OLD
m_ShadowPass = new ShadowRenderPass(owner.shadowSettings);
#endif
// Init Gbuffer description
m_gbufferManager.gbufferCount = m_LitRenderLoop.GetMaterialGBufferCount();
RenderTextureFormat[] RTFormat;

if (!CullResults.GetCullingParameters(camera, out cullingParams))
return;
#if SHADOWS_OLD
m_ShadowPass.UpdateCullingParameters(ref cullingParams);
#else
#endif
var cullResults = CullResults.Cull(ref cullingParams, renderContext);
Resize(camera);

}
else
{
#if SHADOWS_OLD
using (new Utilities.ProfilingSample("Shadow Pass", renderContext))
{
m_ShadowPass.Render(renderContext, cullResults, out m_ShadowsResult);
}
renderContext.SetupCameraProperties(camera); // Need to recall SetupCameraProperties after m_ShadowPass.Render
#endif
#if SHADOWS_OLD
m_LightLoop.PrepareLightsForGPU(m_Owner.shadowSettings, cullResults, camera, ref m_ShadowsResult);
#else
#endif
m_LightLoop.RenderShadows(renderContext, cullResults);
renderContext.SetupCameraProperties(camera); // Need to recall SetupCameraProperties after m_ShadowPass.Render
m_LightLoop.BuildGPULightLists(camera, renderContext, m_CameraDepthStencilBufferRT); // TODO: Use async compute here to run light culling during shadow

{
if (lightingDebug.shadowDebugMode == ShadowMapDebugMode.VisualizeShadowMap)
{
uint visualizeShadowIndex = Math.Min(lightingDebug.shadowMapIndex, (uint)(GetCurrentShadowCount() - 1));
uint visualizeShadowIndex = Math.Min(lightingDebug.shadowMapIndex, (uint)(GetCurrentShadowCount() - 1));
ShadowLight shadowLight = m_ShadowsResult.shadowLights[visualizeShadowIndex];
for (int slice = 0; slice < shadowLight.shadowSliceCount; ++slice)
{

renderContext.ExecuteCommandBuffer(debugCB);
}
#if SHADOWS_OLD
// Function to prepare light structure for GPU lighting
void PrepareLightsForGPU(ShadowSettings shadowSettings, CullResults cullResults, Camera camera, ref ShadowOutput shadowOutput)
{
// build per tile light lists
if (m_LightLoop != null)
m_LightLoop.PrepareLightsForGPU(shadowSettings, cullResults, camera, ref shadowOutput);
}
#endif
void InitAndClearBuffer(Camera camera, ScriptableRenderContext renderContext)
{
using (new Utilities.ProfilingSample("InitAndClearBuffer", renderContext))

16
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/LightDefinition.cs


};
// TODO: we may have to add various parameters here for shadow - was suppose to be coupled with a light loop
// A point light is 6x PunctualShadowData
[GenerateHLSL]
public struct ShadowData
{
// World to ShadowMap matrix
// Include scale and bias for shadow atlas if any
public Matrix4x4 worldToShadow;
public float bias;
public float quality;
public float unused;
public float unused2;
public Vector4 invResolution;
};
[GenerateHLSL]
public enum EnvShapeType
{

40
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/LightDefinition.cs.hlsl


int cookieIndex;
};
// Generated from UnityEngine.Experimental.Rendering.HDPipeline.ShadowData
// PackingRules = Exact
struct ShadowData
{
float4x4 worldToShadow;
float bias;
float quality;
float unused;
float unused2;
float4 invResolution;
};
// Generated from UnityEngine.Experimental.Rendering.HDPipeline.EnvLightData
// PackingRules = Exact
struct EnvLightData

int GetCookieIndex(DirectionalLightData value)
{
return value.cookieIndex;
}
//
// Accessors for UnityEngine.Experimental.Rendering.HDPipeline.ShadowData
//
float4x4 GetWorldToShadow(ShadowData value)
{
return value.worldToShadow;
}
float GetBias(ShadowData value)
{
return value.bias;
}
float GetQuality(ShadowData value)
{
return value.quality;
}
float GetUnused(ShadowData value)
{
return value.unused;
}
float GetUnused2(ShadowData value)
{
return value.unused2;
}
float4 GetInvResolution(ShadowData value)
{
return value.invResolution;
}
//

8
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/LightLoop.cs


//#define SHADOWS_OLD
using UnityEngine;
using UnityEngine;
using UnityEngine.Rendering;
namespace UnityEngine.Experimental.Rendering.HDPipeline

public virtual void ReleaseResolutionDependentBuffers() {}
public virtual void NewFrame() {}
#if SHADOWS_OLD
public virtual void PrepareLightsForGPU(ShadowSettings shadowSettings, CullResults cullResults, Camera camera, ref ShadowOutput shadowOutput) {}
#else
#endif
public virtual void RenderShadows(ScriptableRenderContext renderContext, CullResults cullResults) {}
// TODO: this should not be part of the interface but for now make something working

263
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.cs


//#define SHADOWS_OLD
using UnityEngine.Rendering;
using UnityEngine.Rendering;
#if !SHADOWS_OLD
using ShadowExp;
class ShadowSetup : IDisposable
{
// shadow related stuff

public ShadowSetup(ShadowSettings shadowSettings, out IShadowManager shadowManager)
{
s_ShadowDataBuffer = new ComputeBuffer( k_MaxShadowDataSlots, System.Runtime.InteropServices.Marshal.SizeOf( typeof( ShadowExp.ShadowData ) ) );
s_ShadowPayloadBuffer = new ComputeBuffer( k_MaxShadowDataSlots * k_MaxPayloadSlotsPerShadowData, System.Runtime.InteropServices.Marshal.SizeOf( typeof( ShadowExp.ShadowPayload ) ) );
s_ShadowDataBuffer = new ComputeBuffer( k_MaxShadowDataSlots, System.Runtime.InteropServices.Marshal.SizeOf( typeof( ShadowData ) ) );
s_ShadowPayloadBuffer = new ComputeBuffer( k_MaxShadowDataSlots * k_MaxPayloadSlotsPerShadowData, System.Runtime.InteropServices.Marshal.SizeOf( typeof( ShadowPayload ) ) );
ShadowAtlas.AtlasInit atlasInit;
atlasInit.baseInit.width = (uint)shadowSettings.shadowAtlasWidth;
atlasInit.baseInit.height = (uint)shadowSettings.shadowAtlasHeight;

var varianceInit3 = varianceInit;
varianceInit3.baseInit.shadowmapFormat = ShadowVariance.GetFormat( true, false, true );
m_Shadowmaps = new ShadowmapBase[] { new ShadowExp.ShadowVariance( ref varianceInit ), new ShadowExp.ShadowVariance( ref varianceInit2 ), new ShadowExp.ShadowVariance( ref varianceInit3 ), new ShadowExp.ShadowAtlas( ref atlasInit ) };
m_Shadowmaps = new ShadowmapBase[] { new ShadowVariance( ref varianceInit ), new ShadowVariance( ref varianceInit2 ), new ShadowVariance( ref varianceInit3 ), new ShadowAtlas( ref atlasInit ) };
ShadowExp.ShadowData[] sds;
ShadowData[] sds;
sc.GetShadowDatas(out sds, out offset, out count);
Debug.Assert(offset == 0);
s_ShadowDataBuffer.SetData(sds); // unfortunately we can't pass an offset or count to this function

scInit.dataSyncer = syncer;
scInit.resourceBinder = binder;
m_ShadowMgr = new ShadowExp.ShadowManager(shadowSettings, ref scInit, m_Shadowmaps);
m_ShadowMgr = new ShadowManager(shadowSettings, ref scInit, m_Shadowmaps);
// set global overrides - these need to match the override specified in ShadowDispatch.hlsl
bool useGlobalOverrides = true;
m_ShadowMgr.SetGlobalShadowOverride( GPUShadowType.Point , ShadowAlgorithm.PCF, ShadowVariant.V4, ShadowPrecision.High, useGlobalOverrides );

s_ShadowPayloadBuffer.Release();
}
}
#endif
namespace TilePass
{

Material m_SingleDeferredMaterialSRT = null;
Material m_SingleDeferredMaterialMRT = null;
#if !SHADOWS_OLD
FrameId m_FrameId;
FrameId m_FrameId = new FrameId();
ShadowSetup m_ShadowSetup; // doesn't actually have to reside here, it would be enough to pass the IShadowManager in from the outside
IShadowManager m_ShadowMgr;
List<int> m_ShadowRequests = new List<int>();

m_ShadowMgr = null;
}
}
#endif
int GetNumTileFtplX(Camera camera)

UnityEditor.SceneView.onSceneGUIDelegate += OnSceneGUI;
#endif
#if !SHADOWS_OLD
#endif
#if !SHADOWS_OLD
#endif
#if UNITY_EDITOR
UnityEditor.SceneView.onSceneGUIDelegate -= OnSceneGUI;
#endif

{
return new Vector3(light.finalColor.r, light.finalColor.g, light.finalColor.b);
}
#if SHADOWS_OLD
// Return number of added shadow
public int GetShadows(VisibleLight light, int lightIndex, ref ShadowOutput shadowOutput, ShadowSettings shadowSettings)
{
for (int sliceIndex = 0; sliceIndex < shadowOutput.GetShadowSliceCountLightIndex(lightIndex); ++sliceIndex)
{
ShadowData shadowData = new ShadowData();
int shadowSliceIndex = shadowOutput.GetShadowSliceIndex(lightIndex, sliceIndex);
shadowData.worldToShadow = shadowOutput.shadowSlices[shadowSliceIndex].shadowTransform.transpose; // Transpose for hlsl reading ?
shadowData.bias = light.light.shadowBias;
shadowData.invResolution = new Vector4(1.0f / shadowSettings.shadowAtlasWidth, 1.0f / shadowSettings.shadowAtlasHeight, 0.0f, 0.0f);
m_lightList.shadows.Add(shadowData);
}
return shadowOutput.GetShadowSliceCountLightIndex(lightIndex);
}
#endif
#if SHADOWS_OLD
public bool GetDirectionalLightData(ShadowSettings shadowSettings, GPULightType gpuLightType, VisibleLight light, AdditionalLightData additionalData, int lightIndex, ref ShadowOutput shadowOutput, ref int directionalShadowcount)
#else
#endif
{
var directionalLightData = new DirectionalLightData();

directionalLightData.tileCookie = (light.light.cookie.wrapMode == TextureWrapMode.Repeat);
directionalLightData.cookieIndex = m_CookieTexArray.FetchSlice(light.light.cookie);
}
#if SHADOWS_OLD
bool hasDirectionalShadows = light.light.shadows != LightShadows.None && shadowOutput.GetShadowSliceCountLightIndex(lightIndex) != 0;
bool hasDirectionalNotReachMaxLimit = directionalShadowcount == 0; // Only one cascade shadow allowed
// If we have not found a directional shadow casting light yet, we register the last directional anyway as "sun".
if (directionalShadowcount == 0)
{
m_CurrentSunLight = light.light;
}
if (hasDirectionalShadows && hasDirectionalNotReachMaxLimit) // Note < MaxShadows should be check at shadowOutput creation
{
// Always choose the directional shadow casting light if it exists.
m_CurrentSunLight = light.light;
directionalLightData.shadowIndex = m_lightList.shadows.Count;
directionalShadowcount += GetShadows(light, lightIndex, ref shadowOutput, shadowSettings);
// Fill split information for shaders
for (int s = 0; s < k_MaxCascadeCount; ++s)
{
m_lightList.directionalShadowSplitSphereSqr[s] = shadowOutput.directionalShadowSplitSphereSqr[s];
}
}
#else
// fix up shadow information
int shadowIdx;
if (m_ShadowIndices.TryGetValue(lightIndex, out shadowIdx))

}
m_CurrentSunLight = m_CurrentSunLight == null ? light.light : m_CurrentSunLight;
#endif
m_lightList.directionalLights.Add(directionalLightData);
return true;

return 1.0f - Mathf.Clamp01((distanceToCamera - distanceFadeNear) / (fadeDistance - distanceFadeNear));
}
#if SHADOWS_OLD
public bool GetLightData(ShadowSettings shadowSettings, Camera camera, GPULightType gpuLightType, VisibleLight light, AdditionalLightData additionalData, int lightIndex, ref ShadowOutput shadowOutput, ref int shadowCount)
#else
#endif
{
var lightData = new LightData();

float shadowDistanceFade = ComputeLinearDistanceFade(distanceToCamera, additionalData.shadowFadeDistance);
lightData.shadowDimmer = additionalData.shadowDimmer * shadowDistanceFade;
#if SHADOWS_OLD
// Setup shadow data arrays
// In case lightData.shadowDimmer == 0.0 we need to avoid rendering the shadow map... see how it can be done with the culling (and more specifically, how can we do that BEFORE sending for shadows)
bool hasShadows = lightData.shadowDimmer > 0.0f && distanceToCamera < shadowSettings.maxShadowDistance && light.light.shadows != LightShadows.None && shadowOutput.GetShadowSliceCountLightIndex(lightIndex) != 0;
bool hasNotReachMaxLimit = shadowCount + (lightData.lightType == GPULightType.Point ? 6 : 1) <= k_MaxShadowOnScreen;
// TODO: Read the comment about shadow limit/management at the beginning of this loop
if (hasShadows && hasNotReachMaxLimit)
{
// When we have a point light, we assumed that there is 6 consecutive PunctualShadowData
lightData.shadowIndex = m_lightList.shadows.Count;
shadowCount += GetShadows(light, lightIndex, ref shadowOutput, shadowSettings);
}
#else
// fix up shadow information
int shadowIdx;
if (m_ShadowIndices.TryGetValue(lightIndex, out shadowIdx))

#endif
if (additionalData.archetype != LightArchetype.Punctual)
{
lightData.twoSided = additionalData.isDoubleSided;

m_lightList.bounds.Add(bound);
m_lightList.lightVolumes.Add(lightVolumeData);
}
#if SHADOWS_OLD
public override void PrepareLightsForGPU(ShadowSettings shadowSettings, CullResults cullResults, Camera camera, ref ShadowOutput shadowOutput)
#else
public override int GetCurrentShadowCount()
{
return m_ShadowRequests.Count;

}
public override void PrepareLightsForGPU(ShadowSettings shadowSettings, CullResults cullResults, Camera camera)
#endif
#if !SHADOWS_OLD
// 0. deal with shadows
{
m_FrameId.frameCount++;

uint shadowRequestCount = (uint)m_ShadowRequests.Count;
int[] shadowRequests = m_ShadowRequests.ToArray();
int[] shadowDataIndices;
uint originalRequestCount = shadowRequestCount;
m_ShadowMgr.ProcessShadowRequests(m_FrameId, cullResults, camera, cullResults.visibleLights,
ref shadowRequestCount, shadowRequests, out shadowDataIndices);

m_ShadowIndices.Add(shadowRequests[i], shadowDataIndices[i]);
}
}
#endif
float oldSpecularGlobalDimmer = m_PassSettings.specularGlobalDimmer;
// Change some parameters in case of "special" rendering (can be preview, reflection, etc.
if (camera.cameraType == CameraType.Reflection)

GPULightType gpuLightType = GPULightType.Point;
LightVolumeType lightVolumeType = LightVolumeType.Count;
// Note: LightType.Area is offline only, use for baking, no need to test it
if (additionalData.archetype == LightArchetype.Punctual)
{
switch (light.lightType)
// Note: LightType.Area is offline only, use for baking, no need to test it
if (additionalData.archetype == LightArchetype.Punctual)
case LightType.Point:
if (punctualLightcount >= k_MaxPunctualLightsOnScreen)
continue;
lightCategory = LightCategory.Punctual;
gpuLightType = GPULightType.Point;
lightVolumeType = LightVolumeType.Sphere;
break;
switch (light.lightType)
{
case LightType.Point:
if (punctualLightcount >= k_MaxPunctualLightsOnScreen)
continue;
lightCategory = LightCategory.Punctual;
gpuLightType = GPULightType.Point;
lightVolumeType = LightVolumeType.Sphere;
break;
case LightType.Spot:
if (punctualLightcount >= k_MaxPunctualLightsOnScreen)
continue;
lightCategory = LightCategory.Punctual;
gpuLightType = GPULightType.Spot;
lightVolumeType = LightVolumeType.Cone;
break;
case LightType.Spot:
if (punctualLightcount >= k_MaxPunctualLightsOnScreen)
continue;
lightCategory = LightCategory.Punctual;
gpuLightType = GPULightType.Spot;
lightVolumeType = LightVolumeType.Cone;
break;
case LightType.Directional:
if (directionalLightcount >= k_MaxDirectionalLightsOnScreen)
continue;
lightCategory = LightCategory.Punctual;
gpuLightType = GPULightType.Directional;
// No need to add volume, always visible
lightVolumeType = LightVolumeType.Count; // Count is none
break;
case LightType.Directional:
if (directionalLightcount >= k_MaxDirectionalLightsOnScreen)
continue;
lightCategory = LightCategory.Punctual;
gpuLightType = GPULightType.Directional;
// No need to add volume, always visible
lightVolumeType = LightVolumeType.Count; // Count is none
break;
default:
Debug.Assert(false, "TODO: encountered an unknown LightType.");
break;
default:
Debug.Assert(false, "TODO: encountered an unknown LightType.");
break;
}
}
else
{
switch (additionalData.archetype)
else
case LightArchetype.Area:
if (areaLightCount >= k_MaxAreaLightsOnScreen) { continue; }
lightCategory = LightCategory.Area;
gpuLightType = (additionalData.lightWidth > 0) ? GPULightType.Rectangle : GPULightType.Line;
lightVolumeType = LightVolumeType.Box;
break;
case LightArchetype.Projector:
if (projectorLightCount >= k_MaxProjectorLightsOnScreen) { continue; }
lightCategory = LightCategory.Projector;
switch (light.lightType)
{
case LightType.Directional:
gpuLightType = GPULightType.ProjectorOrtho;
lightVolumeType = LightVolumeType.Box;
break;
case LightType.Spot:
gpuLightType = GPULightType.ProjectorPyramid;
lightVolumeType = LightVolumeType.Cone;
break;
default:
Debug.Assert(false, "Projectors can only be Spot or Directional lights.");
break;
}
break;
default:
Debug.Assert(false, "TODO: encountered an unknown LightArchetype.");
break;
switch (additionalData.archetype)
{
case LightArchetype.Area:
if (areaLightCount >= k_MaxAreaLightsOnScreen) { continue; }
lightCategory = LightCategory.Area;
gpuLightType = (additionalData.lightWidth > 0) ? GPULightType.Rectangle : GPULightType.Line;
lightVolumeType = LightVolumeType.Box;
break;
case LightArchetype.Projector:
if (projectorLightCount >= k_MaxProjectorLightsOnScreen) { continue; }
lightCategory = LightCategory.Projector;
switch (light.lightType)
{
case LightType.Directional:
gpuLightType = GPULightType.ProjectorOrtho;
lightVolumeType = LightVolumeType.Box;
break;
case LightType.Spot:
gpuLightType = GPULightType.ProjectorPyramid;
lightVolumeType = LightVolumeType.Cone;
break;
default:
Debug.Assert(false, "Projectors can only be Spot or Directional lights.");
break;
}
break;
default:
Debug.Assert(false, "TODO: encountered an unknown LightArchetype.");
break;
}
}
#if SHADOWS_OLD
// 5 bit (0x1F) light category, 5 bit (0x1F) GPULightType, 6 bit (0x3F) lightVolume, 16 bit index
sortKeys[sortCount++] = (uint)lightCategory << 27 | (uint)gpuLightType << 22 | (uint)lightVolumeType << 16 | (uint)lightIndex;
#else
uint shadow = m_ShadowIndices.ContainsKey(lightIndex) ? 1u : 0;
// 5 bit (0x1F) light category, 5 bit (0x1F) GPULightType, 5 bit (0x1F) lightVolume, 1 bit for shadow casting, 16 bit index
sortKeys[sortCount++] = (uint)lightCategory << 27 | (uint)gpuLightType << 22 | (uint)lightVolumeType << 17 | shadow << 16 | (uint)lightIndex;
#endif
uint shadow = m_ShadowIndices.ContainsKey(lightIndex) ? 1u : 0;
// 5 bit (0x1F) light category, 5 bit (0x1F) GPULightType, 5 bit (0x1F) lightVolume, 1 bit for shadow casting, 16 bit index
sortKeys[sortCount++] = (uint)lightCategory << 27 | (uint)gpuLightType << 22 | (uint)lightVolumeType << 17 | shadow << 16 | (uint)lightIndex;
}
Array.Sort(sortKeys);

// will be use...)
// The lightLoop is in charge, not the shadow pass.
// For now we will still apply the maximum of shadow here but we don't apply the sorting by priority + slot allocation yet
#if SHADOWS_OLD
int directionalShadowcount = 0;
int shadowCount = 0;
#endif
m_CurrentSunLight = null;
// 2. Go thought all lights, convert them to GPU format.

uint sortKey = sortKeys[sortIndex];
LightCategory lightCategory = (LightCategory)((sortKey >> 27) & 0x1F);
GPULightType gpuLightType = (GPULightType)((sortKey >> 22) & 0x1F);
#if SHADOWS_OLD
LightVolumeType lightVolumeType = (LightVolumeType)((sortKey >> 16) & 0x3F);
#else
#endif
int lightIndex = (int)(sortKey & 0xFFFF);
var light = cullResults.visibleLights[lightIndex];

if (gpuLightType == GPULightType.Directional)
{
#if SHADOWS_OLD
if (GetDirectionalLightData(shadowSettings, gpuLightType, light, additionalData, lightIndex, ref shadowOutput, ref directionalShadowcount))
#else
#endif
#if SHADOWS_OLD
if(GetLightData(shadowSettings, camera, gpuLightType, light, additionalData, lightIndex, ref shadowOutput, ref shadowCount))
#else
// Punctual, area, projector lights - the rendering side.
#endif
// Punctual, area, projector lights - the rendering side.
{
switch (lightCategory)
{

private void BindGlobalParams(CommandBuffer cmd, ComputeShader computeShader, int kernelIndex, Camera camera, ScriptableRenderContext loop)
{
#if !SHADOWS_OLD
#endif
SetGlobalBuffer("g_vLightListGlobal", !usingFptl ? s_PerVoxelLightLists : s_LightList); // opaques list (unless MSAA possibly)
SetGlobalTexture("_CookieTextures", m_CookieTexArray.GetTexCache());

{
var cmd = new CommandBuffer { name = "Push Global Parameters" };
#if !SHADOWS_OLD
#endif
SetGlobalPropertyRedirect(computeShader, kernelIndex, cmd);
BindGlobalParams(cmd, computeShader, kernelIndex, camera, loop);
SetGlobalPropertyRedirect(null, 0, null);

public override void RenderShadows(ScriptableRenderContext renderContext, CullResults cullResults)
{
#if !SHADOWS_OLD
#endif
}
private void SetupRenderingForDebug(LightingDebugSettings lightDebugSettings)

120
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.hlsl


{
int sampleShadow;
int sampleReflection;
#ifdef SHADOWS_USE_SHADOWCTXT
#endif
#ifndef SHADOWS_USE_SHADOWCTXT
//-----------------------------------------------------------------------------
// Shadow sampling function
// ----------------------------------------------------------------------------
float GetPunctualShadowAttenuation(LightLoopContext lightLoopContext, uint lightType, float3 positionWS, int index, float3 L, float2 unPositionSS)
{
int faceIndex = 0;
if (lightType == GPULIGHTTYPE_POINT)
{
GetCubeFaceID(L, faceIndex);
}
ShadowData shadowData = _ShadowDatas[index + faceIndex];
// Note: scale and bias of shadow atlas are included in ShadowTransform but could be apply here.
float4 positionTXS = mul(float4(positionWS, 1.0), shadowData.worldToShadow);
positionTXS.xyz /= positionTXS.w;
// positionTXS.z -= shadowData.bias;
positionTXS.z -= 0.001; // Apply a linear bias
#if UNITY_REVERSED_Z
positionTXS.z = 1.0 - positionTXS.z;
#endif
// float3 shadowPosDX = ddx_fine(positionTXS);
// float3 shadowPosDY = ddy_fine(positionTXS);
return SAMPLE_TEXTURE2D_SHADOW(g_tShadowBuffer, samplerg_tShadowBuffer, positionTXS);
}
// Gets the cascade weights based on the world position of the fragment and the positions of the split spheres for each cascade.
// Returns an invalid split index if past shadowDistance (ie 4 is invalid for cascade)
int GetSplitSphereIndexForDirshadows(float3 positionWS, float4 dirShadowSplitSpheres[4])
{
float3 fromCenter0 = positionWS.xyz - dirShadowSplitSpheres[0].xyz;
float3 fromCenter1 = positionWS.xyz - dirShadowSplitSpheres[1].xyz;
float3 fromCenter2 = positionWS.xyz - dirShadowSplitSpheres[2].xyz;
float3 fromCenter3 = positionWS.xyz - dirShadowSplitSpheres[3].xyz;
float4 distances2 = float4(dot(fromCenter0, fromCenter0), dot(fromCenter1, fromCenter1), dot(fromCenter2, fromCenter2), dot(fromCenter3, fromCenter3));
float4 dirShadowSplitSphereSqRadii;
dirShadowSplitSphereSqRadii.x = dirShadowSplitSpheres[0].w;
dirShadowSplitSphereSqRadii.y = dirShadowSplitSpheres[1].w;
dirShadowSplitSphereSqRadii.z = dirShadowSplitSpheres[2].w;
dirShadowSplitSphereSqRadii.w = dirShadowSplitSpheres[3].w;
if (distances2.w > dirShadowSplitSphereSqRadii.w)
return -1;
float4 weights = float4(distances2 < dirShadowSplitSphereSqRadii);
weights.yzw = saturate(weights.yzw - weights.xyz);
return int(4.0 - dot(weights, float4(4.0, 3.0, 2.0, 1.0)));
}
float GetDirectionalShadowAttenuation(LightLoopContext lightLoopContext, float3 positionWS, int index, float3 L, float2 unPositionSS)
{
// Note Index is 0 for now, but else we need to provide the correct index in _DirShadowSplitSpheres and _ShadowDatas
int shadowSplitIndex = GetSplitSphereIndexForDirshadows(positionWS, _DirShadowSplitSpheres);
if (shadowSplitIndex == -1)
return 1.0;
ShadowData shadowData = _ShadowDatas[shadowSplitIndex];
// Note: scale and bias of shadow atlas are included in ShadowTransform but could be apply here.
float4 positionTXS = mul(float4(positionWS, 1.0), shadowData.worldToShadow);
positionTXS.xyz /= positionTXS.w;
// positionTXS.z -= shadowData.bias;
positionTXS.z -= 0.003; // Apply a linear bias
#if UNITY_REVERSED_Z
positionTXS.z = 1.0 - positionTXS.z;
#endif
float4 vShadow3x3PCFTerms0;
float4 vShadow3x3PCFTerms1;
float4 vShadow3x3PCFTerms2;
float4 vShadow3x3PCFTerms3;
float flTexelEpsilonX = shadowData.invResolution.x;
float flTexelEpsilonY = shadowData.invResolution.y;
vShadow3x3PCFTerms0 = float4(20.0f / 267.0f, 33.0f / 267.0f, 55.0f / 267.0f, 0.0f);
vShadow3x3PCFTerms1 = float4(flTexelEpsilonX, flTexelEpsilonY, -flTexelEpsilonX, -flTexelEpsilonY);
vShadow3x3PCFTerms2 = float4(flTexelEpsilonX, flTexelEpsilonY, 0.0f, 0.0f);
vShadow3x3PCFTerms3 = float4(-flTexelEpsilonX, -flTexelEpsilonY, 0.0f, 0.0f);
// float3 shadowPosDX = ddx_fine(positionTXS);
// float3 shadowPosDY = ddy_fine(positionTXS);
//return SAMPLE_TEXTURE2D_SHADOW(g_tShadowBuffer, samplerg_tShadowBuffer, positionTXS);
float4 v20Taps;
v20Taps.x = SAMPLE_TEXTURE2D_SHADOW(g_tShadowBuffer, samplerg_tShadowBuffer, float3(positionTXS.xy + vShadow3x3PCFTerms1.xy, positionTXS.z)).x; // 1 1
v20Taps.y = SAMPLE_TEXTURE2D_SHADOW(g_tShadowBuffer, samplerg_tShadowBuffer, float3(positionTXS.xy + vShadow3x3PCFTerms1.zy, positionTXS.z)).x; // -1 1
v20Taps.z = SAMPLE_TEXTURE2D_SHADOW(g_tShadowBuffer, samplerg_tShadowBuffer, float3(positionTXS.xy + vShadow3x3PCFTerms1.xw, positionTXS.z)).x; // 1 -1
v20Taps.w = SAMPLE_TEXTURE2D_SHADOW(g_tShadowBuffer, samplerg_tShadowBuffer, float3(positionTXS.xy + vShadow3x3PCFTerms1.zw, positionTXS.z)).x; // -1 -1
float flSum = dot(v20Taps.xyzw, float4(0.25, 0.25, 0.25, 0.25));
if ((flSum == 0.0) || (flSum == 1.0))
return flSum;
flSum *= vShadow3x3PCFTerms0.x * 4.0;
float4 v33Taps;
v33Taps.x = SAMPLE_TEXTURE2D_SHADOW(g_tShadowBuffer, samplerg_tShadowBuffer, float3(positionTXS.xy + vShadow3x3PCFTerms2.xz, positionTXS.z)).x; // 1 0
v33Taps.y = SAMPLE_TEXTURE2D_SHADOW(g_tShadowBuffer, samplerg_tShadowBuffer, float3(positionTXS.xy + vShadow3x3PCFTerms3.xz, positionTXS.z)).x; // -1 0
v33Taps.z = SAMPLE_TEXTURE2D_SHADOW(g_tShadowBuffer, samplerg_tShadowBuffer, float3(positionTXS.xy + vShadow3x3PCFTerms3.zy, positionTXS.z)).x; // 0 -1
v33Taps.w = SAMPLE_TEXTURE2D_SHADOW(g_tShadowBuffer, samplerg_tShadowBuffer, float3(positionTXS.xy + vShadow3x3PCFTerms2.zy, positionTXS.z)).x; // 0 1
flSum += dot(v33Taps.xyzw, vShadow3x3PCFTerms0.yyyy);
flSum += SAMPLE_TEXTURE2D_SHADOW(g_tShadowBuffer, samplerg_tShadowBuffer, positionTXS).x * vShadow3x3PCFTerms0.z;
return flSum;
}
#endif
//-----------------------------------------------------------------------------
// Cookie sampling functions

13
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePassLoop.hlsl


float3(1.0, 1.0, 0.0)
};
#ifdef SHADOWS_USE_SHADOWCTXT
#else
float shadow = GetDirectionalShadowAttenuation(lightLoopContext, positionWS, 0, float3(0.0, 0.0, 0.0), float2(0.0, 0.0));
int shadowSplitIndex = GetSplitSphereIndexForDirshadows(positionWS, _DirShadowSplitSpheres);
#endif
if (shadowSplitIndex == -1)
diffuseLighting = float3(0.0, 0.0, 0.0);

out float3 specularLighting)
{
LightLoopContext context;
#ifndef SHADOWS_USE_SHADOWCTXT
ZERO_INITIALIZE(LightLoopContext, context);
#else
#endif
diffuseLighting = float3(0.0, 0.0, 0.0);
specularLighting = float3(0.0, 0.0, 0.0);

out float3 specularLighting)
{
LightLoopContext context;
#ifndef SHADOWS_USE_SHADOWCTXT
ZERO_INITIALIZE(LightLoopContext, context);
#else
#endif
diffuseLighting = float3(0.0, 0.0, 0.0);
specularLighting = float3(0.0, 0.0, 0.0);

16
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.hlsl


[branch] if (lightData.shadowIndex >= 0 && illuminance > 0.0)
{
#ifdef SHADOWS_USE_SHADOWCTXT
float shadow = GetDirectionalShadowAttenuation(lightLoopContext.shadowContext, positionWS, bsdfData.normalWS, lightData.shadowIndex, L, posInput.unPositionSS);
#else
float shadow = GetDirectionalShadowAttenuation(lightLoopContext, positionWS, lightData.shadowIndex, L, posInput.unPositionSS);
#endif
float shadow = GetDirectionalShadowAttenuation(lightLoopContext.shadowContext, positionWS, bsdfData.normalWS, lightData.shadowIndex, L, posInput.unPositionSS);
illuminance *= shadow;
}

[branch] if (lightData.shadowIndex >= 0 && illuminance > 0.0)
{
float3 offset = float3(0.0, 0.0, 0.0); // GetShadowPosOffset(nDotL, normal);
#ifdef SHADOWS_USE_SHADOWCTXT
float shadow = GetPunctualShadowAttenuation(lightLoopContext.shadowContext, positionWS + offset, bsdfData.normalWS, lightData.shadowIndex, L, posInput.unPositionSS);
#else
float shadow = GetPunctualShadowAttenuation(lightLoopContext, lightData.lightType, positionWS + offset, lightData.shadowIndex, L, posInput.unPositionSS);
#endif
float shadow = GetPunctualShadowAttenuation(lightLoopContext.shadowContext, positionWS + offset, bsdfData.normalWS, lightData.shadowIndex, L, posInput.unPositionSS);
shadow = lerp(1.0, shadow, lightData.shadowDimmer);
illuminance *= shadow;

[branch] if (lightData.shadowIndex >= 0 && illuminance > 0.0)
{
#ifdef SHADOWS_USE_SHADOWCTXT
#else
float shadow = GetDirectionalShadowAttenuation(lightLoopContext, positionWS, lightData.shadowIndex, L, posInput.unPositionSS);
#endif
illuminance *= shadow;
}

10
Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/Shadow.hlsl


//
#define SHADOWS_USE_SHADOWCTXT
#ifdef SHADOWS_USE_SHADOWCTXT
// TODO: Remove this once we've moved over to the new system. Also delete the undef at the bottom again.
#define ShadowData ShadowDataExp
#include "../../common/Shadow/ShadowBase.cs.hlsl" // ShadowData definition, auto generated (don't modify)
#include "ShadowTexFetch.hlsl" // Resource sampling definitions (don't modify)

return GetDirectionalShadowAttenuationDefault( shadowContext, positionWS, normalWS, shadowDataIndex, L, unPositionSS );
}
#endif
#undef ShadowData // TODO: Remove this once we've moved over to the new system. Also delete the define at the top again.
#endif // SHADOWS_USE_SHADOWCTXT
#endif // SHADOW_HLSL

6
Assets/ScriptableRenderPipeline/common/Shadow/Shadow.cs


namespace UnityEngine.Experimental.Rendering
{
// temporary namespace
namespace ShadowExp
{
using ShadowRequestVector = VectorArray<ShadowmapBase.ShadowRequest>;
using ShadowDataVector = VectorArray<ShadowData>;
using ShadowPayloadVector = VectorArray<ShadowPayload>;

return total > 0 ? (uint) total : 0;
}
}
} // end of temporary namespace ShadowExp
} // end of namespace UnityEngine.Experimental.ScriptableRenderLoop

13
Assets/ScriptableRenderPipeline/common/Shadow/ShadowBase.cs


Custom = ShadowAlgorithm.Custom << 3
}
namespace ShadowExp // temporary namespace until everything can be merged into the HDPipeline
{
// Central location for storing various shadow constants and bitmasks. These can be used to pack enums into ints, for example.
// These are all guaranteed to be positive, but C# doesn't like uints, so they're all ints.
public static class ShadowConstants

// -------------- Begin temporary structs that need to be replaced at some point ---------------
public struct SamplerState
{
#pragma warning disable 414 // CS0414 The private field '...' is assigned but its value is never used
#pragma warning restore 414
public static SamplerState Default()
public static SamplerState Default()
{
SamplerState defaultState;
defaultState.filterMode = FilterMode.Bilinear;

public struct ComparisonSamplerState
{
#pragma warning disable 414 // CS0414 The private field '...' is assigned but its value is never used
#pragma warning restore 414
public static ComparisonSamplerState Default()
public static ComparisonSamplerState Default()
{
ComparisonSamplerState defaultState;
defaultState.filterMode = FilterMode.Bilinear;

// allocate the shadow requests in the shadow map, only is called if shadowsCount > 0 - may modify shadowRequests and shadowsCount
protected abstract void AllocateShadows( FrameId frameId, VisibleLight[] lights, uint totalGranted, ref VectorArray<ShadowmapBase.ShadowRequest> grantedRequests, ref VectorArray<int> shadowIndices, ref VectorArray<ShadowData> shadowmapDatas, ref VectorArray<ShadowPayload> shadowmapPayload );
}
} // end of namespace ShadowExp
} // end of namespace UnityEngine.Experimental.ScriptableRenderLoop

28
Assets/ScriptableRenderPipeline/common/Shadow/ShadowBase.cs.hlsl


//
// This file was automatically generated from Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowBase.cs. Please don't edit by hand.
//
// This file was automatically generated from Assets/ScriptableRenderPipeline/common/Shadow/ShadowBase.cs. Please don't edit by hand.
// UnityEngine.Experimental.Rendering.HDPipeline.GPUShadowType: static fields
// UnityEngine.Experimental.Rendering.GPUShadowType: static fields
//
#define GPUSHADOWTYPE_POINT (0)
#define GPUSHADOWTYPE_SPOT (1)

#define GPUSHADOWTYPE_ALL (3)
//
// UnityEngine.Experimental.Rendering.HDPipeline.GPUShadowAlgorithm: static fields
// UnityEngine.Experimental.Rendering.GPUShadowAlgorithm: static fields
//
#define GPUSHADOWALGORITHM_PCF_1TAP (0)
#define GPUSHADOWALGORITHM_PCF_9TAP (1)

#define GPUSHADOWALGORITHM_MSM_HAUS (25)
#define GPUSHADOWALGORITHM_CUSTOM (256)
// Generated from UnityEngine.Experimental.Rendering.HDPipeline.ShadowExp.ShadowData
// Generated from UnityEngine.Experimental.Rendering.ShadowData
float4x4 worldToShadow;
float4 scaleOffset;
float4 texelSizeRcp;
uint id;
uint shadowType;
uint payloadOffset;
float bias;
float normalBias;
float4x4 worldToShadow;
float4 scaleOffset;
float4 texelSizeRcp;
uint id;
uint shadowType;
uint payloadOffset;
float bias;
float normalBias;
// Accessors for UnityEngine.Experimental.Rendering.HDPipeline.ShadowExp.ShadowData
// Accessors for UnityEngine.Experimental.Rendering.ShadowData
//
float4x4 GetWorldToShadow(ShadowData value)
{

10
Assets/ScriptableRenderPipeline/common/Shadow/ShadowUtilities.cs


public static GPUShadowAlgorithm Pack( ShadowAlgorithm algo, ShadowVariant vari, ShadowPrecision prec )
{
int precshift = ShadowExp.ShadowConstants.Bits.k_ShadowVariant + ShadowExp.ShadowConstants.Bits.k_ShadowAlgorithm;
int algoshift = ShadowExp.ShadowConstants.Bits.k_ShadowVariant;
int precshift = ShadowConstants.Bits.k_ShadowVariant + ShadowConstants.Bits.k_ShadowAlgorithm;
int algoshift = ShadowConstants.Bits.k_ShadowVariant;
public static ShadowAlgorithm ExtractAlgorithm( GPUShadowAlgorithm gpuAlgo ) { return (ShadowAlgorithm) ( ShadowExp.ShadowConstants.Masks.k_ShadowAlgorithm & ((int)gpuAlgo >> ShadowExp.ShadowConstants.Bits.k_ShadowVariant) ); }
public static ShadowVariant ExtractVariant( GPUShadowAlgorithm gpuAlgo ) { return (ShadowVariant ) ( ShadowExp.ShadowConstants.Masks.k_ShadowVariant & (int)gpuAlgo ); }
public static ShadowPrecision ExtractPrecision( GPUShadowAlgorithm gpuAlgo ) { return (ShadowPrecision) ( ShadowExp.ShadowConstants.Masks.k_ShadowPrecision & ((int)gpuAlgo >> (ShadowExp.ShadowConstants.Bits.k_ShadowVariant + ShadowExp.ShadowConstants.Bits.k_ShadowAlgorithm)) ); }
public static ShadowAlgorithm ExtractAlgorithm( GPUShadowAlgorithm gpuAlgo ) { return (ShadowAlgorithm) ( ShadowConstants.Masks.k_ShadowAlgorithm & ((int)gpuAlgo >> ShadowConstants.Bits.k_ShadowVariant) ); }
public static ShadowVariant ExtractVariant( GPUShadowAlgorithm gpuAlgo ) { return (ShadowVariant ) ( ShadowConstants.Masks.k_ShadowVariant & (int)gpuAlgo ); }
public static ShadowPrecision ExtractPrecision( GPUShadowAlgorithm gpuAlgo ) { return (ShadowPrecision) ( ShadowConstants.Masks.k_ShadowPrecision & ((int)gpuAlgo >> (ShadowConstants.Bits.k_ShadowVariant + ShadowConstants.Bits.k_ShadowAlgorithm)) ); }
public static void Unpack( GPUShadowAlgorithm gpuAlgo, out ShadowAlgorithm algo, out ShadowVariant vari, out ShadowPrecision prec )
{
algo = ExtractAlgorithm( gpuAlgo );

159
Assets/ScriptableRenderPipeline/fptl/FptlLighting.cs


//#define SHADOWS_OLD
using UnityEngine.Rendering;
using UnityEngine.Rendering;
#if !SHADOWS_OLD
using UnityEngine.Experimental.Rendering.ShadowExp;
class ShadowSetup : IDisposable
{
// shadow related stuff

public ShadowSetup(ShadowSettings shadowSettings, out IShadowManager shadowManager)
{
s_ShadowDataBuffer = new ComputeBuffer(k_MaxShadowDataSlots, System.Runtime.InteropServices.Marshal.SizeOf(typeof(ShadowExp.ShadowData)));
s_ShadowPayloadBuffer = new ComputeBuffer(k_MaxShadowDataSlots * k_MaxPayloadSlotsPerShadowData, System.Runtime.InteropServices.Marshal.SizeOf(typeof(ShadowExp.ShadowPayload)));
s_ShadowDataBuffer = new ComputeBuffer(k_MaxShadowDataSlots, System.Runtime.InteropServices.Marshal.SizeOf(typeof(ShadowData)));
s_ShadowPayloadBuffer = new ComputeBuffer(k_MaxShadowDataSlots * k_MaxPayloadSlotsPerShadowData, System.Runtime.InteropServices.Marshal.SizeOf(typeof(ShadowPayload)));
ShadowAtlas.AtlasInit atlasInit;
atlasInit.baseInit.width = (uint)shadowSettings.shadowAtlasWidth;
atlasInit.baseInit.height = (uint)shadowSettings.shadowAtlasHeight;

atlasInit.cascadeCount = shadowSettings.directionalLightCascadeCount;
atlasInit.cascadeRatios = shadowSettings.directionalLightCascades;
m_Shadowmaps = new ShadowmapBase[] { new ShadowExp.ShadowAtlas(ref atlasInit) };
m_Shadowmaps = new ShadowmapBase[] { new ShadowAtlas(ref atlasInit) };
ShadowExp.ShadowData[] sds;
ShadowData[] sds;
sc.GetShadowDatas(out sds, out offset, out count);
Debug.Assert(offset == 0);
s_ShadowDataBuffer.SetData(sds); // unfortunately we can't pass an offset or count to this function

scInit.dataSyncer = syncer;
scInit.resourceBinder = binder;
m_ShadowMgr = new ShadowExp.ShadowManager(shadowSettings, ref scInit, m_Shadowmaps);
m_ShadowMgr = new ShadowManager(shadowSettings, ref scInit, m_Shadowmaps);
// set global overrides - these need to match the override specified in ShadowDispatch.hlsl
m_ShadowMgr.SetGlobalShadowOverride( GPUShadowType.Point , ShadowAlgorithm.PCF, ShadowVariant.V1, ShadowPrecision.High, true );
m_ShadowMgr.SetGlobalShadowOverride( GPUShadowType.Spot , ShadowAlgorithm.PCF, ShadowVariant.V1, ShadowPrecision.High, true );

s_ShadowPayloadBuffer.Release();
}
}
#endif
public class FptlLightingInstance : RenderPipeline
{

[SerializeField]
ShadowSettings m_ShadowSettings = ShadowSettings.Default;
#if SHADOWS_OLD
ShadowRenderPass m_ShadowPass;
#else
ShadowSetup m_ShadowSetup;
IShadowManager m_ShadowMgr;
FrameId m_FrameId;
ShadowSetup m_ShadowSetup;
IShadowManager m_ShadowMgr;
FrameId m_FrameId = new FrameId();
List<int> m_ShadowRequests = new List<int>();
Dictionary<int, int> m_ShadowIndices = new Dictionary<int,int>();

m_ShadowMgr = null;
}
}
#endif
[SerializeField]
TextureSettings m_TextureSettings = TextureSettings.Default;

const float k_DirectionalLightPullbackDistance = 10000.0f;
[NonSerialized]
private int m_WarnedTooManyLights = 0;
private TextureCache2D m_CookieTexArray;
private TextureCacheCubemap m_CubeCookieTexArray;
private TextureCacheCubemap m_CubeReflTexArray;

ClearComputeBuffers();
#if !SHADOWS_OLD
#endif
}
void ClearComputeBuffers()

m_MatWorldToShadow = new Matrix4x4[k_MaxLights * k_MaxShadowmapPerLights];
m_DirShadowSplitSpheres = new Vector4[k_MaxDirectionalSplit];
m_Shadow3X3PCFTerms = new Vector4[4];
#if SHADOWS_OLD
m_ShadowPass = new ShadowRenderPass(m_ShadowSettings);
#else
#endif
m_SkyboxHelper = new SkyboxHelper();
m_SkyboxHelper.CreateMesh();

vx = worldToView.MultiplyVector(vx);
vy = worldToView.MultiplyVector(vy);
vz = worldToView.MultiplyVector(vz);
#if !SHADOWS_OLD
#else
l.shadowLightIndex = (light.light.shadows != LightShadows.None) ? (uint)nLight : 0xffffffff;
#endif
l.lightAxisX = vx;
l.lightAxisY = vy;
l.lightAxisZ = vz;

return dirLightCount;
}
#if SHADOWS_OLD
void UpdateShadowConstants(IList<VisibleLight> visibleLights, ref ShadowOutput shadow)
{
var nNumLightsIncludingTooMany = 0;
var numLights = 0;
var lightShadowIndex_LightParams = new Vector4[k_MaxLights];
var lightFalloffParams = new Vector4[k_MaxLights];
for (int nLight = 0; nLight < visibleLights.Count; nLight++)
{
nNumLightsIncludingTooMany++;
if (nNumLightsIncludingTooMany > k_MaxLights)
continue;
var light = visibleLights[nLight];
var lightType = light.lightType;
var position = light.light.transform.position;
var lightDir = light.light.transform.forward.normalized;
// Setup shadow data arrays
var hasShadows = shadow.GetShadowSliceCountLightIndex(nLight) != 0;
if (lightType == LightType.Directional)
{
lightShadowIndex_LightParams[numLights] = new Vector4(0, 0, 1, 1);
lightFalloffParams[numLights] = new Vector4(0.0f, 0.0f, float.MaxValue, (float)lightType);
if (hasShadows)
{
for (int s = 0; s < k_MaxDirectionalSplit; ++s)
{
m_DirShadowSplitSpheres[s] = shadow.directionalShadowSplitSphereSqr[s];
}
}
}
else if (lightType == LightType.Point)
{
lightShadowIndex_LightParams[numLights] = new Vector4(0, 0, 1, 1);
lightFalloffParams[numLights] = new Vector4(1.0f, 0.0f, light.range * light.range, (float)lightType);
}
else if (lightType == LightType.Spot)
{
lightShadowIndex_LightParams[numLights] = new Vector4(0, 0, 1, 1);
lightFalloffParams[numLights] = new Vector4(1.0f, 0.0f, light.range * light.range, (float)lightType);
}
if (hasShadows)
{
// Enable shadows
lightShadowIndex_LightParams[numLights].x = 1;
for (int s = 0; s < shadow.GetShadowSliceCountLightIndex(nLight); ++s)
{
var shadowSliceIndex = shadow.GetShadowSliceIndex(nLight, s);
m_MatWorldToShadow[numLights * k_MaxShadowmapPerLights + s] = shadow.shadowSlices[shadowSliceIndex].shadowTransform.transpose;
}
}
numLights++;
}
// Warn if too many lights found
if (nNumLightsIncludingTooMany > k_MaxLights)
{
if (nNumLightsIncludingTooMany > m_WarnedTooManyLights)
{
Debug.LogError("ERROR! Found " + nNumLightsIncludingTooMany + " runtime lights! Valve renderer supports up to " + k_MaxLights +
" active runtime lights at a time!\nDisabling " + (nNumLightsIncludingTooMany - k_MaxLights) + " runtime light" +
((nNumLightsIncludingTooMany - k_MaxLights) > 1 ? "s" : "") + "!\n");
}
m_WarnedTooManyLights = nNumLightsIncludingTooMany;
}
else
{
if (m_WarnedTooManyLights > 0)
{
m_WarnedTooManyLights = 0;
Debug.Log("SUCCESS! Found " + nNumLightsIncludingTooMany + " runtime lights which is within the supported number of lights, " + k_MaxLights + ".\n\n");
}
}
// PCF 3x3 Shadows
var flTexelEpsilonX = 1.0f / m_ShadowSettings.shadowAtlasWidth;
var flTexelEpsilonY = 1.0f / m_ShadowSettings.shadowAtlasHeight;
m_Shadow3X3PCFTerms[0] = new Vector4(20.0f / 267.0f, 33.0f / 267.0f, 55.0f / 267.0f, 0.0f);
m_Shadow3X3PCFTerms[1] = new Vector4(flTexelEpsilonX, flTexelEpsilonY, -flTexelEpsilonX, -flTexelEpsilonY);
m_Shadow3X3PCFTerms[2] = new Vector4(flTexelEpsilonX, flTexelEpsilonY, 0.0f, 0.0f);
m_Shadow3X3PCFTerms[3] = new Vector4(-flTexelEpsilonX, -flTexelEpsilonY, 0.0f, 0.0f);
}
#endif
#if !SHADOWS_OLD
// 0. deal with shadows
{
m_FrameId.frameCount++;

uint shadowRequestCount = (uint)m_ShadowRequests.Count;
int[] shadowRequests = m_ShadowRequests.ToArray();
int[] shadowDataIndices;
uint originalRequestCount = shadowRequestCount;
m_ShadowMgr.ProcessShadowRequests(m_FrameId, inputs, camera, inputs.visibleLights,
ref shadowRequestCount, shadowRequests, out shadowDataIndices);

m_ShadowIndices.Add(shadowRequests[i], shadowDataIndices[i]);
}
}
#endif
var probes = inputs.visibleReflectionProbes;
//ReflectionProbe[] probes = Object.FindObjectsOfType<ReflectionProbe>();

light.color.Set(cl.finalColor.r, cl.finalColor.g, cl.finalColor.b);
light.sliceIndex = 0;
light.lightModel = (uint)LightDefinitions.DIRECT_LIGHT;
#if !SHADOWS_OLD
#else
light.shadowLightIndex = shadowLightIndex;
#endif
shadowLightIndex++;
var bHasCookie = cl.light.cookie != null;

if (!CullResults.GetCullingParameters(camera, out cullingParams))
continue;
#if SHADOWS_OLD
m_ShadowPass.UpdateCullingParameters(ref cullingParams);
#else
#endif
var cullResults = CullResults.Cull(ref cullingParams, renderContext);
ExecuteRenderLoop(camera, cullResults, renderContext);

// do anything we need to do upon a new frame.
NewFrame();
#pragma warning disable 162 // warning CS0162: Unreachable code detected
if (!k_UseAsyncCompute) RenderShadowMaps(cullResults, loop);
#pragma warning restore 162
// generate g-buffer before shadows to leverage async compute
// forward opaques just write to depth.
loop.SetupCameraProperties(camera);

var numLights = GenerateSourceLightBuffers(camera, cullResults);
BuildPerTileLightLists(camera, loop, numLights, projscr, invProjscr);
// render shadow maps (for mobile shadow map rendering should happen before we render g-buffer).
// on GCN it needs to be after to leverage async compute since we need the depth-buffer for optimal light list building.
if (k_UseAsyncCompute)
{
RenderShadowMaps(cullResults, loop);
loop.SetupCameraProperties(camera);
}
#if !SHADOW_OLD
#endif
// Push all global params
var numDirLights = UpdateDirectionalLights(camera, cullResults.visibleLights, m_ShadowIndices);

void RenderShadowMaps(CullResults cullResults, ScriptableRenderContext loop)
{
#if SHADOWS_OLD
ShadowOutput shadows;
m_ShadowPass.Render(loop, cullResults, out shadows);
UpdateShadowConstants(cullResults.visibleLights, ref shadows);
#endif
}
void ResizeIfNecessary(int curWidth, int curHeight)

135
Assets/ScriptableRenderPipeline/fptl/LightingTemplate.hlsl


StructuredBuffer<DirectionalLight> g_dirLightData;
#ifndef SHADOWS_USE_SHADOWCTXT
#define DECLARE_SHADOWMAP( tex ) Texture2D tex; SamplerComparisonState sampler##tex
#ifdef REVERSE_ZBUF
#define SAMPLE_SHADOW( tex, coord ) tex.SampleCmpLevelZero( sampler##tex, (coord).xy, (coord).z )
#else
#define SAMPLE_SHADOW( tex, coord ) tex.SampleCmpLevelZero( sampler##tex, (coord).xy, 1.0-(coord).z )
#endif
DECLARE_SHADOWMAP(g_tShadowBuffer);
float ComputeShadow_PCF_3x3_Gaussian(float3 vPositionWs, float4x4 matWorldToShadow)
{
float4 vPositionTextureSpace = mul(float4(vPositionWs.xyz, 1.0), matWorldToShadow);
vPositionTextureSpace.xyz /= vPositionTextureSpace.w;
float2 shadowMapCenter = vPositionTextureSpace.xy;
if ((shadowMapCenter.x < 0.0f) || (shadowMapCenter.x > 1.0f) || (shadowMapCenter.y < 0.0f) || (shadowMapCenter.y > 1.0f))
return 1.0f;
float objDepth = saturate(257.0 / 256.0 - vPositionTextureSpace.z);
float4 v20Taps;
v20Taps.x = SAMPLE_SHADOW(g_tShadowBuffer, float3(shadowMapCenter.xy + g_vShadow3x3PCFTerms1.xy, objDepth)).x; // 1 1
v20Taps.y = SAMPLE_SHADOW(g_tShadowBuffer, float3(shadowMapCenter.xy + g_vShadow3x3PCFTerms1.zy, objDepth)).x; // -1 1
v20Taps.z = SAMPLE_SHADOW(g_tShadowBuffer, float3(shadowMapCenter.xy + g_vShadow3x3PCFTerms1.xw, objDepth)).x; // 1 -1
v20Taps.w = SAMPLE_SHADOW(g_tShadowBuffer, float3(shadowMapCenter.xy + g_vShadow3x3PCFTerms1.zw, objDepth)).x; // -1 -1
float flSum = dot(v20Taps.xyzw, float4(0.25, 0.25, 0.25, 0.25));
if ((flSum == 0.0) || (flSum == 1.0))
return flSum;
flSum *= g_vShadow3x3PCFTerms0.x * 4.0;
float4 v33Taps;
v33Taps.x = SAMPLE_SHADOW(g_tShadowBuffer, float3(shadowMapCenter.xy + g_vShadow3x3PCFTerms2.xz, objDepth)).x; // 1 0
v33Taps.y = SAMPLE_SHADOW(g_tShadowBuffer, float3(shadowMapCenter.xy + g_vShadow3x3PCFTerms3.xz, objDepth)).x; // -1 0
v33Taps.z = SAMPLE_SHADOW(g_tShadowBuffer, float3(shadowMapCenter.xy + g_vShadow3x3PCFTerms3.zy, objDepth)).x; // 0 -1
v33Taps.w = SAMPLE_SHADOW(g_tShadowBuffer, float3(shadowMapCenter.xy + g_vShadow3x3PCFTerms2.zy, objDepth)).x; // 0 1
flSum += dot(v33Taps.xyzw, g_vShadow3x3PCFTerms0.yyyy);
flSum += SAMPLE_SHADOW(g_tShadowBuffer, float3(shadowMapCenter.xy, objDepth)).x * g_vShadow3x3PCFTerms0.z;
return flSum;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------
/**
* Gets the cascade weights based on the world position of the fragment and the positions of the split spheres for each cascade.
* Returns an invalid split index if past shadowDistance (ie 4 is invalid for cascade)
*/
float GetSplitSphereIndexForDirshadows(float3 wpos)
{
float3 fromCenter0 = wpos.xyz - g_vDirShadowSplitSpheres[0].xyz;
float3 fromCenter1 = wpos.xyz - g_vDirShadowSplitSpheres[1].xyz;
float3 fromCenter2 = wpos.xyz - g_vDirShadowSplitSpheres[2].xyz;
float3 fromCenter3 = wpos.xyz - g_vDirShadowSplitSpheres[3].xyz;
float4 distances2 = float4(dot(fromCenter0, fromCenter0), dot(fromCenter1, fromCenter1), dot(fromCenter2, fromCenter2), dot(fromCenter3, fromCenter3));
float4 vDirShadowSplitSphereSqRadii;
vDirShadowSplitSphereSqRadii.x = g_vDirShadowSplitSpheres[0].w;
vDirShadowSplitSphereSqRadii.y = g_vDirShadowSplitSpheres[1].w;
vDirShadowSplitSphereSqRadii.z = g_vDirShadowSplitSpheres[2].w;
vDirShadowSplitSphereSqRadii.w = g_vDirShadowSplitSpheres[3].w;
fixed4 weights = float4(distances2 < vDirShadowSplitSphereSqRadii);
weights.yzw = saturate(weights.yzw - weights.xyz);
return 4 - dot(weights, float4(4, 3, 2, 1));
}
float SampleShadow(uint type, float3 vPositionWs, float3 vPositionToLightDirWs, uint lightIndex)
{
float flShadowScalar = 1.0;
int shadowSplitIndex = 0;
if (type == DIRECTIONAL_LIGHT)
{
shadowSplitIndex = GetSplitSphereIndexForDirshadows(vPositionWs);
}
else if (type == SPHERE_LIGHT)
{
float3 absPos = abs(vPositionToLightDirWs);
shadowSplitIndex = (vPositionToLightDirWs.z > 0) ? CUBEMAPFACE_NEGATIVE_Z : CUBEMAPFACE_POSITIVE_Z;
if (absPos.x > absPos.y)
{
if (absPos.x > absPos.z)
{
shadowSplitIndex = (vPositionToLightDirWs.x > 0) ? CUBEMAPFACE_NEGATIVE_X : CUBEMAPFACE_POSITIVE_X;
}
}
else
{
if (absPos.y > absPos.z)
{
shadowSplitIndex = (vPositionToLightDirWs.y > 0) ? CUBEMAPFACE_NEGATIVE_Y : CUBEMAPFACE_POSITIVE_Y;
}
}
}
flShadowScalar = ComputeShadow_PCF_3x3_Gaussian(vPositionWs.xyz, g_matWorldToShadow[lightIndex * MAX_SHADOWMAP_PER_LIGHT + shadowSplitIndex]);
return flShadowScalar;
}
#endif
float3 ExecuteLightList(uint start, uint numLights, float3 vP, float3 vPw, float3 Vworld)
{
UnityIndirect ind;

#ifdef SHADOWS_USE_SHADOWCTXT
#endif
float3 ints = 0;

float atten = 1;
#ifdef SHADOWS_USE_SHADOWCTXT
int shadowIdx = asint(lightData.shadowLightIndex);
[branch]
if (shadowIdx >= 0)

}
#else
[branch]
if (lightData.shadowLightIndex != 0xffffffff)
{
float shadowScalar = SampleShadow(DIRECTIONAL_LIGHT, vPw, 0, lightData.shadowLightIndex);
atten *= shadowScalar;
}
#endif
UnityLight light;
light.color.xyz = lightData.color.xyz * atten;
light.dir.xyz = mul((float3x3) g_mViewToWorld, -lightData.lightAxisZ).xyz;

}
atten *= angularAtt.w*(fProjVec>0.0); // finally apply this to the dist att.
#ifdef SHADOWS_USE_SHADOWCTXT
int shadowIdx = asint(lgtDat.shadowLightIndex);
[branch]
if (shadowIdx >= 0)

}
#else
const bool bHasShadow = (lgtDat.flags&HAS_SHADOW)!=0;
[branch]if(bHasShadow)
{
float shadowScalar = SampleShadow(SPOT_LIGHT, vPw, 0, lgtDat.shadowLightIndex);
atten *= shadowScalar;
}
#endif
UnityLight light;
light.color.xyz = lgtDat.color.xyz*atten*angularAtt.xyz;
light.dir.xyz = mul((float3x3) g_mViewToWorld, vL).xyz; //unity_CameraToWorld

atten *= cookieColor.w;
}
#ifdef SHADOWS_USE_SHADOWCTXT
int shadowIdx = asint(lgtDat.shadowLightIndex);
[branch]
if (shadowIdx >= 0)

}
#else
const bool bHasShadow = (lgtDat.flags&HAS_SHADOW)!=0;
[branch]if(bHasShadow)
{
float shadowScalar = SampleShadow(SPHERE_LIGHT, vPw, vLw, lgtDat.shadowLightIndex);
atten *= shadowScalar;
}
#endif
UnityLight light;
light.color.xyz = lgtDat.color.xyz*atten*cookieColor.xyz;
light.dir.xyz = vLw;

正在加载...
取消
保存