public static void ApplySliceTransform(ref ShadowSliceData shadowSliceData, int atlasWidth, int atlasHeight)
        {
            Matrix4x4 sliceTransform     = Matrix4x4.identity;
            float     oneOverAtlasWidth  = 1.0f / atlasWidth;
            float     oneOverAtlasHeight = 1.0f / atlasHeight;

            sliceTransform.m00 = shadowSliceData.resolution * oneOverAtlasWidth;
            sliceTransform.m11 = shadowSliceData.resolution * oneOverAtlasHeight;
            sliceTransform.m03 = shadowSliceData.offsetX * oneOverAtlasWidth;
            sliceTransform.m13 = shadowSliceData.offsetY * oneOverAtlasHeight;

            // Apply shadow slice scale and offset
            shadowSliceData.shadowTransform = sliceTransform * shadowSliceData.shadowTransform;
        }
        public static void RenderShadowSlice(CommandBuffer cmd, ref ScriptableRenderContext context,
                                             ref ShadowSliceData shadowSliceData, ref ShadowDrawingSettings settings,
                                             Matrix4x4 proj, Matrix4x4 view)
        {
            cmd.SetViewport(new Rect(shadowSliceData.offsetX, shadowSliceData.offsetY, shadowSliceData.resolution, shadowSliceData.resolution));
            cmd.EnableScissorRect(new Rect(shadowSliceData.offsetX + 4, shadowSliceData.offsetY + 4, shadowSliceData.resolution - 8, shadowSliceData.resolution - 8));

            cmd.SetViewProjectionMatrices(view, proj);
            context.ExecuteCommandBuffer(cmd);
            cmd.Clear();
            context.DrawShadows(ref settings);
            cmd.DisableScissorRect();
            context.ExecuteCommandBuffer(cmd);
            cmd.Clear();
        }
        public static bool ExtractDirectionalLightMatrix(ref CullingResults cullResults, ref ShadowData shadowData, int shadowLightIndex, int cascadeIndex, int shadowResolution, float shadowNearPlane, out Vector4 cascadeSplitDistance, out ShadowSliceData shadowSliceData, out Matrix4x4 viewMatrix, out Matrix4x4 projMatrix)
        {
            ShadowSplitData splitData;
            bool            success = cullResults.ComputeDirectionalShadowMatricesAndCullingPrimitives(shadowLightIndex,
                                                                                                       cascadeIndex, shadowData.mainLightShadowCascadesCount, shadowData.mainLightShadowCascadesSplit, shadowResolution, shadowNearPlane, out viewMatrix, out projMatrix,
                                                                                                       out splitData);

            cascadeSplitDistance             = splitData.cullingSphere;
            shadowSliceData.offsetX          = (cascadeIndex % 2) * shadowResolution;
            shadowSliceData.offsetY          = (cascadeIndex / 2) * shadowResolution;
            shadowSliceData.resolution       = shadowResolution;
            shadowSliceData.viewMatrix       = viewMatrix;
            shadowSliceData.projectionMatrix = projMatrix;
            shadowSliceData.shadowTransform  = GetShadowTransform(projMatrix, viewMatrix);

            // If we have shadow cascades baked into the atlas we bake cascade transform
            // in each shadow matrix to save shader ALU and L/S
            if (shadowData.mainLightShadowCascadesCount > 1)
            {
                ApplySliceTransform(ref shadowSliceData, shadowData.mainLightShadowmapWidth, shadowData.mainLightShadowmapHeight);
            }

            return(success);
        }
Beispiel #4
0
        /// <inheritdoc/>
        public override void Execute(ScriptableRenderer renderer, ScriptableRenderContext context, ref RenderingData renderingData)
        {
            if (renderer == null)
            {
                throw new ArgumentNullException("renderer");
            }

            if (!renderingData.shadowData.supportsMainCharacterShadows)
            {
                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;
            }

            CommandBuffer cmd = CommandBufferPool.Get(k_RenderMainCharacterShadowmapTag);

            using (new ProfilingSample(cmd, k_RenderMainCharacterShadowmapTag))
            {
                m_MainCharacterShadowmapTexture = RenderTexture.GetTemporary(shadowData.mainCharacterShadowmapWidth,
                                                                             shadowData.mainCharacterShadowmapHeight, k_ShadowmapBufferBits, m_ShadowmapFormat);
                m_MainCharacterShadowmapTexture.filterMode = FilterMode.Bilinear;
                m_MainCharacterShadowmapTexture.wrapMode   = TextureWrapMode.Clamp;
                m_MainCharacterShadowmapTexture.name       = "m_MainCharacterShadowmapTexture";
                SetRenderTarget(cmd, m_MainCharacterShadowmapTexture, RenderBufferLoadAction.DontCare,
                                RenderBufferStoreAction.Store, ClearFlag.Depth, Color.black, TextureDimension.Tex2D);

                Vector4 shadowBias = ShadowUtils.GetShadowBias(ref shadowLight, shadowLightIndex, ref shadowData, m_ProjMatrix, shadowData.mainCharacterShadowmapWidth);
                ShadowUtils.SetupShadowCasterConstantBuffer(cmd, ref shadowLight, shadowBias);

                cmd.SetViewProjectionMatrices(m_ViewMatrix, m_ProjMatrix);
                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("ShadowCaster"));
                //    }
                //}
                ShadowSliceData slice = new ShadowSliceData()
                {
                    offsetX    = 0,
                    offsetY    = 0,
                    resolution = shadowData.mainCharacterShadowmapWidth
                };

                DrawShadowsSettings settings = new DrawShadowsSettings(renderingData.cullResults, shadowLightIndex);
                settings.splitData.cullingSphere = m_CullingSphere;

                ShadowUtils.RenderShadowSlice(cmd, ref context, ref slice, ref settings, m_ProjMatrix, m_ViewMatrix);

                context.ExecuteCommandBuffer(cmd);
                cmd.Clear();

                SetupMainCharacterShadowReceiverConstants(cmd, ref shadowData, shadowLight);
            }

            CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.MainCharacterShadows, true);
            CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.SoftShadows, shadowLight.light.shadows == LightShadows.Soft && shadowData.supportsSoftShadows);
            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);
        }