Exemplo n.º 1
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);
        }
Exemplo n.º 2
0
        public bool Setup(RenderTargetHandle destination, ref RenderingData renderingData)
        {
            Clear();
            this.destination = destination;

            int shadowLightIndex = renderingData.lightData.mainLightIndex;

            if (shadowLightIndex == -1)
            {
                return(false);
            }

            VisibleLight shadowLight = renderingData.lightData.visibleLights[shadowLightIndex];
            Light        light       = shadowLight.light;

            if (light.shadows == LightShadows.None)
            {
                return(false);
            }

            if (shadowLight.lightType != LightType.Directional)
            {
                Debug.LogWarning("Only directional lights are supported as main light.");
            }

            Bounds bounds;

            if (!renderingData.cullResults.GetShadowCasterBounds(shadowLightIndex, out bounds))
            {
                return(false);
            }

            m_ShadowCasterCascadesCount = renderingData.shadowData.mainLightShadowCascadesCount;

            int shadowResolution = ShadowUtils.GetMaxTileResolutionInAtlas(renderingData.shadowData.mainLightShadowmapWidth,
                                                                           renderingData.shadowData.mainLightShadowmapHeight, m_ShadowCasterCascadesCount);

            for (int cascadeIndex = 0; cascadeIndex < m_ShadowCasterCascadesCount; ++cascadeIndex)
            {
                bool success = ShadowUtils.ExtractDirectionalLightMatrix(ref renderingData.cullResults, ref renderingData.shadowData,
                                                                         shadowLightIndex, cascadeIndex, shadowResolution, light.shadowNearPlane,
                                                                         out m_CascadeSplitDistances[cascadeIndex], out m_CascadeSlices[cascadeIndex], out m_CascadeSlices[cascadeIndex].viewMatrix, out m_CascadeSlices[cascadeIndex].projectionMatrix);

                if (!success)
                {
                    return(false);
                }
            }

            return(true);
        }
Exemplo n.º 3
0
        void RenderMainLightCascadeShadowmap(ref ScriptableRenderContext context, ref CullResults 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 DrawShadowsSettings(cullResults, shadowLightIndex);

                m_MainLightShadowmapTexture = RenderTexture.GetTemporary(shadowData.mainLightShadowmapWidth,
                                                                         shadowData.mainLightShadowmapHeight, k_ShadowmapBufferBits, m_ShadowmapFormat);
                m_MainLightShadowmapTexture.filterMode = FilterMode.Bilinear;
                m_MainLightShadowmapTexture.wrapMode   = TextureWrapMode.Clamp;
                SetRenderTarget(cmd, m_MainLightShadowmapTexture, RenderBufferLoadAction.DontCare,
                                RenderBufferStoreAction.Store, ClearFlag.Depth, Color.black, TextureDimension.Tex2D);

                for (int cascadeIndex = 0; cascadeIndex < m_ShadowCasterCascadesCount; ++cascadeIndex)
                {
                    settings.splitData.cullingSphere = m_CascadeSplitDistances[cascadeIndex];
                    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);
        }
Exemplo n.º 4
0
        public bool Setup(RenderTargetHandle destination, ref RenderingData renderingData, int maxVisibleAdditinalLights)
        {
            Clear();
            this.destination = destination;

            if (m_AdditionalLightShadowMatrices.Length != maxVisibleAdditinalLights)
            {
                m_AdditionalLightShadowMatrices  = new Matrix4x4[maxVisibleAdditinalLights];
                m_AdditionalLightSlices          = new ShadowSliceData[maxVisibleAdditinalLights];
                m_AdditionalLightsShadowStrength = new float[maxVisibleAdditinalLights];
            }
            m_AdditionalShadowCastingLightIndices.Clear();

            Bounds bounds;
            List <VisibleLight> visibleLights = renderingData.lightData.visibleLights;
            int additionalLightsCount         = renderingData.lightData.additionalLightsCount;

            for (int i = 0; i < visibleLights.Count && m_AdditionalShadowCastingLightIndices.Count < additionalLightsCount; ++i)
            {
                if (i == renderingData.lightData.mainLightIndex)
                {
                    continue;
                }

                VisibleLight shadowLight = visibleLights[i];
                Light        light       = shadowLight.light;

                if (shadowLight.lightType == LightType.Spot && light != null && light.shadows != LightShadows.None)
                {
                    if (renderingData.cullResults.GetShadowCasterBounds(i, out bounds))
                    {
                        m_AdditionalShadowCastingLightIndices.Add(i);
                    }
                }
            }

            int shadowCastingLightsCount = m_AdditionalShadowCastingLightIndices.Count;

            if (shadowCastingLightsCount == 0)
            {
                return(false);
            }

            // TODO: Add support to point light shadows. We make a simplification here that only works
            // for spot lights and with max spot shadows per pass.
            int atlasWidth      = renderingData.shadowData.additionalLightsShadowmapWidth;
            int atlasHeight     = renderingData.shadowData.additionalLightsShadowmapHeight;
            int sliceResolution = ShadowUtils.GetMaxTileResolutionInAtlas(atlasWidth, atlasHeight, shadowCastingLightsCount);

            bool anyShadows         = false;
            int  shadowSlicesPerRow = (atlasWidth / sliceResolution);

            for (int i = 0; i < shadowCastingLightsCount; ++i)
            {
                int          shadowLightIndex = m_AdditionalShadowCastingLightIndices[i];
                VisibleLight shadowLight      = visibleLights[shadowLightIndex];

                // Currently Only Spot Lights are supported in additional lights
                Debug.Assert(shadowLight.lightType == LightType.Spot);
                Matrix4x4 shadowTransform;
                bool      success = ShadowUtils.ExtractSpotLightMatrix(ref renderingData.cullResults, ref renderingData.shadowData,
                                                                       shadowLightIndex, out shadowTransform, out m_AdditionalLightSlices[i].viewMatrix, out m_AdditionalLightSlices[i].projectionMatrix);

                if (success)
                {
                    // TODO: We need to pass bias and scale list to shader to be able to support multiple
                    // shadow casting additional lights.
                    m_AdditionalLightSlices[i].offsetX         = (i % shadowSlicesPerRow) * sliceResolution;
                    m_AdditionalLightSlices[i].offsetY         = (i / shadowSlicesPerRow) * sliceResolution;
                    m_AdditionalLightSlices[i].resolution      = sliceResolution;
                    m_AdditionalLightSlices[i].shadowTransform = shadowTransform;

                    m_AdditionalLightsShadowStrength[i] = shadowLight.light.shadowStrength;
                    anyShadows = true;
                }
                else
                {
                    m_AdditionalShadowCastingLightIndices.RemoveAt(i--);
                }
            }

            return(anyShadows);
        }