Skip to content

Commit 7df8978

Browse files
# Conflicts: # Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.cs
2 parents 3600301 + 46c13e9 commit 7df8978

34 files changed

+2767
-352
lines changed

Assets/ScriptableRenderLoop/AdditionalLightData.cs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
namespace UnityEngine.Experimental.ScriptableRenderLoop
22
{
3-
//@TODO: We should continously move these values
3+
public enum LightArchetype {Punctual, Rectangle, Line};
4+
5+
//@TODO: We should continuously move these values
46
// into the engine when we can see them being generally useful
57
[RequireComponent(typeof(Light))]
68
public class AdditionalLightData : MonoBehaviour
79
{
10+
811
public const int DefaultShadowResolution = 512;
912

1013
public int shadowResolution = DefaultShadowResolution;
@@ -31,9 +34,8 @@ public float GetInnerSpotPercent01()
3134
public bool affectDiffuse = true;
3235
public bool affectSpecular = true;
3336

34-
// Area Light Hack
35-
public bool treatAsAreaLight = false;
36-
public bool isDoubleSided = false;
37+
public LightArchetype archetype = LightArchetype.Punctual;
38+
public bool isDoubleSided = false;
3739

3840
[RangeAttribute(0.0f, 20.0f)]
3941
public float areaLightLength = 0.0f;

Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.asset.meta

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.cs

Lines changed: 137 additions & 45 deletions
Large diffs are not rendered by default.

Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/LightDefinition.cs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public struct LightData
5050
public int IESIndex;
5151
public int cookieIndex;
5252

53-
public GPULightType lightType;
53+
public GPULightType lightType;
5454
// Area Light specific
5555
public Vector2 size;
5656
public bool twoSided;
@@ -69,7 +69,7 @@ public struct DirectionalLightData
6969
public float cosAngle; // Distance to disk
7070
public float sinAngle; // Disk radius
7171
public int shadowIndex;
72-
public float unsued;
72+
public float unused;
7373
};
7474

7575

@@ -88,6 +88,18 @@ public struct PunctualShadowData
8888
public float unused;
8989
};
9090

91+
[GenerateHLSL]
92+
public struct DirectionalShadowData
93+
{
94+
// World to ShadowMap matrix
95+
// Include scale and bias for shadow atlas if any
96+
public Matrix4x4 worldToShadow;
97+
98+
public float bias;
99+
public float quality;
100+
public Vector2 unused2;
101+
};
102+
91103
[GenerateHLSL]
92104
public enum EnvShapeType
93105
{

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

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ struct DirectionalLightData
6060
float cosAngle;
6161
float sinAngle;
6262
int shadowIndex;
63-
float unsued;
63+
float unused;
6464
};
6565

6666
// Generated from UnityEngine.Experimental.ScriptableRenderLoop.PunctualShadowData
@@ -74,6 +74,16 @@ struct PunctualShadowData
7474
float unused;
7575
};
7676

77+
// Generated from UnityEngine.Experimental.ScriptableRenderLoop.DirectionalShadowData
78+
// PackingRules = Exact
79+
struct DirectionalShadowData
80+
{
81+
float4x4 worldToShadow;
82+
float bias;
83+
float quality;
84+
float2 unused2;
85+
};
86+
7787
// Generated from UnityEngine.Experimental.ScriptableRenderLoop.EnvLightData
7888
// PackingRules = Exact
7989
struct EnvLightData
@@ -195,9 +205,9 @@ int GetShadowIndex(DirectionalLightData value)
195205
{
196206
return value.shadowIndex;
197207
}
198-
float GetUnsued(DirectionalLightData value)
208+
float GetUnused(DirectionalLightData value)
199209
{
200-
return value.unsued;
210+
return value.unused;
201211
}
202212

203213
//
@@ -224,6 +234,26 @@ float GetUnused(PunctualShadowData value)
224234
return value.unused;
225235
}
226236

237+
//
238+
// Accessors for UnityEngine.Experimental.ScriptableRenderLoop.DirectionalShadowData
239+
//
240+
float4x4 GetWorldToShadow(DirectionalShadowData value)
241+
{
242+
return value.worldToShadow;
243+
}
244+
float GetBias(DirectionalShadowData value)
245+
{
246+
return value.bias;
247+
}
248+
float GetQuality(DirectionalShadowData value)
249+
{
250+
return value.quality;
251+
}
252+
float2 GetUnused2(DirectionalShadowData value)
253+
{
254+
return value.unused2;
255+
}
256+
227257
//
228258
// Accessors for UnityEngine.Experimental.ScriptableRenderLoop.EnvLightData
229259
//

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

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,16 @@ string GetKeyword()
2323
static ComputeBuffer s_EnvLightList;
2424
static ComputeBuffer s_AreaLightList;
2525
static ComputeBuffer s_PunctualShadowList;
26+
static ComputeBuffer s_DirectionalShadowList;
2627

