testss
This commit is contained in:
@@ -0,0 +1,263 @@
|
||||
using UnityEngine.Experimental.GlobalIllumination;
|
||||
using Unity.Collections;
|
||||
|
||||
namespace UnityEngine.Rendering.Universal.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// Computes and submits lighting data to the GPU.
|
||||
/// </summary>
|
||||
public class ForwardLights
|
||||
{
|
||||
static class LightConstantBuffer
|
||||
{
|
||||
public static int _MainLightPosition; // DeferredLights.LightConstantBuffer also refers to the same ShaderPropertyID - TODO: move this definition to a common location shared by other UniversalRP classes
|
||||
public static int _MainLightColor; // DeferredLights.LightConstantBuffer also refers to the same ShaderPropertyID - TODO: move this definition to a common location shared by other UniversalRP classes
|
||||
public static int _MainLightOcclusionProbesChannel; // Deferred?
|
||||
|
||||
public static int _AdditionalLightsCount;
|
||||
public static int _AdditionalLightsPosition;
|
||||
public static int _AdditionalLightsColor;
|
||||
public static int _AdditionalLightsAttenuation;
|
||||
public static int _AdditionalLightsSpotDir;
|
||||
public static int _AdditionalLightOcclusionProbeChannel;
|
||||
}
|
||||
|
||||
int m_AdditionalLightsBufferId;
|
||||
int m_AdditionalLightsIndicesId;
|
||||
|
||||
const string k_SetupLightConstants = "Setup Light Constants";
|
||||
private static readonly ProfilingSampler m_ProfilingSampler = new ProfilingSampler(k_SetupLightConstants);
|
||||
MixedLightingSetup m_MixedLightingSetup;
|
||||
|
||||
Vector4[] m_AdditionalLightPositions;
|
||||
Vector4[] m_AdditionalLightColors;
|
||||
Vector4[] m_AdditionalLightAttenuations;
|
||||
Vector4[] m_AdditionalLightSpotDirections;
|
||||
Vector4[] m_AdditionalLightOcclusionProbeChannels;
|
||||
|
||||
bool m_UseStructuredBuffer;
|
||||
|
||||
public ForwardLights()
|
||||
{
|
||||
m_UseStructuredBuffer = RenderingUtils.useStructuredBuffer;
|
||||
|
||||
LightConstantBuffer._MainLightPosition = Shader.PropertyToID("_MainLightPosition");
|
||||
LightConstantBuffer._MainLightColor = Shader.PropertyToID("_MainLightColor");
|
||||
LightConstantBuffer._MainLightOcclusionProbesChannel = Shader.PropertyToID("_MainLightOcclusionProbes");
|
||||
LightConstantBuffer._AdditionalLightsCount = Shader.PropertyToID("_AdditionalLightsCount");
|
||||
|
||||
if (m_UseStructuredBuffer)
|
||||
{
|
||||
m_AdditionalLightsBufferId = Shader.PropertyToID("_AdditionalLightsBuffer");
|
||||
m_AdditionalLightsIndicesId = Shader.PropertyToID("_AdditionalLightsIndices");
|
||||
}
|
||||
else
|
||||
{
|
||||
LightConstantBuffer._AdditionalLightsPosition = Shader.PropertyToID("_AdditionalLightsPosition");
|
||||
LightConstantBuffer._AdditionalLightsColor = Shader.PropertyToID("_AdditionalLightsColor");
|
||||
LightConstantBuffer._AdditionalLightsAttenuation = Shader.PropertyToID("_AdditionalLightsAttenuation");
|
||||
LightConstantBuffer._AdditionalLightsSpotDir = Shader.PropertyToID("_AdditionalLightsSpotDir");
|
||||
LightConstantBuffer._AdditionalLightOcclusionProbeChannel = Shader.PropertyToID("_AdditionalLightsOcclusionProbes");
|
||||
|
||||
int maxLights = UniversalRenderPipeline.maxVisibleAdditionalLights;
|
||||
m_AdditionalLightPositions = new Vector4[maxLights];
|
||||
m_AdditionalLightColors = new Vector4[maxLights];
|
||||
m_AdditionalLightAttenuations = new Vector4[maxLights];
|
||||
m_AdditionalLightSpotDirections = new Vector4[maxLights];
|
||||
m_AdditionalLightOcclusionProbeChannels = new Vector4[maxLights];
|
||||
}
|
||||
}
|
||||
|
||||
public void Setup(ScriptableRenderContext context, ref RenderingData renderingData)
|
||||
{
|
||||
int additionalLightsCount = renderingData.lightData.additionalLightsCount;
|
||||
bool additionalLightsPerVertex = renderingData.lightData.shadeAdditionalLightsPerVertex;
|
||||
CommandBuffer cmd = CommandBufferPool.Get();
|
||||
using (new ProfilingScope(cmd, m_ProfilingSampler))
|
||||
{
|
||||
SetupShaderLightConstants(cmd, ref renderingData);
|
||||
|
||||
CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.AdditionalLightsVertex,
|
||||
additionalLightsCount > 0 && additionalLightsPerVertex);
|
||||
CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.AdditionalLightsPixel,
|
||||
additionalLightsCount > 0 && !additionalLightsPerVertex);
|
||||
|
||||
bool isShadowMask = renderingData.lightData.supportsMixedLighting && m_MixedLightingSetup == MixedLightingSetup.ShadowMask;
|
||||
bool isShadowMaskAlways = isShadowMask && QualitySettings.shadowmaskMode == ShadowmaskMode.Shadowmask;
|
||||
bool isSubtractive = renderingData.lightData.supportsMixedLighting && m_MixedLightingSetup == MixedLightingSetup.Subtractive;
|
||||
CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.LightmapShadowMixing, isSubtractive || isShadowMaskAlways);
|
||||
CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.ShadowsShadowMask, isShadowMask);
|
||||
CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.MixedLightingSubtractive, isSubtractive); // Backward compatibility
|
||||
}
|
||||
context.ExecuteCommandBuffer(cmd);
|
||||
CommandBufferPool.Release(cmd);
|
||||
}
|
||||
|
||||
void InitializeLightConstants(NativeArray<VisibleLight> lights, int lightIndex, out Vector4 lightPos, out Vector4 lightColor, out Vector4 lightAttenuation, out Vector4 lightSpotDir, out Vector4 lightOcclusionProbeChannel)
|
||||
{
|
||||
UniversalRenderPipeline.InitializeLightConstants_Common(lights, lightIndex, out lightPos, out lightColor, out lightAttenuation, out lightSpotDir, out lightOcclusionProbeChannel);
|
||||
|
||||
// When no lights are visible, main light will be set to -1.
|
||||
// In this case we initialize it to default values and return
|
||||
if (lightIndex < 0)
|
||||
return;
|
||||
|
||||
VisibleLight lightData = lights[lightIndex];
|
||||
Light light = lightData.light;
|
||||
|
||||
if (light == null)
|
||||
return;
|
||||
|
||||
if (light.bakingOutput.lightmapBakeType == LightmapBakeType.Mixed &&
|
||||
lightData.light.shadows != LightShadows.None &&
|
||||
m_MixedLightingSetup == MixedLightingSetup.None)
|
||||
{
|
||||
switch (light.bakingOutput.mixedLightingMode)
|
||||
{
|
||||
case MixedLightingMode.Subtractive:
|
||||
m_MixedLightingSetup = MixedLightingSetup.Subtractive;
|
||||
break;
|
||||
case MixedLightingMode.Shadowmask:
|
||||
m_MixedLightingSetup = MixedLightingSetup.ShadowMask;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SetupShaderLightConstants(CommandBuffer cmd, ref RenderingData renderingData)
|
||||
{
|
||||
m_MixedLightingSetup = MixedLightingSetup.None;
|
||||
|
||||
// Main light has an optimized shader path for main light. This will benefit games that only care about a single light.
|
||||
// Universal pipeline also supports only a single shadow light, if available it will be the main light.
|
||||
SetupMainLightConstants(cmd, ref renderingData.lightData);
|
||||
SetupAdditionalLightConstants(cmd, ref renderingData);
|
||||
}
|
||||
|
||||
void SetupMainLightConstants(CommandBuffer cmd, ref LightData lightData)
|
||||
{
|
||||
Vector4 lightPos, lightColor, lightAttenuation, lightSpotDir, lightOcclusionChannel;
|
||||
InitializeLightConstants(lightData.visibleLights, lightData.mainLightIndex, out lightPos, out lightColor, out lightAttenuation, out lightSpotDir, out lightOcclusionChannel);
|
||||
|
||||
cmd.SetGlobalVector(LightConstantBuffer._MainLightPosition, lightPos);
|
||||
cmd.SetGlobalVector(LightConstantBuffer._MainLightColor, lightColor);
|
||||
cmd.SetGlobalVector(LightConstantBuffer._MainLightOcclusionProbesChannel, lightOcclusionChannel);
|
||||
}
|
||||
|
||||
void SetupAdditionalLightConstants(CommandBuffer cmd, ref RenderingData renderingData)
|
||||
{
|
||||
ref LightData lightData = ref renderingData.lightData;
|
||||
var cullResults = renderingData.cullResults;
|
||||
var lights = lightData.visibleLights;
|
||||
int maxAdditionalLightsCount = UniversalRenderPipeline.maxVisibleAdditionalLights;
|
||||
int additionalLightsCount = SetupPerObjectLightIndices(cullResults, ref lightData);
|
||||
if (additionalLightsCount > 0)
|
||||
{
|
||||
if (m_UseStructuredBuffer)
|
||||
{
|
||||
NativeArray<ShaderInput.LightData> additionalLightsData = new NativeArray<ShaderInput.LightData>(additionalLightsCount, Allocator.Temp);
|
||||
for (int i = 0, lightIter = 0; i < lights.Length && lightIter < maxAdditionalLightsCount; ++i)
|
||||
{
|
||||
VisibleLight light = lights[i];
|
||||
if (lightData.mainLightIndex != i)
|
||||
{
|
||||
ShaderInput.LightData data;
|
||||
InitializeLightConstants(lights, i,
|
||||
out data.position, out data.color, out data.attenuation,
|
||||
out data.spotDirection, out data.occlusionProbeChannels);
|
||||
additionalLightsData[lightIter] = data;
|
||||
lightIter++;
|
||||
}
|
||||
}
|
||||
|
||||
var lightDataBuffer = ShaderData.instance.GetLightDataBuffer(additionalLightsCount);
|
||||
lightDataBuffer.SetData(additionalLightsData);
|
||||
|
||||
int lightIndices = cullResults.lightAndReflectionProbeIndexCount;
|
||||
var lightIndicesBuffer = ShaderData.instance.GetLightIndicesBuffer(lightIndices);
|
||||
|
||||
cmd.SetGlobalBuffer(m_AdditionalLightsBufferId, lightDataBuffer);
|
||||
cmd.SetGlobalBuffer(m_AdditionalLightsIndicesId, lightIndicesBuffer);
|
||||
|
||||
additionalLightsData.Dispose();
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0, lightIter = 0; i < lights.Length && lightIter < maxAdditionalLightsCount; ++i)
|
||||
{
|
||||
VisibleLight light = lights[i];
|
||||
if (lightData.mainLightIndex != i)
|
||||
{
|
||||
InitializeLightConstants(lights, i, out m_AdditionalLightPositions[lightIter],
|
||||
out m_AdditionalLightColors[lightIter],
|
||||
out m_AdditionalLightAttenuations[lightIter],
|
||||
out m_AdditionalLightSpotDirections[lightIter],
|
||||
out m_AdditionalLightOcclusionProbeChannels[lightIter]);
|
||||
lightIter++;
|
||||
}
|
||||
}
|
||||
|
||||
cmd.SetGlobalVectorArray(LightConstantBuffer._AdditionalLightsPosition, m_AdditionalLightPositions);
|
||||
cmd.SetGlobalVectorArray(LightConstantBuffer._AdditionalLightsColor, m_AdditionalLightColors);
|
||||
cmd.SetGlobalVectorArray(LightConstantBuffer._AdditionalLightsAttenuation, m_AdditionalLightAttenuations);
|
||||
cmd.SetGlobalVectorArray(LightConstantBuffer._AdditionalLightsSpotDir, m_AdditionalLightSpotDirections);
|
||||
cmd.SetGlobalVectorArray(LightConstantBuffer._AdditionalLightOcclusionProbeChannel, m_AdditionalLightOcclusionProbeChannels);
|
||||
}
|
||||
|
||||
cmd.SetGlobalVector(LightConstantBuffer._AdditionalLightsCount, new Vector4(lightData.maxPerObjectAdditionalLightsCount,
|
||||
0.0f, 0.0f, 0.0f));
|
||||
}
|
||||
else
|
||||
{
|
||||
cmd.SetGlobalVector(LightConstantBuffer._AdditionalLightsCount, Vector4.zero);
|
||||
}
|
||||
}
|
||||
|
||||
int SetupPerObjectLightIndices(CullingResults cullResults, ref LightData lightData)
|
||||
{
|
||||
if (lightData.additionalLightsCount == 0)
|
||||
return lightData.additionalLightsCount;
|
||||
|
||||
var visibleLights = lightData.visibleLights;
|
||||
var perObjectLightIndexMap = cullResults.GetLightIndexMap(Allocator.Temp);
|
||||
int globalDirectionalLightsCount = 0;
|
||||
int additionalLightsCount = 0;
|
||||
|
||||
// Disable all directional lights from the perobject light indices
|
||||
// Pipeline handles main light globally and there's no support for additional directional lights atm.
|
||||
for (int i = 0; i < visibleLights.Length; ++i)
|
||||
{
|
||||
if (additionalLightsCount >= UniversalRenderPipeline.maxVisibleAdditionalLights)
|
||||
break;
|
||||
|
||||
VisibleLight light = visibleLights[i];
|
||||
if (i == lightData.mainLightIndex)
|
||||
{
|
||||
perObjectLightIndexMap[i] = -1;
|
||||
++globalDirectionalLightsCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
perObjectLightIndexMap[i] -= globalDirectionalLightsCount;
|
||||
++additionalLightsCount;
|
||||
}
|
||||
}
|
||||
|
||||
// Disable all remaining lights we cannot fit into the global light buffer.
|
||||
for (int i = globalDirectionalLightsCount + additionalLightsCount; i < perObjectLightIndexMap.Length; ++i)
|
||||
perObjectLightIndexMap[i] = -1;
|
||||
|
||||
cullResults.SetLightIndexMap(perObjectLightIndexMap);
|
||||
|
||||
if (m_UseStructuredBuffer && additionalLightsCount > 0)
|
||||
{
|
||||
int lightAndReflectionProbeIndices = cullResults.lightAndReflectionProbeIndexCount;
|
||||
Assertions.Assert.IsTrue(lightAndReflectionProbeIndices > 0, "Pipelines configures additional lights but per-object light and probe indices count is zero.");
|
||||
cullResults.FillLightAndReflectionProbeIndices(ShaderData.instance.GetLightIndicesBuffer(lightAndReflectionProbeIndices));
|
||||
}
|
||||
|
||||
perObjectLightIndexMap.Dispose();
|
||||
return additionalLightsCount;
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user