|
|
|
|
|
|
|
|
|
|
private bool m_IsOffscreenCamera; |
|
|
|
|
|
|
|
private Vector4 kDefaultLightPosition = new Vector4(0.0f, 0.0f, 1.0f, 0.0f); |
|
|
|
private Vector4 kDefaultLightColor = Color.black; |
|
|
|
private Vector4 kDefaultLightAttenuation = new Vector4(0.0f, 1.0f, 0.0f, 1.0f); |
|
|
|
private Vector4 kDefaultLightSpotDirection = new Vector4(0.0f, 0.0f, 1.0f, 0.0f); |
|
|
|
private Vector4 kDefaultLightSpotAttenuation = new Vector4(0.0f, 1.0f, 0.0f, 0.0f); |
|
|
|
|
|
|
|
private Vector4[] m_LightPositions = new Vector4[kMaxVisibleLights]; |
|
|
|
private Vector4[] m_LightColors = new Vector4[kMaxVisibleLights]; |
|
|
|
private Vector4[] m_LightDistanceAttenuations = new Vector4[kMaxVisibleLights]; |
|
|
|
|
|
|
// If we have a main light we don't shade it in the per-object light loop. We also remove it from the per-object cull list
|
|
|
|
int mainLightPresent = (lightData.mainLightIndex >= 0) ? 1 : 0; |
|
|
|
int additionalPixelLightsCount = visibleLightsCount - mainLightPresent; |
|
|
|
int vertexLightCount = (m_Asset.SupportsVertexLight) ? Math.Min(visibleLights.Count, kMaxPerObjectLights) - additionalPixelLightsCount : 0; |
|
|
|
int vertexLightCount = (m_Asset.SupportsVertexLight) ? Math.Min(visibleLights.Count, kMaxPerObjectLights) - additionalPixelLightsCount - mainLightPresent : 0; |
|
|
|
vertexLightCount = Math.Min(vertexLightCount, kMaxVertexLights); |
|
|
|
|
|
|
|
lightData.pixelAdditionalLightsCount = additionalPixelLightsCount; |
|
|
|
|
|
|
private void InitializeLightConstants(List<VisibleLight> lights, int lightIndex, out Vector4 lightPos, out Vector4 lightColor, out Vector4 lightDistanceAttenuation, out Vector4 lightSpotDir, |
|
|
|
out Vector4 lightSpotAttenuation) |
|
|
|
{ |
|
|
|
float directContributionNotBaked = 1.0f; |
|
|
|
lightPos = new Vector4(0.0f, 0.0f, 1.0f, 0.0f); |
|
|
|
lightColor = Color.black; |
|
|
|
lightDistanceAttenuation = new Vector4(0.0f, 1.0f, 0.0f, directContributionNotBaked); |
|
|
|
lightSpotDir = new Vector4(0.0f, 0.0f, 1.0f, 0.0f); |
|
|
|
lightSpotAttenuation = new Vector4(0.0f, 1.0f, 0.0f, 0.0f); |
|
|
|
lightPos = kDefaultLightPosition; |
|
|
|
lightColor = kDefaultLightColor; |
|
|
|
lightDistanceAttenuation = kDefaultLightSpotAttenuation; |
|
|
|
lightSpotDir = kDefaultLightSpotDirection; |
|
|
|
lightSpotAttenuation = kDefaultLightAttenuation; |
|
|
|
|
|
|
|
// When no lights are visible, main light will be set to -1.
|
|
|
|
// In this case we initialize it to default values and return
|
|
|
|
|
|
|
float oneOverFadeRangeSqr = 1.0f / fadeRangeSqr; |
|
|
|
float lightRangeSqrOverFadeRangeSqr = -lightRangeSqr / fadeRangeSqr; |
|
|
|
float quadAtten = 25.0f / lightRangeSqr; |
|
|
|
lightDistanceAttenuation = new Vector4(quadAtten, oneOverFadeRangeSqr, lightRangeSqrOverFadeRangeSqr, directContributionNotBaked); |
|
|
|
lightDistanceAttenuation = new Vector4(quadAtten, oneOverFadeRangeSqr, lightRangeSqrOverFadeRangeSqr, 1.0f); |
|
|
|
} |
|
|
|
|
|
|
|
if (lightData.lightType == LightType.Spot) |
|
|
|
|
|
|
if (lightData.shadowMapSampleType != LightShadows.None) |
|
|
|
SetupShadowReceiverConstants(cmd, lights[lightData.mainLightIndex]); |
|
|
|
|
|
|
|
if (lightData.totalAdditionalLightsCount > 0) |
|
|
|
SetupAdditionalListConstants(cmd, lights, ref lightData); |
|
|
|
SetupAdditionalListConstants(cmd, lights, ref lightData); |
|
|
|
} |
|
|
|
|
|
|
|
private void SetupMainLightConstants(CommandBuffer cmd, List<VisibleLight> lights, int lightIndex) |
|
|
|
|
|
|
{ |
|
|
|
int additionalLightIndex = 0; |
|
|
|
|
|
|
|
// We need to update per-object light list with the proper map to our global additional light buffer
|
|
|
|
// First we initialize all lights in the map to -1 to tell the system to discard main light index and
|
|
|
|
// remaining lights in the scene that don't fit the max additional light buffer (kMaxVisibileAdditionalLights)
|
|
|
|
int[] perObjectLightIndexMap = m_CullResults.GetLightIndexMap(); |
|
|
|
for (int i = 0; i < lights.Count; ++i) |
|
|
|
perObjectLightIndexMap[i] = -1; |
|
|
|
if (lightData.totalAdditionalLightsCount > 0) |
|
|
|
{ |
|
|
|
// We need to update per-object light list with the proper map to our global additional light buffer
|
|
|
|
// First we initialize all lights in the map to -1 to tell the system to discard main light index and
|
|
|
|
// remaining lights in the scene that don't fit the max additional light buffer (kMaxVisibileAdditionalLights)
|
|
|
|
int[] perObjectLightIndexMap = m_CullResults.GetLightIndexMap(); |
|
|
|
for (int i = 0; i < lights.Count; ++i) |
|
|
|
perObjectLightIndexMap[i] = -1; |
|
|
|
for (int i = 0; i < lights.Count && additionalLightIndex < kMaxVisibleLights; ++i) |
|
|
|
{ |
|
|
|
if (i != lightData.mainLightIndex) |
|
|
|
for (int i = 0; i < lights.Count && additionalLightIndex < kMaxVisibleLights; ++i) |
|
|
|
// The engine performs per-object light culling and initialize 8 light indices into two vec4 constants unity_4LightIndices0 and unity_4LightIndices1.
|
|
|
|
// In the shader we iterate over each visible light using the indices provided in these constants to index our global light buffer
|
|
|
|
// ex: first light position would be m_LightPosisitions[unity_4LightIndices[0]];
|
|
|
|
if (i != lightData.mainLightIndex) |
|
|
|
{ |
|
|
|
// The engine performs per-object light culling and initialize 8 light indices into two vec4 constants unity_4LightIndices0 and unity_4LightIndices1.
|
|
|
|
// In the shader we iterate over each visible light using the indices provided in these constants to index our global light buffer
|
|
|
|
// ex: first light position would be m_LightPosisitions[unity_4LightIndices[0]];
|
|
|
|
// However since we sorted the lights we need to tell the engine how to map the original/unsorted indices to our global buffer
|
|
|
|
// We do it by settings the perObjectLightIndexMap to the appropriate additionalLightIndex.
|
|
|
|
perObjectLightIndexMap[GetLightUnsortedIndex(i)] = additionalLightIndex; |
|
|
|
InitializeLightConstants(lights, i, out m_LightPositions[additionalLightIndex], |
|
|
|
out m_LightColors[additionalLightIndex], |
|
|
|
out m_LightDistanceAttenuations[additionalLightIndex], |
|
|
|
out m_LightSpotDirections[additionalLightIndex], |
|
|
|
out m_LightSpotAttenuations[additionalLightIndex]); |
|
|
|
additionalLightIndex++; |
|
|
|
// However since we sorted the lights we need to tell the engine how to map the original/unsorted indices to our global buffer
|
|
|
|
// We do it by settings the perObjectLightIndexMap to the appropriate additionalLightIndex.
|
|
|
|
perObjectLightIndexMap[GetLightUnsortedIndex(i)] = additionalLightIndex; |
|
|
|
InitializeLightConstants(lights, i, out m_LightPositions[additionalLightIndex], |
|
|
|
out m_LightColors[additionalLightIndex], |
|
|
|
out m_LightDistanceAttenuations[additionalLightIndex], |
|
|
|
out m_LightSpotDirections[additionalLightIndex], |
|
|
|
out m_LightSpotAttenuations[additionalLightIndex]); |
|
|
|
additionalLightIndex++; |
|
|
|
} |
|
|
|
m_CullResults.SetLightIndexMap(perObjectLightIndexMap); |
|
|
|
|
|
|
|
cmd.SetGlobalVector(PerCameraBuffer._AdditionalLightCount, new Vector4(lightData.pixelAdditionalLightsCount, |
|
|
|
lightData.totalAdditionalLightsCount, 0.0f, 0.0f)); |
|
|
|
m_CullResults.SetLightIndexMap(perObjectLightIndexMap); |
|
|
|
else |
|
|
|
{ |
|
|
|
cmd.SetGlobalVector(PerCameraBuffer._AdditionalLightCount, Vector4.zero); |
|
|
|
cmd.SetGlobalVector(PerCameraBuffer._AdditionalLightCount, new Vector4(lightData.pixelAdditionalLightsCount, |
|
|
|
lightData.totalAdditionalLightsCount, 0.0f, 0.0f)); |
|
|
|
// Clear to default all light cosntant data
|
|
|
|
for (int i = 0; i < kMaxVisibleLights; ++i) |
|
|
|
InitializeLightConstants(lights, -1, out m_LightPositions[additionalLightIndex], |
|
|
|
out m_LightColors[additionalLightIndex], |
|
|
|
out m_LightDistanceAttenuations[additionalLightIndex], |
|
|
|
out m_LightSpotDirections[additionalLightIndex], |
|
|
|
out m_LightSpotAttenuations[additionalLightIndex]); |
|
|
|
} |
|
|
|
|
|
|
|
cmd.SetGlobalVectorArray(PerCameraBuffer._AdditionalLightPosition, m_LightPositions); |
|
|
|
cmd.SetGlobalVectorArray(PerCameraBuffer._AdditionalLightColor, m_LightColors); |
|
|
|
cmd.SetGlobalVectorArray(PerCameraBuffer._AdditionalLightDistanceAttenuation, m_LightDistanceAttenuations); |
|
|
|