2728
void ClearComputeBuffers()
2829
{
2930
if (s_DirectionalLights != null)
3031
s_DirectionalLights.Release();
3132

33+
if (s_DirectionalShadowList != null)
34+
s_DirectionalShadowList.Release();
35+
3236
if (s_PunctualLightList != null)
3337
s_PunctualLightList.Release();
3438

@@ -47,6 +51,7 @@ public void Rebuild()
4751
ClearComputeBuffers();
4852

4953
s_DirectionalLights = new ComputeBuffer(HDRenderLoop.k_MaxDirectionalLightsOnSCreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(DirectionalLightData)));
54+
s_DirectionalShadowList = new ComputeBuffer(HDRenderLoop.k_MaxCascadeCount, System.Runtime.InteropServices.Marshal.SizeOf(typeof(DirectionalShadowData)));
5055
s_PunctualLightList = new ComputeBuffer(HDRenderLoop.k_MaxPunctualLightsOnSCreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(LightData)));
5156
s_AreaLightList = new ComputeBuffer(HDRenderLoop.k_MaxAreaLightsOnSCreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(LightData)));
5257
s_EnvLightList = new ComputeBuffer(HDRenderLoop.k_MaxEnvLightsOnSCreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(EnvLightData)));
@@ -57,6 +62,8 @@ public void OnDisable()
5762
{
5863
s_DirectionalLights.Release();
5964
s_DirectionalLights = null;
65+
s_DirectionalShadowList.Release();
66+
s_DirectionalShadowList = null;
6067
s_PunctualLightList.Release();
6168
s_PunctualLightList = null;
6269
s_AreaLightList.Release();
@@ -67,23 +74,30 @@ public void OnDisable()
6774
s_PunctualShadowList = null;
6875
}
6976

77+
public void PrepareLightsForGPU(CullResults cullResults, Camera camera, HDRenderLoop.LightList lightList) {}
78+
7079
public void PushGlobalParams(Camera camera, RenderLoop loop, HDRenderLoop.LightList lightList)
7180
{
7281
s_DirectionalLights.SetData(lightList.directionalLights.ToArray());
82+
s_DirectionalShadowList.SetData(lightList.directionalShadows.ToArray());
7383
s_PunctualLightList.SetData(lightList.punctualLights.ToArray());
7484
s_AreaLightList.SetData(lightList.areaLights.ToArray());
7585
s_EnvLightList.SetData(lightList.envLights.ToArray());
7686
s_PunctualShadowList.SetData(lightList.punctualShadows.ToArray());
7787

7888
Shader.SetGlobalBuffer("_DirectionalLightList", s_DirectionalLights);
7989
Shader.SetGlobalInt("_DirectionalLightCount", lightList.directionalLights.Count);
90+
Shader.SetGlobalBuffer("_DirectionalShadowList", s_DirectionalShadowList);
8091
Shader.SetGlobalBuffer("_PunctualLightList", s_PunctualLightList);
8192
Shader.SetGlobalInt("_PunctualLightCount", lightList.punctualLights.Count);
8293
Shader.SetGlobalBuffer("_AreaLightList", s_AreaLightList);
8394
Shader.SetGlobalInt("_AreaLightCount", lightList.areaLights.Count);
8495
Shader.SetGlobalBuffer("_PunctualShadowList", s_PunctualShadowList);
8596
Shader.SetGlobalBuffer("_EnvLightList", s_EnvLightList);
86-
Shader.SetGlobalInt("_EnvLightCount", lightList.envLights.Count);
97+
Shader.SetGlobalInt("_EnvLightCount", lightList.envLights.Count);
98+
99+
Shader.SetGlobalVectorArray("_DirShadowSplitSpheres", lightList.directionalShadowSplitSphereSqr);
100+
87101
}
88102
}
89103
}

Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/SinglePass/SinglePass.hlsl

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,11 @@
99

1010

