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); }
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); }