Example #1
0
        ///// <summary>
        ///// Creates a new AlphaTestEffect by cloning parameter settings from an existing instance.
        ///// </summary>
        //protected AlphaTestEffect(AlphaTestEffect cloneSource)
        //    : base(cloneSource)
        //{
        //    fogEnabled = cloneSource.fogEnabled;
        //    vertexColorEnabled = cloneSource.vertexColorEnabled;

        //    world = cloneSource.world;
        //    view = cloneSource.view;
        //    projection = cloneSource.projection;

        //    diffuseColor = cloneSource.diffuseColor;

        //    alpha = cloneSource.alpha;

        //    fogStart = cloneSource.fogStart;
        //    fogEnd = cloneSource.fogEnd;

        //    alphaFunction = cloneSource.alphaFunction;
        //    referenceAlpha = cloneSource.referenceAlpha;
        //}


        ///// <summary>
        ///// Creates a clone of the current AlphaTestEffect instance.
        ///// </summary>
        //public override Effect Clone()
        //{
        //    return new AlphaTestEffect(this);
        //}

        /// <summary>
        /// Lazily computes derived parameter values immediately before applying the effect.
        /// </summary>
        protected internal override EffectPass OnApply(EffectPass pass)
        {
            // Recompute the world+view+projection matrix or fog vector?
            dirtyFlags = EffectHelpers.SetWorldViewProjAndFog(dirtyFlags, ref world, ref view, ref projection, ref worldView, fogEnabled, fogStart, fogEnd, worldViewProjParam, fogVectorParam);

            // Recompute the diffuse/alpha material color parameter?
            if ((dirtyFlags & EffectDirtyFlags.MaterialColor) != 0)
            {
                diffuseColorParam.SetValue(new Vector4(diffuseColor * alpha, alpha));

                dirtyFlags &= ~EffectDirtyFlags.MaterialColor;
            }

            // Recompute the alpha test settings?
            if ((dirtyFlags & EffectDirtyFlags.AlphaTest) != 0)
            {
                var  alphaTest = new Vector4();
                bool eqNe      = false;

                // Convert reference alpha from 8 bit integer to 0-1 float format.
                float reference = (float)referenceAlpha / 255f;

                // Comparison tolerance of half the 8 bit integer precision.
                const float threshold = 0.5f / 255f;

                switch (alphaFunction)
                {
                case Direct3D11.Comparison.Less:
                    // Shader will evaluate: clip((a < x) ? z : w)
                    alphaTest.X = reference - threshold;
                    alphaTest.Z = 1;
                    alphaTest.W = -1;
                    break;

                case Direct3D11.Comparison.LessEqual:
                    // Shader will evaluate: clip((a < x) ? z : w)
                    alphaTest.X = reference + threshold;
                    alphaTest.Z = 1;
                    alphaTest.W = -1;
                    break;

                case Direct3D11.Comparison.GreaterEqual:
                    // Shader will evaluate: clip((a < x) ? z : w)
                    alphaTest.X = reference - threshold;
                    alphaTest.Z = -1;
                    alphaTest.W = 1;
                    break;

                case Direct3D11.Comparison.Greater:
                    // Shader will evaluate: clip((a < x) ? z : w)
                    alphaTest.X = reference + threshold;
                    alphaTest.Z = -1;
                    alphaTest.W = 1;
                    break;

                case Direct3D11.Comparison.Equal:
                    // Shader will evaluate: clip((abs(a - x) < Y) ? z : w)
                    alphaTest.X = reference;
                    alphaTest.Y = threshold;
                    alphaTest.Z = 1;
                    alphaTest.W = -1;
                    eqNe        = true;
                    break;

                case Direct3D11.Comparison.NotEqual:
                    // Shader will evaluate: clip((abs(a - x) < Y) ? z : w)
                    alphaTest.X = reference;
                    alphaTest.Y = threshold;
                    alphaTest.Z = -1;
                    alphaTest.W = 1;
                    eqNe        = true;
                    break;

                case Direct3D11.Comparison.Never:
                    // Shader will evaluate: clip((a < x) ? z : w)
                    alphaTest.Z = -1;
                    alphaTest.W = -1;
                    break;

                case Direct3D11.Comparison.Always:
                default:
                    // Shader will evaluate: clip((a < x) ? z : w)
                    alphaTest.Z = 1;
                    alphaTest.W = 1;
                    break;
                }

                alphaTestParam.SetValue(alphaTest);

                dirtyFlags &= ~EffectDirtyFlags.AlphaTest;

                // If we changed between less/greater vs. equal/notequal
                // compare modes, we must also update the shader index.
                if (isEqNe != eqNe)
                {
                    isEqNe      = eqNe;
                    dirtyFlags |= EffectDirtyFlags.ShaderIndex;
                }
            }

            // Recompute the shader index?
            if ((dirtyFlags & EffectDirtyFlags.ShaderIndex) != 0)
            {
                int shaderIndex = 0;

                if (!fogEnabled)
                {
                    shaderIndex += 1;
                }

                if (vertexColorEnabled)
                {
                    shaderIndex += 2;
                }

                if (isEqNe)
                {
                    shaderIndex += 4;
                }

                shaderPass = pass.SubPasses[shaderIndex];

                dirtyFlags &= ~EffectDirtyFlags.ShaderIndex;
            }

            return(base.OnApply(shaderPass));
        }
