浏览代码

Light refactor to sort lights and disable directional lights from per object light lists.

/RenderPassXR_Sandbox
Felipe Lira 7 年前
当前提交
961ab624
共有 8 个文件被更改,包括 278 次插入251 次删除
  1. 365
      ScriptableRenderPipeline/LightweightPipeline/LightweightPipeline.cs
  2. 47
      ScriptableRenderPipeline/LightweightPipeline/LightweightPipelineAsset.cs
  3. 25
      ScriptableRenderPipeline/LightweightPipeline/LightweightPipelineUtils.cs
  4. 7
      ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightInput.cginc
  5. 21
      ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightLighting.cginc
  6. 58
      ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightPassLit.cginc
  7. 3
      ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightStandard.shader
  8. 3
      ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightStandardSimpleLighting.shader

365
ScriptableRenderPipeline/LightweightPipeline/LightweightPipeline.cs


using System;
using System.Collections.Generic;
using UnityEngine.Rendering;
using UnityEngine.Rendering.PostProcessing;
using UnityEngine.XR;

{
public int pixelLightsCount;
public int vertexLightsCount;
public int mainLightIndex;
public int shadowLightIndex;
public bool isSingleLight;
public bool shadowsRendered;

private Vector4[] m_LightSpotDirections = new Vector4[kMaxVisibleLights];
private Camera m_CurrCamera = null;
private LightType m_SingleLightType = LightType.Directional;
private int m_LightIndicesCount = 0;
private ComputeBuffer m_LightIndexListBuffer;

private PostProcessRenderContext m_PostProcessRenderContext;
private CameraComparer m_CameraComparer = new CameraComparer();
private LightComparer m_LightComparer = new LightComparer();
private Mesh m_BlitQuad = null;
private Material m_BlitMaterial = null;

{
m_CurrCamera = camera;
PostProcessLayer postProcessLayer;
RenderingConfiguration renderingConfig = SetupRendering(out postProcessLayer);
bool postProcessEnabled = LightweightUtils.HasFlag(renderingConfig, RenderingConfiguration.PostProcess);
ScriptableCullingParameters cullingParameters;
if (!CullResults.GetCullingParameters(m_CurrCamera, stereoEnabled, out cullingParameters))
continue;

LightData lightData;
InitializeLightData(visibleLights, out lightData);
// Render Shadow Map
if (lightData.shadowLightIndex > -1)
lightData.shadowsRendered = RenderShadows(ref m_CullResults,
ref visibleLights[lightData.shadowLightIndex], lightData.shadowLightIndex, ref context);
ShadowPass(visibleLights, ref context, ref lightData);
ForwardPass(visibleLights, ref context, ref lightData, stereoEnabled);
// Setup camera matrices
context.SetupCameraProperties(m_CurrCamera, stereoEnabled);
context.Submit();
}
}
// Setup light and shadow shader constants
SetupShaderLightConstants(visibleLights, ref lightData, ref m_CullResults, ref context);
if (lightData.shadowsRendered)
SetupShadowShaderConstants(ref context, ref visibleLights[lightData.shadowLightIndex],
lightData.shadowLightIndex, m_ShadowCasterCascadesCount);
SetShaderKeywords(ref lightData, ref context);
private void ShadowPass(VisibleLight[] visibleLights, ref ScriptableRenderContext context, ref LightData lightData)
{
if (m_Asset.AreShadowsEnabled() && lightData.mainLightIndex != -1)
{
VisibleLight mainLight = visibleLights[lightData.mainLightIndex];
if (mainLight.light.shadows != LightShadows.None)
lightData.shadowsRendered = RenderShadows (ref m_CullResults,
ref mainLight, lightData.shadowLightIndex, ref context);
}
}
RendererConfiguration rendererSettings = GetRendererSettings(ref lightData);
private void ForwardPass(VisibleLight[] visibleLights, ref ScriptableRenderContext context, ref LightData lightData, bool stereoEnabled)
{
PostProcessLayer postProcessLayer;
RenderingConfiguration renderingConfig = SetupRendering(out postProcessLayer);
bool postProcessEnabled = LightweightUtils.HasFlag(renderingConfig, RenderingConfiguration.PostProcess);
BeginForwardRendering(ref context, renderingConfig);
RenderOpaques(ref context, rendererSettings);
context.DrawSkybox(m_CurrCamera);
if (postProcessEnabled)
RenderPostProcess(ref context, postProcessLayer, true);
CommandBuffer cmd = CommandBufferPool.Get("SetupShaderConstants");
SetupShaderLightConstants(cmd, visibleLights, ref lightData, ref m_CullResults, ref context);
if (lightData.shadowsRendered)
SetupShadowShaderConstants(cmd, ref context, ref visibleLights[lightData.mainLightIndex],
lightData.mainLightIndex, m_ShadowCasterCascadesCount);
SetShaderKeywords(cmd, ref lightData, visibleLights);
context.ExecuteCommandBuffer(cmd);
CommandBufferPool.Release(cmd);
RenderTransparents(ref context, rendererSettings);
// Setup camera matrices
context.SetupCameraProperties(m_CurrCamera, stereoEnabled);
RendererConfiguration rendererSettings = GetRendererSettings(ref lightData);
if (postProcessEnabled)
RenderPostProcess(ref context, postProcessLayer, false);
BeginForwardRendering(ref context, renderingConfig);
RenderOpaques(ref context, rendererSettings);
context.DrawSkybox(m_CurrCamera);
EndForwardRendering(ref context, renderingConfig);
if (postProcessEnabled)
RenderPostProcess(ref context, postProcessLayer, true);
// Release temporary RT
var discardRT = CommandBufferPool.Get();
discardRT.ReleaseTemporaryRT(m_ShadowMapTexture);
discardRT.ReleaseTemporaryRT(m_CameraColorTexture);
discardRT.ReleaseTemporaryRT(m_CameraDepthTexture);
context.ExecuteCommandBuffer(discardRT);
CommandBufferPool.Release(discardRT);
RenderTransparents(ref context, rendererSettings);
if (postProcessEnabled)
RenderPostProcess(ref context, postProcessLayer, false);
EndForwardRendering(ref context, renderingConfig);
context.Submit();
}
// Release temporary RT
var discardRT = CommandBufferPool.Get();
discardRT.ReleaseTemporaryRT(m_ShadowMapTexture);
discardRT.ReleaseTemporaryRT(m_CameraColorTexture);
discardRT.ReleaseTemporaryRT(m_CameraDepthTexture);
context.ExecuteCommandBuffer(discardRT);
CommandBufferPool.Release(discardRT);
}
private void RenderOpaques(ref ScriptableRenderContext context, RendererConfiguration settings)

};
context.DrawRenderers(m_CullResults.visibleRenderers, ref transparentSettings, transparentFilterSettings);
}
private void BuildShadowSettings()

