public Vector2 RelativeZeroHLSL(ShadowCasterMap shadowMap)
        {
            Vector2 sizedRelativeZero      = this.RelativeZero * shadowMap.PrecisionRatio;
            float   shadowmapRelativeZeroX = sizedRelativeZero.X / shadowMap.Size.X;

            shadowmapRelativeZeroX -= (shadowmapRelativeZeroX % shadowMap.PixelSizeHLSL.X) * shadowMap.PrecisionRatio;
            float shadowmapRelativeZeroY = sizedRelativeZero.Y / shadowMap.Size.Y;

            shadowmapRelativeZeroY -= (shadowmapRelativeZeroY % shadowMap.PixelSizeHLSL.Y) * shadowMap.PrecisionRatio;
            return(new Vector2(shadowmapRelativeZeroX, shadowmapRelativeZeroY));
        }
        private void ExecuteTechniqueDistortAndComputeDistance(ShadowCasterMap shadowCasterMap, LightSource light, RenderTarget2D destination, string techniqueName, int radius)
        {
            graphicsDevice.SetRenderTarget(destination);
            graphicsDevice.Clear(Color.White);

            this.currenteRenderTargetSize.X = radius;
            this.currenteRenderTargetSize.Y = radius;
            this.lightsFX.ResolveShadowsEffect.Parameters["renderTargetSize"].SetValue(this.currenteRenderTargetSize);

            this.lightsFX.ResolveShadowsEffect.Parameters["lightRelativeZero"].SetValue(light.RelativeZeroHLSL(shadowCasterMap));

            Vector2 shadowCasterMapPortion = (light.Size * shadowCasterMap.PrecisionRatio) / shadowCasterMap.Size;

            this.lightsFX.ResolveShadowsEffect.Parameters["shadowCasterMapPortion"].SetValue(shadowCasterMapPortion);

            this.lightsFX.ResolveShadowsEffect.Parameters["InputTexture"].SetValue(shadowCasterMap.Map);

            this.lightsFX.ResolveShadowsEffect.CurrentTechnique = this.lightsFX.ResolveShadowsEffect.Techniques[techniqueName];

            this.lightsFX.ResolveShadowsEffect.CurrentTechnique.Passes[0].Apply();
            ShadowMapResolver.QuadRender.Render(this.graphicsDevice, Vector2.One * -1, Vector2.One);

            graphicsDevice.SetRenderTarget(null);
        }
        public void ResolveShadows(ShadowCasterMap shadowCasterMap, LightSource resultLight, PostEffect postEffect, float distanceMod, int radius)
        {
            BlendState backupBlendState = graphicsDevice.BlendState;

            graphicsDevice.BlendState = BlendState.Opaque;

            this.ExecuteTechniqueDistortAndComputeDistance(shadowCasterMap, resultLight, shadowMapDistorted, "DistortAndComputeDistances", radius);

            Vector2 sizeVector = new Vector2(radius, radius);

            // Horizontal reduction
            this.ApplyHorizontalReduction(shadowMapDistorted, this.shadowMapDigested);

            this.distanceMod = distanceMod;

            switch (postEffect)
            {
            case PostEffect.LinearAttenuation:
            {
                this.ExecuteTechniqueDrawShadows(resultLight.PrintedLight, "DrawShadowsLinearAttenuation", this.shadowMapDigested, sizeVector);
            }
            break;

            case PostEffect.LinearAttenuation_BlurLow:
            {
                this.ExecuteTechniqueDrawShadows(shadowsRT, "DrawShadowsNoAttenuationPreBlur", this.shadowMapDigested, sizeVector);
                this.ExecuteTechniqueBlurH(shadowsRT, processedShadowsRT, "BlurHorizontallyLow", sizeVector);
                this.ExecuteTechniqueBlurV(processedShadowsRT, resultLight.PrintedLight, "BlurVerticallyLowLinearAttenuation", sizeVector);
            }
            break;

            case PostEffect.LinearAttenuation_BlurMid:
            {
                this.ExecuteTechniqueDrawShadows(shadowsRT, "DrawShadowsNoAttenuationPreBlur", this.shadowMapDigested, sizeVector);
                this.ExecuteTechniqueBlurH(shadowsRT, processedShadowsRT, "BlurHorizontallyMid", sizeVector);
                this.ExecuteTechniqueBlurV(processedShadowsRT, resultLight.PrintedLight, "BlurVerticallyMidLinearAttenuation", sizeVector);
            }
            break;

            case PostEffect.LinearAttenuation_BlurHigh:
            {
                this.ExecuteTechniqueDrawShadows(shadowsRT, "DrawShadowsNoAttenuationPreBlur", this.shadowMapDigested, sizeVector);
                this.ExecuteTechniqueBlurH(shadowsRT, processedShadowsRT, "BlurHorizontallyHigh", sizeVector);
                this.ExecuteTechniqueBlurV(processedShadowsRT, resultLight.PrintedLight, "BlurVerticallyHighLinearAttenuation", sizeVector);
            }
            break;

            case PostEffect.CurveAttenuation:
            {
                this.ExecuteTechniqueDrawShadows(resultLight.PrintedLight, "DrawShadowsCurveAttenuation", this.shadowMapDigested, sizeVector);
            }
            break;

            case PostEffect.CurveAttenuation_BlurLow:
            {
                this.ExecuteTechniqueDrawShadows(shadowsRT, "DrawShadowsNoAttenuationPreBlur", this.shadowMapDigested, sizeVector);
                this.ExecuteTechniqueBlurH(shadowsRT, processedShadowsRT, "BlurHorizontallyLow", sizeVector);
                this.ExecuteTechniqueBlurV(processedShadowsRT, resultLight.PrintedLight, "BlurVerticallyLowCurveAttenuation", sizeVector);
            }
            break;

            case PostEffect.CurveAttenuation_BlurMid:
            {
                this.ExecuteTechniqueDrawShadows(shadowsRT, "DrawShadowsNoAttenuationPreBlur", this.shadowMapDigested, sizeVector);
                this.ExecuteTechniqueBlurH(shadowsRT, processedShadowsRT, "BlurHorizontallyMid", sizeVector);
                this.ExecuteTechniqueBlurV(processedShadowsRT, resultLight.PrintedLight, "BlurVerticallyMidCurveAttenuation", sizeVector);
            }
            break;

            case PostEffect.CurveAttenuation_BlurHigh:
            {
                this.ExecuteTechniqueDrawShadows(shadowsRT, "DrawShadowsNoAttenuationPreBlur", this.shadowMapDigested, sizeVector);
                this.ExecuteTechniqueBlurH(shadowsRT, processedShadowsRT, "BlurHorizontallyHigh", sizeVector);
                this.ExecuteTechniqueBlurV(processedShadowsRT, resultLight.PrintedLight, "BlurVerticallyHighCurveAttenuation", sizeVector);
            }
            break;

            case PostEffect.Only_BlurLow:
            {
                this.ExecuteTechniqueDrawShadows(shadowsRT, "DrawShadowsNoAttenuationPreBlur", this.shadowMapDigested, sizeVector);
                this.ExecuteTechniqueBlurH(shadowsRT, processedShadowsRT, "BlurHorizontallyLow", sizeVector);
                this.ExecuteTechniqueBlurV(processedShadowsRT, resultLight.PrintedLight, "BlurVerticallyLowNoAttenuation", sizeVector);
            }
            break;

            case PostEffect.Only_BlurMid:
            {
                this.ExecuteTechniqueDrawShadows(shadowsRT, "DrawShadowsNoAttenuationPreBlur", this.shadowMapDigested, sizeVector);
                this.ExecuteTechniqueBlurH(shadowsRT, processedShadowsRT, "BlurHorizontallyMid", sizeVector);
                this.ExecuteTechniqueBlurV(processedShadowsRT, resultLight.PrintedLight, "BlurVerticallyMidNoAttenuation", sizeVector);
            }
            break;

            case PostEffect.Only_BlurHigh:
            {
                this.ExecuteTechniqueDrawShadows(shadowsRT, "DrawShadowsNoAttenuationPreBlur", this.shadowMapDigested, sizeVector);
                this.ExecuteTechniqueBlurH(shadowsRT, processedShadowsRT, "BlurHorizontallyHigh", sizeVector);
                this.ExecuteTechniqueBlurV(processedShadowsRT, resultLight.PrintedLight, "BlurVerticallyHighNoAttenuation", sizeVector);
            }
            break;

            default:                     //NOFX
            {
                this.ExecuteTechniqueDrawShadows(resultLight.PrintedLight, "DrawShadowsNoAttenuation", this.shadowMapDigested, sizeVector);
            }
            break;
            }
            graphicsDevice.BlendState = backupBlendState;
        }
 public void ResolveShadows(ShadowCasterMap shadowCasterMap, LightSource resultLight, PostEffect postEffect, int radius)
 {
     this.ResolveShadows(shadowCasterMap, resultLight, postEffect, 1f, radius);
 }
 public void ResolveShadows(ShadowCasterMap shadowCasterMap, LightSource resultLight, PostEffect postEffect, float distanceMod, Vector2 newPosition, int radius)
 {
     resultLight.Position = newPosition;
     this.ResolveShadows(shadowCasterMap, resultLight, postEffect, distanceMod, radius);
 }