Exemplo n.º 1
0
        protected override void OnMaterialRender(uint passId, Material material, ref bool skipPass)
        {
            base.OnMaterialRender(passId, material, ref skipPass);

            const int rt_downscale        = 100;
            const int rt_blurHorizontal   = 200;
            const int rt_blurVertical     = 300;
            const int rt_autoFocus1       = 400;
            const int rt_autoFocus2       = 401;
            const int rt_autoFocus3       = 402;
            const int rt_autoFocusFinal   = 403;
            const int rt_autoFocusCurrent = 404;
            //const int rt_blurFactors = 500;
            const int rt_targetOutput = 600;

            //Skip auto focus passes if no auto focus is enabled
            if (!autoFocus)
            {
                if (passId == rt_autoFocus1 || passId == rt_autoFocus2 || passId == rt_autoFocus3 ||
                    passId == rt_autoFocusFinal || passId == rt_autoFocusCurrent)
                {
                    skipPass = true;
                    return;
                }
            }

            // Prepare the fragment params offsets
            switch (passId)
            {
            case rt_downscale:
            {
                Vec2[] sampleOffsets = new Vec2[16];

                CalculateDownScale4x4SampleOffsets(Owner.DimensionsInPixels.Size, sampleOffsets);

                //convert to Vec4 array
                Vec4[] vec4Offsets = new Vec4[16];
                for (int n = 0; n < 16; n++)
                {
                    Vec2 offset = sampleOffsets[n];
                    vec4Offsets[n] = new Vec4(offset[0], offset[1], 0, 0);
                }

                GpuProgramParameters parameters = material.GetBestTechnique().
                                                  Passes[0].FragmentProgramParameters;
                parameters.SetNamedConstant("sampleOffsets", vec4Offsets);
            }
            break;

            case rt_blurHorizontal:
            case rt_blurVertical:
            {
                // horizontal and vertical blur
                bool horizontal = passId == rt_blurHorizontal;

                float[] sampleOffsets = new float[15];
                Vec4[]  sampleWeights = new Vec4[15];

                CalculateBlurSampleOffsets(horizontal ? downscaleTextureSize.X : downscaleTextureSize.Y,
                                           sampleOffsets, sampleWeights, 3, 1);

                //convert to Vec4 array
                Vec4[] vec4Offsets = new Vec4[15];
                for (int n = 0; n < 15; n++)
                {
                    float offset = sampleOffsets[n] * blurSpread;

                    if (horizontal)
                    {
                        vec4Offsets[n] = new Vec4(offset, 0, 0, 0);
                    }
                    else
                    {
                        vec4Offsets[n] = new Vec4(0, offset, 0, 0);
                    }
                }

                GpuProgramParameters parameters = material.GetBestTechnique().
                                                  Passes[0].FragmentProgramParameters;
                parameters.SetNamedConstant("sampleOffsets", vec4Offsets);
                parameters.SetNamedConstant("sampleWeights", sampleWeights);
            }
            break;

            case rt_autoFocus1:
            {
                GpuProgramParameters parameters = material.GetBestTechnique().
                                                  Passes[0].FragmentProgramParameters;
                parameters.SetNamedAutoConstant("farClipDistance",
                                                GpuProgramParameters.AutoConstantType.FarClipDistance);
            }
            break;

            case rt_autoFocus2:
            case rt_autoFocus3:
            {
                Vec2[] sampleOffsets = new Vec2[16];

                string textureSizeFrom = null;
                switch (passId)
                {
                case rt_autoFocus2: textureSizeFrom = "rt_autoFocus1"; break;

                case rt_autoFocus3: textureSizeFrom = "rt_autoFocus2"; break;

                default: Trace.Assert(false); break;
                }
                Vec2I sourceTextureSize = Technique.GetTextureDefinition(textureSizeFrom).Size;
                CalculateDownScale4x4SampleOffsets(sourceTextureSize, sampleOffsets);

                //convert to Vec4 array
                Vec4[] vec4Offsets = new Vec4[16];
                for (int n = 0; n < 16; n++)
                {
                    Vec2 offset = sampleOffsets[n];
                    vec4Offsets[n] = new Vec4(offset[0], offset[1], 0, 0);
                }

                GpuProgramParameters parameters = material.GetBestTechnique().
                                                  Passes[0].FragmentProgramParameters;
                parameters.SetNamedConstant("sampleOffsets", vec4Offsets);
            }
            break;

            case rt_autoFocusFinal:
            {
                GpuProgramParameters parameters = material.GetBestTechnique().
                                                  Passes[0].FragmentProgramParameters;

                Vec4 properties = Vec4.Zero;
                properties.X = autoFocusRange.Minimum;
                properties.Y = autoFocusRange.Maximum;
                properties.Z = RendererWorld.Instance.FrameRenderTimeStep * autoFocusTransitionSpeed;
                parameters.SetNamedConstant("properties", properties);
            }
            break;

            case rt_autoFocusCurrent:
                break;

            //case rt_blurFactors:
            //   {
            //      GpuProgramParameters parameters = material.GetBestTechnique().
            //         Passes[ 0 ].FragmentProgramParameters;
            //      parameters.SetNamedAutoConstant( "farClipDistance",
            //         GpuProgramParameters.AutoConstantType.FarClipDistance );

            //      Vec4 properties = Vec4.Zero;
            //      properties.X = autoFocus ? -1.0f : focalDistance;
            //      properties.Y = focalSize;
            //      properties.Z = backgroundTransitionLength;
            //      properties.W = blurForeground ? foregroundTransitionLength : -1;
            //      parameters.SetNamedConstant( "properties", properties );
            //   }
            //   break;

            //Final pass
            case rt_targetOutput:
            {
                GpuProgramParameters parameters = material.GetBestTechnique().
                                                  Passes[0].FragmentProgramParameters;

                parameters.SetNamedAutoConstant("farClipDistance",
                                                GpuProgramParameters.AutoConstantType.FarClipDistance);

                Vec4 properties = Vec4.Zero;
                properties.X = autoFocus ? -1.0f : focalDistance;
                properties.Y = focalSize;
                properties.Z = backgroundTransitionLength;
                properties.W = blurForeground ? foregroundTransitionLength : -1;
                parameters.SetNamedConstant("properties", properties);

                //Vec2[] sampleOffsets = new Vec2[ 49 ];
                //Vec2 textureSize = Owner.DimensionsInPixels.Size.ToVec2();
                //for( int y = -3; y <= 3; y++ )
                //   for( int x = -3; x <= 3; x++ )
                //      sampleOffsets[ ( y + 3 ) * 7 + ( x + 3 ) ] = new Vec2( x, y ) / textureSize;

                ////convert to Vec4 array
                //Vec4[] vec4Offsets = new Vec4[ 49 ];
                //for( int n = 0; n < 49; n++ )
                //{
                //   Vec2 offset = sampleOffsets[ n ];
                //   vec4Offsets[ n ] = new Vec4( offset[ 0 ], offset[ 1 ], 0, 0 );
                //}
                //parameters.SetNamedConstant( "sampleOffsets", vec4Offsets );
            }
            break;
            }
        }
        protected override void OnMaterialRender(uint passId, Material material, ref bool skipPass)
        {
            base.OnMaterialRender(passId, material, ref skipPass);

            //update material scheme
            {
                string materialScheme = RendererWorld.Instance.DefaultViewport.MaterialScheme;

                foreach (CompositionTechnique technique in Compositor.Techniques)
                {
                    foreach (CompositionTargetPass pass in technique.TargetPasses)
                    {
                        pass.MaterialScheme = materialScheme;
                    }
                    if (technique.OutputTargetPass != null)
                    {
                        technique.OutputTargetPass.MaterialScheme = materialScheme;
                    }
                }
            }

            const int rt_luminance0       = 994;
            const int rt_luminance1       = 993;
            const int rt_luminance2       = 992;
            const int rt_luminance3       = 991;
            const int rt_luminance4       = 990;
            const int rt_brightPass       = 800;
            const int rt_bloomBlur        = 700;
            const int rt_bloomHorizontal  = 701;
            const int rt_bloomVertical    = 702;
            const int rt_adaptedLuminance = 500;
            const int rt_targetOutput     = 600;

            //Skip adaptation passes if adaptation switched off.
            if (!Adaptation)
            {
                if (passId == rt_luminance0 || passId == rt_luminance1 || passId == rt_luminance2 ||
                    passId == rt_luminance3 || passId == rt_luminance4)
                {
                    skipPass = true;
                    return;
                }
            }

            //Skip bloom passes if bloom switched off
            if (BloomScale == 0)
            {
                if (passId == rt_brightPass || passId == rt_bloomBlur || passId == rt_bloomHorizontal ||
                    passId == rt_bloomVertical)
                {
                    skipPass = true;
                    return;
                }
            }

            // Prepare the fragment params offsets
            switch (passId)
            {
            case rt_luminance0:
            {
                Vec2[] sampleOffsets = new Vec2[9];

                // Initialize the sample offsets for the initial luminance pass.
                int textureSize = Technique.GetTextureDefinition("rt_luminance0").Size.X;

                float tu = 1.0f / (3.0f * textureSize);

                int index = 0;
                for (int x = -1; x <= 1; x++)
                {
                    for (int y = -1; y <= 1; y++)
                    {
                        sampleOffsets[index] = new Vec2(x, y) * tu;
                        index++;
                    }
                }

                GpuProgramParameters parameters = material.GetBestTechnique().
                                                  Passes[0].FragmentProgramParameters;

                //convert to Vec4 array
                Vec4[] vec4Offsets = new Vec4[9];
                for (int n = 0; n < 9; n++)
                {
                    Vec2 offset = sampleOffsets[n];
                    vec4Offsets[n] = new Vec4(offset[0], offset[1], 0, 0);
                }

                parameters.SetNamedConstant("sampleOffsets", vec4Offsets);
            }
            break;

            case rt_luminance1:
            case rt_luminance2:
            case rt_luminance3:
            case rt_luminance4:
            {
                Vec2[] sampleOffsets = new Vec2[16];

                string textureSizeFrom = null;
                switch (passId)
                {
                case rt_luminance1: textureSizeFrom = "rt_luminance0"; break;

                case rt_luminance2: textureSizeFrom = "rt_luminance1"; break;

                case rt_luminance3: textureSizeFrom = "rt_luminance2"; break;

                case rt_luminance4: textureSizeFrom = "rt_luminance3"; break;

                default: Trace.Assert(false); break;
                }
                Vec2I textureSize = Technique.GetTextureDefinition(textureSizeFrom).Size;
                CalculateDownScale4x4SampleOffsets(textureSize, sampleOffsets);

                //convert to Vec4 array
                Vec4[] vec4Offsets = new Vec4[16];
                for (int n = 0; n < 16; n++)
                {
                    Vec2 offset = sampleOffsets[n];
                    vec4Offsets[n] = new Vec4(offset[0], offset[1], 0, 0);
                }

                GpuProgramParameters parameters = material.GetBestTechnique().
                                                  Passes[0].FragmentProgramParameters;
                parameters.SetNamedConstant("sampleOffsets", vec4Offsets);
            }
            break;

            //BrightPass
            case rt_brightPass:
            {
                Vec2[] sampleOffsets = new Vec2[16];

                Vec2I textureSize = Owner.DimensionsInPixels.Size;
                CalculateDownScale4x4SampleOffsets(textureSize, sampleOffsets);

                //convert to Vec4 array
                Vec4[] vec4Offsets = new Vec4[16];
                for (int n = 0; n < 16; n++)
                {
                    Vec2 offset = sampleOffsets[n];
                    vec4Offsets[n] = new Vec4(offset[0], offset[1], 0, 0);
                }

                GpuProgramParameters parameters = material.GetBestTechnique().
                                                  Passes[0].FragmentProgramParameters;
                parameters.SetNamedConstant("brightThreshold", BloomBrightThreshold);
                parameters.SetNamedConstant("sampleOffsets", vec4Offsets);
            }
            break;

            case rt_bloomBlur:
            {
                Vec2[] sampleOffsets = new Vec2[13];
                Vec4[] sampleWeights = new Vec4[13];

                Vec2I textureSize = brightPassTextureSize;
                CalculateGaussianBlur5x5SampleOffsets(textureSize, sampleOffsets, sampleWeights, 1);

                //convert to Vec4 array
                Vec4[] vec4Offsets = new Vec4[13];
                for (int n = 0; n < 13; n++)
                {
                    Vec2 offset = sampleOffsets[n];
                    vec4Offsets[n] = new Vec4(offset.X, offset.Y, 0, 0);
                }

                GpuProgramParameters parameters = material.GetBestTechnique().
                                                  Passes[0].FragmentProgramParameters;
                parameters.SetNamedConstant("sampleOffsets", vec4Offsets);
                parameters.SetNamedConstant("sampleWeights", sampleWeights);
            }
            break;

            case rt_bloomHorizontal:
            case rt_bloomVertical:
            {
                // horizontal and vertical bloom
                bool horizontal = passId == rt_bloomHorizontal;

                float[] sampleOffsets = new float[15];
                Vec4[]  sampleWeights = new Vec4[15];

                Vec2I textureSize = bloomTextureSize;
                CalculateBloomSampleOffsets(horizontal ? textureSize.X : textureSize.Y,
                                            sampleOffsets, sampleWeights, 3, 2);

                //convert to Vec4 array
                Vec4[] vec4Offsets = new Vec4[15];
                for (int n = 0; n < 15; n++)
                {
                    float offset = sampleOffsets[n];

                    if (horizontal)
                    {
                        vec4Offsets[n] = new Vec4(offset, 0, 0, 0);
                    }
                    else
                    {
                        vec4Offsets[n] = new Vec4(0, offset, 0, 0);
                    }
                }

                GpuProgramParameters parameters = material.GetBestTechnique().
                                                  Passes[0].FragmentProgramParameters;
                parameters.SetNamedConstant("sampleOffsets", vec4Offsets);
                parameters.SetNamedConstant("sampleWeights", sampleWeights);
            }
            break;

            case rt_adaptedLuminance:
            {
                float elapsedTime;
                {
                    float currentTime = RendererWorld.Instance.FrameRenderTime;
                    if (lastLuminanceCalculationTime != -1)
                    {
                        elapsedTime = currentTime - lastLuminanceCalculationTime;
                    }
                    else
                    {
                        elapsedTime = 1000;
                    }
                    lastLuminanceCalculationTime = currentTime;
                }

                GpuProgramParameters parameters = material.GetBestTechnique().
                                                  Passes[0].FragmentProgramParameters;
                parameters.SetNamedConstant("adaptationMinimum", Adaptation ? AdaptationMinimum : 1);
                parameters.SetNamedConstant("adaptationMaximum", Adaptation ? AdaptationMaximum : 1);
                parameters.SetNamedConstant("adaptationVelocity", AdaptationVelocity);
                parameters.SetNamedConstant("elapsedTime", elapsedTime);
            }
            break;

            //Final pass
            case rt_targetOutput:
            {
                GpuProgramParameters parameters = material.GetBestTechnique().
                                                  Passes[0].FragmentProgramParameters;
                parameters.SetNamedConstant("adaptationMiddleBrightness",
                                            Adaptation ? AdaptationMiddleBrightness : 1);
                parameters.SetNamedConstant("bloomScale", BloomScale);
            }
            break;
            }
        }