1111
StructuredBuffer<DirectionalLightData> _DirectionalLightList;
12+
StructuredBuffer<DirectionalShadowData> _DirectionalShadowList;
1213
StructuredBuffer<LightData> _PunctualLightList;
14+
StructuredBuffer<PunctualShadowData> _PunctualShadowList;
1315
StructuredBuffer<LightData> _AreaLightList;
1416
StructuredBuffer<EnvLightData> _EnvLightList;
15-
StructuredBuffer<PunctualShadowData> _PunctualShadowList;
1617

1718
//TEXTURE2D_ARRAY(_ShadowArray);
1819
//SAMPLER2D_SHADOW(sampler_ShadowArray);
@@ -43,6 +44,7 @@ CBUFFER_START(UnityPerLightLoop)
4344
int _EnvLightCount;
4445
EnvLightData _EnvLightSky;
4546
float4 _ShadowMapSize;
47+
float4 _DirShadowSplitSpheres[4]; // TODO share this max between C# and hlsl
4648
CBUFFER_END
4749

4850
struct LightLoopContext
@@ -84,6 +86,51 @@ float GetPunctualShadowAttenuation(LightLoopContext lightLoopContext, float3 pos
8486
return SAMPLE_TEXTURE2D_SHADOW(g_tShadowBuffer, samplerg_tShadowBuffer, positionTXS);
8587
}
8688

