浏览代码

Optimized shader path for single directional light.

/RenderPassXR_Sandbox
Felipe Lira 7 年前
当前提交
578640d3
共有 3 个文件被更改,包括 82 次插入50 次删除
  1. 92
      Assets/ScriptableRenderPipeline/LightweightPipeline/LightweightPipeline.cs
  2. 6
      Assets/ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightPipeline.shader
  3. 34
      Assets/ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightPipelineCore.cginc

92
Assets/ScriptableRenderPipeline/LightweightPipeline/LightweightPipeline.cs


cmd.Dispose();
// Setup light and shadow shader constants
SetupLightShaderVariables(visibleLights, ref cullResults, ref context, ref lightData);
SetupShaderLightConstants(visibleLights, ref cullResults, ref context, ref lightData);
if (shadowsRendered)
SetupShadowShaderVariables(ref context, m_ShadowCasterCascadesCount);

cullResults.FillLightIndices(m_LightIndexListBuffer);
}
private void SetupLightShaderVariables(VisibleLight[] lights, ref CullResults cullResults, ref ScriptableRenderContext context, ref LightData lightData)
private void SetupShaderLightConstants(VisibleLight[] lights, ref CullResults cullResults, ref ScriptableRenderContext context, ref LightData lightData)
{
if (lightData.isSingleDirectionalLight)
SetupShaderSingleDirectionalLightConstants(ref lights [0], ref context);
else
SetupShaderLightListConstants(lights, ref cullResults, ref context);
CommandBuffer cmd = new CommandBuffer() { name = "SetShaderKeywords" };
SetShaderKeywords(cmd, lightData.isSingleDirectionalLight, lightData.vertexLightsCount > 0);
cmd.SetGlobalVector("globalLightData", new Vector4(lightData.pixelLightsCount, m_ShadowLightIndex, m_Asset.ShadowMinNormalBias, m_Asset.ShadowNormalBias));
context.ExecuteCommandBuffer(cmd);
cmd.Dispose();
}
private void SetupShaderSingleDirectionalLightConstants(ref VisibleLight light, ref ScriptableRenderContext context)
{
Vector4 lightDir = -light.localToWorld.GetColumn(2);
CommandBuffer cmd = new CommandBuffer() { name = "SetupLightConstants" };
cmd.SetGlobalVector("_LightPosition0", new Vector4(lightDir.x, lightDir.y, lightDir.z, 0.0f));
cmd.SetGlobalColor("_LightColor0", light.finalColor);
context.ExecuteCommandBuffer(cmd);
cmd.Dispose();
}
// TODO: Perform tests on light lights memory pattern access (SOA vs AOS vs Swizzling)
private void SetupShaderLightListConstants(VisibleLight[] lights, ref CullResults cullResults, ref ScriptableRenderContext context)
int maxLights = 1;
if (!lightData.isSingleDirectionalLight)
{
FillLightIndices(ref cullResults, lights.Length);
maxLights = Math.Min(kMaxVisibleLights, lights.Length);
}
FillLightIndices(ref cullResults, lights.Length);
int maxLights = Math.Min(kMaxVisibleLights, lights.Length);
for (int i = 0; i < maxLights; ++i)
for (int i = 0; i < maxLights; ++i)
VisibleLight currLight = lights[i];
if (currLight.lightType == LightType.Directional)
VisibleLight currLight = lights [i];
if (currLight.lightType == LightType.Directional)
Vector4 dir = -currLight.localToWorld.GetColumn(2);
m_LightPositions[i] = new Vector4(dir.x, dir.y, dir.z, 0.0f);
}
else
Vector4 dir = -currLight.localToWorld.GetColumn (2);
m_LightPositions [i] = new Vector4 (dir.x, dir.y, dir.z, 0.0f);
}
else
Vector4 pos = currLight.localToWorld.GetColumn(3);
m_LightPositions[i] = new Vector4(pos.x, pos.y, pos.z, 1.0f);
Vector4 pos = currLight.localToWorld.GetColumn (3);
m_LightPositions [i] = new Vector4 (pos.x, pos.y, pos.z, 1.0f);
}
m_LightColors[i] = currLight.finalColor;

