5 using System.Collections.Generic;
7 using SiliconStudio.Paradox.DataModel;
8 using SiliconStudio.Paradox.Engine;
9 using SiliconStudio.Paradox.EntityModel;
10 using SiliconStudio.Paradox.Games;
11 using SiliconStudio.Paradox.Graphics;
13 namespace SiliconStudio.
Paradox.Effects.Modules.Processors
20 #region Private members
22 private readonly List<ShadowMapTexture> shadowMapDefaultTextures;
24 private readonly List<ShadowMapTexture> shadowMapVsmTextures;
26 private readonly Dictionary<ShadowMapTexture, int> texturesDefault;
28 private readonly Dictionary<ShadowMapTexture, int> texturesVsm;
30 private readonly List<EntityLightShadow> activeLightShadowMaps;
32 private bool shadowMapFullWarningDone =
false;
39 : base(device, manageShadows)
41 shadowMapDefaultTextures =
new List<ShadowMapTexture>();
42 shadowMapVsmTextures =
new List<ShadowMapTexture>();
43 texturesDefault =
new Dictionary<ShadowMapTexture, int>();
44 texturesVsm =
new Dictionary<ShadowMapTexture, int>();
46 activeLightShadowMaps =
new List<EntityLightShadow>();
51 #region Public methods
60 foreach (var texture
in shadowMapDefaultTextures)
62 texture.GuillotinePacker.Clear(texture.ShadowMapDepthBuffer.Texture.Width, texture.ShadowMapDepthBuffer.Texture.Height);
63 texturesDefault[texture] = texture.ShadowMapDepthBuffer.Texture.Width * texture.ShadowMapDepthBuffer.Texture.Height;
65 foreach (var texture
in shadowMapVsmTextures)
67 texture.GuillotinePacker.Clear(texture.ShadowMapDepthBuffer.Texture.Width, texture.ShadowMapDepthBuffer.Texture.Height);
68 texturesVsm[texture] = texture.ShadowMapDepthBuffer.Texture.Width * texture.ShadowMapDepthBuffer.Texture.Height;
72 shadowMapDefaultTextures.Sort(ShadowMapTextureComparerDefault);
73 shadowMapVsmTextures.Sort(ShadowMapTextureComparerVsm);
76 foreach (var light
in Lights)
79 if (light.Value.Light.ShadowMap && light.Value.ShadowMap == null)
80 CreateShadowMap(light.Value);
83 if (!light.Value.Light.ShadowMap && light.Value.ShadowMap != null)
84 RemoveShadowMap(light.Value);
87 FillActiveLightShadowMaps();
89 InternalActiveShadowMaps.Clear();
90 InternalActiveShadowMapTextures.Clear();
92 foreach (var light
in activeLightShadowMaps)
97 if (ChooseShadowMapTexture(light, shadowMapVsmTextures, texturesVsm))
99 shadowMapVsmTextures.Sort(ShadowMapTextureComparerVsm);
100 InternalActiveShadowMaps.Add(light.ShadowMap);
101 InternalActiveShadowMapTextures.Add(light.ShadowMap.Texture);
107 if (ChooseShadowMapTexture(light, shadowMapDefaultTextures, texturesDefault))
109 shadowMapDefaultTextures.Sort(ShadowMapTextureComparerDefault);
110 InternalActiveShadowMaps.Add(light.ShadowMap);
111 InternalActiveShadowMapTextures.Add(light.ShadowMap.Texture);
117 foreach (var light
in activeLightShadowMaps)
118 UpdateEntityLightShadow(light);
120 activeLightShadowMaps.Clear();
123 foreach (var texture
in shadowMapDefaultTextures)
124 texture.GuillotinePacker.Clear(texture.ShadowMapDepthBuffer.Texture.Width, texture.ShadowMapDepthBuffer.Texture.Height);
125 foreach (var texture
in shadowMapVsmTextures)
126 texture.GuillotinePacker.Clear(texture.ShadowMapDepthBuffer.Texture.Width, texture.ShadowMapDepthBuffer.Texture.Height);
132 #region Protected methods
143 texturesVsm.Add(shadowMapTexture, shadowMapTexture.ShadowMapDepthTexture.Width * shadowMapTexture.ShadowMapDepthTexture.Height);
144 shadowMapVsmTextures.Add(shadowMapTexture);
148 texturesDefault.Add(shadowMapTexture, shadowMapTexture.ShadowMapDepthTexture.Width * shadowMapTexture.ShadowMapDepthTexture.Height);
149 shadowMapDefaultTextures.Add(shadowMapTexture);
152 InternalShadowMapTextures.Add(shadowMapTexture);
158 texturesDefault.Clear();
160 shadowMapDefaultTextures.Clear();
161 shadowMapVsmTextures.Clear();
162 activeLightShadowMaps.Clear();
164 base.OnSystemRemove();
170 if (ManageShadows && data.
ShadowMap != null)
171 RemoveShadowMap(data);
172 base.OnEntityRemoved(entity, data);
180 LightDirection = light.Light.LightDirection,
181 ShadowMapSize = light.Light.ShadowMapMinSize,
182 ShadowNearDistance = light.Light.ShadowNearDistance,
183 ShadowFarDistance = light.Light.ShadowFarDistance,
184 CascadeCount = light.Light.ShadowMapCascadeCount,
186 Layers = light.Light.Layers
189 InternalShadowMaps.Add(shadowMap);
190 light.ShadowMap = shadowMap;
195 #region Private methods
197 private void FillActiveLightShadowMaps()
199 foreach (var light
in Lights)
202 if (light.Value.Light.Enabled && light.Value.Light.ShadowMap && light.Value.ShadowMap != null && light.Value.ShadowMap.Update)
203 activeLightShadowMaps.Add(light.Value);
207 activeLightShadowMaps.Sort(CompareShadows);
210 private void RemoveShadowMap(EntityLightShadow data)
212 InternalShadowMaps.Remove(data.ShadowMap);
213 InternalActiveShadowMaps.Remove(data.ShadowMap);
214 data.ShadowMap = null;
217 private bool ChooseShadowMapTexture(EntityLightShadow light, List<ShadowMapTexture> shadowMapTextures, Dictionary<ShadowMapTexture, int> shadowMapRemainingSize)
219 var shadowMap = light.ShadowMap;
220 var shadowMapSize = light.Light.ShadowMapMaxSize;
222 while (shadowMapSize > 0)
224 if (shadowMapSize < light.Light.ShadowMapMinSize)
225 shadowMapSize = light.Light.ShadowMapMinSize;
227 foreach (var shadowMapTexture
in shadowMapTextures)
229 if (shadowMapTexture.GuillotinePacker.TryInsert(shadowMapSize, shadowMapSize, shadowMap.CascadeCount))
231 shadowMap.Texture = shadowMapTexture;
232 shadowMapRemainingSize[shadowMapTexture] = shadowMapRemainingSize[shadowMapTexture] - (shadowMap.CascadeCount * shadowMapSize * shadowMapSize);
233 shadowMap.ShadowMapSize = shadowMapSize;
238 if (shadowMapSize == light.Light.ShadowMapMinSize)
244 if (!shadowMapFullWarningDone)
246 shadowMapFullWarningDone =
true;
247 Logger.Warning(
"Unable to find a texture to create the shadow map.");
250 shadowMap.Texture = null;
254 private int ShadowMapTextureComparerDefault(ShadowMapTexture texture0, ShadowMapTexture texture1)
256 return texturesDefault[texture0] - texturesDefault[texture1];
259 private int ShadowMapTextureComparerVsm(ShadowMapTexture texture0, ShadowMapTexture texture1)
261 return texturesVsm[texture0] - texturesVsm[texture1];
266 #region Private static methods
269 private static int CompareShadows(EntityLightShadow shadow0, EntityLightShadow shadow1)
271 var lightTypeComparaison = GetLightTypeValue(shadow0.Light.Type) - GetLightTypeValue(shadow1.Light.Type);
272 if (lightTypeComparaison != 0)
273 return lightTypeComparaison;
275 var shadowMapSizeDiff = shadow0.Light.ShadowMapMaxSize - shadow1.Light.ShadowMapMaxSize;
276 if (shadowMapSizeDiff > 0)
278 if (shadowMapSizeDiff < 0)
286 private static int GetLightTypeValue(
LightType lightType)
290 case LightType.Point:
292 case LightType.Spherical:
294 case LightType.Directional:
299 throw new ArgumentOutOfRangeException(
"lightType");
Game entity. It usually aggregates multiple EntityComponent
A class handling the allocation of shadow maps with a fixed budget of shadow map textures. This class is meant to be inherited with the desired budget since it has no texture at all.
Represents a shadow map for the ShadowMapRenderer.
void AddShadowMapTexture(ShadowMapTexture shadowMapTexture, ShadowMapFilterType filterType)
Adds the shadow map texture to the budget of textures.
Performs primitive-based rendering, creates resources, handles system-level variables, adjusts gamma ramp levels, and creates shaders. See The+GraphicsDevice+class to learn more about the class.
Current timing used for variable-step (real time) or fixed-step (game time) games.
override void OnEntityRemoved(Entity entity, EntityLightShadow data)
override void OnSystemRemove()
override void CreateShadowMap(EntityLightShadow light)
Represents a texture to use with ShadowMapRenderer.
LightShadowProcessorWithBudget(GraphicsDevice device, bool manageShadows)
override void Update(GameTime time)