浏览代码

Moved shadow related files into ShaderLibrary and common to reflect their general usage.

Added support for the new shadow library to fptl.
Introduced a new shadow include inline file to support different shadow setups for different light loops per project.
Restructured the code a bit in order to support multiple instances per project.
Fixed and issue with broken shaders when one of the samplers was set to 0.
/main
uygar 7 年前
当前提交
1d081a77
共有 71 个文件被更改,包括 1368 次插入785 次删除
  1. 4
      Assets/ScriptableRenderPipeline/AdditionalLightData.cs
  2. 2
      Assets/ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipeline.cs
  3. 1
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/LightLoop.cs
  4. 4
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/Lighting.hlsl
  5. 13
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.cs
  6. 7
      Assets/ScriptableRenderPipeline/RenderPasses/ShadowRenderPass.cs
  7. 213
      Assets/ScriptableRenderPipeline/fptl/FptlLighting.cs
  8. 56
      Assets/ScriptableRenderPipeline/fptl/LightingTemplate.hlsl
  9. 2
      ProjectSettings/ProjectVersion.txt
  10. 5
      Assets/ScriptableRenderPipeline/common/Shadow/ShadowBase.cs.hlsl
  11. 14
      Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/Shadow.hlsl
  12. 43
      Assets/ScriptableRenderPipeline/common/Shadow/ShadowBase.cs
  13. 2
      Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/Resources/ShadowBlurMoments.compute
  14. 13
      Assets/ScriptableRenderPipeline/common/Shadow/Shadow.cs
  15. 9
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/ShadowContext.hlsl.meta
  16. 9
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/ShadowDispatch.hlsl.meta
  17. 94
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowBase.cs.hlsl.orig
  18. 8
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowBase.cs.hlsl.orig.meta
  19. 9
      Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow.meta
  20. 25
      Assets/ScriptableRenderPipeline/ShadowIncludes.inl
  21. 8
      Assets/ScriptableRenderPipeline/ShadowIncludes.inl.meta
  22. 9
      Assets/ScriptableRenderPipeline/common/Shadow.meta
  23. 26
      Assets/ScriptableRenderPipeline/fptl/ShadowContext.hlsl
  24. 9
      Assets/ScriptableRenderPipeline/fptl/ShadowContext.hlsl.meta
  25. 36
      Assets/ScriptableRenderPipeline/fptl/ShadowDispatch.hlsl
  26. 9
      Assets/ScriptableRenderPipeline/fptl/ShadowDispatch.hlsl.meta
  27. 9
      Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/Resources.meta
  28. 9
      Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/Shadow.hlsl.meta
  29. 277
      Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/ShadowAlgorithms.hlsl
  30. 9
      Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/ShadowAlgorithms.hlsl.meta
  31. 9
      Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/ShadowAlgorithmsCustom.hlsl.meta
  32. 9
      Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/ShadowMoments.hlsl.meta
  33. 9
      Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/ShadowSampling.hlsl.meta
  34. 133
      Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/ShadowTexFetch.hlsl
  35. 9
      Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/ShadowTexFetch.hlsl.meta
  36. 12
      Assets/ScriptableRenderPipeline/common/Shadow/Shadow.cs.meta
  37. 9
      Assets/ScriptableRenderPipeline/common/Shadow/ShadowBase.cs.hlsl.meta
  38. 12
      Assets/ScriptableRenderPipeline/common/Shadow/ShadowBase.cs.meta
  39. 260
      Assets/ScriptableRenderPipeline/common/Shadow/ShadowUtilities.cs
  40. 12
      Assets/ScriptableRenderPipeline/common/Shadow/ShadowUtilities.cs.meta
  41. 12
      Assets/ScriptableRenderPipeline/common/Shadow/VectorArray.cs.meta
  42. 9
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/Shadow.hlsl.meta
  43. 12
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/Shadow.cs.meta
  44. 9
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowAlgorithms.hlsl.meta
  45. 9
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowAlgorithmsCustom.hlsl.meta
  46. 9
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowBase.cs.hlsl.meta
  47. 12
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowBase.cs.meta
  48. 9
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowContext.hlsl.meta
  49. 9
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowDispatch.hlsl.meta
  50. 114
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowTexFetch.hlsl
  51. 9
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowTexFetch.hlsl.meta
  52. 222
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowUtilities.cs
  53. 12
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowUtilities.cs.meta
  54. 12
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/VectorArray.cs.meta
  55. 259
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowAlgorithms.hlsl
  56. 9
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowSampling.hlsl.meta
  57. 9
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowMoments.hlsl.meta
  58. 9
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/Resources.meta
  59. 0
      /Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/ShadowAlgorithmsCustom.hlsl
  60. 0
      /Assets/ScriptableRenderPipeline/common/Shadow/ShadowBase.cs.hlsl
  61. 0
      /Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/ShadowDispatch.hlsl
  62. 0
      /Assets/ScriptableRenderPipeline/common/Shadow/VectorArray.cs
  63. 0
      /Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/ShadowContext.hlsl
  64. 0
      /Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/ShadowSampling.hlsl
  65. 0
      /Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/Shadow.hlsl
  66. 0
      /Assets/ScriptableRenderPipeline/common/Shadow/ShadowBase.cs
  67. 0
      /Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/ShadowMoments.hlsl
  68. 0
      /Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/Resources
  69. 0
      /Assets/ScriptableRenderPipeline/common/Shadow/Shadow.cs

4
Assets/ScriptableRenderPipeline/AdditionalLightData.cs


[UnityEditor.CanEditMultipleObjects]
public class AdditionalLightDataEditor : UnityEditor.Editor
{
static HDPipeline.ShadowExp.ShadowRegistry m_ShadowRegistry;
static ShadowExp.ShadowRegistry m_ShadowRegistry;
public static void SetRegistry( HDPipeline.ShadowExp.ShadowRegistry registry ) { m_ShadowRegistry = registry; }
public static void SetRegistry( ShadowExp.ShadowRegistry registry ) { m_ShadowRegistry = registry; }
void OnEnable()
{

2
Assets/ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipeline.cs


#if SHADOWS_OLD
m_ShadowPass.UpdateCullingParameters(ref cullingParams);
#else
cullingParams.shadowDistance = Mathf.Min( 1000.0f, cullingParams.shadowDistance );
m_LightLoop.UpdateCullingParameters( ref cullingParams );
#endif
var cullResults = CullResults.Cull(ref cullingParams, renderContext);

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


public virtual void PrepareLightsForGPU(ShadowSettings shadowSettings, CullResults cullResults, Camera camera, ref ShadowOutput shadowOutput) { }
#else
public virtual int GetCurrentShadowCount() { return 0; }
public virtual void UpdateCullingParameters( ref CullingParameters cullingParams ) { }
public virtual void PrepareLightsForGPU(ShadowSettings shadowSettings, CullResults cullResults, Camera camera) { }
#endif
public virtual void RenderShadows( ScriptableRenderContext renderContext, CullResults cullResults ) { }

4
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/Lighting.hlsl


#include "../Lighting/LightDefinition.cs.hlsl"
#include "../Lighting/LightUtilities.hlsl"
#include "../Shadow/Shadow.hlsl"
#define SHADOW_TILEPASS
#include "../../ShaderLibrary/Shadow/Shadow.hlsl"
#undef SHADOW_TILEPASS
#if defined(LIGHTLOOP_SINGLE_PASS) || defined(LIGHTLOOP_TILE_PASS)
#include "../Lighting/TilePass/TilePass.hlsl"

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


{
if( m_Shadowmaps != null )
{
(m_Shadowmaps[3] as ShadowAtlas).Dispose();
Utilities.SafeRelease( s_ShadowDataBuffer );
Utilities.SafeRelease( s_ShadowPayloadBuffer );
if (s_ShadowDataBuffer != null)
s_ShadowDataBuffer.Release();
if (s_ShadowPayloadBuffer != null)
s_ShadowPayloadBuffer.Release();
}
}
#endif

public override int GetCurrentShadowCount()
{
return m_ShadowRequests.Count;
}
public override void UpdateCullingParameters(ref CullingParameters cullingParams)
{
m_ShadowMgr.UpdateCullingParameters( ref cullingParams );
}
public override void PrepareLightsForGPU(ShadowSettings shadowSettings, CullResults cullResults, Camera camera)

7
Assets/ScriptableRenderPipeline/RenderPasses/ShadowRenderPass.cs


#define SHADOWS_OLD // can't disable this until fptl has moved over as well
//#define SHADOWS_OLD
#if SHADOWS_OLD
using UnityEngine.Rendering;
using UnityEngine.Profiling;
using System.Collections.Generic;

}
}
}
#if SHADOWS_OLD
public struct InputShadowLightData
{
public int lightIndex;

loop.DrawShadows(ref settings);
}
}
#endif
#endif

213
Assets/ScriptableRenderPipeline/fptl/FptlLighting.cs


//#define SHADOWS_OLD
using UnityEngine.Rendering;
using System;
using System.Collections.Generic;