return renderingConfig;
}
private void InitializeLightData(VisibleLight[] lights, out LightData lightData)
private void InitializeLightData(VisibleLight[] visibleLights, out LightData lightData)
int lightsCount = lights.Length;
int lightsCount = visibleLights.Length;
lightData.shadowsRendered = false;
// TODO: Handle Vertex lights in this case
lightData.isSingleLight = lightData.pixelLightsCount <= 1;
if (lightData.isSingleLight)
m_SingleLightType = (lightData.pixelLightsCount == 1) ? lights[0].lightType : LightType.Directional;
if (lightsCount <= 1)
{
// If 0 lights then mainLightIndex is initialized to -1
lightData.mainLightIndex = lightData.shadowLightIndex = lightsCount - 1;
lightData.isSingleLight = true;
return;
}
lightData.isSingleLight = false;
SortLights(visibleLights, out lightData.mainLightIndex, out lightData.shadowLightIndex);
}
private void SortLights(VisibleLight[] visibleLights, out int mainLightIndex, out int shadowLightIndex)
{
int totalVisibleLights = visibleLights.Length;
int maxVisibleLights = Math.Min(totalVisibleLights, kMaxVisibleLights);
int[] lightIndexMap = m_CullResults.GetLightIndexMap();
int[] visibleLightHashes = new int[totalVisibleLights];
for (int i = 0; i < totalVisibleLights; ++i)
visibleLightHashes[i] = visibleLights[i].GetHashCode();
for (int i = 0; i < totalVisibleLights; ++i)
if (visibleLights[i].lightType == LightType.Directional)
lightIndexMap[i] = -1;
// Sorts on the following priority:
// Puntual lights as they need to be culled perobject
// Shadow casting lights
// Realtime < Mixed
// Light Intensity
Array.Sort(visibleLights, m_LightComparer);
Dictionary<int, int> visibleLightsMap = new Dictionary<int, int>();
for (int i = 0; i < totalVisibleLights; ++i)
visibleLightsMap.Add(visibleLights[i].GetHashCode(), i);
// Lightweight pipeline only upload kMaxVisibleLights to shader cbuffer.
// We tell the pipe to disable remaining lights by setting it to -1.
for (int i = 0; i < totalVisibleLights; ++i)
{
int index = visibleLightsMap [visibleLightHashes[i]];
if (lightIndexMap[i] != -1)
lightIndexMap[i] = (index < kMaxVisibleLights) ? index : -1;
}
m_CullResults.SetLightIndexMap(lightIndexMap);
lightData.shadowsRendered = false;
bool shadowsEnabled = m_Asset.AreShadowsEnabled();
mainLightIndex = -1;
if (shadowsEnabled && visibleLights[0].light.shadows != LightShadows.None)
mainLightIndex = 0;
InitializeMainShadowLightIndex(lights, out lightData.shadowLightIndex);
int lightIter = 0;
for (; lightIter < maxVisibleLights; ++lightIter)
{
if (visibleLights[lightIter].lightType == LightType.Directional)
{
if (mainLightIndex == -1 ||
(mainLightIndex == 0 && visibleLights[lightIter].light.shadows != LightShadows.None))
mainLightIndex = lightIter;
break;
}
}
// Main light and shadow lights are always the same. However,
// there an incovinience of the shadow caster pass takes the original
// shadow light index. After sorting lights that index is lost. We
// retrieve it by getting looking for the main light hash in the light hash list
shadowLightIndex = -1;
if (shadowsEnabled && mainLightIndex != -1)
{
int shadowLightHash = visibleLights[mainLightIndex].GetHashCode();
for (int i = 0; i < totalVisibleLights; ++i)
if (visibleLightHashes[i] == shadowLightHash)
{
shadowLightIndex = i;
break;
}
}
}
private void InitializeLightConstants(VisibleLight[] lights, int lightIndex, out Vector4 lightPos, out Vector4 lightColor, out Vector4 lightSpotDir,

}
}
private void SetupShaderLightConstants(VisibleLight[] lights, ref LightData lightData, ref CullResults cullResults, ref ScriptableRenderContext context)
private void SetupShaderLightConstants(CommandBuffer cmd, VisibleLight[] lights, ref LightData lightData, ref CullResults cullResults, ref ScriptableRenderContext context)
CommandBuffer cmd = CommandBufferPool.Get("SetupSingleLightConstants");
// When glossy reflections are OFF in the shader we set a constant color to use as indirect specular
SphericalHarmonicsL2 ambientSH = RenderSettings.ambientProbe;
Vector4 glossyEnvColor = new Vector4(ambientSH[0, 0], ambientSH[1, 0], ambientSH[2, 0]) * RenderSettings.reflectionIntensity;

