private void InitializeLightData(VisibleLight[] lights, out LightData lightData) { for (int i = 0; i < kMaxVisibleLights; ++i) { m_LightPositions[i] = Vector4.zero; m_LightColors[i] = Vector4.zero; m_LightAttenuations[i] = new Vector4(0.0f, 1.0f, 0.0f, 0.0f); m_LightSpotDirections[i] = new Vector4(0.0f, 0.0f, 1.0f, 0.0f); } int lightsCount = lights.Length; int maxPerPixelLights = Math.Min(m_Asset.MaxSupportedPixelLights, kMaxPerObjectLights); lightData.pixelLightsCount = Math.Min(lightsCount, maxPerPixelLights); lightData.vertexLightsCount = (m_Asset.SupportsVertexLight) ? Math.Min(lightsCount - lightData.pixelLightsCount, kMaxPerObjectLights) : 0; lightData.isSingleDirectionalLight = lightData.pixelLightsCount == 1 && lightData.vertexLightsCount == 0 && lights[0].lightType == LightType.Directional; // Directional light path can handle unlit. if (lightsCount == 0) { lightData.isSingleDirectionalLight = true; } lightData.shadowsRendered = false; InitializeMainShadowLightIndex(lights, out lightData.shadowLightIndex); }
private void InitializeLightData(VisibleLight[] lights, out LightData lightData) { for (int i = 0; i < kMaxVisibleLights; ++i) { m_LightPositions[i] = Vector4.zero; m_LightColors[i] = Vector4.zero; m_LightAttenuations[i] = new Vector4(0.0f, 1.0f, 0.0f, 0.0f); m_LightSpotDirections[i] = new Vector4(0.0f, 0.0f, 1.0f, 0.0f); } int lightsCount = lights.Length; lightData.pixelLightsCount = Mathf.Min(lightsCount, m_Asset.MaxSupportedPixelLights); lightData.vertexLightsCount = (m_Asset.SupportsVertexLight) ? Mathf.Min(lightsCount - lightData.pixelLightsCount, kMaxVertexLights) : 0; lightData.isSingleDirectionalLight = lightData.pixelLightsCount == 1 && lightData.vertexLightsCount == 0 && lights[0].lightType == LightType.Directional; }
void SetShaderKeywords(CommandBuffer cmd, ref CameraData cameraData, ref LightData lightData, ref ShadowData shadowData) { int vertexLightsCount = lightData.totalAdditionalLightsCount - lightData.pixelAdditionalLightsCount; CoreUtils.SetKeyword(cmd, LightweightKeywordStrings.AdditionalLights, lightData.totalAdditionalLightsCount > 0); CoreUtils.SetKeyword(cmd, LightweightKeywordStrings.MixedLightingSubtractive, m_MixedLightingSetup == MixedLightingSetup.Subtractive); CoreUtils.SetKeyword(cmd, LightweightKeywordStrings.VertexLights, vertexLightsCount > 0); List <VisibleLight> visibleLights = lightData.visibleLights; // If shadows were resolved in screen space we don't sample shadowmap in lit shader. In that case we just set softDirectionalShadows to false. bool softDirectionalShadows = shadowData.renderDirectionalShadows && !shadowData.requiresScreenSpaceShadowResolve && shadowData.supportsSoftShadows && lightData.mainLightIndex != -1 && visibleLights[lightData.mainLightIndex].light.shadows == LightShadows.Soft; bool softLocalShadows = false; if (shadowData.renderLocalShadows && shadowData.supportsSoftShadows) { List <int> visibleLocalLightIndices = lightData.visibleLocalLightIndices; for (int i = 0; i < visibleLocalLightIndices.Count; ++i) { if (visibleLights[visibleLocalLightIndices[i]].light.shadows == LightShadows.Soft) { softLocalShadows = true; break; } } } // Currently shadow filtering keyword is shared between local and directional shadows. bool hasSoftShadows = softDirectionalShadows || softLocalShadows; CoreUtils.SetKeyword(cmd, LightweightKeywordStrings.DirectionalShadows, shadowData.renderDirectionalShadows); CoreUtils.SetKeyword(cmd, LightweightKeywordStrings.LocalShadows, shadowData.renderLocalShadows); CoreUtils.SetKeyword(cmd, LightweightKeywordStrings.SoftShadows, hasSoftShadows); CoreUtils.SetKeyword(cmd, LightweightKeywordStrings.CascadeShadows, shadowData.directionalLightCascadeCount > 1); // TODO: Remove this. legacy particles support will be removed from Unity in 2018.3. This should be a shader_feature instead with prop exposed in the Standard particles shader. CoreUtils.SetKeyword(cmd, LightweightKeywordStrings.SoftParticles, cameraData.requiresSoftParticles); }
void SetShaderKeywords(CommandBuffer cmd, ref CameraData cameraData, ref LightData lightData, ref ShadowData shadowData) { CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.AdditionalLightsVertex, lightData.additionalLightsCount > 0 && lightData.shadeAdditionalLightsPerVertex); CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.AdditionalLightsPixel, lightData.additionalLightsCount > 0 && !lightData.shadeAdditionalLightsPerVertex); CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.MixedLightingSubtractive, lightData.supportsMixedLighting && m_MixedLightingSetup == MixedLightingSetup.Subtractive); List <VisibleLight> visibleLights = lightData.visibleLights; // If shadows were resolved in screen space we don't sample shadowmap in lit shader. In that case we just set softDirectionalShadows to false. bool softMainLightShadows = shadowData.supportsMainLightShadows && !shadowData.requiresScreenSpaceShadowResolve && shadowData.supportsSoftShadows && lightData.mainLightIndex != -1 && visibleLights[lightData.mainLightIndex].light.shadows == LightShadows.Soft; bool softAdditionalLightShadows = false; if (shadowData.supportsAdditionalLightShadows && shadowData.supportsSoftShadows) { List <int> visibleAdditionalLightIndices = lightData.additionalLightIndices; for (int i = 0; i < visibleAdditionalLightIndices.Count; ++i) { if (visibleLights[visibleAdditionalLightIndices[i]].light.shadows == LightShadows.Soft) { softAdditionalLightShadows = true; break; } } } // Currently shadow filtering keyword is shared between additional and directional shadows. bool hasSoftShadows = softMainLightShadows || softAdditionalLightShadows; CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.MainLightShadows, shadowData.supportsMainLightShadows); CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.AdditionalLightShadows, shadowData.supportsAdditionalLightShadows); CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.SoftShadows, hasSoftShadows); CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.MainLightShadowCascades, shadowData.mainLightShadowCascadesCount > 1); }
void RenderMainLightCascadeShadowmap(ref ScriptableRenderContext context, ref CullingResults cullResults, ref LightData lightData, ref ShadowData shadowData) { int shadowLightIndex = lightData.mainLightIndex; if (shadowLightIndex == -1) { return; } VisibleLight shadowLight = lightData.visibleLights[shadowLightIndex]; CommandBuffer cmd = CommandBufferPool.Get(k_RenderMainLightShadowmapTag); using (new ProfilingSample(cmd, k_RenderMainLightShadowmapTag)) { var settings = new ShadowDrawingSettings(cullResults, shadowLightIndex); m_MainLightShadowmapTexture = ShadowUtils.GetTemporaryShadowTexture(shadowData.mainLightShadowmapWidth, shadowData.mainLightShadowmapHeight, k_ShadowmapBufferBits); SetRenderTarget(cmd, m_MainLightShadowmapTexture, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store, ClearFlag.Depth, Color.black, TextureDimension.Tex2D); for (int cascadeIndex = 0; cascadeIndex < m_ShadowCasterCascadesCount; ++cascadeIndex) { var splitData = settings.splitData; splitData.cullingSphere = m_CascadeSplitDistances[cascadeIndex]; settings.splitData = splitData; Vector4 shadowBias = ShadowUtils.GetShadowBias(ref shadowLight, shadowLightIndex, ref shadowData, m_CascadeSlices[cascadeIndex].projectionMatrix, m_CascadeSlices[cascadeIndex].resolution); ShadowUtils.SetupShadowCasterConstantBuffer(cmd, ref shadowLight, shadowBias); ShadowUtils.RenderShadowSlice(cmd, ref context, ref m_CascadeSlices[cascadeIndex], ref settings, m_CascadeSlices[cascadeIndex].projectionMatrix, m_CascadeSlices[cascadeIndex].viewMatrix); } SetupMainLightShadowReceiverConstants(cmd, ref shadowData, shadowLight); } CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.MainLightShadows, true); CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.MainLightShadowCascades, shadowData.mainLightShadowCascadesCount > 1); CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.SoftShadows, shadowLight.light.shadows == LightShadows.Soft && shadowData.supportsSoftShadows); context.ExecuteCommandBuffer(cmd); CommandBufferPool.Release(cmd); }
void RenderAdditionalShadowmapAtlas(ref ScriptableRenderContext context, ref CullResults cullResults, ref LightData lightData, ref ShadowData shadowData) { List <VisibleLight> visibleLights = lightData.visibleLights; bool additionalLightHasSoftShadows = false; CommandBuffer cmd = CommandBufferPool.Get(k_RenderAdditionalLightShadows); using (new ProfilingSample(cmd, k_RenderAdditionalLightShadows)) { int shadowmapWidth = shadowData.additionalLightsShadowmapWidth; int shadowmapHeight = shadowData.additionalLightsShadowmapHeight; m_AdditionalLightsShadowmapTexture = RenderTexture.GetTemporary(shadowmapWidth, shadowmapHeight, k_ShadowmapBufferBits, m_AdditionalShadowmapFormat); m_AdditionalLightsShadowmapTexture.filterMode = FilterMode.Bilinear; m_AdditionalLightsShadowmapTexture.wrapMode = TextureWrapMode.Clamp; SetRenderTarget(cmd, m_AdditionalLightsShadowmapTexture, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store, ClearFlag.Depth, Color.black, TextureDimension.Tex2D); for (int i = 0; i < m_AdditionalShadowCastingLightIndices.Count; ++i) { int shadowLightIndex = m_AdditionalShadowCastingLightIndices[i]; VisibleLight shadowLight = visibleLights[shadowLightIndex]; if (m_AdditionalShadowCastingLightIndices.Count > 1) { ShadowUtils.ApplySliceTransform(ref m_AdditionalLightSlices[i], shadowmapWidth, shadowmapHeight); } var settings = new DrawShadowsSettings(cullResults, shadowLightIndex); Vector4 shadowBias = ShadowUtils.GetShadowBias(ref shadowLight, shadowLightIndex, ref shadowData, m_AdditionalLightSlices[i].projectionMatrix, m_AdditionalLightSlices[i].resolution); ShadowUtils.SetupShadowCasterConstantBuffer(cmd, ref shadowLight, shadowBias); ShadowUtils.RenderShadowSlice(cmd, ref context, ref m_AdditionalLightSlices[i], ref settings, m_AdditionalLightSlices[i].projectionMatrix, m_AdditionalLightSlices[i].viewMatrix); additionalLightHasSoftShadows |= shadowLight.light.shadows == LightShadows.Soft; } SetupAdditionalLightsShadowReceiverConstants(cmd, ref shadowData); } // We share soft shadow settings for main light and additional lights to save keywords. // So we check here if pipeline supports soft shadows and either main light or any additional light has soft shadows // to enable the keyword. // TODO: In PC and Consoles we can upload shadow data per light and branch on shader. That will be more likely way faster. bool mainLightHasSoftShadows = shadowData.supportsMainLightShadows && lightData.mainLightIndex != -1 && visibleLights[lightData.mainLightIndex].light.shadows == LightShadows.Soft; bool softShadows = shadowData.supportsSoftShadows && (mainLightHasSoftShadows || additionalLightHasSoftShadows); CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.AdditionalLightShadows, true); CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.SoftShadows, softShadows); context.ExecuteCommandBuffer(cmd); CommandBufferPool.Release(cmd); }
/// <inheritdoc/> public override void Execute(ScriptableRenderer renderer, ScriptableRenderContext context, ref RenderingData renderingData) { if (renderer == null) { throw new ArgumentNullException("renderer"); } if (!renderingData.shadowData.supportsDeepShadowMaps) { return; } LightData lightData = renderingData.lightData; int shadowLightIndex = lightData.mainLightIndex; if (shadowLightIndex == -1) { return; } VisibleLight shadowLight = lightData.visibleLights[shadowLightIndex]; ShadowData shadowData = renderingData.shadowData; if (!GetVPMatrix(shadowLight.light)) { return; } if (null == _ResetCompute) { _ResetCompute = renderer.GetCompute(ComputeHandle.ResetDeepShadowDataCompute); KernelResetBuffer = _ResetCompute.FindKernel("KernelResetBuffer"); } CommandBuffer cmd = CommandBufferPool.Get(k_RenderDeepShadowCaster); using (new ProfilingSample(cmd, k_RenderDeepShadowCaster)) { int deepShadowMapsSize = shadowData.deepShadowMapsSize; int deepShadowMapsDepth = shadowData.deepShadowMapsDepth; // Reset cmd.SetComputeBufferParam(_ResetCompute, KernelResetBuffer, "_CountBuffer", _CountBuffer); cmd.SetComputeBufferParam(_ResetCompute, KernelResetBuffer, "_DataBuffer", _DataBuffer); cmd.SetComputeIntParam(_ResetCompute, "_DeepShadowMapSize", deepShadowMapsSize); cmd.SetComputeIntParam(_ResetCompute, "_DeepShadowMapDepth", deepShadowMapsDepth); cmd.DispatchCompute(_ResetCompute, KernelResetBuffer, deepShadowMapsSize / 8, deepShadowMapsSize / 8, 1); _Temp = RenderTexture.GetTemporary(deepShadowMapsSize, deepShadowMapsSize, 0, RenderTextureFormat.R8); //Without rt, the second row of the vp matrix is negated // Cast SetRenderTarget(cmd, _Temp, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.DontCare, ClearFlag.Color, Color.black, TextureDimension.Tex2D); cmd.SetViewport(new Rect(Vector2.zero, Vector2.one * deepShadowMapsSize)); Vector4 shadowBias = ShadowUtils.GetShadowBias(ref shadowLight, shadowLightIndex, ref shadowData, _ProjMatrix, shadowData.deepShadowMapsSize); ShadowUtils.SetupShadowCasterConstantBuffer(cmd, ref shadowLight, shadowBias); cmd.SetViewProjectionMatrices(_ViewMatrix, _ProjMatrix); cmd.SetRandomWriteTarget(1, _CountBuffer); cmd.SetRandomWriteTarget(2, _DataBuffer); cmd.SetGlobalInt("_DeepShadowMapSize", deepShadowMapsSize); cmd.SetGlobalInt("_DeepShadowMapDepth", deepShadowMapsDepth); context.ExecuteCommandBuffer(cmd); cmd.Clear(); //foreach (var r in _Renderers) //{ // for (int i = 0, imax = r.sharedMaterials.Length; i < imax; i++) // { // cmd.DrawRenderer(r, r.sharedMaterials[i], i, r.sharedMaterials[i].FindPass("DeepShadowCaster")); // } //} ShadowSliceData slice = new ShadowSliceData() { offsetX = 0, offsetY = 0, resolution = deepShadowMapsSize, }; cmd.SetGlobalMatrix("_DeepShadowMapsWorldToShadow", _DeepShadowMatrix); DrawShadowsSettings settings = new DrawShadowsSettings(renderingData.cullResults, shadowLightIndex); settings.splitData.cullingSphere = _CullingSphere; cmd.EnableShaderKeyword("_DEEP_SHADOW_CASTER"); cmd.SetGlobalInt("_ShadowCasterZWrite", 0); ShadowUtils.RenderShadowSlice(cmd, ref context, ref slice, ref settings, _ProjMatrix, _ViewMatrix); cmd.DisableShaderKeyword("_DEEP_SHADOW_CASTER"); cmd.SetGlobalInt("_ShadowCasterZWrite", 1); context.ExecuteCommandBuffer(cmd); cmd.Clear(); // For Resolve SetupDeepShadowMapResolverConstants(cmd, ref shadowData, shadowLight); cmd.ClearRandomWriteTargets(); } context.ExecuteCommandBuffer(cmd); CommandBufferPool.Release(cmd); }
void SetupShaderConstants(ref ScriptableRenderContext context, ref CameraData cameraData, ref LightData lightData, ref ShadowData shadowData) { CommandBuffer cmd = CommandBufferPool.Get("SetupShaderConstants"); SetupShaderLightConstants(cmd, ref lightData); SetShaderKeywords(cmd, ref cameraData, ref lightData, ref shadowData); context.ExecuteCommandBuffer(cmd); CommandBufferPool.Release(cmd); }
/// <inheritdoc/> public override void Execute(ScriptableRenderer renderer, ScriptableRenderContext context, ref RenderingData renderingData) { if (renderer == null) { throw new ArgumentNullException("renderer"); } if (!renderingData.shadowData.supportsDeepShadowMaps) { return; } LightData lightData = renderingData.lightData; int shadowLightIndex = lightData.mainLightIndex; if (shadowLightIndex == -1) { return; } VisibleLight shadowLight = lightData.visibleLights[shadowLightIndex]; ShadowData shadowData = renderingData.shadowData; RenderTargetIdentifier result; CommandBuffer cmd = CommandBufferPool.Get(k_RenderScreenSpaceDeepShadowMaps); using (new ProfilingSample(cmd, k_RenderScreenSpaceDeepShadowMaps)) { #if UNITY_EDITOR var testDescriptor = _Descriptor; testDescriptor.enableRandomWrite = true; testDescriptor.colorFormat = RenderTextureFormat.ARGB32; cmd.GetTemporaryRT(_DeepShadowTest.id, testDescriptor); var _ResetCompute = renderer.GetCompute(ComputeHandle.ResetDeepShadowDataCompute); int KernelTestDeepShadowMap = _ResetCompute.FindKernel("KernelTestDeepShadowMap"); cmd.SetRenderTarget(_DeepShadowTest.Identifier()); cmd.SetComputeBufferParam(_ResetCompute, KernelTestDeepShadowMap, "_CountBuffer", _CountBuffer); cmd.SetComputeBufferParam(_ResetCompute, KernelTestDeepShadowMap, "_DataBuffer", _DataBuffer); cmd.SetComputeTextureParam(_ResetCompute, KernelTestDeepShadowMap, "_TestRt", _DeepShadowTest.Identifier()); cmd.DispatchCompute(_ResetCompute, KernelTestDeepShadowMap, shadowData.deepShadowMapsSize / 8, shadowData.deepShadowMapsSize / 8, 1); context.ExecuteCommandBuffer(cmd); cmd.Clear(); #endif // Resolve Material ssdsm = renderer.GetMaterial(MaterialHandle.ScreenSpaceDeepShadowMaps); ssdsm.SetBuffer(Shader.PropertyToID("_CountBuffer"), _CountBuffer); ssdsm.SetBuffer(Shader.PropertyToID("_DataBuffer"), _DataBuffer); cmd.GetTemporaryRT(_DeepShadowLut.id, _Descriptor); RenderTargetIdentifier lutId = _DeepShadowLut.Identifier(); SetRenderTarget(cmd, lutId, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store, ClearFlag.Color | ClearFlag.Depth, Color.black, _Descriptor.dimension); cmd.Blit(lutId, lutId, ssdsm); result = lutId; // Blur int blurOffset = shadowData.deepShadowMapsBlurOffset; if (blurOffset > 0) { Material pom = renderer.GetMaterial(MaterialHandle.GaussianBlur); cmd.GetTemporaryRT(_DeepShadowTmp.id, _Descriptor); RenderTargetIdentifier src = lutId; RenderTargetIdentifier dst = _DeepShadowTmp.Identifier(); while (blurOffset > 0) { pom.SetFloat("_SampleOffset", blurOffset); SetRenderTarget(cmd, dst, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store, ClearFlag.Color | ClearFlag.Depth, Color.black, _Descriptor.dimension); cmd.Blit(src, dst, pom); result = dst; dst = src; src = result; blurOffset >>= 1; } } //TODO : for stereo context.ExecuteCommandBuffer(cmd); cmd.Clear(); cmd.SetGlobalTexture(_Destination.id, result); cmd.ReleaseTemporaryRT(_DeepShadowTest.id); } //SetKeyword CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.DeepShadowMaps, true); context.ExecuteCommandBuffer(cmd); CommandBufferPool.Release(cmd); }
private void SetupLightShaderVariables(VisibleLight[] lights, ref CullResults cullResults, ref ScriptableRenderContext context, ref LightData lightData) { int maxLights = 1; if (!lightData.isSingleDirectionalLight) { FillLightIndices(ref cullResults, lights.Length); maxLights = Math.Min(kMaxVisibleLights, lights.Length); } for (int i = 0; i < maxLights; ++i) { 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 pos = currLight.localToWorld.GetColumn(3); m_LightPositions[i] = new Vector4(pos.x, pos.y, pos.z, 1.0f); } m_LightColors[i] = currLight.finalColor; float rangeSq = currLight.range * currLight.range; float quadAtten = (currLight.lightType == LightType.Directional) ? 0.0f : 25.0f / rangeSq; if (currLight.lightType == LightType.Spot) { Vector4 dir = currLight.localToWorld.GetColumn(2); m_LightSpotDirections[i] = new Vector4(-dir.x, -dir.y, -dir.z, 0.0f); float spotAngle = Mathf.Deg2Rad * currLight.spotAngle; float cosOuterAngle = Mathf.Cos(spotAngle * 0.5f); float cosInneAngle = Mathf.Cos(spotAngle * 0.25f); float angleRange = cosInneAngle - cosOuterAngle; m_LightAttenuations[i] = new Vector4(cosOuterAngle, Mathf.Approximately(angleRange, 0.0f) ? 1.0f : angleRange, quadAtten, rangeSq); } else { 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); context.ExecuteCommandBuffer(cmd); cmd.Dispose(); }
public void SetupPerObjectLightIndices(ref CullingResults cullResults, ref LightData lightData) { if (lightData.additionalLightsCount == 0) { return; } var visibleLights = lightData.visibleLights; var perObjectLightIndexMap = cullResults.GetLightIndexMap(Allocator.Temp); int directionalLightsCount = 0; int additionalLightsCount = 0; // Disable all directional lights from the perobject light indices // Pipeline handles them globally. for (int i = 0; i < visibleLights.Length; ++i) { if (additionalLightsCount >= maxVisibleAdditionalLights) { break; } VisibleLight light = visibleLights[i]; if (light.lightType == LightType.Directional) { perObjectLightIndexMap[i] = -1; ++directionalLightsCount; } else { perObjectLightIndexMap[i] -= directionalLightsCount; ++additionalLightsCount; } } // Disable all remaining lights we cannot fit into the global light buffer. for (int i = directionalLightsCount + additionalLightsCount; i < visibleLights.Length; ++i) { perObjectLightIndexMap[i] = -1; } cullResults.SetLightIndexMap(perObjectLightIndexMap); perObjectLightIndexMap.Dispose(); // if not using a compute buffer, engine will set indices in 2 vec4 constants // unity_4LightIndices0 and unity_4LightIndices1 if (useStructuredBufferForLights) { int lightIndicesCount = cullResults.lightAndReflectionProbeIndexCount; if (lightIndicesCount > 0) { if (perObjectLightIndices == null) { perObjectLightIndices = new ComputeBuffer(lightIndicesCount, sizeof(int)); } else if (perObjectLightIndices.count < lightIndicesCount) { perObjectLightIndices.Release(); perObjectLightIndices = new ComputeBuffer(lightIndicesCount, sizeof(int)); } cullResults.FillLightAndReflectionProbeIndices(perObjectLightIndices); } } }