Skip to content

Commit f4df5c2

Browse files
committed
Added spot light shadow support.
1 parent b1ba628 commit f4df5c2

4 files changed

Lines changed: 67 additions & 36 deletions

File tree

Assets/LowEndMobilePipeline/Editor/LegacyShadersToLowEndUpgrader.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,14 @@ private static class SupportedUpgradeParams
7070
reflectionSource = (float)LowendMobilePipelineMaterialEditor.ReflectionSource.Cubemap
7171
};
7272

73+
static public UpgradeParams diffuseCubemapAlpha = new UpgradeParams()
74+
{
75+
blendMode = (float)LowendMobilePipelineMaterialEditor.BlendMode.Alpha,
76+
specularSource = (float)LowendMobilePipelineMaterialEditor.SpecularSource.NoSpecular,
77+
glosinessSource = (float)LowendMobilePipelineMaterialEditor.GlossinessSource.BaseAlpha,
78+
reflectionSource = (float)LowendMobilePipelineMaterialEditor.ReflectionSource.Cubemap
79+
};
80+
7381
static public UpgradeParams specularCubemapAlpha = new UpgradeParams()
7482
{
7583
blendMode = (float)LowendMobilePipelineMaterialEditor.BlendMode.Alpha,
@@ -135,6 +143,7 @@ private static void GetUpgraders(ref List<MaterialUpgrader> materialUpgraders)
135143
/////////////////////////////////////
136144
// Reflective Shader Upgraders /
137145
/////////////////////////////////////
146+
materialUpgraders.Add(new LegacyBlinnPhongUpgrader("Reflective/Diffuse Transperant", SupportedUpgradeParams.diffuseCubemapAlpha));
138147
materialUpgraders.Add(new LegacyBlinnPhongUpgrader("Reflective/Diffuse Reflection Spec", SupportedUpgradeParams.specularCubemap));
139148
materialUpgraders.Add(new LegacyBlinnPhongUpgrader("Reflective/Diffuse Reflection Spec Transp", SupportedUpgradeParams.specularCubemapAlpha));
140149

Assets/LowEndMobilePipeline/LowEndMobilePipeline.cs

Lines changed: 44 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,6 @@ private void BuildShadowSettings()
123123
}
124124
}
125125