if (lightData.isSingleLight)
SetupShaderSingleLightConstants(cmd, lights, (lightData.pixelLightsCount > 0) ? 0 : -1, ref context);
else
SetupShaderLightListConstants(cmd, lights, ref lightData, ref context);
if (lightData.mainLightIndex != -1)
SetupMainLightConstants(cmd, lights, lightData.mainLightIndex, ref context);
context.ExecuteCommandBuffer(cmd);
CommandBufferPool.Release(cmd);
if (!lightData.isSingleLight)
SetupAdditionalListConstants(cmd, lights, ref lightData, ref context);
private void SetupShaderSingleLightConstants(CommandBuffer cmd, VisibleLight[] lights, int lightIndex, ref ScriptableRenderContext context)
private void SetupMainLightConstants(CommandBuffer cmd, VisibleLight[] lights, int lightIndex, ref ScriptableRenderContext context)
{
Vector4 lightPos, lightColor, lightSpotDir, lightAttenuationParams;
InitializeLightConstants(lights, lightIndex, out lightPos, out lightColor, out lightSpotDir, out lightAttenuationParams);

cmd.SetGlobalVector("_LightAttenuationParams", lightAttenuationParams);
}
private void SetupShaderLightListConstants(CommandBuffer cmd, VisibleLight[] lights, ref LightData lightData, ref ScriptableRenderContext context)
private void SetupAdditionalListConstants(CommandBuffer cmd, VisibleLight[] lights, ref LightData lightData, ref ScriptableRenderContext context)
// Lightweight pipeline only upload kMaxVisibleLights to shader cbuffer.
// We tell the pipe to disable remaining lights by setting it to -1.
int[] lightIndexMap = m_CullResults.GetLightIndexMap();
for (int i = kMaxVisibleLights; i < lightIndexMap.Length; ++i)
lightIndexMap[i] = -1;
m_CullResults.SetLightIndexMap(lightIndexMap);
cmd.SetGlobalVector("globalLightCount", new Vector4 (lightData.pixelLightsCount, lightData.vertexLightsCount, 0.0f, 0.0f));
cmd.SetGlobalVectorArray ("globalLightPos", m_LightPositions);

}
private void SetShaderKeywords(ref LightData lightData, ref ScriptableRenderContext context)
private void SetupShadowShaderConstants(CommandBuffer cmd, ref ScriptableRenderContext context, ref VisibleLight shadowLight, int shadowLightIndex, int cascadeCount)
{
Vector3 shadowLightDir = Vector3.Normalize(shadowLight.localToWorld.GetColumn(2));
float bias = shadowLight.light.shadowBias * 0.1f;
float normalBias = shadowLight.light.shadowNormalBias;
float shadowResolution = m_ShadowSlices[0].shadowResolution;
const int maxShadowCascades = 4;
Matrix4x4[] shadowMatrices = new Matrix4x4[maxShadowCascades];
for (int i = 0; i < cascadeCount; ++i)
shadowMatrices[i] = (cascadeCount >= i) ? m_ShadowSlices[i].shadowTransform : Matrix4x4.identity;
// TODO: shadow resolution per cascade in case cascades endup being supported.
float invShadowResolution = 1.0f / shadowResolution;
float[] pcfKernel =
{
-0.5f * invShadowResolution, 0.5f * invShadowResolution,
0.5f * invShadowResolution, 0.5f * invShadowResolution,
-0.5f * invShadowResolution, -0.5f * invShadowResolution,
0.5f * invShadowResolution, -0.5f * invShadowResolution
};
cmd.SetGlobalMatrixArray("_WorldToShadow", shadowMatrices);
cmd.SetGlobalVectorArray("_DirShadowSplitSpheres", m_DirectionalShadowSplitDistances);
cmd.SetGlobalVector("_ShadowLightDirection", new Vector4(-shadowLightDir.x, -shadowLightDir.y, -shadowLightDir.z, 0.0f));
cmd.SetGlobalVector("_ShadowData", new Vector4(shadowLightIndex, bias, normalBias, 0.0f));
cmd.SetGlobalFloatArray("_PCFKernel", pcfKernel);
}
private void SetShaderKeywords(CommandBuffer cmd, ref LightData lightData, VisibleLight[] visibleLights)
CommandBuffer cmd = new CommandBuffer() { name = "SetShaderKeywords" };
SetShaderKeywords(cmd, lightData.shadowsRendered, lightData.isSingleLight, lightData.vertexLightsCount > 0);
context.ExecuteCommandBuffer(cmd);
cmd.Dispose();
LightweightUtils.SetKeyword(cmd, "_LIGHTWEIGHT_FORCE_LINEAR", m_Asset.ForceLinearRendering);
LightweightUtils.SetKeyword(cmd, "_VERTEX_LIGHTS", lightData.vertexLightsCount > 0);
LightweightUtils.SetKeyword(cmd, "_ATTENUATION_TEXTURE", m_Asset.AttenuationTexture != null);
int mainLightIndex = lightData.mainLightIndex;
LightweightUtils.SetKeyword (cmd, "_MAIN_DIRECTIONAL_LIGHT", mainLightIndex != -1 && visibleLights[mainLightIndex].lightType == LightType.Directional);
LightweightUtils.SetKeyword (cmd, "_MAIN_SPOT_LIGHT", mainLightIndex != -1 && visibleLights[mainLightIndex].lightType == LightType.Spot);
LightweightUtils.SetKeyword (cmd, "_MAIN_POINT_LIGHT", mainLightIndex != -1 && visibleLights[mainLightIndex].lightType == LightType.Point);
LightweightUtils.SetKeyword(cmd, "_ADDITIONAL_LIGHTS", !lightData.isSingleLight);
string[] shadowKeywords = new string[] { "_HARD_SHADOWS", "_SOFT_SHADOWS", "_HARD_SHADOWS_CASCADES", "_SOFT_SHADOWS_CASCADES" };
for (int i = 0; i < shadowKeywords.Length; ++i)
cmd.DisableShaderKeyword(shadowKeywords[i]);
if (m_Asset.AreShadowsEnabled() && lightData.shadowsRendered)
{
int keywordIndex = (int)m_Asset.ShadowSetting - 1;
if (m_Asset.CascadeCount > 1)
keywordIndex += 2;
cmd.EnableShaderKeyword(shadowKeywords[keywordIndex]);
}
}
private bool RenderShadows(ref CullResults cullResults, ref VisibleLight shadowLight, int shadowLightIndex, ref ScriptableRenderContext context)