Example #2
0
        /// <summary>
        /// Applies the specified parameters to the effect including all dependent parameters (<see cref="ViewProjectionParameter"/>, <see cref="WorldViewParameter"/>...etc.) if they are defined in the effect.
        /// </summary>
        /// <param name="context">The context caching precompute value (like ViewProjection).</param>
        /// <param name="world">The world.</param>
        /// <param name="view">The view.</param>
        /// <param name="projection">The projection.</param>
        public void Apply(ref EffectDefaultParametersContext context, ref Matrix world, ref Matrix view, ref Matrix projection)
        {
            // If effect doesn't implement IEffectMatrices, we can still use
            // directly standard dynamic parameters.
            if (WorldParameter != null)
            {
                WorldParameter.SetValue(ref world);
            }

            if (ViewParameter != null)
            {
                ViewParameter.SetValue(ref view);
            }

            if (ProjectionParameter != null)
            {
                ProjectionParameter.SetValue(ref projection);
            }

            if (ViewInverseParameter != null)
            {
                if (!context.IsViewInverseCalculated)
                {
                    Matrix.Invert(ref view, out context.ViewInverse);
                    context.IsViewInverseCalculated = true;
                }
                ViewInverseParameter.SetValue(ref context.ViewInverse);
            }

            if (WorldViewParameter != null)
            {
                Matrix worldView;
                Matrix.Multiply(ref world, ref view, out worldView);
                WorldViewParameter.SetValue(ref worldView);
            }

            if (ViewProjectionParameter != null)
            {
                if (!context.IsViewProjectionCalculated)
                {
                    Matrix.Multiply(ref view, ref projection, out context.ViewProjection);
                    context.IsViewProjectionCalculated = true;
                }
                ViewProjectionParameter.SetValue(ref context.ViewProjection);
            }

            if (WorldInverseTransposeParameter != null || WorldInverseTransposeViewParameter != null)
            {
                Matrix worldTranspose;
                Matrix worldInverseTranspose;
                Matrix.Invert(ref world, out worldTranspose);
                Matrix.Transpose(ref worldTranspose, out worldInverseTranspose);

                if (WorldInverseTransposeParameter != null)
                {
                    WorldInverseTransposeParameter.SetValue(ref worldInverseTranspose);
                }

                if (WorldInverseTransposeViewParameter != null)
                {
                    Matrix worldInverseViewTranspose;
                    Matrix.Multiply(ref worldInverseTranspose, ref view, out worldInverseViewTranspose);
                    WorldInverseTransposeViewParameter.SetValue(ref worldInverseViewTranspose);
                }
            }

            if (WorldViewProjectionParameter != null)
            {
                if (!context.IsViewProjectionCalculated)
                {
                    Matrix.Multiply(ref view, ref projection, out context.ViewProjection);
                    context.IsViewProjectionCalculated = true;
                }

                Matrix worldViewProjection;
                Matrix.Multiply(ref world, ref context.ViewProjection, out worldViewProjection);

                WorldViewProjectionParameter.SetValue(ref worldViewProjection);
            }
        }