if (currLight.lightType == LightType.Spot)
if (currLight.lightType == LightType.Spot)
Vector4 dir = currLight.localToWorld.GetColumn(2);
m_LightSpotDirections[i] = new Vector4(-dir.x, -dir.y, -dir.z, 0.0f);
Vector4 dir = currLight.localToWorld.GetColumn (2);
m_LightSpotDirections [i] = new Vector4 (-dir.x, -dir.y, -dir.z, 0.0f);
float cosOuterAngle = Mathf.Cos(spotAngle * 0.5f);
float cosInneAngle = Mathf.Cos(spotAngle * 0.25f);
float cosOuterAngle = Mathf.Cos (spotAngle * 0.5f);
float cosInneAngle = Mathf.Cos (spotAngle * 0.25f);
m_LightAttenuations[i] = new Vector4(cosOuterAngle,
Mathf.Approximately(angleRange, 0.0f) ? 1.0f : angleRange, quadAtten, rangeSq);
}
m_LightAttenuations [i] = new Vector4 (cosOuterAngle,
Mathf.Approximately (angleRange, 0.0f) ? 1.0f : angleRange, quadAtten, rangeSq);
}
m_LightSpotDirections[i] = new Vector4(0.0f, 0.0f, 1.0f, 0.0f) ;
m_LightAttenuations[i] = new Vector4(-1.0f, 1.0f, quadAtten, rangeSq);
m_LightSpotDirections [i] = new Vector4 (0.0f, 0.0f, 1.0f, 0.0f);
m_LightAttenuations [i] = new Vector4 (-1.0f, 1.0f, quadAtten, rangeSq);
CommandBuffer cmd = new CommandBuffer() {name = "SetupShadowShaderConstants"};
cmd.SetGlobalVectorArray("globalLightPos", m_LightPositions);
cmd.SetGlobalVectorArray("globalLightColor", m_LightColors);
cmd.SetGlobalVectorArray("globalLightAtten", m_LightAttenuations);
cmd.SetGlobalVectorArray("globalLightSpotDir", m_LightSpotDirections);
if (!lightData.isSingleDirectionalLight)
cmd.SetGlobalBuffer("globalLightIndexList", m_LightIndexListBuffer);
cmd.SetGlobalVector("globalLightData", new Vector4(lightData.pixelLightsCount, m_ShadowLightIndex, m_Asset.ShadowMinNormalBias, m_Asset.ShadowNormalBias));
SetShaderKeywords(cmd, lightData.isSingleDirectionalLight, lightData.vertexLightsCount > 0);
CommandBuffer cmd = new CommandBuffer () { name = "SetupShadowShaderConstants" };
cmd.SetGlobalVectorArray ("globalLightPos", m_LightPositions);
cmd.SetGlobalVectorArray ("globalLightColor", m_LightColors);
cmd.SetGlobalVectorArray ("globalLightAtten", m_LightAttenuations);
cmd.SetGlobalVectorArray ("globalLightSpotDir", m_LightSpotDirections);
cmd.SetGlobalBuffer ("globalLightIndexList", m_LightIndexListBuffer);
context.ExecuteCommandBuffer(cmd);
cmd.Dispose();
}

{
return (type == LightType.Directional || type == LightType.Spot);
}
}
}

6
Assets/ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightPipeline.shader


half3 color = half3(0, 0, 0);
#ifdef _SINGLE_DIRECTIONAL_LIGHT
LightInput lightData;
INITIALIZE_LIGHT(lightData, 0);
half NdotL;
color = EvaluateOneLight(lightData, diffuse, specularGloss, normal, i.posWS, viewDir, NdotL);
half NdotL;
color = EvaluateDirectionalLight(diffuse, specularGloss, normal, _LightPosition0, viewDir, NdotL) * _LightColor0;
#ifdef _SHADOWS
float bias = max(globalLightData.z, (1.0 - NdotL) * globalLightData.w);
color *= ComputeShadowAttenuation(i, bias);

34
Assets/ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightPipelineCore.cginc


float4 hpos : SV_POSITION;
};
// Per object light list data
#ifndef _SINGLE_DIRECTIONAL_LIGHT
half4 unity_LightIndicesOffsetAndCount;
StructuredBuffer<uint> globalLightIndexList;
// The variables are very similar to built-in unity_LightColor, unity_LightPosition,
// unity_LightAtten, unity_SpotDirection as used by the VertexLit shaders, except here
// we use world space positions instead of view space.

half4 globalLightAtten[MAX_VISIBLE_LIGHTS];
float4 globalLightData; // x: pixelLightCount, y = shadowLightIndex, z = minShadowNormalBiasOffset, w = shadowNormalBiasOffset
// Per object light list data
#ifndef _SINGLE_DIRECTIONAL_LIGHT
half4 unity_LightIndicesOffsetAndCount;
StructuredBuffer<uint> globalLightIndexList;
#else
float4 _LightPosition0;
float4 globalLightData; // x: pixelLightCount, y = shadowLightIndex, z = minShadowNormalBiasOffset, w = shadowNormalBiasOffset
half _Shininess;
samplerCUBE _Cube;
half4 _ReflectColor;

#endif
}
inline half3 EvaluateDirectionalLight(half3 diffuseColor, half4 specularGloss, half3 normal, half3 lightDir, half3 viewDir, out half NdotL)
{
NdotL = saturate(dot(normal, lightDir));
half3 diffuse = diffuseColor * NdotL;
#if defined(_SPECGLOSSMAP_BASE_ALPHA) || defined(_SPECGLOSSMAP) || defined(_SPECULAR_COLOR)
half3 halfVec = normalize(lightDir + viewDir);
half NdotH = saturate(dot(normal, halfVec));
half3 specular = specularGloss.rgb * pow(NdotH, _Shininess * 128.0) * specularGloss.a;
return diffuse + specular;
#else
return diffuse;
#endif
}
inline half3 EvaluateOneLight(LightInput lightInput, half3 diffuseColor, half4 specularGloss, half3 normal, float3 posWorld, half3 viewDir, out half NdotL)
{
float3 posToLight = lightInput.pos.xyz;

NdotL = saturate(dot(normal, lightDir));
half3 halfVec = normalize(lightDir + viewDir);
half NdotH = saturate(dot(normal, halfVec));
half3 halfVec = normalize(lightDir + viewDir);
half NdotH = saturate(dot(normal, halfVec));
half3 specular = specularGloss.rgb * lightColor * pow(NdotH, _Shininess * 128.0) * specularGloss.a;
return diffuse + specular;
#else

正在加载...
取消
保存