currentTileCount = atlasWidth / resolution * atlasHeight / resolution;
}
return resolution;
}
private void SetupShadowShaderConstants(ref ScriptableRenderContext context, ref VisibleLight shadowLight, int shadowLightIndex, int cascadeCount)
{
Vector3 shadowLightDir = Vector3.Normalize(shadowLight.localToWorld.GetColumn(2));
float bias = shadowLight.light.shadowBias * 0.1f;
float normalBias = shadowLight.light.shadowNormalBias;
float shadowResolution = m_ShadowSlices[0].shadowResolution;
const int maxShadowCascades = 4;
Matrix4x4[] shadowMatrices = new Matrix4x4[maxShadowCascades];
for (int i = 0; i < cascadeCount; ++i)
shadowMatrices[i] = (cascadeCount >= i) ? m_ShadowSlices[i].shadowTransform : Matrix4x4.identity;
// TODO: shadow resolution per cascade in case cascades endup being supported.
float invShadowResolution = 1.0f / shadowResolution;
float[] pcfKernel =
{
-0.5f * invShadowResolution, 0.5f * invShadowResolution,
0.5f * invShadowResolution, 0.5f * invShadowResolution,
-0.5f * invShadowResolution, -0.5f * invShadowResolution,
0.5f * invShadowResolution, -0.5f * invShadowResolution
};
var setupShadow = CommandBufferPool.Get("SetupShadowShaderConstants");
setupShadow.SetGlobalMatrixArray("_WorldToShadow", shadowMatrices);
setupShadow.SetGlobalVectorArray("_DirShadowSplitSpheres", m_DirectionalShadowSplitDistances);
setupShadow.SetGlobalVector("_ShadowLightDirection", new Vector4(-shadowLightDir.x, -shadowLightDir.y, -shadowLightDir.z, 0.0f));
setupShadow.SetGlobalVector("_ShadowData", new Vector4(shadowLightIndex, bias, normalBias, 0.0f));
setupShadow.SetGlobalFloatArray("_PCFKernel", pcfKernel);
context.ExecuteCommandBuffer(setupShadow);
CommandBufferPool.Release(setupShadow);
}
private void SetShaderKeywords(CommandBuffer cmd, bool renderShadows, bool singleLight, bool vertexLightSupport)
{
LightweightUtils.SetKeyword(cmd, "_LIGHTWEIGHT_FORCE_LINEAR", m_Asset.ForceLinearRendering);
LightweightUtils.SetKeyword(cmd, "_VERTEX_LIGHTS", vertexLightSupport);
LightweightUtils.SetKeyword(cmd, "_ATTENUATION_TEXTURE", m_Asset.AttenuationTexture != null);
if (!singleLight)
{
LightweightUtils.SetKeyword(cmd, "_SINGLE_DIRECTIONAL_LIGHT", false);
LightweightUtils.SetKeyword(cmd, "_SINGLE_SPOT_LIGHT", false);
LightweightUtils.SetKeyword(cmd, "_SINGLE_POINT_LIGHT", false);
}
else
{
switch (m_SingleLightType)
{
case LightType.Directional:
LightweightUtils.SetKeyword(cmd, "_SINGLE_DIRECTIONAL_LIGHT", true);
LightweightUtils.SetKeyword(cmd, "_SINGLE_SPOT_LIGHT", false);
LightweightUtils.SetKeyword(cmd, "_SINGLE_POINT_LIGHT", false);
break;
case LightType.Spot:
LightweightUtils.SetKeyword(cmd, "_SINGLE_DIRECTIONAL_LIGHT", false);
LightweightUtils.SetKeyword(cmd, "_SINGLE_SPOT_LIGHT", true);
LightweightUtils.SetKeyword(cmd, "_SINGLE_POINT_LIGHT", false);
break;
case LightType.Point:
LightweightUtils.SetKeyword(cmd, "_SINGLE_DIRECTIONAL_LIGHT", false);
LightweightUtils.SetKeyword(cmd, "_SINGLE_SPOT_LIGHT", false);
LightweightUtils.SetKeyword(cmd, "_SINGLE_POINT_LIGHT", true);
break;
}
}
string[] shadowKeywords = new string[] { "_HARD_SHADOWS", "_SOFT_SHADOWS", "_HARD_SHADOWS_CASCADES", "_SOFT_SHADOWS_CASCADES" };
for (int i = 0; i < shadowKeywords.Length; ++i)
cmd.DisableShaderKeyword(shadowKeywords[i]);
if (renderShadows && m_Asset.CurrShadowType != ShadowType.NO_SHADOW)
{
int keywordIndex = (int)m_Asset.CurrShadowType - 1;
if (m_Asset.CascadeCount > 1)
keywordIndex += 2;
cmd.EnableShaderKeyword(shadowKeywords[keywordIndex]);
}
}
private void InitializeMainShadowLightIndex(VisibleLight[] lights, out int shadowIndex)
{
shadowIndex = -1;
if (m_Asset.CurrShadowType == ShadowType.NO_SHADOW)
return;
float maxIntensity = -1;
for (int i = 0; i < lights.Length; ++i)
{
Light light = lights[i].light;
if (light.shadows != LightShadows.None && IsSupportedShadowType(light.type) && light.intensity > maxIntensity)
{
shadowIndex = i;
maxIntensity = light.intensity;
}
}
}
private bool IsSupportedShadowType(LightType type)
{
return (type == LightType.Directional || type == LightType.Spot);
}
private void BeginForwardRendering(ref ScriptableRenderContext context, RenderingConfiguration renderingConfig)