#if !SHADOWS_OLD
using UnityEngine.Experimental.Rendering.ShadowExp;
class ShadowSetup : IDisposable
{
// shadow related stuff
const int k_MaxShadowDataSlots = 64;
const int k_MaxPayloadSlotsPerShadowData = 4;
ShadowmapBase[] m_Shadowmaps;
ShadowManager m_ShadowMgr;
static ComputeBuffer s_ShadowDataBuffer;
static ComputeBuffer s_ShadowPayloadBuffer;
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)));
ShadowAtlas.AtlasInit atlasInit;
atlasInit.baseInit.width = (uint)shadowSettings.shadowAtlasWidth;
atlasInit.baseInit.height = (uint)shadowSettings.shadowAtlasHeight;
atlasInit.baseInit.slices = 1;
atlasInit.baseInit.shadowmapBits = 32;
atlasInit.baseInit.shadowmapFormat = RenderTextureFormat.Shadowmap;
atlasInit.baseInit.samplerState = SamplerState.Default();
atlasInit.baseInit.comparisonSamplerState = ComparisonSamplerState.Default();
atlasInit.baseInit.clearColor = new Vector4(0.0f, 0.0f, 0.0f, 0.0f);
atlasInit.baseInit.maxPayloadCount = 0;
atlasInit.baseInit.shadowSupport = ShadowmapBase.ShadowSupport.Directional | ShadowmapBase.ShadowSupport.Point | ShadowmapBase.ShadowSupport.Spot;
atlasInit.shaderKeyword = null;
atlasInit.cascadeCount = shadowSettings.directionalLightCascadeCount;
atlasInit.cascadeRatios = shadowSettings.directionalLightCascades;
m_Shadowmaps = new ShadowmapBase[] { new ShadowExp.ShadowAtlas(ref atlasInit) };
ShadowContext.SyncDel syncer = (ShadowContext sc) =>
{
// update buffers
uint offset, count;
ShadowExp.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
ShadowPayload[] payloads;
sc.GetPayloads(out payloads, out offset, out count);
Debug.Assert(offset == 0);
s_ShadowPayloadBuffer.SetData(payloads);
};
// binding code. This needs to be in sync with ShadowContext.hlsl
ShadowContext.BindDel binder = (ShadowContext sc, CommandBuffer cb) =>
{
// bind buffers
cb.SetGlobalBuffer("_ShadowDatasExp", s_ShadowDataBuffer);
cb.SetGlobalBuffer("_ShadowPayloads", s_ShadowPayloadBuffer);
// bind textures
uint offset, count;
RenderTargetIdentifier[] tex;
sc.GetTex2DArrays(out tex, out offset, out count);
cb.SetGlobalTexture("_ShadowmapExp_PCF", tex[0]);
// TODO: Currently samplers are hard coded in ShadowContext.hlsl, so we can't really set them here
};
ShadowContext.CtxtInit scInit;
scInit.storage.maxShadowDataSlots = k_MaxShadowDataSlots;
scInit.storage.maxPayloadSlots = k_MaxShadowDataSlots * k_MaxPayloadSlotsPerShadowData;
scInit.storage.maxTex2DArraySlots = 1;
scInit.storage.maxTexCubeArraySlots = 0;
scInit.storage.maxComparisonSamplerSlots = 1;
scInit.storage.maxSamplerSlots = 0;
scInit.dataSyncer = syncer;
scInit.resourceBinder = binder;
m_ShadowMgr = new ShadowExp.ShadowManager(shadowSettings, ref scInit, m_Shadowmaps);
shadowManager = m_ShadowMgr;
}
public void Dispose()
{
if (m_Shadowmaps != null)
{
(m_Shadowmaps[0] as ShadowAtlas).Dispose();
m_Shadowmaps = null;
}
m_ShadowMgr = null;
if( s_ShadowDataBuffer != null )
s_ShadowDataBuffer.Release();
if( s_ShadowPayloadBuffer != null )
s_ShadowPayloadBuffer.Release();
}
}
#endif
public class FptlLightingInstance : RenderPipeline
{
private readonly FptlLighting m_Owner;

[SerializeField]
ShadowSettings m_ShadowSettings = ShadowSettings.Default;
#if SHADOWS_OLD
#else
ShadowSetup m_ShadowSetup;
IShadowManager m_ShadowMgr;
FrameId m_FrameId;
List<int> m_ShadowRequests = new List<int>();
Dictionary<int, int> m_ShadowIndices = new Dictionary<int,int>();
void InitShadowSystem(ShadowSettings shadowSettings)
{
m_ShadowSetup = new ShadowSetup(shadowSettings, out m_ShadowMgr);
}
void DeinitShadowSystem()
{
if (m_ShadowSetup != null)
{
m_ShadowSetup.Dispose();
m_ShadowSetup = null;
m_ShadowMgr = null;
}
}
#endif
[SerializeField]
TextureSettings m_TextureSettings = TextureSettings.Default;

public bool enableBigTilePrepass = true;
public bool enableDrawLightBoundsDebug = false;
public bool enableDrawTileDebug = false;
public bool enableReflectionProbeDebug = false;
public bool enableReflectionProbeDebug = false;
public bool enableComputeLightEvaluation = false;
const bool k_UseDepthBuffer = true;// // only has an impact when EnableClustered is true (requires a depth-prepass)
const bool k_UseAsyncCompute = true; // should not use on mobile

if (enableClustered)
{
if (s_GlobalLightListAtomic != null)
s_GlobalLightListAtomic.Release();
if (s_GlobalLightListAtomic != null)
s_GlobalLightListAtomic.Release();
#if !SHADOWS_OLD
DeinitShadowSystem();
#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
#else
InitShadowSystem(m_ShadowSettings);
#endif
m_SkyboxHelper = new SkyboxHelper();
m_SkyboxHelper.CreateMesh();

m_DeferredMaterial.EnableKeyword(bUseClusteredForDeferred ? "USE_CLUSTERED_LIGHTLIST" : "USE_FPTL_LIGHTLIST");
m_DeferredReflectionMaterial.EnableKeyword(bUseClusteredForDeferred ? "USE_CLUSTERED_LIGHTLIST" : "USE_FPTL_LIGHTLIST");
if (enableDrawTileDebug) {
m_DeferredMaterial.EnableKeyword ("ENABLE_DEBUG");
} else {
m_DeferredMaterial.DisableKeyword ("ENABLE_DEBUG");
}
if (enableDrawTileDebug) {
m_DeferredMaterial.EnableKeyword ("ENABLE_DEBUG");
} else {
m_DeferredMaterial.DisableKeyword ("ENABLE_DEBUG");
}
if (enableReflectionProbeDebug) {
m_DeferredReflectionMaterial.EnableKeyword ("ENABLE_DEBUG");
} else {
m_DeferredReflectionMaterial.DisableKeyword ("ENABLE_DEBUG");
}
if (enableReflectionProbeDebug) {
m_DeferredReflectionMaterial.EnableKeyword ("ENABLE_DEBUG");
} else {
m_DeferredReflectionMaterial.DisableKeyword ("ENABLE_DEBUG");
}
cmd.SetGlobalBuffer("g_vLightListGlobal", bUseClusteredForDeferred ? s_PerVoxelLightLists : s_LightList); // opaques list (unless MSAA possibly)

return camera.projectionMatrix * GetFlipMatrix();
}
static int UpdateDirectionalLights(Camera camera, IList<VisibleLight> visibleLights)
static int UpdateDirectionalLights(Camera camera, IList<VisibleLight> visibleLights, Dictionary<int,int> shadowIndices)
{
var dirLightCount = 0;
var lights = new List<DirectionalLight>();

vx = worldToView.MultiplyVector(vx);
vy = worldToView.MultiplyVector(vy);
vz = worldToView.MultiplyVector(vz);
#if !SHADOWS_OLD
int shadowIdx;
l.shadowLightIndex = shadowIndices.TryGetValue((int)nLight, out shadowIdx) ? (uint)shadowIdx : 0x80000000;
#else
#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;

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++;
// get the indices for all lights that want to have shadows
m_ShadowRequests.Clear();
m_ShadowRequests.Capacity = inputs.visibleLights.Length;
int lcnt = inputs.visibleLights.Length;
for (int i = 0; i < lcnt; ++i)
{
VisibleLight vl = inputs.visibleLights[i];
if (vl.light.shadows != LightShadows.None && vl.light.GetComponent<AdditionalLightData>().shadowDimmer > 0.0f)
m_ShadowRequests.Add(i);
}
// pass this list to a routine that assigns shadows based on some heuristic
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);
// update the visibleLights with the shadow information
m_ShadowIndices.Clear();
for (uint i = 0; i < shadowRequestCount; i++)
{
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
int shadowIdx;
light.shadowLightIndex = m_ShadowIndices.TryGetValue( (int) shadowLightIndex, out shadowIdx ) ? (uint) shadowIdx : 0x80000000;
#else
#endif
shadowLightIndex++;
var bHasCookie = cl.light.cookie != null;

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

loop.SetupCameraProperties(camera);
}
#if !SHADOW_OLD
m_ShadowMgr.RenderShadows( m_FrameId, loop, cullResults, cullResults.visibleLights );
m_ShadowMgr.SyncData();
m_ShadowMgr.BindResources( loop );
#endif
var numDirLights = UpdateDirectionalLights(camera, cullResults.visibleLights);
var numDirLights = UpdateDirectionalLights(camera, cullResults.visibleLights, m_ShadowIndices);
PushGlobalParams(camera, loop, CameraToWorld(camera), projscr, invProjscr, numDirLights);
// do deferred lighting

void RenderShadowMaps(CullResults cullResults, ScriptableRenderContext loop)
{
#if SHADOWS_OLD
#endif
}
void ResizeIfNecessary(int curWidth, int curHeight)

56
Assets/ScriptableRenderPipeline/fptl/LightingTemplate.hlsl


#define CUBEMAPFACE_POSITIVE_Z 4
#define CUBEMAPFACE_NEGATIVE_Z 5
#define SHADOW_FPTL
# if defined(SHADER_API_D3D11)
# include "../ShaderLibrary/API/D3D11.hlsl"
# elif defined(SHADER_API_PSSL)
# include "../ShaderLibrary/API/PSSL.hlsl"
# elif defined(SHADER_API_XBOXONE)
# include "../ShaderLibrary/API/D3D11.hlsl"
# include "../ShaderLibrary/API/D3D11_1.hlsl"
# elif defined(SHADER_API_METAL)
# include "../ShaderLibrary/API/Metal.hlsl"
# else
# error unsupported shader api
# endif
# include "../ShaderLibrary/API/Validate.hlsl"
# include "../ShaderLibrary/Shadow/Shadow.hlsl"
#undef SHADOW_FPTL
CBUFFER_START(ShadowLightData)
float4 g_vShadow3x3PCFTerms0;

StructuredBuffer<DirectionalLight> g_dirLightData;
#ifndef SHADOWS_USE_SHADOWCTXT
#define DECLARE_SHADOWMAP( tex ) Texture2D tex; SamplerComparisonState sampler##tex
#ifdef REVERSE_ZBUF

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)
{

ind.specular = 0;
#ifdef SHADOWS_USE_SHADOWCTXT
ShadowContext shadowContext = InitShadowContext();
#endif
float3 ints = 0;

float atten = 1;
#ifdef SHADOWS_USE_SHADOWCTXT
int shadowIdx = asint(lightData.shadowLightIndex);
[branch]
if (shadowIdx >= 0)
{
float shadow = GetDirectionalShadowAttenuation(shadowContext, vPw, 0.0.xxx, shadowIdx, 0.0.xxx);
atten *= shadow;
}
#else
[branch]
if (lightData.shadowLightIndex != 0xffffffff)
{

#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)
{
float shadow = GetPunctualShadowAttenuation(shadowContext, vPw, 0.0.xxx, shadowIdx, 0.0.xxx);
atten *= shadow;
}
#else
const bool bHasShadow = (lgtDat.flags&HAS_SHADOW)!=0;
[branch]if(bHasShadow)
{

#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)
{
float shadow = GetPunctualShadowAttenuation(shadowContext, vPw, 0.0.xxx, shadowIdx, vLw);
atten *= shadow;
}
#else
const bool bHasShadow = (lgtDat.flags&HAS_SHADOW)!=0;
[branch]if(bHasShadow)
{

#endif
UnityLight light;
light.color.xyz = lgtDat.color.xyz*atten*cookieColor.xyz;
light.dir.xyz = vLw;

2
ProjectSettings/ProjectVersion.txt


m_EditorVersion: 2017.1.0a5
m_EditorVersion: 2017.1.0a6

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


uint id;
uint shadowType;
uint payloadOffset;
int lightType;
float bias;
float normalBias;
};

uint GetPayloadOffset(ShadowData value)
{
return value.payloadOffset;
}
int GetLightType(ShadowData value)
{
return value.lightType;
}
float GetBias(ShadowData value)
{

14
Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/Shadow.hlsl


// TODO: Remove this once we've moved over to the new system. Also delete the undef at the bottom again.
#define ShadowData ShadowDataExp
#include "ShadowBase.cs.hlsl" // ShadowData definition, auto generated (don't modify)
#include "ShadowTexFetch.hlsl" // Resource sampling definitions (don't modify)
#include "../../common/Shadow/ShadowBase.cs.hlsl" // ShadowData definition, auto generated (don't modify)
#include "ShadowTexFetch.hlsl" // Resource sampling definitions (don't modify)
// Declares a shadow context struct with members and sampling code based on whether _...Slots > 0
#define SHADOWCONTEXT_DECLARE( _Tex2DArraySlots, _TexCubeArraySlots, _SamplerCompSlots, _SamplerSlots ) \

// Shadow context definition and initialization, i.e. resource binding (project header, must be kept in sync with C# runtime)
#include "ShadowContext.hlsl"
#define SHADOW_CONTEXT_INCLUDE
#include "../../ShadowIncludes.inl"
#undef SHADOW_CONTEXT_INCLUDE
//#include "ShadowContext.hlsl"
// helper function to extract shadowmap data from the ShadowData struct
void UnpackShadowmapId( uint shadowmapId, out uint texIdx, out uint sampIdx, out float slice )

}
// include project specific shadow dispatcher. If this file is not empty, it MUST define which default shadows it's overriding
#include "ShadowDispatch.hlsl"
#define SHADOW_DISPATCH_INCLUDE
#include "../../ShadowIncludes.inl"
#undef SHADOW_DISPATCH_INCLUDE
//#include "ShadowDispatch.hlsl"
// if shadow dispatch is empty we'll fall back to default shadow sampling implementations
#ifndef SHADOW_DISPATCH_USE_CUSTOM_PUNCTUAL

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


using System;
using System.Collections.Generic;
namespace UnityEngine.Experimental.Rendering.HDPipeline
namespace UnityEngine.Experimental.Rendering
[Serializable]
public class ShadowSettings
{
public bool enabled;
public int shadowAtlasWidth;
public int shadowAtlasHeight;
public float maxShadowDistance;
public int directionalLightCascadeCount;
public Vector3 directionalLightCascades;
public float directionalLightNearPlaneOffset;
static ShadowSettings defaultShadowSettings = null;
public static ShadowSettings Default
{
get
{
if (defaultShadowSettings == null)
{
defaultShadowSettings = new ShadowSettings();
defaultShadowSettings.enabled = true;
defaultShadowSettings.shadowAtlasHeight = defaultShadowSettings.shadowAtlasWidth = 4096;
defaultShadowSettings.directionalLightCascadeCount = 1;
defaultShadowSettings.directionalLightCascades = new Vector3(0.05F, 0.2F, 0.3F);
defaultShadowSettings.directionalLightCascadeCount = 4;
defaultShadowSettings.directionalLightNearPlaneOffset = 5;
defaultShadowSettings.maxShadowDistance = 1000.0F;
}
return defaultShadowSettings;
}
}
}
[GenerateHLSL]
public enum GPUShadowType
{

AdditionalLightData ald = l.GetComponent<AdditionalLightData>();
Debug.Assert(ald != null, "Light has no valid AdditionalLightData component attached.");
GPULightType lightType;
ShadowUtils.MapLightType( ald.archetype, l.type, out lightType, out shadowType );
ShadowUtils.MapLightType( ald.archetype, l.type, out shadowType );
// check if this has supported shadows
if( (int) shadowType >= ShadowConstants.Counts.k_GPUShadowType )

public uint payloadOffset; // if this shadow type requires additional data it can be fetched from a global Buffer<uint> at payloadOffset.
// light related params (need to be set via ShadowMgr and derivatives)
public GPULightType lightType; // the light type
public float bias; // bias setting
public float normalBias; // bias based on the normal

void SyncData();
// Binds resources to shader stages just before rendering the lighting pass
void BindResources( ScriptableRenderContext renderContext );
// Fixes up some parameters within the cullResults
void UpdateCullingParameters( ref CullingParameters cullingParams );
}
abstract public class ShadowManagerBase : ShadowRegistry, IShadowManager

public abstract void SyncData();
public abstract void BindResources( ScriptableRenderContext renderContext );
public abstract void UpdateCullingParameters( ref CullingParameters cullingParams );
// sort the shadow requests in descending priority - may only modify shadowRequests
protected abstract void PrioritizeShadowCasters( Camera camera, VisibleLight[] lights, uint shadowRequestsCount, int[] shadowRequests );
// prune the shadow requests - may modify shadowRequests and shadowsCountshadowRequestsCount

2
Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/Resources/ShadowBlurMoments.compute


#pragma kernel main_MSM_17 KERNEL_MAIN=main_MSM_17 SHADOW_MOMENT_ALGORITHM=MSM MAX_MSAA=1 BLUR_SIZE=17
#include "ShaderLibrary/common.hlsl"
#include "HDRenderPipeline/Shadow/ShadowMoments.hlsl"
#include "ShaderLibrary/Shadow/ShadowMoments.hlsl"
#define BLUR_BORDER (BLUR_SIZE / 2)
#define LDS_SIZE (THREADS + BLUR_BORDER + BLUR_BORDER)

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


using System;
namespace UnityEngine.Experimental.Rendering.HDPipeline
namespace UnityEngine.Experimental.Rendering
{
// temporary namespace
namespace ShadowExp

override public void Update( FrameId frameId, ScriptableRenderContext renderContext, CullResults cullResults, VisibleLight[] lights )
{
var profilingSample = new Utilities.ProfilingSample("Shadowmap" + m_TexSlot, renderContext);
var profilingSample = new HDPipeline.Utilities.ProfilingSample("Shadowmap" + m_TexSlot, renderContext);
if (!string.IsNullOrEmpty( m_ShaderKeyword ) )
{

AdditionalLightDataEditor.SetRegistry( this );
}
public override void UpdateCullingParameters( ref CullingParameters cullingParams )
{
cullingParams.shadowDistance = Mathf.Min( m_ShadowSettings.maxShadowDistance, cullingParams.shadowDistance );
}
public override void ProcessShadowRequests( FrameId frameId, CullResults cullResults, Camera camera, VisibleLight[] lights, ref uint shadowRequestsCount, int[] shadowRequests, out int[] shadowDataIndices )
{
shadowDataIndices = null;

// set light specific values that are not related to the shadowmap
GPUShadowType shadowtype;
ShadowUtils.MapLightType( ald.archetype, vl.lightType, out sd.lightType, out shadowtype );
ShadowUtils.MapLightType( ald.archetype, vl.lightType, out shadowtype );
// current bias value range is way too large, so scale by 0.01 for now until we've decided whether to actually keep this value or not.
sd.bias = 0.01f * (SystemInfo.usesReversedZBuffer ? l.shadowBias : -l.shadowBias);
sd.normalBias = 100.0f * l.shadowNormalBias;

public override void RenderShadows( FrameId frameId, ScriptableRenderContext renderContext, CullResults cullResults, VisibleLight[] lights )
{
using (new Utilities.ProfilingSample("Render Shadows Exp", renderContext))
using (new HDPipeline.Utilities.ProfilingSample("Render Shadows Exp", renderContext))
{
foreach( var sm in m_Shadowmaps )
{

9
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/ShadowContext.hlsl.meta


fileFormatVersion: 2
guid: b0e81431fe3a7604fb9f9dd2a96bd7e0
timeCreated: 1491321445
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

9
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/ShadowDispatch.hlsl.meta


fileFormatVersion: 2
guid: e7e55b7306a2b2f43886918882a8935a
timeCreated: 1491321445
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

94
Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowBase.cs.hlsl.orig


//
// This file was automatically generated from Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowBase.cs. Please don't edit by hand.
//
#ifndef SHADOWBASE_CS_HLSL
#define SHADOWBASE_CS_HLSL
//
// UnityEngine.Experimental.Rendering.HDPipeline.GPUShadowType: static fields
//
#define GPUSHADOWTYPE_POINT (0)
#define GPUSHADOWTYPE_SPOT (1)
#define GPUSHADOWTYPE_DIRECTIONAL (2)
#define GPUSHADOWTYPE_MAX (3)
#define GPUSHADOWTYPE_UNKNOWN (3)
#define GPUSHADOWTYPE_ALL (3)
//
<<<<<<< HEAD
// UnityEngine.Experimental.Rendering.HDPipeline.GPUShadowAlgorithm: static fields
//
#define GPUSHADOWALGORITHM_PCF_1TAP (0)
#define GPUSHADOWALGORITHM_PCF_9TAP (1)
#define GPUSHADOWALGORITHM_VSM (8)
#define GPUSHADOWALGORITHM_EVSM_2 (16)
#define GPUSHADOWALGORITHM_EVSM_4 (17)
#define GPUSHADOWALGORITHM_MSM_HAM (24)
#define GPUSHADOWALGORITHM_MSM_HAUS (25)
#define GPUSHADOWALGORITHM_CUSTOM (256)
=======
// UnityEngine.Experimental.Rendering.HDPipeline.GPUShadowSampling: static fields
//
#define GPUSHADOWSAMPLING_PCF_1TAP (0)
#define GPUSHADOWSAMPLING_PCF_9TAPS_ADAPTIVE (1)
#define GPUSHADOWSAMPLING_VSM_1TAP (2)
#define GPUSHADOWSAMPLING_MSM_1TAP (3)
>>>>>>> master
// Generated from UnityEngine.Experimental.Rendering.HDPipeline.ShadowExp.ShadowData
// PackingRules = Exact
struct ShadowData
{
float4x4 worldToShadow;
float4 scaleOffset;
float2 texelSizeRcp;
uint id;
uint shadowType;
uint payloadOffset;
int lightType;
float bias;
float normalBias;
};
//
// Accessors for UnityEngine.Experimental.Rendering.HDPipeline.ShadowExp.ShadowData
//
float4x4 GetWorldToShadow(ShadowData value)
{
return value.worldToShadow;
}
float4 GetScaleOffset(ShadowData value)
{
return value.scaleOffset;
}
float2 GetTexelSizeRcp(ShadowData value)
{
return value.texelSizeRcp;
}
uint GetId(ShadowData value)
{
return value.id;
}
uint GetShadowType(ShadowData value)
{
return value.shadowType;
}
uint GetPayloadOffset(ShadowData value)
{
return value.payloadOffset;
}
int GetLightType(ShadowData value)
{
return value.lightType;
}
float GetBias(ShadowData value)
{
return value.bias;
}
float GetNormalBias(ShadowData value)
{
return value.normalBias;
}
#endif

8
Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowBase.cs.hlsl.orig.meta


fileFormatVersion: 2
guid: 84fb1d4060005f846a843b1c1bf1d48d
timeCreated: 1490622303
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

9
Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow.meta


fileFormatVersion: 2
guid: d52d6e1ad3dca474ebd73d054d17fb2e
folderAsset: yes
timeCreated: 1491314187
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

25
Assets/ScriptableRenderPipeline/ShadowIncludes.inl


// This file is inlined by ShaderLibrary/Shadow/Shadow.hlsl twice.
// Each time either SHADOW_CONTEXT_INCLUDE or SHADOW_DISPATCH_INCLUDE is defined.
// In the case of SHADOW_CONTEXT_INCLUDE a valid path must be given to a file that contains
// the code to initialize a shadow context.
// SHADOW_DISPATCH_INCLUDE is optional.
#ifdef SHADOW_CONTEXT_INCLUDE
# ifdef SHADOW_TILEPASS
# include "HDRenderPipeline/Lighting/TilePass/ShadowContext.hlsl"
# elif defined( SHADOW_FPTL )
# include "fptl/ShadowContext.hlsl"
# else
# error "No valid path to the shadow context has been given."
# endif
#endif
#ifdef SHADOW_DISPATCH_INCLUDE
# ifdef SHADOW_TILEPASS
# include "HDRenderPipeline/Lighting/TilePass/ShadowDispatch.hlsl"
# elif defined( SHADOW_FPTL )
# include "fptl/ShadowDispatch.hlsl"
# else
// It's ok not to have a dispatcher include as it only acts as an override
# endif
#endif

8
Assets/ScriptableRenderPipeline/ShadowIncludes.inl.meta


fileFormatVersion: 2
guid: cbc2765f95de56a47a8f39f5f1badd58
timeCreated: 1491314187
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

9
Assets/ScriptableRenderPipeline/common/Shadow.meta


fileFormatVersion: 2
guid: d49f97c73daab8a4a8d389c977c2345f
folderAsset: yes
timeCreated: 1491321440
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

26
Assets/ScriptableRenderPipeline/fptl/ShadowContext.hlsl


// This can be custom for each project and needs to be in sync with the ShadowMgr
#define SHADOWCONTEXT_MAX_TEX2DARRAY 1
#define SHADOWCONTEXT_MAX_TEXCUBEARRAY 0
#define SHADOWCONTEXT_MAX_SAMPLER 0
#define SHADOWCONTEXT_MAX_COMPSAMPLER 1
SHADOWCONTEXT_DECLARE( SHADOWCONTEXT_MAX_TEX2DARRAY, SHADOWCONTEXT_MAX_TEXCUBEARRAY, SHADOWCONTEXT_MAX_COMPSAMPLER, SHADOWCONTEXT_MAX_SAMPLER );
TEXTURE2D_ARRAY(_ShadowmapExp_PCF);
SAMPLER2D_SHADOW(sampler_ShadowmapExp_PCF);
StructuredBuffer<ShadowData> _ShadowDatasExp;
StructuredBuffer<int4> _ShadowPayloads;
ShadowContext InitShadowContext()
{
ShadowContext sc;
sc.shadowDatas = _ShadowDatasExp;
sc.payloads = _ShadowPayloads;
sc.tex2DArray[0] = _ShadowmapExp_PCF;
sc.compSamplers[0] = sampler_ShadowmapExp_PCF;
return sc;
}

9
Assets/ScriptableRenderPipeline/fptl/ShadowContext.hlsl.meta


fileFormatVersion: 2
guid: 30016f0dcc663b14483b62ccf2e8a7ce
timeCreated: 1491395507
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

36
Assets/ScriptableRenderPipeline/fptl/ShadowDispatch.hlsl


#define SHADOW_DISPATCH_USE_CUSTOM_DIRECTIONAL // enables hardcoded resources and algorithm for directional lights
#define SHADOW_DISPATCH_USE_CUSTOM_PUNCTUAL // enables hardcoded resources and algorithm for punctual lights
// example of overriding directional lights
#ifdef SHADOW_DISPATCH_USE_CUSTOM_DIRECTIONAL
float GetDirectionalShadowAttenuation( ShadowContext shadowContext, float3 positionWS, float3 normalWS, int shadowDataIndex, float3 L )
{
Texture2DArray tex = shadowContext.tex2DArray[0];
SamplerComparisonState compSamp = shadowContext.compSamplers[0];
uint algo = GPUSHADOWALGORITHM_PCF_9TAP;
return EvalShadow_CascadedDepth( shadowContext, algo, tex, compSamp, positionWS, normalWS, shadowDataIndex, L );
}
float GetDirectionalShadowAttenuation( ShadowContext shadowContext, float3 positionWS, float3 normalWS, int shadowDataIndex, float3 L, float2 unPositionSS )
{
return GetDirectionalShadowAttenuation( shadowContext, positionWS, normalWS, shadowDataIndex, L );
}
#endif
// example of overriding punctual lights
#ifdef SHADOW_DISPATCH_USE_CUSTOM_PUNCTUAL
float GetPunctualShadowAttenuation( ShadowContext shadowContext, float3 positionWS, float3 normalWS, int shadowDataIndex, float3 L )
{
// example for choosing the same algo
Texture2DArray tex = shadowContext.tex2DArray[0];
SamplerComparisonState compSamp = shadowContext.compSamplers[0];
uint algo = GPUSHADOWALGORITHM_PCF_9TAP;
return EvalShadow_PunctualDepth( shadowContext, algo, tex, compSamp, positionWS, normalWS, shadowDataIndex, L );
}
float GetPunctualShadowAttenuation( ShadowContext shadowContext, float3 positionWS, float3 normalWS, int shadowDataIndex, float3 L, float2 unPositionSS )
{
return GetPunctualShadowAttenuation( shadowContext, positionWS, normalWS, shadowDataIndex, L );
}
#endif

9
Assets/ScriptableRenderPipeline/fptl/ShadowDispatch.hlsl.meta


fileFormatVersion: 2
guid: 631ee816f7a634d48ae2c70c43a46e98
timeCreated: 1491395507
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

9
Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/Resources.meta


fileFormatVersion: 2
guid: f2f1273335a3dc54686dd5620bfc6790
folderAsset: yes
timeCreated: 1491321440
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

9
Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/Shadow.hlsl.meta


fileFormatVersion: 2
guid: 3d03971a8848ee14bb29a3c4ee9790b8
timeCreated: 1491321444
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

277
Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/ShadowAlgorithms.hlsl


// Various shadow algorithms
// There are two variants provided, one takes the texture and sampler explicitly so they can be statically passed in.
// The variant without resource parameters dynamically accesses the texture when sampling.
// Helper function to offset depth based on the surface normal and light direction.
// If the light hits the surface perpendicularly there will be no offset.
float3 EvalShadow_NormalBias( float3 normalWS, float NoL, float2 texelSize, float normalBias )
{
return max( texelSize.x, texelSize.y ) * normalBias * (1.0 - NoL) * normalWS;
}
// function called by spot, point and directional eval routines to calculate shadow coordinates
float3 EvalShadow_GetTexcoords( ShadowData sd, float3 positionWS )
{
float4 posCS = mul( float4( positionWS, 1.0 ), sd.worldToShadow );
posCS.z -= sd.bias * posCS.w;
float3 posNDC = posCS.xyz / posCS.w;
// calc TCs
float3 posTC = posNDC * 0.5 + 0.5;
posTC.xy = posTC.xy * sd.scaleOffset.xy + sd.scaleOffset.zw;
#if UNITY_REVERSED_Z
posTC.z = 1.0 - posTC.z;
#endif
return posTC;
}
int EvalShadow_GetCubeFaceID( float3 dir )
{
// TODO: Use faceID intrinsic on console
float3 adir = abs(dir);
// +Z -Z
int faceIndex = dir.z > 0.0 ? CUBEMAPFACE_NEGATIVE_Z : CUBEMAPFACE_POSITIVE_Z;
// +X -X
if (adir.x > adir.y && adir.x > adir.z)
{
faceIndex = dir.x > 0.0 ? CUBEMAPFACE_NEGATIVE_X : CUBEMAPFACE_POSITIVE_X;
}
// +Y -Y
else if (adir.y > adir.x && adir.y > adir.z)
{
faceIndex = dir.y > 0.0 ? CUBEMAPFACE_NEGATIVE_Y : CUBEMAPFACE_POSITIVE_Y;
}
return faceIndex;
}
//
// Point shadows
//
float EvalShadow_PointDepth( ShadowContext shadowContext, float3 positionWS, float3 normalWS, int index, float3 L )
{
// load the right shadow data for the current face
int faceIndex = EvalShadow_GetCubeFaceID( L ) + 1;
ShadowData sd = shadowContext.shadowDatas[index + faceIndex];
uint payloadOffset = GetPayloadOffset( sd );
// normal based bias
positionWS += EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L ) ), sd.texelSizeRcp.zw, sd.normalBias );
// get shadowmap texcoords
float3 posTC = EvalShadow_GetTexcoords( sd, positionWS );
// get the algorithm
uint shadowType, shadowAlgorithm;
UnpackShadowType( sd.shadowType, shadowType, shadowAlgorithm );
// sample the texture according to the given algorithm
uint texIdx, sampIdx;
float slice;
UnpackShadowmapId( sd.id, texIdx, sampIdx, slice );
return SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sd.bias, slice, shadowAlgorithm, texIdx, sampIdx );
}
#define EvalShadow_PointDepth_( _samplerType ) \
float EvalShadow_PointDepth( ShadowContext shadowContext, uint shadowAlgorithm, Texture2DArray tex, _samplerType samp, float3 positionWS, float3 normalWS, int index, float3 L ) \
{ \
/* load the right shadow data for the current face */ \
int faceIndex = EvalShadow_GetCubeFaceID( L ) + 1; \
ShadowData sd = shadowContext.shadowDatas[index + faceIndex]; \
uint payloadOffset = GetPayloadOffset( sd ); \
/* normal based bias */ \
positionWS += EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L ) ), sd.texelSizeRcp.zw, sd.normalBias ); \
/* get shadowmap texcoords */ \
float3 posTC = EvalShadow_GetTexcoords( sd, positionWS ); \
/* sample the texture */ \
float slice; \
UnpackShadowmapId( sd.id, slice ); \
return SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sd.bias, slice, shadowAlgorithm, tex, samp ); \
}
EvalShadow_PointDepth_( SamplerComparisonState )
EvalShadow_PointDepth_( SamplerState )
#undef EvalShadow_PointDepth_
//
// Spot shadows
//
float EvalShadow_SpotDepth( ShadowContext shadowContext, float3 positionWS, float3 normalWS, int index, float3 L )
{
// load the right shadow data for the current face
ShadowData sd = shadowContext.shadowDatas[index];
uint payloadOffset = GetPayloadOffset( sd );
// normal based bias
positionWS += EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L ) ), sd.texelSizeRcp.zw, sd.normalBias );
// get shadowmap texcoords
float3 posTC = EvalShadow_GetTexcoords( sd, positionWS );
// get the algorithm
uint shadowType, shadowAlgorithm;
UnpackShadowType( sd.shadowType, shadowType, shadowAlgorithm );
// sample the texture according to the given algorithm
uint texIdx, sampIdx;
float slice;
UnpackShadowmapId( sd.id, texIdx, sampIdx, slice );
return SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sd.bias, slice, shadowAlgorithm, texIdx, sampIdx );
}
#define EvalShadow_SpotDepth_( _samplerType ) \
float EvalShadow_SpotDepth( ShadowContext shadowContext, uint shadowAlgorithm, Texture2DArray tex, _samplerType samp, float3 positionWS, float3 normalWS, int index, float3 L ) \
{ \
/* load the right shadow data for the current face */ \
ShadowData sd = shadowContext.shadowDatas[index]; \
uint payloadOffset = GetPayloadOffset( sd ); \
/* normal based bias */ \
positionWS += EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L ) ), sd.texelSizeRcp.zw, sd.normalBias ); \
/* get shadowmap texcoords */ \
float3 posTC = EvalShadow_GetTexcoords( sd, positionWS ); \
/* sample the texture */ \
float slice; \
UnpackShadowmapId( sd.id, slice ); \
return SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sd.bias, slice, shadowAlgorithm, tex, samp ); \
}
EvalShadow_SpotDepth_( SamplerComparisonState )
EvalShadow_SpotDepth_( SamplerState )
#undef EvalShadow_SpotDepth_
//
// Punctual shadows for Point and Spot
//
float EvalShadow_PunctualDepth( ShadowContext shadowContext, float3 positionWS, float3 normalWS, int index, float3 L )
{
// load the right shadow data for the current face
int faceIndex = 0;
// get the algorithm
uint shadowType, shadowAlgorithm;
UnpackShadowType( shadowContext.shadowDatas[index].shadowType, shadowType );
[branch]
if( shadowType == GPUSHADOWTYPE_POINT )
{
faceIndex = EvalShadow_GetCubeFaceID( L ) + 1;
}
ShadowData sd = shadowContext.shadowDatas[index + faceIndex];
uint payloadOffset = GetPayloadOffset( sd );
// normal based bias
positionWS += EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L ) ), sd.texelSizeRcp.zw, sd.normalBias );
// get shadowmap texcoords
float3 posTC = EvalShadow_GetTexcoords( sd, positionWS );
// sample the texture according to the given algorithm
uint texIdx, sampIdx;
float slice;
UnpackShadowmapId( sd.id, texIdx, sampIdx, slice );
UnpackShadowType( sd.shadowType, shadowType, shadowAlgorithm );
return SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sd.bias, slice, shadowAlgorithm, texIdx, sampIdx );
}
#define EvalShadow_PunctualDepth_( _samplerType ) \
float EvalShadow_PunctualDepth( ShadowContext shadowContext, uint shadowAlgorithm, Texture2DArray tex, _samplerType samp, float3 positionWS, float3 normalWS, int index, float3 L ) \
{ \
/* load the right shadow data for the current face */ \
int faceIndex = 0; \
/* get the shadow type */ \
uint shadowType; \
UnpackShadowType( shadowContext.shadowDatas[index].shadowType, shadowType ); \
\
[branch] \
if( shadowType == GPUSHADOWTYPE_POINT ) \
{ \
faceIndex = EvalShadow_GetCubeFaceID( L ) + 1; \
} \
\
ShadowData sd = shadowContext.shadowDatas[index + faceIndex]; \
uint payloadOffset = GetPayloadOffset( sd ); \
/* normal based bias */ \
positionWS += EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L ) ), sd.texelSizeRcp.zw, sd.normalBias ); \
/* get shadowmap texcoords */ \
float3 posTC = EvalShadow_GetTexcoords( sd, positionWS ); \
/* sample the texture */ \
float slice; \
UnpackShadowmapId( sd.id, slice ); \
return SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sd.bias, slice, shadowAlgorithm, tex, samp ); \
}
EvalShadow_PunctualDepth_( SamplerComparisonState )
EvalShadow_PunctualDepth_( SamplerState )
#undef EvalShadow_PunctualDepth_
//
// Directional shadows (cascaded shadow map)
//
int EvalShadow_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 ) ) );
}
uint EvalShadow_LoadSplitSpheres( ShadowContext shadowContext, int index, out float4 splitSpheres[4] )
{
uint offset = GetPayloadOffset( shadowContext.shadowDatas[index] );
splitSpheres[0] = asfloat( shadowContext.payloads[offset + 0] );
splitSpheres[1] = asfloat( shadowContext.payloads[offset + 1] );
splitSpheres[2] = asfloat( shadowContext.payloads[offset + 2] );
splitSpheres[3] = asfloat( shadowContext.payloads[offset + 3] );
return offset + 4;
}
float EvalShadow_CascadedDepth( ShadowContext shadowContext, float3 positionWS, float3 normalWS, int index, float3 L )
{
// load the right shadow data for the current face
float4 dirShadowSplitSpheres[4];
uint payloadOffset = EvalShadow_LoadSplitSpheres( shadowContext, index, dirShadowSplitSpheres );
int shadowSplitIndex = EvalShadow_GetSplitSphereIndexForDirshadows( positionWS, dirShadowSplitSpheres );
if( shadowSplitIndex < 0 )
return 1.0;
ShadowData sd = shadowContext.shadowDatas[index + 1 + shadowSplitIndex];
// normal based bias
positionWS += EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L ) ), sd.texelSizeRcp.zw, sd.normalBias );
// get shadowmap texcoords
float3 posTC = EvalShadow_GetTexcoords( sd, positionWS );
// sample the texture
uint texIdx, sampIdx;
float slice;
UnpackShadowmapId( sd.id, texIdx, sampIdx, slice );
uint shadowType, shadowAlgorithm;
UnpackShadowType( sd.shadowType, shadowType, shadowAlgorithm );
return SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sd.bias, slice, shadowAlgorithm, texIdx, sampIdx );
}
#define EvalShadow_CascadedDepth_( _samplerType ) \
float EvalShadow_CascadedDepth( ShadowContext shadowContext, uint shadowAlgorithm, Texture2DArray tex, _samplerType samp, float3 positionWS, float3 normalWS, int index, float3 L ) \
{ \
/* load the right shadow data for the current face */ \
float4 dirShadowSplitSpheres[4]; \
uint payloadOffset = EvalShadow_LoadSplitSpheres( shadowContext, index, dirShadowSplitSpheres ); \
uint shadowSplitIndex = EvalShadow_GetSplitSphereIndexForDirshadows( positionWS, dirShadowSplitSpheres ); \
ShadowData sd = shadowContext.shadowDatas[index + 1 + shadowSplitIndex]; \
/* normal based bias */ \
positionWS += EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L ) ), sd.texelSizeRcp.zw, sd.normalBias ); \
/* get shadowmap texcoords */ \
float3 posTC = EvalShadow_GetTexcoords( sd, positionWS ); \
/* sample the texture */ \
float slice; \
UnpackShadowmapId( sd.id, slice ); \
\
return SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sd.bias, slice, shadowAlgorithm, tex, samp ); \
}
EvalShadow_CascadedDepth_( SamplerComparisonState )
EvalShadow_CascadedDepth_( SamplerState )
#undef EvalShadow_CascadedDepth_