89+
// Gets the cascade weights based on the world position of the fragment and the positions of the split spheres for each cascade.
90+
// Returns an invalid split index if past shadowDistance (ie 4 is invalid for cascade)
91+
uint GetSplitSphereIndexForDirshadows(float3 positionWS, float4 dirShadowSplitSpheres[4])
92+
{
93+
float3 fromCenter0 = positionWS.xyz - dirShadowSplitSpheres[0].xyz;
94+
float3 fromCenter1 = positionWS.xyz - dirShadowSplitSpheres[1].xyz;
95+
float3 fromCenter2 = positionWS.xyz - dirShadowSplitSpheres[2].xyz;
96+
float3 fromCenter3 = positionWS.xyz - dirShadowSplitSpheres[3].xyz;
97+
float4 distances2 = float4(dot(fromCenter0, fromCenter0), dot(fromCenter1, fromCenter1), dot(fromCenter2, fromCenter2), dot(fromCenter3, fromCenter3));
98+
99+
float4 dirShadowSplitSphereSqRadii;
100+
dirShadowSplitSphereSqRadii.x = dirShadowSplitSpheres[0].w;
101+
dirShadowSplitSphereSqRadii.y = dirShadowSplitSpheres[1].w;
102+
dirShadowSplitSphereSqRadii.z = dirShadowSplitSpheres[2].w;
103+
dirShadowSplitSphereSqRadii.w = dirShadowSplitSpheres[3].w;
104+
105+
float4 weights = float4(distances2 < dirShadowSplitSphereSqRadii);
106+
weights.yzw = saturate(weights.yzw - weights.xyz);
107+
108+
return uint(4.0 - dot(weights, float4(4.0, 3.0, 2.0, 1.0)));
109+
}
110+
111+
float GetDirectionalShadowAttenuation(LightLoopContext lightLoopContext, float3 positionWS, int index, float3 L, float2 unPositionSS)
112+
{
113+
// Note Index is 0 for now, but else we need to provide the correct index in _DirShadowSplitSpheres and _DirectionalShadowList
114+
uint shadowSplitIndex = GetSplitSphereIndexForDirshadows(positionWS, _DirShadowSplitSpheres);
115+
116+
DirectionalShadowData shadowData = _DirectionalShadowList[shadowSplitIndex];
117+
118+
// Note: scale and bias of shadow atlas are included in ShadowTransform but could be apply here.
119+
float4 positionTXS = mul(float4(positionWS, 1.0), shadowData.worldToShadow);
120+
positionTXS.xyz /= positionTXS.w;
121+
// positionTXS.z -= shadowData.bias; // Apply a linear bias
122+
positionTXS.z -= 0.003;
123+
124+
#if UNITY_REVERSED_Z
125+
positionTXS.z = 1.0 - positionTXS.z;
126+
#endif
127+
128+
// float3 shadowPosDX = ddx_fine(positionTXS);
129+
// float3 shadowPosDY = ddy_fine(positionTXS);
130+
131+
return SAMPLE_TEXTURE2D_SHADOW(g_tShadowBuffer, samplerg_tShadowBuffer, positionTXS);
132+
}
133+
87134
//-----------------------------------------------------------------------------
88135
// IES sampling function
89136
// ----------------------------------------------------------------------------
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
#ifndef __CLUSTEREDUTILS_H__
2+
#define __CLUSTEREDUTILS_H__
3+
4+
#ifndef FLT_EPSILON
5+
#define FLT_EPSILON 1.192092896e-07f
6+
#endif
7+
8+
float GetScaleFromBase(float base)
9+
{
10+
const float C = (float)(1 << g_iLog2NumClusters);
11+
const float geomSeries = (1.0 - pow(base, C)) / (1 - base); // geometric series: sum_k=0^{C-1} base^k
12+
return geomSeries / (g_fFarPlane - g_fNearPlane);
13+
}
14+
15+
int SnapToClusterIdxFlex(float z_in, float suggestedBase, bool logBasePerTile)
16+
{
17+
#if USE_LEFTHAND_CAMERASPACE
18+
float z = z_in;
19+
#else
20+
float z = -z_in;
21+
#endif
22+
23+
float userscale = g_fClustScale;
24+
if (logBasePerTile)
25+
userscale = GetScaleFromBase(suggestedBase);
26+
27+
// using the inverse of the geometric series
28+
const float dist = max(0, z - g_fNearPlane);
29+
return (int)clamp(log2(dist * userscale * (suggestedBase - 1.0f) + 1) / log2(suggestedBase), 0.0, (float)((1 << g_iLog2NumClusters) - 1));
30+
}
31+
32+
int SnapToClusterIdx(float z_in, float suggestedBase)
33+
{
34+
#ifdef ENABLE_DEPTH_TEXTURE_BACKPLANE
35+
bool logBasePerTile = true; // resolved compile time
36+
#else
37+
bool logBasePerTile = false;
38+
#endif
39+
40+
return SnapToClusterIdxFlex(z_in, suggestedBase, logBasePerTile);
41+
}
42+
43+
float ClusterIdxToZFlex(int k, float suggestedBase, bool logBasePerTile)
44+
{
45+
float res;
46+
47+
float userscale = g_fClustScale;
48+
if (logBasePerTile)
49+
userscale = GetScaleFromBase(suggestedBase);
50+
51+
float dist = (pow(suggestedBase, (float)k) - 1.0) / (userscale * (suggestedBase - 1.0f));
52+
res = dist + g_fNearPlane;
53+
54+
#if USE_LEFTHAND_CAMERASPACE
55+
return res;
56+
#else
57+
return -res;
58+
#endif
59+
}
60+
61+
float ClusterIdxToZ(int k, float suggestedBase)
62+
{
63+
#ifdef ENABLE_DEPTH_TEXTURE_BACKPLANE
64+
bool logBasePerTile = true; // resolved compile time
65+
#else
66+
bool logBasePerTile = false;
67+
#endif
68+
69+
return ClusterIdxToZFlex(k, suggestedBase, logBasePerTile);
70+
}
71+
72+
// generate a log-base value such that half of the clusters are consumed from near plane to max. opaque depth of tile.
73+
float SuggestLogBase50(float tileFarPlane)
74+
{
75+
const float C = (float)(1 << g_iLog2NumClusters);
76+
float normDist = clamp((tileFarPlane - g_fNearPlane) / (g_fFarPlane - g_fNearPlane), FLT_EPSILON, 1.0);
77+
float suggested_base = pow((1.0 + sqrt(max(0.0, 1.0 - 4.0 * normDist * (1.0 - normDist)))) / (2.0 * normDist), 2.0 / C); //
78+
return max(g_fClustBase, suggested_base);
79+
}
80+
81+
// generate a log-base value such that (approximately) a quarter of the clusters are consumed from near plane to max. opaque depth of tile.
82+
float SuggestLogBase25(float tileFarPlane)
83+
{
84+
const float C = (float)(1 << g_iLog2NumClusters);
85+
float normDist = clamp((tileFarPlane - g_fNearPlane) / (g_fFarPlane - g_fNearPlane), FLT_EPSILON, 1.0);
86+
float suggested_base = pow((1 / 2.3) * max(0.0, (0.8 / normDist) - 1), 4.0 / (C * 2)); // approximate inverse of d*x^4 + (-x) + (1-d) = 0 - d is normalized distance
87+
return max(g_fClustBase, suggested_base);
88+
}
89+
90+
#endif

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

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)