47
ScriptableRenderPipeline/LightweightPipeline/LightweightPipelineAsset.cs


private static readonly string m_PipelineFolder = "Assets/ScriptableRenderPipeline/LightweightPipeline";
private static readonly string m_AssetName = "LightweightPipelineAsset.asset";
[SerializeField] private int m_MaxPixelLights = 1;
[SerializeField] private bool m_SupportsVertexLight = true;
[SerializeField] private MSAAQuality m_MSAA = MSAAQuality.Disabled;
[SerializeField] private float m_RenderScale = 1.0f;
[SerializeField] private ShadowType m_ShadowType = ShadowType.HARD_SHADOWS;
[SerializeField] private ShadowResolution m_ShadowAtlasResolution = ShadowResolution._1024;
[SerializeField] private float m_ShadowNearPlaneOffset = 2.0f;
[SerializeField] private float m_ShadowDistance = 50.0f;
[SerializeField] private ShadowCascades m_ShadowCascades = ShadowCascades.NO_CASCADES;
[SerializeField] private float m_Cascade2Split = 0.25f;
[SerializeField] private Vector3 m_Cascade4Split = new Vector3(0.067f, 0.2f, 0.467f);
[SerializeField] private bool m_LinearRendering = true;
[SerializeField] private Texture2D m_AttenuationTexture;
[SerializeField] private Material m_DefaultDiffuseMaterial;
[SerializeField] private Material m_DefaultParticleMaterial;
[SerializeField] private Material m_DefaultLineMaterial;
[SerializeField] private Material m_DefaultSpriteMaterial;
[SerializeField] private Material m_DefaultUIMaterial;
[SerializeField] private Shader m_DefaultShader;
#if UNITY_EDITOR
[UnityEditor.MenuItem("RenderPipeline/LightweightPipeline/Create Pipeline Asset", false, 15)]
static void CreateLightweightPipeline()