9
Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/ShadowAlgorithms.hlsl.meta


fileFormatVersion: 2
guid: e2ca1e297ddf0b54f9d72244a419844b
timeCreated: 1491321445
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

9
Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/ShadowAlgorithmsCustom.hlsl.meta


fileFormatVersion: 2
guid: aa4f463e1cdf08f42934e66c91cd612e
timeCreated: 1491321444
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

9
Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/ShadowMoments.hlsl.meta


fileFormatVersion: 2
guid: 46258e7f416004a4db9dc7cc2c5a3b62
timeCreated: 1491321444
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

9
Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/ShadowSampling.hlsl.meta


fileFormatVersion: 2
guid: 870dbce0ad39569448fa01659ed39fd0
timeCreated: 1491321444
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

133
Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/ShadowTexFetch.hlsl


// This file contains various helper declarations for declaring and sampling members of the ShadowContext struct.
// shadow lookup routines when dynamic array access is possible
#if SHADOW_SUPPORTS_DYNAMIC_INDEXING != 0
// Shader model >= 5.1
# define SHADOW_DEFINE_SAMPLING_FUNC_T2DA_COMP( _Tex2DArraySlots , _SamplerCompSlots ) float4 SampleCompShadow_T2DA( ShadowContext ctxt, uint texIdx, uint sampIdx, float3 tcs, float slice ) { return SAMPLE_TEXTURE2D_ARRAY_SHADOW( ctxt.tex2DArray[texIdx], ctxt.compSamplers[sampIdx], tcs, slice ); }
# define SHADOW_DEFINE_SAMPLING_FUNC_T2DA_SAMP( _Tex2DArraySlots , _SamplerSlots ) float4 SampleShadow_T2DA( ShadowContext ctxt, uint texIdx, uint sampIdx, float2 tcs, float slice, float lod = 0.0 ) { return SAMPLE_TEXTURE2D_ARRAY_LOD( ctxt.tex2DArray[texIdx], ctxt.samplers[sampIdx], tcs, slice, lod ); }
# define SHADOW_DEFINE_SAMPLING_FUNC_TCA_COMP( _TexCubeArraySlots, _SamplerCompSlots ) float4 SampleCompShadow_TCA( ShadowContext ctxt, uint texIdx, uint sampIdx, float4 tcs, float cubeIdx ) { return SAMPLE_TEXTURECUBE_ARRAY_SHADOW( ctxt.texCubeArray[texIdx], ctxt.compSamplers[sampIdx], tcs, cubeIdx );}
# define SHADOW_DEFINE_SAMPLING_FUNC_TCA_SAMP( _TexCubeArraySlots, _SamplerSlots ) float4 SampleShadow_TCA( ShadowContext ctxt, uint texIdx, uint sampIdx, float3 tcs, float cubeIdx, float lod = 0.0 ) { return SAMPLE_TEXTURECUBE_ARRAY_LOD( ctxt.texCubeArray[texIdx], ctxt.samplers[sampIdx], tcs, cubeIdx, lod ); }
#else // helper macros if dynamic indexing does not work
// Sampler and texture combinations are static. No shadowmap will ever be sampled with two different samplers.
// Once shadowmaps and samplers are fixed consider writing custom dispatchers directly accessing textures and samplers.
# define SHADOW_DEFINE_SAMPLING_FUNC_T2DA_COMP( _Tex2DArraySlots, _SamplerCompSlots ) \
float4 SampleCompShadow_T2DA( ShadowContext ctxt, uint texIdx, uint sampIdx, float3 tcs, float slice ) \
{ \
float4 res = 1.0.xxxx; \
[unroll] for( uint i = 0; i < _Tex2DArraySlots; i++ ) \
{ \
[unroll] for( uint j = 0; j < _SamplerCompSlots; j++ ) \
{ \
[branch] if( i == texIdx && j == sampIdx ) \
{ \
res = SAMPLE_TEXTURE2D_ARRAY_SHADOW( ctxt.tex2DArray[i], ctxt.compSamplers[j], tcs, slice ); \
break; \
} \
} \
} \
return res; \
}
# define SHADOW_DEFINE_SAMPLING_FUNC_T2DA_SAMP( _Tex2DArraySlots, _SamplerSlots ) \
float4 SampleShadow_T2DA( ShadowContext ctxt, uint texIdx, uint sampIdx, float2 tcs, float slice, float lod = 0.0 ) \
{ \
float4 res = 1.0.xxxx; \
[unroll] for( uint i = 0; i < _Tex2DArraySlots; i++ ) \
{ \
[unroll] for( uint j = 0; j < _SamplerSlots; j++ ) \
{ \
[branch] if( i == texIdx && j == sampIdx ) \
{ \
res = SAMPLE_TEXTURE2D_ARRAY_LOD( ctxt.tex2DArray[i], ctxt.samplers[j], tcs, slice, lod ); \
break; \
} \
} \
} \
return res; \
}
# define SHADOW_DEFINE_SAMPLING_FUNC_TCA_COMP( _TexCubeArraySlots, _SamplerCompSlots ) \
float4 SampleCompShadow_TCA( ShadowContext ctxt, uint texIdx, uint sampIdx, float4 tcs, float cubeIdx ) \
{ \
float4 res = 1.0.xxxx; \
[unroll] for( uint i = 0; i < _TexCubeArraySlots; i++ ) \
{ \
[unroll] for( uint j = 0; j < _SamplerCompSlots; j++ ) \
{ \
[branch] if( i == texIdx && j == sampIdx ) \
{ \
res = SAMPLE_TEXTURECUBE_ARRAY_SHADOW( ctxt.texCubeArray[i], ctxt.compSamplers[j], tcs, cubeIdx ); \
break; \
} \
} \
} \
return res; \
}
# define SHADOW_DEFINE_SAMPLING_FUNC_TCA_SAMP( _TexCubeArraySlots, _SamplerSlots ) \
float4 SampleShadow_TCA( ShadowContext ctxt, uint texIdx, uint sampIdx, float3 tcs, float cubeIdx, float lod = 0.0 ) \
{ \
float4 res = 1.0.xxxx; \
[unroll] for( uint i = 0; i < _TexCubeArraySlots; i++ ) \
{ \
[unroll] for( uint j = 0; j < _SamplerSlots; j++ ) \
{ \
[branch] if( i == texIdx && j == sampIdx ) \
{ \
res = SAMPLE_TEXTURECUBE_ARRAY_LOD( ctxt.texCubeArray[i], ctxt.samplers[j], tcs, cubeIdx, lod ); \
break; \
} \
} \
} \
return res; \
}
#endif // SHADOW_SUPPORTS_DYNAMIC_INDEXING != 0
// helper macro to suppress code generation if _cnt is 0
#define SHADOW_DECLARE_SAMPLING_FUNC_T2DA_COMP( _Tex2DArraySlots , _SamplerCompSlots ) float4 SampleCompShadow_T2DA( ShadowContext ctxt, uint texIdx, uint sampIdx, float3 tcs, float slice );
#define SHADOW_DECLARE_SAMPLING_FUNC_T2DA_SAMP( _Tex2DArraySlots , _SamplerSlots ) float4 SampleShadow_T2DA( ShadowContext ctxt, uint texIdx, uint sampIdx, float2 tcs, float slice, float lod = 0.0 );
#define SHADOW_DECLARE_SAMPLING_FUNC_TCA_COMP( _TexCubeArraySlots, _SamplerCompSlots ) float4 SampleCompShadow_TCA( ShadowContext ctxt, uint texIdx, uint sampIdx, float4 tcs, float cubeIdx );
#define SHADOW_DECLARE_SAMPLING_FUNC_TCA_SAMP( _TexCubeArraySlots, _SamplerSlots ) float4 SampleShadow_TCA( ShadowContext ctxt, uint texIdx, uint sampIdx, float3 tcs, float cubeIdx, float lod = 0.0 );
#define SHADOW_CAT( _left, _right ) _left ## _right
#define SHADOW_CHECK_0( _macro )
#define SHADOW_CHECK_1( _macro ) _macro
#define SHADOW_CHECK_2( _macro ) _macro
#define SHADOW_CHECK_3( _macro ) _macro
#define SHADOW_CHECK_4( _macro ) _macro
#define SHADOW_CHECK_5( _macro ) _macro
#define SHADOW_CHECK_6( _macro ) _macro
#define SHADOW_CHECK_7( _macro ) _macro
#define SHADOW_CHECK_8( _macro ) _macro
#define SHADOW_CHECK_9( _macro ) _macro
#define SHADOW_CHECK( _cnt, _macro ) SHADOW_CAT( SHADOW_CHECK_ , _cnt ) ( _macro )
#define SHADOW_CHECK_ALT_0( _macro, _alt ) _alt
#define SHADOW_CHECK_ALT_1( _macro, _alt ) _macro
#define SHADOW_CHECK_ALT_2( _macro, _alt ) _macro
#define SHADOW_CHECK_ALT_3( _macro, _alt ) _macro
#define SHADOW_CHECK_ALT_4( _macro, _alt ) _macro
#define SHADOW_CHECK_ALT_5( _macro, _alt ) _macro
#define SHADOW_CHECK_ALT_6( _macro, _alt ) _macro
#define SHADOW_CHECK_ALT_7( _macro, _alt ) _macro
#define SHADOW_CHECK_ALT_8( _macro, _alt ) _macro
#define SHADOW_CHECK_ALT_9( _macro, _alt ) _macro
#define SHADOW_CHECK_ALT( _cnt, _macro, _alt ) SHADOW_CAT( SHADOW_CHECK_ALT_ , _cnt ) ( _macro, _alt )
// helper macro to declare texture members for the shadow context.
#define SHADOWCONTEXT_DECLARE_TEXTURES( _Tex2DArraySlots, _TexCubeArraySlots, _SamplerCompSlots, _SamplerSlots ) \
SHADOW_CHECK( _Tex2DArraySlots , Texture2DArray tex2DArray[_Tex2DArraySlots]; ) \
SHADOW_CHECK( _TexCubeArraySlots, TextureCubeArray texCubeArray[_TexCubeArraySlots]; ) \
SHADOW_CHECK( _SamplerCompSlots , SamplerComparisonState compSamplers[_Tex2DArraySlots]; ) \
SHADOW_CHECK( _SamplerSlots , SamplerState samplers[_Tex2DArraySlots]; )
// helper macro to declare texture sampling functions for the shadow context.
#define SHADOW_DEFINE_SAMPLING_FUNCS( _Tex2DArraySlots, _TexCubeArraySlots, _SamplerCompSlots, _SamplerSlots ) \
SHADOW_CHECK( _Tex2DArraySlots , SHADOW_CHECK_ALT( _SamplerCompSlots, SHADOW_DEFINE_SAMPLING_FUNC_T2DA_COMP( _Tex2DArraySlots, _SamplerCompSlots ), SHADOW_DECLARE_SAMPLING_FUNC_T2DA_COMP( _Tex2DArraySlots, _SamplerCompSlots ) ) ) \
SHADOW_CHECK( _Tex2DArraySlots , SHADOW_CHECK_ALT( _SamplerSlots , SHADOW_DEFINE_SAMPLING_FUNC_T2DA_SAMP( _Tex2DArraySlots, _SamplerSlots ), SHADOW_DECLARE_SAMPLING_FUNC_T2DA_SAMP( _Tex2DArraySlots, _SamplerSlots ) ) ) \
SHADOW_CHECK( _TexCubeArraySlots, SHADOW_CHECK_ALT( _SamplerCompSlots, SHADOW_DEFINE_SAMPLING_FUNC_TCA_COMP(_TexCubeArraySlots, _SamplerCompSlots ), SHADOW_DECLARE_SAMPLING_FUNC_TCA_COMP(_TexCubeArraySlots, _SamplerCompSlots ) ) ) \
SHADOW_CHECK( _TexCubeArraySlots, SHADOW_CHECK_ALT( _SamplerSlots , SHADOW_DEFINE_SAMPLING_FUNC_TCA_SAMP(_TexCubeArraySlots, _SamplerSlots ), SHADOW_DECLARE_SAMPLING_FUNC_TCA_SAMP(_TexCubeArraySlots, _SamplerSlots ) ) )

