Exemple #1
0
        /// <summary>
        /// Renders the shadow map using the orthographic camera created in
        /// CalculateFrustum.
        /// </summary>
        protected void renderShadowMap(RenderPrimitives renderDelegate, int splitIndex)
        {
            // Set the viewport for the current split
            Viewport splitViewport = new Viewport();

            splitViewport.MinZ   = 0;
            splitViewport.MaxZ   = 1;
            splitViewport.Width  = ShadowMapSize;
            splitViewport.Height = ShadowMapSize;
            splitViewport.X      = splitIndex * ShadowMapSize;
            splitViewport.Y      = 0;

            context.Rasterizer.SetViewports(splitViewport);

            renderDelegate(lightCameras[splitIndex]);
        }
Exemple #2
0
        /// <summary>
        /// Renders a list of models to the shadow map, and returns a surface
        /// containing the shadow occlusion factor
        /// </summary>
        /// <param name="modelList">The list of models to render</param>
        /// <param name="depthTexture">Texture containing depth for the scene</param>
        /// <param name="light">The light for which the shadow is being calculated</param>
        /// <param name="mainCamera">The camera viewing the scene containing the light</param>
        /// <returns>The shadow occlusion texture</returns>
        public void UpdateShadowMap(RenderPrimitives renderDelegate, DirectionalLight light, ICamera mainCamera)
        {
            context.ClearDepthStencilView(shadowMapDsv, DepthStencilClearFlags.Depth, 1, 0);
            context.ClearState();
            context.OutputMerger.SetTargets(shadowMapDsv);



            // Get corners of the main camera's bounding frustum
            Matrix cameraTransform, viewMatrix;

            viewMatrix      = mainCamera.View;
            cameraTransform = Matrix.Invert(viewMatrix);



            BoundingFrustum frustum = new BoundingFrustum(mainCamera.ViewProjection);

            frustum.GetCorners(frustumCornersWS);


            Vector3.TransformCoordinate(frustumCornersWS, ref viewMatrix, frustumCornersVS);
            for (int i = 0; i < 4; i++)
            {
                farFrustumCornersVS[i] = frustumCornersVS[i + 4];
            }

            // Calculate the cascade splits.  We calculate these so that each successive
            // split is larger than the previous, giving the closest split the most amount
            // of shadow detail.
            float N = NumSplits;
            float near = mainCamera.NearClip, far = mainCamera.FarClip;

            splitDepths[0]         = near;
            splitDepths[NumSplits] = far;
            const float splitConstant = 0.95f;

            for (int i = 1; i < splitDepths.Length - 1; i++)
            {
                splitDepths[i] = splitConstant * near * (float)Math.Pow(far / near, i / N) + (1.0f - splitConstant) * ((near + (i / N)) * (far - near));
            }



            // Render our scene geometry to each split of the cascade
            for (int i = 0; i < NumSplits; i++)
            {
                float minZ = splitDepths[i];
                float maxZ = splitDepths[i + 1];

                lightCameras[i] = CalculateFrustum(light, mainCamera, minZ, maxZ);

                renderShadowMap(renderDelegate, i);
            }


            // We'll use these clip planes to determine which split a pixel belongs to
            for (int i = 0; i < NumSplits; i++)
            {
                lightClipPlanes[i].X = -splitDepths[i];
                lightClipPlanes[i].Y = -splitDepths[i + 1];

                lightViewProjectionMatrices[i] = lightCameras[i].ViewProjection;
                //lightProjectionMatrices[i] = lightCameras[i].Projection;
                //lightCameras[ i ].GetViewProjMatrix( out  );
            }
        }