DestroyCreatedInstances();
}
[SerializeField] private int m_MaxPixelLights = 1;
[SerializeField] private bool m_SupportsVertexLight = true;
[SerializeField] private MSAAQuality m_MSAA = MSAAQuality.Disabled;
[SerializeField] private float m_RenderScale = 1.0f;
[SerializeField] private ShadowType m_ShadowType = ShadowType.HARD_SHADOWS;
[SerializeField] private ShadowResolution m_ShadowAtlasResolution = ShadowResolution._1024;
[SerializeField] private float m_ShadowNearPlaneOffset = 2.0f;
[SerializeField] private float m_ShadowDistance = 50.0f;
[SerializeField] private ShadowCascades m_ShadowCascades = ShadowCascades.NO_CASCADES;
[SerializeField] private float m_Cascade2Split = 0.25f;
[SerializeField] private Vector3 m_Cascade4Split = new Vector3(0.067f, 0.2f, 0.467f);
[SerializeField] private bool m_LinearRendering = true;
[SerializeField] private Texture2D m_AttenuationTexture;
[SerializeField] private Material m_DefaultDiffuseMaterial;
[SerializeField] private Material m_DefaultParticleMaterial;
[SerializeField] private Material m_DefaultLineMaterial;
[SerializeField] private Material m_DefaultSpriteMaterial;
[SerializeField] private Material m_DefaultUIMaterial;
[SerializeField] private Shader m_DefaultShader;
public bool AreShadowsEnabled()
{
return ShadowSetting != ShadowType.NO_SHADOW;
}
public int MaxSupportedPixelLights
{

set { m_RenderScale = value; }
}
public ShadowType CurrShadowType
public ShadowType ShadowSetting
{
get { return m_ShadowType; }
private set { m_ShadowType = value; }

25
ScriptableRenderPipeline/LightweightPipeline/LightweightPipelineUtils.cs


}
}
public class LightComparer : IComparer<VisibleLight>
{
public int Compare(VisibleLight lhs, VisibleLight rhs)
{
Light lhsLight = lhs.light;
Light rhsLight = rhs.light;
if (lhs.lightType != rhs.lightType)
return (rhs.lightType != LightType.Directional) ? 1 : -1;
if (lhsLight.shadows != rhsLight.shadows)
return (int)rhsLight.shadows - (int)lhsLight.shadows;
if (lhsLight.lightmapBakeType != rhsLight.lightmapBakeType)
return (rhsLight.lightmapBakeType == LightmapBakeType.Realtime) ? 1 : -1;
return (int)(lhsLight.intensity * 100.0f) - (int)(rhsLight.intensity * 100.0f);
}
}
[Flags]
public enum RenderingConfiguration
{

cmd.EnableShaderKeyword(keyword);
else
cmd.DisableShaderKeyword(keyword);
}
public static bool IsSupportedShadowType(LightType lightType)
{
return lightType == LightType.Directional || lightType == LightType.Spot;
}
public static bool PlatformSupportsMSAABackBuffer()