9
Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/ShadowTexFetch.hlsl.meta


fileFormatVersion: 2
guid: a9c17fbca36dfb744b42fb48d3829887
timeCreated: 1491321444
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

12
Assets/ScriptableRenderPipeline/common/Shadow/Shadow.cs.meta


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

9
Assets/ScriptableRenderPipeline/common/Shadow/ShadowBase.cs.hlsl.meta


fileFormatVersion: 2
guid: 78929777594e2d84aba05af5bf6463d0
timeCreated: 1491321444
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

12
Assets/ScriptableRenderPipeline/common/Shadow/ShadowBase.cs.meta


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

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


namespace UnityEngine.Experimental.Rendering
{
public class ShadowUtilsConstants
{
// Matches ScriptableShadowsUtility.cpp
public enum CubemapEdge
{
kCubeEdgePX_PY = 0,
kCubeEdgePX_NY,
kCubeEdgePX_PZ,
kCubeEdgePX_NZ,
kCubeEdgeNX_PY,
kCubeEdgeNX_NY,
kCubeEdgeNX_PZ,
kCubeEdgeNX_NZ,
kCubeEdgePY_PZ,
kCubeEdgePY_NZ,
kCubeEdgeNY_PZ,
kCubeEdgeNY_NZ,
kCubeEdge_Count
};
public static readonly CubemapEdge[,] kCubemapEdgesPerFace = new CubemapEdge[6,4]
{
{ CubemapEdge.kCubeEdgePX_PY, CubemapEdge.kCubeEdgePX_NY, CubemapEdge.kCubeEdgePX_PZ, CubemapEdge.kCubeEdgePX_NZ }, // PX
{ CubemapEdge.kCubeEdgeNX_PY, CubemapEdge.kCubeEdgeNX_NY, CubemapEdge.kCubeEdgeNX_PZ, CubemapEdge.kCubeEdgeNX_NZ }, // NX
{ CubemapEdge.kCubeEdgePX_PY, CubemapEdge.kCubeEdgeNX_PY, CubemapEdge.kCubeEdgePY_PZ, CubemapEdge.kCubeEdgePY_NZ }, // PY
{ CubemapEdge.kCubeEdgePX_NY, CubemapEdge.kCubeEdgeNX_NY, CubemapEdge.kCubeEdgeNY_PZ, CubemapEdge.kCubeEdgeNY_NZ }, // NY
{ CubemapEdge.kCubeEdgePX_PZ, CubemapEdge.kCubeEdgeNX_PZ, CubemapEdge.kCubeEdgePY_PZ, CubemapEdge.kCubeEdgeNY_PZ }, // PZ
{ CubemapEdge.kCubeEdgePX_NZ, CubemapEdge.kCubeEdgeNX_NZ, CubemapEdge.kCubeEdgePY_NZ, CubemapEdge.kCubeEdgeNY_NZ } // NZ
};
const float oneOverSqr2 = 0.70710678118654752440084436210485f;
public static readonly Vector3[] kCubemapEdgeDirections = new Vector3[(int)CubemapEdge.kCubeEdge_Count]
{
new Vector3( oneOverSqr2, oneOverSqr2, 0 ),
new Vector3( oneOverSqr2, -oneOverSqr2, 0 ),
new Vector3( oneOverSqr2, 0, oneOverSqr2 ),
new Vector3( oneOverSqr2, 0, -oneOverSqr2 ),
new Vector3( -oneOverSqr2, oneOverSqr2, 0 ),
new Vector3( -oneOverSqr2, -oneOverSqr2, 0 ),
new Vector3( -oneOverSqr2, 0, oneOverSqr2 ),
new Vector3( -oneOverSqr2, 0, -oneOverSqr2 ),
new Vector3( 0, oneOverSqr2, oneOverSqr2 ),
new Vector3( 0, oneOverSqr2, -oneOverSqr2 ),
new Vector3( 0, -oneOverSqr2, oneOverSqr2 ),
new Vector3( 0, -oneOverSqr2, -oneOverSqr2 )
};
// Cubemap faces with flipped z coordinate.
// These matrices do NOT match what we have in Skybox.cpp.
// The C++ runtime flips y as well and requires patching up
// the culling state. Using these matrices keeps the winding
// order, but may need some special treatment if rendering
// into an actual cubemap.
public static readonly Matrix4x4[] kCubemapFaces = new Matrix4x4[]
{
new Matrix4x4( // pos X
new Vector4( 0.0f, 0.0f, -1.0f, 0.0f ),
new Vector4( 0.0f, 1.0f, 0.0f, 0.0f ),
new Vector4( -1.0f, 0.0f, 0.0f, 0.0f ),
new Vector4( 0.0f, 0.0f, 0.0f, 1.0f ) ),
new Matrix4x4( // neg x
new Vector4( 0.0f, 0.0f, 1.0f, 0.0f ),
new Vector4( 0.0f, 1.0f, 0.0f, 0.0f ),
new Vector4( 1.0f, 0.0f, 0.0f, 0.0f ),
new Vector4( 0.0f, 0.0f, 0.0f, 1.0f ) ),
new Matrix4x4( // pos y
new Vector4( 1.0f, 0.0f, 0.0f, 0.0f ),
new Vector4( 0.0f, 0.0f, -1.0f, 0.0f ),
new Vector4( 0.0f, -1.0f, 0.0f, 0.0f ),
new Vector4( 0.0f, 0.0f, 0.0f, 1.0f ) ),
new Matrix4x4( // neg y
new Vector4( 1.0f, 0.0f, 0.0f, 0.0f ),
new Vector4( 0.0f, 0.0f, 1.0f, 0.0f ),
new Vector4( 0.0f, 1.0f, 0.0f, 0.0f ),
new Vector4( 0.0f, 0.0f, 0.0f, 1.0f ) ),
new Matrix4x4( // pos z
new Vector4( 1.0f, 0.0f, 0.0f, 0.0f ),
new Vector4( 0.0f, 1.0f, 0.0f, 0.0f ),
new Vector4( 0.0f, 0.0f, -1.0f, 0.0f ),
new Vector4( 0.0f, 0.0f, 0.0f, 1.0f ) ),
new Matrix4x4( // neg z
new Vector4( -1.0f, 0.0f, 0.0f, 0.0f ),
new Vector4( 0.0f, 1.0f, 0.0f, 0.0f ),
new Vector4( 0.0f, 0.0f, 1.0f, 0.0f ),
new Vector4( 0.0f, 0.0f, 0.0f, 1.0f ) )
};
}
public class ShadowUtils
{
public static Matrix4x4 ExtractSpotLightMatrix( VisibleLight vl, out Matrix4x4 view, out Matrix4x4 proj, out Vector4 lightDir, out ShadowSplitData splitData )
{
splitData = new ShadowSplitData();
splitData.cullingSphere.Set( 0.0f, 0.0f, 0.0f, float.NegativeInfinity );
splitData.cullingPlaneCount = 0;
// get lightDir
lightDir = vl.light.transform.forward;
// calculate view
Matrix4x4 scaleMatrix = Matrix4x4.identity;
scaleMatrix.m22 = -1.0f;
view = scaleMatrix * vl.localToWorld.inverse;
// following code is from SharedLightData::GetNearPlaneMinBound
float percentageBound = 0.01f * vl.light.range;
float fixedBound = 0.1f;
float nearmin = fixedBound <= percentageBound ? fixedBound : percentageBound;
// calculate projection
float zfar = vl.range;
float znear = vl.light.shadowNearPlane >= nearmin ? vl.light.shadowNearPlane : nearmin;
float fov = vl.spotAngle;
proj = Matrix4x4.Perspective(fov, 1.0f, znear, zfar);
// and the compound
return proj * view;
}
public static Matrix4x4 ExtractPointLightMatrix( VisibleLight vl, uint faceIdx, float fovBias, out Matrix4x4 view, out Matrix4x4 proj, out Vector4 lightDir, out ShadowSplitData splitData )
{
Debug.Assert( faceIdx <= (uint) CubemapFace.NegativeZ, "Tried to extract cubemap face " + faceIdx + "." );
splitData = new ShadowSplitData();
splitData.cullingSphere.Set( 0.0f, 0.0f, 0.0f, float.NegativeInfinity );
splitData.cullingPlaneCount = 4;
// get lightDir
lightDir = vl.light.transform.forward;
// calculate the view matrices
Vector3 lpos = vl.light.transform.position;
view = ShadowUtilsConstants.kCubemapFaces[faceIdx];
Vector3 inverted_viewpos = ShadowUtilsConstants.kCubemapFaces[faceIdx].MultiplyPoint( -lpos );
view.SetColumn( 3, new Vector4( inverted_viewpos.x, inverted_viewpos.y, inverted_viewpos.z, 1.0f ) );
for( int i = 0; i < 4; ++i )
{
ShadowUtilsConstants.CubemapEdge cubemapEdge = ShadowUtilsConstants.kCubemapEdgesPerFace[faceIdx,i];
Vector3 cullingPlaneDirection = ShadowUtilsConstants.kCubemapEdgeDirections[(int)cubemapEdge];
splitData.SetCullingPlane( i, new Plane( cullingPlaneDirection, lpos ) );
}
// following code is from SharedLightData::GetNearPlaneMinBound
float percentageBound = 0.01f * vl.light.range;
float fixedBound = 0.1f;
float nearmin = fixedBound <= percentageBound ? fixedBound : percentageBound;
// calculate projection
float farPlane = vl.range;
float nearPlane = vl.light.shadowNearPlane >= nearmin ? vl.light.shadowNearPlane : nearmin;
proj = Matrix4x4.Perspective( 90.0f + fovBias, 1.0f, nearPlane, farPlane );
// and the compound
return proj * view;
}
public static Matrix4x4 ExtractDirectionalLightMatrix( VisibleLight vl, uint cascadeIdx, int cascadeCount, Vector3 splitRatio, float nearPlaneOffset, uint width, uint height, out Matrix4x4 view, out Matrix4x4 proj, out Vector4 lightDir, out ShadowSplitData splitData, CullResults cullResults, int lightIndex )
{
Debug.Assert( width == height, "Currently the cascaded shadow mapping code requires square cascades." );
splitData = new ShadowSplitData();
splitData.cullingSphere.Set(0.0f, 0.0f, 0.0f, float.NegativeInfinity);
splitData.cullingPlaneCount = 0;
// get lightDir
lightDir = vl.light.transform.forward;
// TODO: At some point this logic should be moved to C#, then the parameters cullResults and lightIndex can be removed as well
// For directional lights shadow data is extracted from the cullResults, so that needs to be somehow provided here.
// Check ScriptableShadowsUtility.cpp ComputeDirectionalShadowMatricesAndCullingPrimitives(...) for details.
cullResults.ComputeDirectionalShadowMatricesAndCullingPrimitives( lightIndex, (int) cascadeIdx, cascadeCount, splitRatio, (int) width, nearPlaneOffset, out view, out proj, out splitData );
// and the compound
return proj * view;
}
public static bool MapLightType( LightArchetype la, LightType lt, out HDPipeline.GPULightType gputype, out GPUShadowType shadowtype )
{
switch( la )
{
case LightArchetype.Punctual : return MapLightType( lt, out gputype, out shadowtype );
case LightArchetype.Rectangle : gputype = HDPipeline.GPULightType.Rectangle; shadowtype = GPUShadowType.Unknown; return true;
case LightArchetype.Line : gputype = HDPipeline.GPULightType.Line; shadowtype = GPUShadowType.Unknown; return true;
default : gputype = HDPipeline.GPULightType.Spot; shadowtype = GPUShadowType.Unknown; return false; // <- probably not what you want
}
}
public static bool MapLightType( LightType lt, out HDPipeline.GPULightType gputype, out GPUShadowType shadowtype )
{
switch( lt )
{
case LightType.Spot : gputype = HDPipeline.GPULightType.Spot; shadowtype = GPUShadowType.Spot; return true;
case LightType.Directional : gputype = HDPipeline.GPULightType.Directional; shadowtype = GPUShadowType.Directional; return true;
case LightType.Point : gputype = HDPipeline.GPULightType.Point; shadowtype = GPUShadowType.Point; return true;
default:
case LightType.Area : gputype = HDPipeline.GPULightType.Rectangle; shadowtype = GPUShadowType.Unknown; return false; // area lights by themselves can't be mapped to any GPU type
}
}
public static bool MapLightType(LightArchetype la, LightType lt, out GPUShadowType shadowtype)
{
switch (la)
{
case LightArchetype.Punctual:
return MapLightType(lt, out shadowtype);
case LightArchetype.Rectangle:
shadowtype = GPUShadowType.Unknown;
return true;
case LightArchetype.Line:
shadowtype = GPUShadowType.Unknown;
return true;
default:
shadowtype = GPUShadowType.Unknown;
return false; // <- probably not what you want
}
}
public static bool MapLightType(LightType lt, out GPUShadowType shadowtype)
{
switch (lt)
{
case LightType.Spot:
shadowtype = GPUShadowType.Spot;
return true;
case LightType.Directional:
shadowtype = GPUShadowType.Directional;
return true;
case LightType.Point:
shadowtype = GPUShadowType.Point;
return true;
default:
case LightType.Area:
shadowtype = GPUShadowType.Unknown;
return false; // area lights by themselves can't be mapped to any GPU type
}
}
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;
return (GPUShadowAlgorithm) ( (int) prec << precshift | ((int) algo << algoshift) | (int)vari);
}
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 void Unpack( GPUShadowAlgorithm gpuAlgo, out ShadowAlgorithm algo, out ShadowVariant vari, out ShadowPrecision prec )
{
algo = ExtractAlgorithm( gpuAlgo );
vari = ExtractVariant( gpuAlgo );
prec = ExtractPrecision( gpuAlgo );
}
public static GPUShadowAlgorithm ClearPrecision( GPUShadowAlgorithm gpuAlgo )
{
var algo = ExtractAlgorithm( gpuAlgo );
var vari = ExtractVariant( gpuAlgo );
return Pack( algo, vari, ShadowPrecision.Low );
}
public static float Asfloat( uint val ) { return System.BitConverter.ToSingle( System.BitConverter.GetBytes( val ), 0 ); }
public static float Asfloat( int val ) { return System.BitConverter.ToSingle( System.BitConverter.GetBytes( val ), 0 ); }
public static int Asint( float val ) { return System.BitConverter.ToInt32( System.BitConverter.GetBytes( val ), 0 ); }
public static uint Asuint( float val ) { return System.BitConverter.ToUInt32( System.BitConverter.GetBytes( val ), 0 ); }
}
} // end of namespace UnityEngine.Experimental.ScriptableRenderLoop

