예제 #1
0
        public static Color GetShadowTintForBox(Box B, IShadowCaster CallingShadowCaster = null, Enums.ShadowCasterClass ExcludedClasses = Enums.ShadowCasterClass.None)
        {
            float darkestTint = 1f;

            for (int i = 0; i < VisibleShadowCasters.Count; i++)
            {
                IShadowCaster shadowCaster = VisibleShadowCasters[i];
                if (
                    shadowCaster == CallingShadowCaster ||
                    (
                        ExcludedClasses != Enums.ShadowCasterClass.None &&
                        (shadowCaster.ShadowCasterClass() & ExcludedClasses) != Enums.ShadowCasterClass.None
                    )
                    )
                {
                    continue;
                }
                Box shadowVolume = shadowCaster.GetShadowVolume();
                Box?shadowBox    = shadowVolume.GetIntersectionVolume(B);
                if (shadowBox == null)
                {
                    continue;
                }
                Texture2D shadowTexture = shadowCaster.GetShadowTexture();
                int       x1;
                int       y1;
                int       x2;
                int       y2;
                if (shadowCaster.ShouldTile())
                {
                    x1 = (int)(shadowBox.Value.Left - shadowVolume.Left);
                    y1 = (int)(shadowBox.Value.Back - shadowVolume.Back);
                    x2 = x1 + (int)shadowBox.Value.Width;
                    y2 = y1 + (int)shadowBox.Value.Depth;
                }
                else
                {
                    x1 = (int)Math.Floor((shadowBox.Value.Left - shadowVolume.Left) / shadowVolume.Width * shadowTexture.Width);
                    y1 = (int)Math.Floor((shadowBox.Value.Back - shadowVolume.Back) / shadowVolume.Depth * shadowTexture.Height);
                    x2 = x1 + (int)Math.Floor((shadowBox.Value.Width / shadowVolume.Width) * (shadowTexture.Width - 1));
                    y2 = y1 + (int)Math.Floor((shadowBox.Value.Depth / shadowVolume.Depth) * (shadowTexture.Height - 1));
                }
                float a = GetShadowStrengthOverArea(shadowTexture, x1, y1, x2, y2) * (shadowBox.Value.TopDownSurfaceArea / B.TopDownSurfaceArea) * shadowCaster.GetShadowOpacity();
                if (a > 0)
                {
                    a = 1 - a;
                    if (a < darkestTint)
                    {
                        darkestTint = a;
                    }
                }
            }
            if (darkestTint == 1f)
            {
                return(Color.White);
            }
            float invertDarkest = 1 - darkestTint;

            return(new Color(
                       1 - (invertDarkest - GLOBAL_SHADOW_COLOR.R / 255f * invertDarkest),
                       1 - (invertDarkest - GLOBAL_SHADOW_COLOR.G / 255f * invertDarkest),
                       1 - (invertDarkest - GLOBAL_SHADOW_COLOR.B / 255f * invertDarkest)
                       ));
        }
예제 #2
0
        public static Color GetShadowTintForPoint(Vector3 P, IShadowCaster CallingShadowCaster = null, Enums.ShadowCasterClass ExcludedClasses = Enums.ShadowCasterClass.None)
        {
            float shadowFactor = GetShadowFactorForPoint(P, CallingShadowCaster, ExcludedClasses);

            if (shadowFactor == 0)
            {
                return(Color.White);
            }
            float colorChannel = shadowFactor * GLOBAL_SHADOW_OPACITY;

            return(new Color(
                       1 - (colorChannel - GLOBAL_SHADOW_COLOR.R / 255f * colorChannel),
                       1 - (colorChannel - GLOBAL_SHADOW_COLOR.G / 255f * colorChannel),
                       1 - (colorChannel - GLOBAL_SHADOW_COLOR.B / 255f * colorChannel)
                       ));
        }
예제 #3
0
        public static Color Get3SampledShadowTintForPoint(Vector3 P, float Radius, IShadowCaster CallingShadowCaster = null, Enums.ShadowCasterClass ExcludedClasses = Enums.ShadowCasterClass.None)
        {
            float sampledShadowFactor = (
                GetShadowFactorForPoint(P + SHADOW_3_SAMPLE_1 * Radius, CallingShadowCaster, ExcludedClasses) +
                GetShadowFactorForPoint(P + SHADOW_3_SAMPLE_2 * Radius, CallingShadowCaster, ExcludedClasses) +
                GetShadowFactorForPoint(P + SHADOW_3_SAMPLE_3 * Radius, CallingShadowCaster, ExcludedClasses)
                ) / 3f;

            if (sampledShadowFactor == 0)
            {
                return(Color.White);
            }
            float colorChannel = sampledShadowFactor * GLOBAL_SHADOW_OPACITY;

            return(new Color(
                       1 - (colorChannel - GLOBAL_SHADOW_COLOR.R / 255f * colorChannel),
                       1 - (colorChannel - GLOBAL_SHADOW_COLOR.G / 255f * colorChannel),
                       1 - (colorChannel - GLOBAL_SHADOW_COLOR.B / 255f * colorChannel)
                       ));
        }
예제 #4
0
        private static float GetShadowFactorForPoint(Vector3 P, IShadowCaster CallingShadowCaster, Enums.ShadowCasterClass ExcludedClasses = Enums.ShadowCasterClass.None)
        {
            float?cachedValue = SpatialShadowMap.Get(P);

            if (cachedValue.HasValue)
            {
                return(cachedValue.Value);
            }
            byte darkestTint = 0;

            for (int i = 0; i < VisibleShadowCasters.Count; i++)
            {
                IShadowCaster shadowCaster = VisibleShadowCasters[i];
                if (
                    shadowCaster == CallingShadowCaster ||
                    (
                        ExcludedClasses != Enums.ShadowCasterClass.None &&
                        (shadowCaster.ShadowCasterClass() & ExcludedClasses) != Enums.ShadowCasterClass.None
                    )
                    )
                {
                    continue;
                }
                Box shadowVolume = shadowCaster.GetShadowVolume();
                if (shadowVolume.Top < P.Y || !shadowVolume.DoesContainPoint(P))
                {
                    continue;
                }
                Texture2D shadowTexture = shadowCaster.GetShadowTexture();
                byte[]    colorData     = GetTextureData(shadowTexture);
                int       ix;
                int       iy;
                if (shadowCaster.ShouldTile())
                {
                    ix = (int)(P.X - shadowVolume.Left) % shadowTexture.Width;
                    iy = (int)(P.Z - shadowVolume.Back) % shadowTexture.Height;
                }
                else
                {
                    ix = (int)Math.Floor((P.X - shadowVolume.Left) / shadowVolume.Width * shadowTexture.Width);
                    iy = (int)Math.Floor((P.Z - shadowVolume.Back) / shadowVolume.Depth * shadowTexture.Height);
                }
                byte pointColorA = colorData[ix + iy * shadowTexture.Width];
                if (pointColorA > darkestTint)
                {
                    darkestTint = pointColorA;
                    if (darkestTint == byte.MaxValue)
                    {
                        break;
                    }
                }
            }
            SpatialShadowMap.AttemptInsert(darkestTint / 255f, P);
            return(darkestTint / 255f);
        }