Пример #1
0
        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);
        }
Пример #2
0
        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);
        }
Пример #4
0
        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);
        }
Пример #6
0
        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);
        }
Пример #7
0
        /// <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);
        }
Пример #8
0
        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);
        }
Пример #9
0
        /// <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);
        }
Пример #10
0
        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();
        }
Пример #11
0
        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);
                }
            }
        }