12
Assets/ScriptableRenderPipeline/common/Shadow/ShadowUtilities.cs.meta


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

12
Assets/ScriptableRenderPipeline/common/Shadow/VectorArray.cs.meta


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

9
Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/Shadow.hlsl.meta


fileFormatVersion: 2
guid: 1c64d27a91e935140a9f402077f52fa0
timeCreated: 1477395059
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

12
Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/Shadow.cs.meta


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

9
Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowAlgorithms.hlsl.meta


fileFormatVersion: 2
guid: 9900a5b8191991b4d9e2c37413d85dc3
timeCreated: 1485511902
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

9
Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowAlgorithmsCustom.hlsl.meta


fileFormatVersion: 2
guid: 1163a3730c1812748b5cc5a7ecfbaf0c
timeCreated: 1485511901
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

9
Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowBase.cs.hlsl.meta


fileFormatVersion: 2
guid: 68d59da52ffb57240bdf73300a2736bf
timeCreated: 1485788693
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

12
Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowBase.cs.meta


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

9
Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowContext.hlsl.meta


fileFormatVersion: 2
guid: 4091aef5166b0624db069f6dbfd0673a
timeCreated: 1485511901
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

9
Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowDispatch.hlsl.meta


fileFormatVersion: 2
guid: 1c09a112d6337c7468843f1d64d7795f
timeCreated: 1485511901
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