7
ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightInput.cginc


light.atten = globalLightAtten[lightIndex]; \
light.spotDir = globalLightSpotDir[lightIndex]
#if !(defined(_SINGLE_DIRECTIONAL_LIGHT) || defined(_SINGLE_SPOT_LIGHT) || defined(_SINGLE_POINT_LIGHT))
#define _MULTIPLE_LIGHTS
#if (defined(_MAIN_DIRECTIONAL_LIGHT) || defined(_MAIN_SPOT_LIGHT) || defined(_MAIN_POINT_LIGHT))
#define _MAIN_LIGHT
#endif
#ifdef _SPECULAR_SETUP

sampler2D _AttenuationTexture;
// Per object light list data
#ifdef _MULTIPLE_LIGHTS
half4 unity_LightIndicesOffsetAndCount;
half4 unity_4LightIndices0;

float4 globalLightPos[MAX_VISIBLE_LIGHTS];
half4 globalLightSpotDir[MAX_VISIBLE_LIGHTS];
float4 globalLightAtten[MAX_VISIBLE_LIGHTS];
#else
#endif
half _Shininess;
half4 _GlossyEnvironmentColor;

21
ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightLighting.cginc


// normalized light dir
lightDirection = half3(posToLightVec * rsqrt(distanceSqr));
#if !(defined(_SINGLE_POINT_LIGHT) || defined(_SINGLE_DIRECTIONAL_LIGHT))
#endif
return half(lightAtten);
}

float4 attenuationParams = lightInput.atten;
#ifdef _SINGLE_DIRECTIONAL_LIGHT
// Light pos holds normalized light dir
lightDirection = lightInput.pos;
return 1.0;
#else
// TODO: Test separating dir lights into diff loop by sorting on the pipe and setting -1 on LightIndexMap.
#ifdef _ATTENUATION_TEXTURE
float u = (distanceSqr * attenuationParams.z) / attenuationParams.w;
float lightAtten = tex2D(_AttenuationTexture, float2(u, 0.0)).a;

// normalized light dir
lightDirection = half3(posToLightVec * rsqrt(distanceSqr));
#ifndef _SINGLE_POINT_LIGHT
#endif
}
#endif // _SINGLE_DIRECTIONAL_LIGHT
inline half ComputeMainLightAttenuation(LightInput lightInput, half3 normal, float3 worldPos, out half3 lightDirection)
{
#ifdef _MAIN_DIRECTIONAL_LIGHT
// Light pos holds normalized light dir
lightDirection = lightInput.pos;
return 1.0;
#else
return ComputeLightAttenuation(lightInput, normal, worldPos, lightDirection);
#endif
}
inline half3 LightingLambert(half3 diffuseColor, half3 lightDir, half3 normal, half atten)

58
ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightPassLit.cginc


half3 color = LightweightBRDFIndirect(brdfData, indirectLight, roughness2, fresnelTerm);
half3 lightDirection;
#ifndef _MULTIPLE_LIGHTS
#ifdef _MAIN_LIGHT
half lightAtten = ComputeLightAttenuation(light, normal, i.posWS.xyz, lightDirection);
half lightAtten = ComputeMainLightAttenuation(light, normal, i.posWS.xyz, lightDirection);
#ifdef _SHADOWS
lightAtten *= ComputeShadowAttenuation(i, _ShadowLightDirection.xyz);

