protected override void CreateShadowMap(EntityLightShadow light) { var shadowMapDesc = light.Light.Shadow as LightShadowMap; // create the shadow map var shadowMap = new ShadowMap { LightDirection = light.Light.Direction, LightPosition = light.Entity.Transformation.Translation, ShadowMapSize = shadowMapDesc.MaxSize, ShadowNearDistance = shadowMapDesc.NearDistance, ShadowFarDistance = shadowMapDesc.FarDistance, CascadeCount = light.Light.Type is LightDirectional ? shadowMapDesc.CascadeCount : 1, // cascades are only supported for directional shadow maps //Fov = light.Light.SpotFieldAngle, Filter = shadowMapDesc.FilterType, Layers = light.Light.Layers }; // find or create the shadow map texture ShadowMapTexture chosenTexture = null; chosenTexture = AllocateOrChooseTexture(shadowMap, shadowMapDesc.FilterType == LightShadowMapFilterType.Variance ? texturesVsm : texturesDefault); shadowMap.Texture = chosenTexture; InternalShadowMaps.Add(shadowMap); light.ShadowMap = shadowMap; }
/// <inheritdoc/> protected override void OnEntityRemoved(Entity entity, EntityLightShadow data) { if (ManageShadows && data.ShadowMap != null) { InternalShadowMaps.Remove(data.ShadowMap); List <ShadowMap> shadowMaps = null; if (!texturesDefault.TryGetValue(data.ShadowMap.Texture, out shadowMaps)) { texturesVsm.TryGetValue(data.ShadowMap.Texture, out shadowMaps); } if (shadowMaps == null) { throw new Exception("Untracked shadow map texture"); } shadowMaps.Remove(data.ShadowMap); // if no more shadow maps on this texture, delete it. if (shadowMaps.Count == 0) { InternalShadowMapTextures.Remove(data.ShadowMap.Texture); Utilities.Dispose(ref data.ShadowMap.Texture.ShadowMapDepthTexture); Utilities.Dispose(ref data.ShadowMap.Texture.ShadowMapTargetTexture); Utilities.Dispose(ref data.ShadowMap.Texture.IntermediateBlurTexture); if (!texturesDefault.Remove(data.ShadowMap.Texture)) { texturesVsm.Remove(data.ShadowMap.Texture); } } } base.OnEntityRemoved(entity, data); }
/// <inheritdoc/> protected override void OnEntityRemoved(Entity entity, EntityLightShadow data) { if (ManageShadows && data.ShadowMap != null) { RemoveShadowMap(data); } base.OnEntityRemoved(entity, data); }
protected override void CreateShadowMap(EntityLightShadow light) { // create the shadow map var shadowMap = new ShadowMap { LightDirection = light.Light.LightDirection, ShadowMapSize = light.Light.ShadowMapMinSize, ShadowNearDistance = light.Light.ShadowNearDistance, ShadowFarDistance = light.Light.ShadowFarDistance, CascadeCount = light.Light.ShadowMapCascadeCount, Filter = light.Light.ShadowMapFilterType, Layers = light.Light.Layers }; InternalShadowMaps.Add(shadowMap); light.ShadowMap = shadowMap; }
private bool ChooseShadowMapTexture(EntityLightShadow light, List <ShadowMapTexture> shadowMapTextures, Dictionary <ShadowMapTexture, int> shadowMapRemainingSize) { var shadowMap = light.ShadowMap; var shadowMapDesc = (LightShadowMap)light.Light.Shadow; var shadowMapSize = shadowMapDesc.MaxSize; // find best texture while (shadowMapSize > 0) { if (shadowMapSize < shadowMapDesc.MinSize) { shadowMapSize = shadowMapDesc.MinSize; } foreach (var shadowMapTexture in shadowMapTextures) { if (shadowMapTexture.GuillotinePacker.TryInsert(shadowMapSize, shadowMapSize, shadowMap.CascadeCount)) { shadowMap.Texture = shadowMapTexture; shadowMapRemainingSize[shadowMapTexture] = shadowMapRemainingSize[shadowMapTexture] - (shadowMap.CascadeCount * shadowMapSize * shadowMapSize); shadowMap.ShadowMapSize = shadowMapSize; return(true); } } if (shadowMapSize == shadowMapDesc.MinSize) { break; } shadowMapSize /= 2; } // Issue a warning only once if (!shadowMapFullWarningDone) { shadowMapFullWarningDone = true; Logger.Warning("Unable to find a texture to create the shadow map."); } shadowMap.Texture = null; return(false); }
// returns shadow0 - shadow1 private static int CompareShadows(EntityLightShadow shadow0, EntityLightShadow shadow1) { var lightTypeComparaison = GetLightTypeValue(shadow0.Light.Type) - GetLightTypeValue(shadow1.Light.Type); if (lightTypeComparaison != 0) { return(lightTypeComparaison); } // TODO: Shadow light comparison //var shadowMapSizeDiff = shadow0.Light.ShadowMapMaxSize - shadow1.Light.ShadowMapMaxSize; //if (shadowMapSizeDiff > 0) // return -1; //if (shadowMapSizeDiff < 0) // return 1; // TODO: more comparisons return(0); }
private void RemoveShadowMap(EntityLightShadow data) { InternalShadowMaps.Remove(data.ShadowMap); InternalActiveShadowMaps.Remove(data.ShadowMap); data.ShadowMap = null; }