浏览代码

Added spot light shadow support.

/vr_sandbox
Felipe Lira 8 年前
当前提交
820537f9
共有 4 个文件被更改,包括 67 次插入36 次删除
  1. 9
      Assets/LowEndMobilePipeline/Editor/LegacyShadersToLowEndUpgrader.cs
  2. 67
      Assets/LowEndMobilePipeline/LowEndMobilePipeline.cs
  3. 2
      Assets/LowEndMobilePipeline/Shaders/LowEndMobilePipeline.shader
  4. 25
      Assets/LowEndMobilePipeline/Shaders/LowEndMobilePipelineCore.cginc

9
Assets/LowEndMobilePipeline/Editor/LegacyShadersToLowEndUpgrader.cs


reflectionSource = (float)LowendMobilePipelineMaterialEditor.ReflectionSource.Cubemap
};
static public UpgradeParams diffuseCubemapAlpha = new UpgradeParams()
{
blendMode = (float)LowendMobilePipelineMaterialEditor.BlendMode.Alpha,
specularSource = (float)LowendMobilePipelineMaterialEditor.SpecularSource.NoSpecular,
glosinessSource = (float)LowendMobilePipelineMaterialEditor.GlossinessSource.BaseAlpha,
reflectionSource = (float)LowendMobilePipelineMaterialEditor.ReflectionSource.Cubemap
};
static public UpgradeParams specularCubemapAlpha = new UpgradeParams()
{
blendMode = (float)LowendMobilePipelineMaterialEditor.BlendMode.Alpha,

/////////////////////////////////////
// Reflective Shader Upgraders /
/////////////////////////////////////
materialUpgraders.Add(new LegacyBlinnPhongUpgrader("Reflective/Diffuse Transperant", SupportedUpgradeParams.diffuseCubemapAlpha));
materialUpgraders.Add(new LegacyBlinnPhongUpgrader("Reflective/Diffuse Reflection Spec", SupportedUpgradeParams.specularCubemap));
materialUpgraders.Add(new LegacyBlinnPhongUpgrader("Reflective/Diffuse Reflection Spec Transp", SupportedUpgradeParams.specularCubemapAlpha));

67
Assets/LowEndMobilePipeline/LowEndMobilePipeline.cs


}
}
#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
}
}

2
Assets/LowEndMobilePipeline/Shaders/LowEndMobilePipeline.shader


#endif
#ifndef _SHADOW_CASCADES
o.shadowCoord = mul(_WorldToShadow[0], float4(o.posWS, 1.0)).xyz;
o.shadowCoord = mul(_WorldToShadow[0], float4(o.posWS, 1.0));
#endif
#ifndef LIGHTMAP_ON

25
Assets/LowEndMobilePipeline/Shaders/LowEndMobilePipelineCore.cginc


half4 viewDir : TEXCOORD5; // xyz: viewDir
UNITY_FOG_COORDS_PACKED(6, half4) // x: fogCoord, yzw: vertexColor
#ifndef _SHADOW_CASCADES
float3 shadowCoord : TEXCOORD7;
float4 shadowCoord : TEXCOORD7;
#endif
float4 hpos : SV_POSITION;
};

return 4 - dot(weights, fixed4(4, 3, 2, 1));
}
inline half ShadowAttenuation(half2 shadowCoord, half shadowCoordDepth)
inline half ShadowAttenuation(half3 shadowCoord)
{
if (shadowCoord.x <= 0 || shadowCoord.x >= 1 || shadowCoord.y <= 0 || shadowCoord.y >= 1)
return 1;

return step(depth, shadowCoordDepth);
return step(depth, shadowCoord.z);
return step(shadowCoordDepth, depth);
return step(shadowCoord.z, depth);
#endif
}

half2 offset = half2(0, 0);
half attenuation = ShadowAttenuation(shadowCoord.xy + half2(_PCFKernel[0], _PCFKernel[1]) + offset, shadowCoord.z) +
ShadowAttenuation(shadowCoord.xy + half2(_PCFKernel[2], _PCFKernel[3]) + offset, shadowCoord.z) +
ShadowAttenuation(shadowCoord.xy + half2(_PCFKernel[4], _PCFKernel[5]) + offset, shadowCoord.z) +
ShadowAttenuation(shadowCoord.xy + half2(_PCFKernel[6], _PCFKernel[7]) + offset, shadowCoord.z);
half attenuation = ShadowAttenuation(half3(shadowCoord.xy + half2(_PCFKernel[0], _PCFKernel[1]) + offset, shadowCoord.z)) +
ShadowAttenuation(half3(shadowCoord.xy + half2(_PCFKernel[2], _PCFKernel[3]) + offset, shadowCoord.z)) +
ShadowAttenuation(half3(shadowCoord.xy + half2(_PCFKernel[4], _PCFKernel[5]) + offset, shadowCoord.z)) +
ShadowAttenuation(half3(shadowCoord.xy + half2(_PCFKernel[6], _PCFKernel[7]) + offset, shadowCoord.z));
return attenuation * 0.25;
}

inline half ComputeShadowAttenuation(v2f i)
{
half3 shadowCoord;
half4 shadowCoord;
shadowCoord = mul(_WorldToShadow[cascadeIndex], half4(i.posWS, 1.0)).xyz;
shadowCoord = mul(_WorldToShadow[cascadeIndex], half4(i.posWS, 1.0));
shadowCoord.xyz /= shadowCoord.w;
return ShadowPCF(shadowCoord);
return ShadowPCF(shadowCoord.xyz);
return ShadowAttenuation(shadowCoord.xy, shadowCoord.z);
return ShadowAttenuation(shadowCoord.xyz);
#endif
}
正在加载...
取消
保存