114
Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowTexFetch.hlsl


// This file contains various helper declarations for declaring and sampling members of the ShadowContext struct.
// shadow lookup routines when dynamic array access is possible
#if SHADOW_SUPPORTS_DYNAMIC_INDEXING != 0
// Shader model >= 5.1
# define SHADOW_DEFINE_SAMPLING_FUNC_T2DA_COMP( _Tex2DArraySlots , _SamplerCompSlots ) float4 SampleCompShadow_T2DA( ShadowContext ctxt, uint texIdx, uint sampIdx, float3 tcs, float slice ) { return SAMPLE_TEXTURE2D_ARRAY_SHADOW( ctxt.tex2DArray[texIdx], ctxt.compSamplers[sampIdx], tcs, slice ); }
# define SHADOW_DEFINE_SAMPLING_FUNC_T2DA_SAMP( _Tex2DArraySlots , _SamplerSlots ) float4 SampleShadow_T2DA( ShadowContext ctxt, uint texIdx, uint sampIdx, float2 tcs, float slice, float lod = 0.0 ) { return SAMPLE_TEXTURE2D_ARRAY_LOD( ctxt.tex2DArray[texIdx], ctxt.samplers[sampIdx], tcs, slice, lod ); }
# define SHADOW_DEFINE_SAMPLING_FUNC_TCA_COMP( _TexCubeArraySlots, _SamplerCompSlots ) float4 SampleCompShadow_TCA( ShadowContext ctxt, uint texIdx, uint sampIdx, float4 tcs, float cubeIdx ) { return SAMPLE_TEXTURECUBE_ARRAY_SHADOW( ctxt.texCubeArray[texIdx], ctxt.compSamplers[sampIdx], tcs, cubeIdx );}
# define SHADOW_DEFINE_SAMPLING_FUNC_TCA_SAMP( _TexCubeArraySlots, _SamplerSlots ) float4 SampleShadow_TCA( ShadowContext ctxt, uint texIdx, uint sampIdx, float3 tcs, float cubeIdx, float lod = 0.0 ) { return SAMPLE_TEXTURECUBE_ARRAY_LOD( ctxt.texCubeArray[texIdx], ctxt.samplers[sampIdx], tcs, cubeIdx, lod ); }
#else // helper macros if dynamic indexing does not work
// Sampler and texture combinations are static. No shadowmap will ever be sampled with two different samplers.
// Once shadowmaps and samplers are fixed consider writing custom dispatchers directly accessing textures and samplers.
# define SHADOW_DEFINE_SAMPLING_FUNC_T2DA_COMP( _Tex2DArraySlots, _SamplerCompSlots ) \
float4 SampleCompShadow_T2DA( ShadowContext ctxt, uint texIdx, uint sampIdx, float3 tcs, float slice ) \
{ \
float4 res = 1.0.xxxx; \
[unroll] for( uint i = 0; i < _Tex2DArraySlots; i++ ) \
{ \
[unroll] for( uint j = 0; j < _SamplerCompSlots; j++ ) \
{ \
[branch] if( i == texIdx && j == sampIdx ) \
{ \
res = SAMPLE_TEXTURE2D_ARRAY_SHADOW( ctxt.tex2DArray[i], ctxt.compSamplers[j], tcs, slice ); \
break; \
} \
} \
} \
return res; \
}
# define SHADOW_DEFINE_SAMPLING_FUNC_T2DA_SAMP( _Tex2DArraySlots, _SamplerSlots ) \
float4 SampleShadow_T2DA( ShadowContext ctxt, uint texIdx, uint sampIdx, float2 tcs, float slice, float lod = 0.0 ) \
{ \
float4 res = 1.0.xxxx; \
[unroll] for( uint i = 0; i < _Tex2DArraySlots; i++ ) \
{ \
[unroll] for( uint j = 0; j < _SamplerSlots; j++ ) \
{ \
[branch] if( i == texIdx && j == sampIdx ) \
{ \
res = SAMPLE_TEXTURE2D_ARRAY_LOD( ctxt.tex2DArray[i], ctxt.samplers[j], tcs, slice, lod ); \
break; \
} \
} \
} \
return res; \
}
# define SHADOW_DEFINE_SAMPLING_FUNC_TCA_COMP( _TexCubeArraySlots, _SamplerCompSlots ) \
float4 SampleCompShadow_TCA( ShadowContext ctxt, uint texIdx, uint sampIdx, float4 tcs, float cubeIdx ) \
{ \
float4 res = 1.0.xxxx; \
[unroll] for( uint i = 0; i < _TexCubeArraySlots; i++ ) \
{ \
[unroll] for( uint j = 0; j < _SamplerCompSlots; j++ ) \
{ \
[branch] if( i == texIdx && j == sampIdx ) \
{ \
res = SAMPLE_TEXTURECUBE_ARRAY_SHADOW( ctxt.texCubeArray[i], ctxt.compSamplers[j], tcs, cubeIdx ); \
break; \
} \
} \
} \
return res; \
}
# define SHADOW_DEFINE_SAMPLING_FUNC_TCA_SAMP( _TexCubeArraySlots, _SamplerSlots ) \
float4 SampleShadow_TCA( ShadowContext ctxt, uint texIdx, uint sampIdx, float3 tcs, float cubeIdx, float lod = 0.0 ) \
{ \
float4 res = 1.0.xxxx; \
[unroll] for( uint i = 0; i < _TexCubeArraySlots; i++ ) \
{ \
[unroll] for( uint j = 0; j < _SamplerSlots; j++ ) \
{ \
[branch] if( i == texIdx && j == sampIdx ) \
{ \
res = SAMPLE_TEXTURECUBE_ARRAY_LOD( ctxt.texCubeArray[i], ctxt.samplers[j], tcs, cubeIdx, lod ); \
break; \
} \
} \
} \
return res; \
}
#endif // SHADOW_SUPPORTS_DYNAMIC_INDEXING != 0
// helper macro to suppress code generation if _cnt is 0
#define SHADOW_CHECK_0( _macro )
#define SHADOW_CHECK_1( _macro ) _macro
#define SHADOW_CHECK_2( _macro ) _macro
#define SHADOW_CHECK_3( _macro ) _macro
#define SHADOW_CHECK_4( _macro ) _macro
#define SHADOW_CHECK_5( _macro ) _macro
#define SHADOW_CHECK_6( _macro ) _macro
#define SHADOW_CHECK_7( _macro ) _macro
#define SHADOW_CHECK_8( _macro ) _macro
#define SHADOW_CHECK_9( _macro ) _macro
#define SHADOW_CHECK( _cnt, _macro ) MERGE_NAME( SHADOW_CHECK_ , _cnt ) ( _macro )
// helper macro to declare texture members for the shadow context.
#define SHADOWCONTEXT_DECLARE_TEXTURES( _Tex2DArraySlots, _TexCubeArraySlots, _SamplerCompSlots, _SamplerSlots ) \
SHADOW_CHECK( _Tex2DArraySlots , Texture2DArray tex2DArray[_Tex2DArraySlots]; ) \
SHADOW_CHECK( _TexCubeArraySlots, TextureCubeArray texCubeArray[_Tex2DArraySlots]; ) \
SHADOW_CHECK( _SamplerCompSlots , SamplerComparisonState compSamplers[_Tex2DArraySlots]; ) \
SHADOW_CHECK( _SamplerSlots , SamplerState samplers[_Tex2DArraySlots]; )
// helper macro to declare texture sampling functions for the shadow context.
#define SHADOW_DEFINE_SAMPLING_FUNCS( _Tex2DArraySlots, _TexCubeArraySlots, _SamplerCompSlots, _SamplerSlots ) \
SHADOW_CHECK( _Tex2DArraySlots , SHADOW_CHECK( _SamplerCompSlots, SHADOW_DEFINE_SAMPLING_FUNC_T2DA_COMP( _Tex2DArraySlots, _SamplerCompSlots ) ) ) \
SHADOW_CHECK( _Tex2DArraySlots , SHADOW_CHECK( _SamplerSlots , SHADOW_DEFINE_SAMPLING_FUNC_T2DA_SAMP( _Tex2DArraySlots, _SamplerSlots ) ) ) \
SHADOW_CHECK( _TexCubeArraySlots, SHADOW_CHECK( _SamplerCompSlots, SHADOW_DEFINE_SAMPLING_FUNC_TCA_COMP(_TexCubeArraySlots, _SamplerCompSlots ) ) ) \
SHADOW_CHECK( _TexCubeArraySlots, SHADOW_CHECK( _SamplerSlots , SHADOW_DEFINE_SAMPLING_FUNC_TCA_SAMP(_TexCubeArraySlots, _SamplerSlots ) ) )