half3 radiance = light.color * (lightAtten * NdotL);
color += LightweightBDRF(brdfData, roughness2, normal, lightDirection, i.viewDir.xyz) * radiance;
#else
#ifdef _SHADOWS
half shadowAttenuation = ComputeShadowAttenuation(i, _ShadowLightDirection.xyz);
#ifdef _ADDITIONAL_LIGHTS
int pixelLightCount = min(globalLightCount.x, unity_LightIndicesOffsetAndCount.y);
for (int lightIter = 0; lightIter < pixelLightCount; ++lightIter)
{

half lightAtten = ComputeLightAttenuation(light, normal, i.posWS.xyz, lightDirection);
#ifdef _SHADOWS
lightAtten *= max(shadowAttenuation, half(lightIndex != _ShadowData.x));
#endif
half NdotL = saturate(dot(normal, lightDirection));
half3 radiance = light.color * (lightAtten * NdotL);
color += LightweightBDRF(brdfData, roughness2, normal, lightDirection, i.viewDir.xyz) * radiance;

half3 lightDirection;
#ifndef _MULTIPLE_LIGHTS
#if defined(LIGHTMAP_ON)
half3 color = DecodeLightmap(UNITY_SAMPLE_TEX2D(unity_Lightmap, i.uv01.zw)) * diffuse;
#else
half3 color = (SHEvalLinearL0L1(half4(normal, 1.0)) + i.fogCoord.yzw) * diffuse;
#endif
#ifdef _MAIN_LIGHT
half lightAtten = ComputeLightAttenuation(lightInput, normal, worldPos, lightDirection);
half lightAtten = ComputeMainLightAttenuation(lightInput, normal, worldPos, lightDirection);
half3 color = LightingBlinnPhong(diffuse, specularGloss, lightDirection, normal, viewDir, lightAtten) * lightInput.color;
color += LightingBlinnPhong(diffuse, specularGloss, lightDirection, normal, viewDir, lightAtten) * lightInput.color;
half3 color = LightingLambert(diffuse, lightDirection, normal, lightAtten) * lightInput.color;
color += LightingLambert(diffuse, lightDirection, normal, lightAtten) * lightInput.color;
#else
half3 color = half3(0, 0, 0);
#ifdef _SHADOWS
half shadowAttenuation = ComputeShadowAttenuation(i, _ShadowLightDirection.xyz);
#ifdef _ADDITIONAL_LIGHTS
int pixelLightCount = min(globalLightCount.x, unity_LightIndicesOffsetAndCount.y);
for (int lightIter = 0; lightIter < pixelLightCount; ++lightIter)
{

half lightAtten = ComputeLightAttenuation(lightData, normal, worldPos, lightDirection);
#ifdef _SHADOWS
lightAtten *= max(shadowAttenuation, half(lightIndex != _ShadowData.x));
#endif
#ifdef LIGHTWEIGHT_SPECULAR_HIGHLIGHTS
color += LightingBlinnPhong(diffuse, specularGloss, lightDirection, normal, viewDir, lightAtten) * lightData.color;

}
#endif // _MULTIPLE_LIGHTS
#endif // _ADDITIONAL_LIGHTS
#if defined(LIGHTMAP_ON)
color += DecodeLightmap(UNITY_SAMPLE_TEX2D(unity_Lightmap, i.uv01.zw)) * diffuse;
#else
color += (SHEvalLinearL0L1(half4(normal, 1.0)) + i.fogCoord.yzw) * diffuse;
#endif
#if _REFLECTION_CUBEMAP
// TODO: we can use reflect vec to compute specular instead of half when computing cubemap reflection
half3 reflectVec = reflect(-i.viewDir.xyz, normal);
color += texCUBE(_Cube, reflectVec).rgb * specularGloss.rgb;
#elif defined(_REFLECTION_PROBE)
half3 reflectVec = reflect(-i.viewDir.xyz, normal);
half4 reflectionProbe = UNITY_SAMPLE_TEXCUBE(unity_SpecCube0, reflectVec);
color += reflectionProbe.rgb * (reflectionProbe.a * unity_SpecCube0_HDR.x) * specularGloss.rgb;
#endif
return OutputColor(color, alpha);
};

3
ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightStandard.shader


#pragma shader_feature _ _OCCLUSIONMAP
#pragma shader_feature _PARALLAXMAP
#pragma multi_compile _ _SINGLE_DIRECTIONAL_LIGHT _SINGLE_SPOT_LIGHT _SINGLE_POINT_LIGHT
#pragma multi_compile _ _MAIN_DIRECTIONAL_LIGHT _MAIN_SPOT_LIGHT _MAIN_POINT_LIGHT
#pragma multi_compile _ _ADDITIONAL_LIGHTS
#pragma multi_compile _ _LIGHTWEIGHT_FORCE_LINEAR
#pragma multi_compile _ UNITY_SINGLE_PASS_STEREO STEREO_INSTANCING_ON STEREO_MULTIVIEW_ON
#pragma multi_compile _ LIGHTMAP_ON

3
ScriptableRenderPipeline/LightweightPipeline/Shaders/LightweightStandardSimpleLighting.shader


#pragma shader_feature _NORMALMAP
#pragma shader_feature _EMISSION
#pragma multi_compile _ _MAIN_DIRECTIONAL_LIGHT _MAIN_SPOT_LIGHT _MAIN_POINT_LIGHT
#pragma multi_compile _ _ADDITIONAL_LIGHTS
#pragma multi_compile _ _SINGLE_DIRECTIONAL_LIGHT _SINGLE_SPOT_LIGHT _SINGLE_POINT_LIGHT
#pragma multi_compile _ LIGHTMAP_ON
#pragma multi_compile _ _HARD_SHADOWS _SOFT_SHADOWS _HARD_SHADOWS_CASCADES _SOFT_SHADOWS_CASCADES
#pragma multi_compile _ _VERTEX_LIGHTS

正在加载...
取消
保存