|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
#region HelperMethods
|
|
|
|
|
|
|
|
private void SetupLightShaderVariables(VisibleLight[] lights, ScriptableRenderContext context) |
|
|
|
{ |
|
|
|
if (lights.Length <= 0) |
|
|
|
|
|
|
int lightIndex = -1; |
|
|
|
for (int i = 0; i < lightCount; ++i) |
|
|
|
{ |
|
|
|
if (lights[i].light.shadows != LightShadows.None && lights[i].lightType == LightType.Directional) |
|
|
|
LightType type = lights[i].lightType; |
|
|
|
if (lights[i].light.shadows != LightShadows.None && (type == LightType.Directional || type == LightType.Spot)) |
|
|
|
if (lights[i].lightType == LightType.Spot) |
|
|
|
cascadeCount = 1; |
|
|
|
|
|
|
|
shadowResolution = GetMaxTileResolutionInAtlas(m_ShadowSettings.shadowAtlasWidth, |
|
|
|
m_ShadowSettings.shadowAtlasHeight, cascadeCount); |
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
float shadowNearPlane = m_Asset.ShadowNearOffset; |
|
|
|
Vector3 splitRatio = m_ShadowSettings.directionalLightCascades; |
|
|
|
Vector3 lightDir = lights[lightIndex].light.transform.forward; |
|
|
|
for (int cascadeIdx = 0; cascadeIdx < cascadeCount; ++cascadeIdx) |
|
|
|
Vector3 lightDir = Vector3.Normalize(lights[lightIndex].light.transform.forward); |
|
|
|
|
|
|
|
Matrix4x4 view, proj; |
|
|
|
var settings = new DrawShadowsSettings(cullResults, lightIndex); |
|
|
|
bool needRendering = false; |
|
|
|
|
|
|
|
if (lights[lightIndex].lightType == LightType.Spot) |
|
|
|
Matrix4x4 view, proj; |
|
|
|
var settings = new DrawShadowsSettings(cullResults, lightIndex); |
|
|
|
bool needRendering = cullResults.ComputeDirectionalShadowMatricesAndCullingPrimitives(lightIndex, |
|
|
|
needRendering = cullResults.ComputeSpotShadowMatricesAndCullingPrimitives(lightIndex, out view, out proj, |
|
|
|
out settings.splitData); |
|
|
|
|
|
|
|
if (needRendering) |
|
|
|
{ |
|
|
|
SetupShadowSliceTransform(0, shadowResolution, proj, view); |
|
|
|
RenderShadowSlice(ref context, lightDir, 0, proj, view, settings); |
|
|
|
} |
|
|
|
} |
|
|
|
else if (lights[lightIndex].lightType == LightType.Directional) |
|
|
|
{ |
|
|
|
for (int cascadeIdx = 0; cascadeIdx < cascadeCount; ++cascadeIdx) |
|
|
|
{ |
|
|
|
needRendering = cullResults.ComputeDirectionalShadowMatricesAndCullingPrimitives(lightIndex, |
|
|
|
out settings.splitData); |
|
|
|
out settings.splitData); |
|
|
|
m_DirectionalShadowSplitDistances[cascadeIdx] = settings.splitData.cullingSphere; |
|
|
|
m_DirectionalShadowSplitDistances[cascadeIdx].w *= settings.splitData.cullingSphere.w; |
|
|
|
m_DirectionalShadowSplitDistances[cascadeIdx] = settings.splitData.cullingSphere; |
|
|
|
m_DirectionalShadowSplitDistances[cascadeIdx].w *= settings.splitData.cullingSphere.w; |
|
|
|
if (needRendering) |
|
|
|
{ |
|
|
|
SetupShadowSliceTransform(cascadeIdx, shadowResolution, proj, view); |
|
|
|
RenderShadowSlice(ref context, lightDir, cascadeIdx, proj, view, settings); |
|
|
|
if (needRendering) |
|
|
|
{ |
|
|
|
SetupShadowSliceTransform(cascadeIdx, shadowResolution, proj, view); |
|
|
|
RenderShadowSlice(ref context, lightDir, cascadeIdx, proj, view, settings); |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
Debug.LogWarning("Only spot and directional shadow casters are supported in lowend mobile pipeline"); |
|
|
|
} |
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
|
|
|
void SetShaderKeywords(CommandBuffer cmd) |
|
|
|
{ |
|
|
|
if (m_Asset.SupportsVertexLight) |
|
|
|
cmd.EnableShaderKeyword("_VERTEX_LIGHTS"); |
|
|
|
else |
|
|
|
cmd.DisableShaderKeyword("_VERTEX_LIGHTS"); |
|
|
|
if (m_Asset.SupportsVertexLight) |
|
|
|
cmd.EnableShaderKeyword("_VERTEX_LIGHTS"); |
|
|
|
else |
|
|
|
cmd.DisableShaderKeyword("_VERTEX_LIGHTS"); |
|
|
|
cmd.DisableShaderKeyword("_SHADOW_CASCADES"); |
|
|
|
cmd.DisableShaderKeyword("_SHADOW_CASCADES"); |
|
|
|
cmd.EnableShaderKeyword("_SHADOW_CASCADES"); |
|
|
|
cmd.EnableShaderKeyword("_SHADOW_CASCADES"); |
|
|
|
|
|
|
|
switch (m_Asset.CurrShadowType) |
|
|
|
{ |
|
|
|
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
#endregion
|
|
|
|
} |
|
|
|
} |