9
Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowTexFetch.hlsl.meta


fileFormatVersion: 2
guid: 2ac0d1cc115e6ec42b5c47d2ee13f139
timeCreated: 1485873843
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

222
Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowUtilities.cs


namespace UnityEngine.Experimental.Rendering.HDPipeline
{
public class ShadowUtilsConstants
{
// Matches ScriptableShadowsUtility.cpp
public enum CubemapEdge
{
kCubeEdgePX_PY = 0,
kCubeEdgePX_NY,
kCubeEdgePX_PZ,
kCubeEdgePX_NZ,
kCubeEdgeNX_PY,
kCubeEdgeNX_NY,
kCubeEdgeNX_PZ,
kCubeEdgeNX_NZ,
kCubeEdgePY_PZ,
kCubeEdgePY_NZ,
kCubeEdgeNY_PZ,
kCubeEdgeNY_NZ,
kCubeEdge_Count
};
public static readonly CubemapEdge[,] kCubemapEdgesPerFace = new CubemapEdge[6,4]
{
{ CubemapEdge.kCubeEdgePX_PY, CubemapEdge.kCubeEdgePX_NY, CubemapEdge.kCubeEdgePX_PZ, CubemapEdge.kCubeEdgePX_NZ }, // PX
{ CubemapEdge.kCubeEdgeNX_PY, CubemapEdge.kCubeEdgeNX_NY, CubemapEdge.kCubeEdgeNX_PZ, CubemapEdge.kCubeEdgeNX_NZ }, // NX
{ CubemapEdge.kCubeEdgePX_PY, CubemapEdge.kCubeEdgeNX_PY, CubemapEdge.kCubeEdgePY_PZ, CubemapEdge.kCubeEdgePY_NZ }, // PY
{ CubemapEdge.kCubeEdgePX_NY, CubemapEdge.kCubeEdgeNX_NY, CubemapEdge.kCubeEdgeNY_PZ, CubemapEdge.kCubeEdgeNY_NZ }, // NY
{ CubemapEdge.kCubeEdgePX_PZ, CubemapEdge.kCubeEdgeNX_PZ, CubemapEdge.kCubeEdgePY_PZ, CubemapEdge.kCubeEdgeNY_PZ }, // PZ
{ CubemapEdge.kCubeEdgePX_NZ, CubemapEdge.kCubeEdgeNX_NZ, CubemapEdge.kCubeEdgePY_NZ, CubemapEdge.kCubeEdgeNY_NZ } // NZ
};
const float oneOverSqr2 = 0.70710678118654752440084436210485f;
public static readonly Vector3[] kCubemapEdgeDirections = new Vector3[(int)CubemapEdge.kCubeEdge_Count]
{
new Vector3( oneOverSqr2, oneOverSqr2, 0 ),
new Vector3( oneOverSqr2, -oneOverSqr2, 0 ),
new Vector3( oneOverSqr2, 0, oneOverSqr2 ),
new Vector3( oneOverSqr2, 0, -oneOverSqr2 ),
new Vector3( -oneOverSqr2, oneOverSqr2, 0 ),
new Vector3( -oneOverSqr2, -oneOverSqr2, 0 ),
new Vector3( -oneOverSqr2, 0, oneOverSqr2 ),
new Vector3( -oneOverSqr2, 0, -oneOverSqr2 ),
new Vector3( 0, oneOverSqr2, oneOverSqr2 ),
new Vector3( 0, oneOverSqr2, -oneOverSqr2 ),
new Vector3( 0, -oneOverSqr2, oneOverSqr2 ),
new Vector3( 0, -oneOverSqr2, -oneOverSqr2 )
};
// Cubemap faces with flipped z coordinate.
// These matrices do NOT match what we have in Skybox.cpp.
// The C++ runtime flips y as well and requires patching up
// the culling state. Using these matrices keeps the winding
// order, but may need some special treatment if rendering
// into an actual cubemap.
public static readonly Matrix4x4[] kCubemapFaces = new Matrix4x4[]
{
new Matrix4x4( // pos X
new Vector4( 0.0f, 0.0f, -1.0f, 0.0f ),
new Vector4( 0.0f, 1.0f, 0.0f, 0.0f ),
new Vector4( -1.0f, 0.0f, 0.0f, 0.0f ),
new Vector4( 0.0f, 0.0f, 0.0f, 1.0f ) ),
new Matrix4x4( // neg x
new Vector4( 0.0f, 0.0f, 1.0f, 0.0f ),
new Vector4( 0.0f, 1.0f, 0.0f, 0.0f ),
new Vector4( 1.0f, 0.0f, 0.0f, 0.0f ),
new Vector4( 0.0f, 0.0f, 0.0f, 1.0f ) ),
new Matrix4x4( // pos y
new Vector4( 1.0f, 0.0f, 0.0f, 0.0f ),
new Vector4( 0.0f, 0.0f, -1.0f, 0.0f ),
new Vector4( 0.0f, -1.0f, 0.0f, 0.0f ),
new Vector4( 0.0f, 0.0f, 0.0f, 1.0f ) ),
new Matrix4x4( // neg y
new Vector4( 1.0f, 0.0f, 0.0f, 0.0f ),
new Vector4( 0.0f, 0.0f, 1.0f, 0.0f ),
new Vector4( 0.0f, 1.0f, 0.0f, 0.0f ),
new Vector4( 0.0f, 0.0f, 0.0f, 1.0f ) ),
new Matrix4x4( // pos z
new Vector4( 1.0f, 0.0f, 0.0f, 0.0f ),
new Vector4( 0.0f, 1.0f, 0.0f, 0.0f ),
new Vector4( 0.0f, 0.0f, -1.0f, 0.0f ),
new Vector4( 0.0f, 0.0f, 0.0f, 1.0f ) ),
new Matrix4x4( // neg z
new Vector4( -1.0f, 0.0f, 0.0f, 0.0f ),
new Vector4( 0.0f, 1.0f, 0.0f, 0.0f ),
new Vector4( 0.0f, 0.0f, 1.0f, 0.0f ),
new Vector4( 0.0f, 0.0f, 0.0f, 1.0f ) )
};
}
public class ShadowUtils
{
public static Matrix4x4 ExtractSpotLightMatrix( VisibleLight vl, out Matrix4x4 view, out Matrix4x4 proj, out Vector4 lightDir, out ShadowSplitData splitData )
{
splitData = new ShadowSplitData();
splitData.cullingSphere.Set( 0.0f, 0.0f, 0.0f, float.NegativeInfinity );
splitData.cullingPlaneCount = 0;
// get lightDir
lightDir = vl.light.transform.forward;
// calculate view
Matrix4x4 scaleMatrix = Matrix4x4.identity;
scaleMatrix.m22 = -1.0f;
view = scaleMatrix * vl.localToWorld.inverse;
// following code is from SharedLightData::GetNearPlaneMinBound
float percentageBound = 0.01f * vl.light.range;
float fixedBound = 0.1f;
float nearmin = fixedBound <= percentageBound ? fixedBound : percentageBound;
// calculate projection
float zfar = vl.range;
float znear = vl.light.shadowNearPlane >= nearmin ? vl.light.shadowNearPlane : nearmin;
float fov = vl.spotAngle;
proj = Matrix4x4.Perspective(fov, 1.0f, znear, zfar);
// and the compound
return proj * view;
}
public static Matrix4x4 ExtractPointLightMatrix( VisibleLight vl, uint faceIdx, float fovBias, out Matrix4x4 view, out Matrix4x4 proj, out Vector4 lightDir, out ShadowSplitData splitData )
{
Debug.Assert( faceIdx <= (uint) CubemapFace.NegativeZ, "Tried to extract cubemap face " + faceIdx + "." );
splitData = new ShadowSplitData();
splitData.cullingSphere.Set( 0.0f, 0.0f, 0.0f, float.NegativeInfinity );
splitData.cullingPlaneCount = 4;
// get lightDir
lightDir = vl.light.transform.forward;
// calculate the view matrices
Vector3 lpos = vl.light.transform.position;
view = ShadowUtilsConstants.kCubemapFaces[faceIdx];
Vector3 inverted_viewpos = ShadowUtilsConstants.kCubemapFaces[faceIdx].MultiplyPoint( -lpos );
view.SetColumn( 3, new Vector4( inverted_viewpos.x, inverted_viewpos.y, inverted_viewpos.z, 1.0f ) );
for( int i = 0; i < 4; ++i )
{
ShadowUtilsConstants.CubemapEdge cubemapEdge = ShadowUtilsConstants.kCubemapEdgesPerFace[faceIdx,i];
Vector3 cullingPlaneDirection = ShadowUtilsConstants.kCubemapEdgeDirections[(int)cubemapEdge];
splitData.SetCullingPlane( i, new Plane( cullingPlaneDirection, lpos ) );
}
// following code is from SharedLightData::GetNearPlaneMinBound
float percentageBound = 0.01f * vl.light.range;
float fixedBound = 0.1f;
float nearmin = fixedBound <= percentageBound ? fixedBound : percentageBound;
// calculate projection
float farPlane = vl.range;
float nearPlane = vl.light.shadowNearPlane >= nearmin ? vl.light.shadowNearPlane : nearmin;
proj = Matrix4x4.Perspective( 90.0f + fovBias, 1.0f, nearPlane, farPlane );
// and the compound
return proj * view;
}
public static Matrix4x4 ExtractDirectionalLightMatrix( VisibleLight vl, uint cascadeIdx, int cascadeCount, Vector3 splitRatio, float nearPlaneOffset, uint width, uint height, out Matrix4x4 view, out Matrix4x4 proj, out Vector4 lightDir, out ShadowSplitData splitData, CullResults cullResults, int lightIndex )
{
Debug.Assert( width == height, "Currently the cascaded shadow mapping code requires square cascades." );
splitData = new ShadowSplitData();
splitData.cullingSphere.Set(0.0f, 0.0f, 0.0f, float.NegativeInfinity);
splitData.cullingPlaneCount = 0;
// get lightDir
lightDir = vl.light.transform.forward;
// TODO: At some point this logic should be moved to C#, then the parameters cullResults and lightIndex can be removed as well
// For directional lights shadow data is extracted from the cullResults, so that needs to be somehow provided here.
// Check ScriptableShadowsUtility.cpp ComputeDirectionalShadowMatricesAndCullingPrimitives(...) for details.
cullResults.ComputeDirectionalShadowMatricesAndCullingPrimitives( lightIndex, (int) cascadeIdx, cascadeCount, splitRatio, (int) width, nearPlaneOffset, out view, out proj, out splitData );
// and the compound
return proj * view;
}
public static bool MapLightType( LightArchetype la, LightType lt, out GPULightType gputype, out GPUShadowType shadowtype )
{
switch( la )
{
case LightArchetype.Punctual : return MapLightType( lt, out gputype, out shadowtype );
case LightArchetype.Rectangle : gputype = GPULightType.Rectangle; shadowtype = GPUShadowType.Unknown; return true;
case LightArchetype.Line : gputype = GPULightType.Line; shadowtype = GPUShadowType.Unknown; return true;
default : gputype = GPULightType.Spot; shadowtype = GPUShadowType.Unknown; return false; // <- probably not what you want
}
}
public static bool MapLightType( LightType lt, out GPULightType gputype, out GPUShadowType shadowtype )
{
switch( lt )
{
case LightType.Spot : gputype = GPULightType.Spot; shadowtype = GPUShadowType.Spot; return true;
case LightType.Directional : gputype = GPULightType.Directional; shadowtype = GPUShadowType.Directional; return true;
case LightType.Point : gputype = GPULightType.Point; shadowtype = GPUShadowType.Point; return true;
default:
case LightType.Area : gputype = GPULightType.Rectangle; shadowtype = GPUShadowType.Unknown; return false; // area lights by themselves can't be mapped to any GPU type
}
}
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;
return (GPUShadowAlgorithm) ( (int) prec << precshift | ((int) algo << algoshift) | (int)vari);
}
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 void Unpack( GPUShadowAlgorithm gpuAlgo, out ShadowAlgorithm algo, out ShadowVariant vari, out ShadowPrecision prec )
{
algo = ExtractAlgorithm( gpuAlgo );
vari = ExtractVariant( gpuAlgo );
prec = ExtractPrecision( gpuAlgo );
}
public static GPUShadowAlgorithm ClearPrecision( GPUShadowAlgorithm gpuAlgo )
{
var algo = ExtractAlgorithm( gpuAlgo );
var vari = ExtractVariant( gpuAlgo );
return Pack( algo, vari, ShadowPrecision.Low );
}
public static float Asfloat( uint val ) { return System.BitConverter.ToSingle( System.BitConverter.GetBytes( val ), 0 ); }
public static float Asfloat( int val ) { return System.BitConverter.ToSingle( System.BitConverter.GetBytes( val ), 0 ); }
public static int Asint( float val ) { return System.BitConverter.ToInt32( System.BitConverter.GetBytes( val ), 0 ); }
public static uint Asuint( float val ) { return System.BitConverter.ToUInt32( System.BitConverter.GetBytes( val ), 0 ); }
}
} // end of namespace UnityEngine.Experimental.ScriptableRenderLoop

