public void Initialize(RenderView renderView, RenderLight renderLight, IDirectLight light, LightShadowMap shadowMap, int size, ILightShadowMapRenderer renderer)
        {
            if (renderView == null)
            {
                throw new ArgumentNullException(nameof(renderView));
            }
            if (renderLight == null)
            {
                throw new ArgumentNullException(nameof(renderLight));
            }
            if (light == null)
            {
                throw new ArgumentNullException(nameof(light));
            }
            if (shadowMap == null)
            {
                throw new ArgumentNullException(nameof(shadowMap));
            }
            if (renderer == null)
            {
                throw new ArgumentNullException(nameof(renderer));
            }

            RenderView   = renderView;
            RenderLight  = renderLight;
            Light        = light;
            Shadow       = shadowMap;
            Size         = size;
            FilterType   = Shadow.Filter == null || !Shadow.Filter.RequiresCustomBuffer() ? null : Shadow.Filter.GetType();
            Renderer     = renderer;
            Atlas        = null; // Reset the atlas, It will be setup after
            CascadeCount = 1;

            ShadowType = renderer.GetShadowType(Shadow);
        }
Exemple #2
0
        private void AssignRectangle(LightShadowMapTexture lightShadowMapTexture)
        {
            var size = lightShadowMapTexture.Size;

            // Try to fit the shadow map into an existing atlas
            ShadowMapAtlasTexture currentAtlas = null;

            foreach (var atlas in atlases)
            {
                if (atlas.TryInsert(size, size, lightShadowMapTexture.CascadeCount, (int index, ref Rectangle rectangle) => lightShadowMapTexture.SetRectangle(index, rectangle)))
                {
                    currentAtlas = atlas;
                    break;
                }
            }

            // Allocate a new atlas texture
            if (currentAtlas == null)
            {
                // For now, our policy is to allow only one shadow map, esp. because we can have only one shadow texture per lighting group
                // TODO: Group by DirectLightGroups, so that we can have different atlas per lighting group
                // TODO: Allow multiple textures per LightingGroup (using array of Texture?)
                if (atlases.Count == 0)
                {
                    // TODO: handle FilterType texture creation here
                    // TODO: This does not work for Omni lights
                    // TODO: Allow format selection externally

                    var texture = Texture.New2D(RenderSystem.GraphicsDevice, maximumTextureSize, maximumTextureSize, 1, PixelFormat.D32_Float, TextureFlags.DepthStencil | TextureFlags.ShaderResource);
                    currentAtlas = new ShadowMapAtlasTexture(texture, atlases.Count)
                    {
                        FilterType = lightShadowMapTexture.FilterType
                    };
                    atlases.Add(currentAtlas);

                    for (int i = 0; i < lightShadowMapTexture.CascadeCount; i++)
                    {
                        var rect = Rectangle.Empty;
                        currentAtlas.Insert(size, size, ref rect);
                        lightShadowMapTexture.SetRectangle(i, rect);
                    }
                }
            }

            // Make sure the atlas cleared (will be clear just once)
            lightShadowMapTexture.Atlas     = currentAtlas;
            lightShadowMapTexture.TextureId = (byte)(currentAtlas?.Id ?? 0);
        }