126-
#region HelperMethods
127-
128126
private void SetupLightShaderVariables(VisibleLight[] lights, ScriptableRenderContext context)
129127
{
130128
if (lights.Length <= 0)
@@ -196,9 +194,13 @@ private bool RenderShadows(CullResults cullResults, ScriptableRenderContext cont
196194
int lightIndex = -1;
197195
for (int i = 0; i < lightCount; ++i)
198196
{
199-
if (lights[i].light.shadows != LightShadows.None && lights[i].lightType == LightType.Directional)
197+
LightType type = lights[i].lightType;
198+
if (lights[i].light.shadows != LightShadows.None && (type == LightType.Directional || type == LightType.Spot))
200199
{
201200
lightIndex = i;
201+
if (lights[i].lightType == LightType.Spot)
202+
cascadeCount = 1;
203+
202204
shadowResolution = GetMaxTileResolutionInAtlas(m_ShadowSettings.shadowAtlasWidth,
203205
m_ShadowSettings.shadowAtlasHeight, cascadeCount);
204206
break;
@@ -224,24 +226,45 @@ private bool RenderShadows(CullResults cullResults, ScriptableRenderContext cont
224226

225227
float shadowNearPlane = m_Asset.ShadowNearOffset;
226228
Vector3 splitRatio = m_ShadowSettings.directionalLightCascades;
227-
Vector3 lightDir = lights[lightIndex].light.transform.forward;
228-
for (int cascadeIdx = 0; cascadeIdx < cascadeCount; ++cascadeIdx)
229-
{
230-
Matrix4x4 view, proj;
231-
var settings = new DrawShadowsSettings(cullResults, lightIndex);
232-
bool needRendering = cullResults.ComputeDirectionalShadowMatricesAndCullingPrimitives(lightIndex,
233-
cascadeIdx, cascadeCount, splitRatio, shadowResolution, shadowNearPlane, out view, out proj,
234-
out settings.splitData);
229+
Vector3 lightDir = Vector3.Normalize(lights[lightIndex].light.transform.forward);
235230

236-
m_DirectionalShadowSplitDistances[cascadeIdx] = settings.splitData.cullingSphere;
237-
m_DirectionalShadowSplitDistances[cascadeIdx].w *= settings.splitData.cullingSphere.w;
231+
Matrix4x4 view, proj;
232+
var settings = new DrawShadowsSettings(cullResults, lightIndex);
233+
bool needRendering = false;
234+
235+
if (lights[lightIndex].lightType == LightType.Spot)
236+
{
237+
needRendering = cullResults.ComputeSpotShadowMatricesAndCullingPrimitives(lightIndex, out view, out proj,
238+
out settings.splitData);
238239

239240
if (needRendering)
240241
{
241-
SetupShadowSliceTransform(cascadeIdx, shadowResolution, proj, view);
242-
RenderShadowSlice(ref context, lightDir, cascadeIdx, proj, view, settings);
242+
SetupShadowSliceTransform(0, shadowResolution, proj, view);
243+
RenderShadowSlice(ref context, lightDir, 0, proj, view, settings);
244+
}
245+
}
246+
else if (lights[lightIndex].lightType == LightType.Directional)
247+
{
248+
for (int cascadeIdx = 0; cascadeIdx < cascadeCount; ++cascadeIdx)
249+
{
250+
needRendering = cullResults.ComputeDirectionalShadowMatricesAndCullingPrimitives(lightIndex,
251+
cascadeIdx, cascadeCount, splitRatio, shadowResolution, shadowNearPlane, out view, out proj,
252+
out settings.splitData);
253+
254+
m_DirectionalShadowSplitDistances[cascadeIdx] = settings.splitData.cullingSphere;
255+
m_DirectionalShadowSplitDistances[cascadeIdx].w *= settings.splitData.cullingSphere.w;
256+
257+
if (needRendering)
258+
{
259+
SetupShadowSliceTransform(cascadeIdx, shadowResolution, proj, view);
260+
RenderShadowSlice(ref context, lightDir, cascadeIdx, proj, view, settings);
261+
}
243262
}
244263
}
264+
else
265+
{
266+
Debug.LogWarning("Only spot and directional shadow casters are supported in lowend mobile pipeline");
267+
}
245268

246269
return true;
247270
}
@@ -343,15 +366,15 @@ void SetupShadowShaderVariables(ScriptableRenderContext context, int cascadeCoun
343366

344367
void SetShaderKeywords(CommandBuffer cmd)
345368
{
346-
if (m_Asset.SupportsVertexLight)
347-
cmd.EnableShaderKeyword("_VERTEX_LIGHTS");
348-
else
349-
cmd.DisableShaderKeyword("_VERTEX_LIGHTS");
369+
if (m_Asset.SupportsVertexLight)
370+
cmd.EnableShaderKeyword("_VERTEX_LIGHTS");
371+
else
372+
cmd.DisableShaderKeyword("_VERTEX_LIGHTS");
350373

351374
if (m_Asset.CascadeCount == 1)
352-
cmd.DisableShaderKeyword("_SHADOW_CASCADES");
375+
cmd.DisableShaderKeyword("_SHADOW_CASCADES");
353376
else
354-
cmd.EnableShaderKeyword("_SHADOW_CASCADES");
377+
cmd.EnableShaderKeyword("_SHADOW_CASCADES");
355378

356379
switch (m_Asset.CurrShadowType)
357380
{
@@ -371,7 +394,5 @@ void SetShaderKeywords(CommandBuffer cmd)
371394
break;
372395
}
373396
}
374-
375-
#endregion
376397
}
377398
}

Assets/LowEndMobilePipeline/Shaders/LowEndMobilePipeline.shader

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ Shader "ScriptableRenderPipeline/LowEndMobile/NonPBR"
126126
#endif
127127

128128
#ifndef _SHADOW_CASCADES
129-
o.shadowCoord = mul(_WorldToShadow[0], float4(o.posWS, 1.0)).xyz;
129+
o.shadowCoord = mul(_WorldToShadow[0], float4(o.posWS, 1.0));
130130
#endif
131131

132132
#ifndef LIGHTMAP_ON

Assets/LowEndMobilePipeline/Shaders/LowEndMobilePipelineCore.cginc

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ struct v2f
3939
half4 viewDir : TEXCOORD5; // xyz: viewDir
4040
UNITY_FOG_COORDS_PACKED(6, half4) // x: fogCoord, yzw: vertexColor
4141
#ifndef _SHADOW_CASCADES
42-
float3 shadowCoord : TEXCOORD7;
42+
float4 shadowCoord : TEXCOORD7;
4343
#endif
4444
float4 hpos : SV_POSITION;
4545
};
@@ -150,27 +150,27 @@ inline half ComputeCascadeIndex(float3 wpos)
150150
return 4 - dot(weights, fixed4(4, 3, 2, 1));
151151
}
152152

153-
inline half ShadowAttenuation(half2 shadowCoord, half shadowCoordDepth)
153+
inline half ShadowAttenuation(half3 shadowCoord)
154154
{
155155
if (shadowCoord.x <= 0 || shadowCoord.x >= 1 || shadowCoord.y <= 0 || shadowCoord.y >= 1)
156156
return 1;
157157

158158
half depth = tex2D(_ShadowMap, shadowCoord).r;
159159
#if defined(UNITY_REVERSED_Z)
160-
return step(depth, shadowCoordDepth);
160+
return step(depth, shadowCoord.z);
161161
#else
162-
return step(shadowCoordDepth, depth);
162+
return step(shadowCoord.z, depth);
163163
#endif
164164
}
165165

166166
inline half ShadowPCF(half3 shadowCoord)
167167
{
168168
// TODO: simulate textureGatherOffset not available, simulate it
169169
half2 offset = half2(0, 0);
170-
half attenuation = ShadowAttenuation(shadowCoord.xy + half2(_PCFKernel[0], _PCFKernel[1]) + offset, shadowCoord.z) +
171-
ShadowAttenuation(shadowCoord.xy + half2(_PCFKernel[2], _PCFKernel[3]) + offset, shadowCoord.z) +
172-
ShadowAttenuation(shadowCoord.xy + half2(_PCFKernel[4], _PCFKernel[5]) + offset, shadowCoord.z) +
173-
ShadowAttenuation(shadowCoord.xy + half2(_PCFKernel[6], _PCFKernel[7]) + offset, shadowCoord.z);
170+
half attenuation = ShadowAttenuation(half3(shadowCoord.xy + half2(_PCFKernel[0], _PCFKernel[1]) + offset, shadowCoord.z)) +
171+
ShadowAttenuation(half3(shadowCoord.xy + half2(_PCFKernel[2], _PCFKernel[3]) + offset, shadowCoord.z)) +
172+
ShadowAttenuation(half3(shadowCoord.xy + half2(_PCFKernel[4], _PCFKernel[5]) + offset, shadowCoord.z)) +
173+
ShadowAttenuation(half3(shadowCoord.xy + half2(_PCFKernel[6], _PCFKernel[7]) + offset, shadowCoord.z));
174174
return attenuation * 0.25;
175175
}
176176

@@ -207,22 +207,23 @@ inline half3 EvaluateOneLight(LightInput lightInput, half3 diffuseColor, half4 s
207207

208208
inline half ComputeShadowAttenuation(v2f i)
209209
{
210-
half3 shadowCoord;
210+
half4 shadowCoord;
211211
#ifndef _SHADOW_CASCADES
212212
shadowCoord = i.shadowCoord;
213213
#else
214214
int cascadeIndex = ComputeCascadeIndex(i.posWS);
215215
if (cascadeIndex < 4)
216-
shadowCoord = mul(_WorldToShadow[cascadeIndex], half4(i.posWS, 1.0)).xyz;
216+
shadowCoord = mul(_WorldToShadow[cascadeIndex], half4(i.posWS, 1.0));
217217
else
218218
return 1.0;
219219
#endif
220220

221+
shadowCoord.xyz /= shadowCoord.w;
221222
shadowCoord.z = saturate(shadowCoord.z);
222223

223224
#ifdef SOFT_SHADOWS
224-
return ShadowPCF(shadowCoord);
225+
return ShadowPCF(shadowCoord.xyz);
225226
#else
226-
return ShadowAttenuation(shadowCoord.xy, shadowCoord.z);
227+
return ShadowAttenuation(shadowCoord.xyz);
227228
#endif
228229
}

0 commit comments

Comments
 (0)