12
Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowUtilities.cs.meta


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

12
Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/VectorArray.cs.meta


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

259
Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowAlgorithms.hlsl


// Various shadow algorithms
// There are two variants provided, one takes the texture and sampler explicitly so they can be statically passed in.
// The variant without resource parameters dynamically accesses the texture when sampling.
// Helper function to offset depth based on the surface normal and light direction.
// If the light hits the surface perpendicularly there will be no offset.
float3 EvalShadow_NormalBias( float3 normalWS, float NoL, float2 texelSize, float normalBias )
{
return max( texelSize.x, texelSize.y ) * normalBias * (1.0 - NoL) * normalWS;
}
// function called by spot, point and directional eval routines to calculate shadow coordinates
float3 EvalShadow_GetTexcoords( ShadowData sd, float3 positionWS )
{
float4 posCS = mul( float4( positionWS, 1.0 ), sd.worldToShadow );
posCS.z -= sd.bias * posCS.w;
float3 posNDC = posCS.xyz / posCS.w;
// calc TCs
float3 posTC = posNDC * 0.5 + 0.5;
posTC.xy = posTC.xy * sd.scaleOffset.xy + sd.scaleOffset.zw;
#if UNITY_REVERSED_Z
posTC.z = 1.0 - posTC.z;
#endif
return posTC;
}
//
// Point shadows
//
float EvalShadow_PointDepth( ShadowContext shadowContext, float3 positionWS, float3 normalWS, int index, float3 L )
{
// load the right shadow data for the current face
int faceIndex = 0;
GetCubeFaceID( L, faceIndex );
ShadowData sd = shadowContext.shadowDatas[index + 1 + faceIndex];
uint payloadOffset = GetPayloadOffset( sd );
// normal based bias
positionWS += EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L ) ), sd.texelSizeRcp.zw, sd.normalBias );
// get shadowmap texcoords
float3 posTC = EvalShadow_GetTexcoords( sd, positionWS );
// get the algorithm
uint shadowType, shadowAlgorithm;
UnpackShadowType( sd.shadowType, shadowType, shadowAlgorithm );
// sample the texture according to the given algorithm
uint texIdx, sampIdx;
float slice;
UnpackShadowmapId( sd.id, texIdx, sampIdx, slice );
return SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sd.bias, slice, shadowAlgorithm, texIdx, sampIdx );
}
#define EvalShadow_PointDepth_( _samplerType ) \
float EvalShadow_PointDepth( ShadowContext shadowContext, uint shadowAlgorithm, Texture2DArray tex, _samplerType samp, float3 positionWS, float3 normalWS, int index, float3 L ) \
{ \
/* load the right shadow data for the current face */ \
int faceIndex = 0; \
GetCubeFaceID( L, faceIndex ); \
ShadowData sd = shadowContext.shadowDatas[index + 1 + faceIndex]; \
uint payloadOffset = GetPayloadOffset( sd ); \
/* normal based bias */ \
positionWS += EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L ) ), sd.texelSizeRcp.zw, sd.normalBias ); \
/* get shadowmap texcoords */ \
float3 posTC = EvalShadow_GetTexcoords( sd, positionWS ); \
/* sample the texture */ \
float slice; \
UnpackShadowmapId( sd.id, slice ); \
return SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sd.bias, slice, shadowAlgorithm, tex, samp ); \
}
EvalShadow_PointDepth_( SamplerComparisonState )
EvalShadow_PointDepth_( SamplerState )
#undef EvalShadow_PointDepth_
//
// Spot shadows
//
float EvalShadow_SpotDepth( ShadowContext shadowContext, float3 positionWS, float3 normalWS, int index, float3 L )
{
// load the right shadow data for the current face
ShadowData sd = shadowContext.shadowDatas[index];
uint payloadOffset = GetPayloadOffset( sd );
// normal based bias
positionWS += EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L ) ), sd.texelSizeRcp.zw, sd.normalBias );
// get shadowmap texcoords
float3 posTC = EvalShadow_GetTexcoords( sd, positionWS );
// get the algorithm
uint shadowType, shadowAlgorithm;
UnpackShadowType( sd.shadowType, shadowType, shadowAlgorithm );
// sample the texture according to the given algorithm
uint texIdx, sampIdx;
float slice;
UnpackShadowmapId( sd.id, texIdx, sampIdx, slice );
return SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sd.bias, slice, shadowAlgorithm, texIdx, sampIdx );
}
#define EvalShadow_SpotDepth_( _samplerType ) \
float EvalShadow_SpotDepth( ShadowContext shadowContext, uint shadowAlgorithm, Texture2DArray tex, _samplerType samp, float3 positionWS, float3 normalWS, int index, float3 L ) \
{ \
/* load the right shadow data for the current face */ \
ShadowData sd = shadowContext.shadowDatas[index]; \
uint payloadOffset = GetPayloadOffset( sd ); \
/* normal based bias */ \
positionWS += EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L ) ), sd.texelSizeRcp.zw, sd.normalBias ); \
/* get shadowmap texcoords */ \
float3 posTC = EvalShadow_GetTexcoords( sd, positionWS ); \
/* sample the texture */ \
float slice; \
UnpackShadowmapId( sd.id, slice ); \
return SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sd.bias, slice, shadowAlgorithm, tex, samp ); \
}
EvalShadow_SpotDepth_( SamplerComparisonState )
EvalShadow_SpotDepth_( SamplerState )
#undef EvalShadow_SpotDepth_
//
// Punctual shadows for Point and Spot
//
float EvalShadow_PunctualDepth( ShadowContext shadowContext, float3 positionWS, float3 normalWS, int index, float3 L )
{
// load the right shadow data for the current face
int faceIndex = 0;
// get the algorithm
uint shadowType, shadowAlgorithm;
UnpackShadowType( shadowContext.shadowDatas[index].shadowType, shadowType );
[branch]
if( shadowType == GPUSHADOWTYPE_POINT )
{
GetCubeFaceID( L, faceIndex );
faceIndex++;
}
ShadowData sd = shadowContext.shadowDatas[index + faceIndex];
uint payloadOffset = GetPayloadOffset( sd );
// normal based bias
positionWS += EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L ) ), sd.texelSizeRcp.zw, sd.normalBias );
// get shadowmap texcoords
float3 posTC = EvalShadow_GetTexcoords( sd, positionWS );
// sample the texture according to the given algorithm
uint texIdx, sampIdx;
float slice;
UnpackShadowmapId( sd.id, texIdx, sampIdx, slice );
UnpackShadowType( sd.shadowType, shadowType, shadowAlgorithm );
return SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sd.bias, slice, shadowAlgorithm, texIdx, sampIdx );
}
#define EvalShadow_PunctualDepth_( _samplerType ) \
float EvalShadow_PunctualDepth( ShadowContext shadowContext, uint shadowAlgorithm, Texture2DArray tex, _samplerType samp, float3 positionWS, float3 normalWS, int index, float3 L ) \
{ \
/* load the right shadow data for the current face */ \
int faceIndex = 0; \
/* get the shadow type */ \
uint shadowType; \
UnpackShadowType( shadowContext.shadowDatas[index].shadowType, shadowType ); \
\
[branch] \
if( shadowType == GPUSHADOWTYPE_POINT ) \
{ \
GetCubeFaceID( L, faceIndex ); \
faceIndex++; \
} \
\
ShadowData sd = shadowContext.shadowDatas[index + faceIndex]; \
uint payloadOffset = GetPayloadOffset( sd ); \
/* normal based bias */ \
positionWS += EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L ) ), sd.texelSizeRcp.zw, sd.normalBias ); \
/* get shadowmap texcoords */ \
float3 posTC = EvalShadow_GetTexcoords( sd, positionWS ); \
/* sample the texture */ \
float slice; \
UnpackShadowmapId( sd.id, slice ); \
return SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sd.bias, slice, shadowAlgorithm, tex, samp ); \
}
EvalShadow_PunctualDepth_( SamplerComparisonState )
EvalShadow_PunctualDepth_( SamplerState )
#undef EvalShadow_PunctualDepth_
//
// Directional shadows (cascaded shadow map)
//
int EvalShadow_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 ) ) );
}
uint EvalShadow_LoadSplitSpheres( ShadowContext shadowContext, int index, out float4 splitSpheres[4] )
{
uint offset = GetPayloadOffset( shadowContext.shadowDatas[index] );
splitSpheres[0] = asfloat( shadowContext.payloads[offset + 0] );
splitSpheres[1] = asfloat( shadowContext.payloads[offset + 1] );
splitSpheres[2] = asfloat( shadowContext.payloads[offset + 2] );
splitSpheres[3] = asfloat( shadowContext.payloads[offset + 3] );
return offset + 4;
}
float EvalShadow_CascadedDepth( ShadowContext shadowContext, float3 positionWS, float3 normalWS, int index, float3 L )
{
// load the right shadow data for the current face
float4 dirShadowSplitSpheres[4];
uint payloadOffset = EvalShadow_LoadSplitSpheres( shadowContext, index, dirShadowSplitSpheres );
int shadowSplitIndex = EvalShadow_GetSplitSphereIndexForDirshadows( positionWS, dirShadowSplitSpheres );
if( shadowSplitIndex < 0 )
return 1.0;
ShadowData sd = shadowContext.shadowDatas[index + 1 + shadowSplitIndex];
// normal based bias
positionWS += EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L ) ), sd.texelSizeRcp.zw, sd.normalBias );
// get shadowmap texcoords
float3 posTC = EvalShadow_GetTexcoords( sd, positionWS );
// sample the texture
uint texIdx, sampIdx;
float slice;
UnpackShadowmapId( sd.id, texIdx, sampIdx, slice );
uint shadowType, shadowAlgorithm;
UnpackShadowType( sd.shadowType, shadowType, shadowAlgorithm );
return SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sd.bias, slice, shadowAlgorithm, texIdx, sampIdx );
}
#define EvalShadow_CascadedDepth_( _samplerType ) \
float EvalShadow_CascadedDepth( ShadowContext shadowContext, uint shadowAlgorithm, Texture2DArray tex, _samplerType samp, float3 positionWS, float3 normalWS, int index, float3 L ) \
{ \
/* load the right shadow data for the current face */ \
float4 dirShadowSplitSpheres[4]; \
uint payloadOffset = EvalShadow_LoadSplitSpheres( shadowContext, index, dirShadowSplitSpheres ); \
uint shadowSplitIndex = EvalShadow_GetSplitSphereIndexForDirshadows( positionWS, dirShadowSplitSpheres ); \
ShadowData sd = shadowContext.shadowDatas[index + 1 + shadowSplitIndex]; \
/* normal based bias */ \
positionWS += EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L ) ), sd.texelSizeRcp.zw, sd.normalBias ); \
/* get shadowmap texcoords */ \
float3 posTC = EvalShadow_GetTexcoords( sd, positionWS ); \
/* sample the texture */ \
float slice; \
UnpackShadowmapId( sd.id, slice ); \
\
return SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sd.bias, slice, shadowAlgorithm, tex, samp ); \
}
EvalShadow_CascadedDepth_( SamplerComparisonState )
EvalShadow_CascadedDepth_( SamplerState )
#undef EvalShadow_CascadedDepth_

9
Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowSampling.hlsl.meta


fileFormatVersion: 2
guid: 32c86a80860fd014ba44f8b7a7914a5c
timeCreated: 1487253249
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

9
Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowMoments.hlsl.meta


fileFormatVersion: 2
guid: fac04f0cf24b3844e8745273c0627fd1
timeCreated: 1488300302
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

9
Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/Resources.meta


fileFormatVersion: 2
guid: 8450f392b53a9ef45b6f93b11a8d49af
folderAsset: yes
timeCreated: 1488205057
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

/Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowAlgorithmsCustom.hlsl → /Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/ShadowAlgorithmsCustom.hlsl

/Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowBase.cs.hlsl → /Assets/ScriptableRenderPipeline/common/Shadow/ShadowBase.cs.hlsl

/Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowDispatch.hlsl → /Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/ShadowDispatch.hlsl

/Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/VectorArray.cs → /Assets/ScriptableRenderPipeline/common/Shadow/VectorArray.cs

/Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowContext.hlsl → /Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/ShadowContext.hlsl

/Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowSampling.hlsl → /Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/ShadowSampling.hlsl

/Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/Shadow.hlsl → /Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/Shadow.hlsl

/Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowBase.cs → /Assets/ScriptableRenderPipeline/common/Shadow/ShadowBase.cs

/Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowMoments.hlsl → /Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/ShadowMoments.hlsl

/Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/Resources → /Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/Resources

/Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/Shadow.cs → /Assets/ScriptableRenderPipeline/common/Shadow/Shadow.cs

正在加载...
取消
保存