コード例 #1
0
        /// <summary>
        /// Creates the configuration controls of this asset.
        /// </summary>
        public static void AddControls(HorizonBasedAmbientOcclusion asset, Window owner, ComboBox comboBoxResource)
        {
            GroupBox groupGeneral = CommonControls.Group("General", owner);
            
            #region Quality

            var quality = CommonControls.ComboBox("Quality", groupGeneral);
            // Add textures name
            quality.Items.Add("Low");
            quality.Items.Add("Middle");
            quality.Items.Add("High");
            // Events
            quality.ItemIndexChanged += delegate
            {
                switch (quality.ItemIndex)
                {
                    case 0: asset.Quality = HorizonBasedAmbientOcclusion.QualityType.LowQuality; break;
                    case 1: asset.Quality = HorizonBasedAmbientOcclusion.QualityType.MiddleQuality; break;
                    case 2: asset.Quality = HorizonBasedAmbientOcclusion.QualityType.HighQuality; break;
                }
            };
            quality.Draw += delegate
            {
                if (quality.ListBoxVisible)
                    return;
                switch (asset.Quality)
                {
                    case HorizonBasedAmbientOcclusion.QualityType.LowQuality    : quality.ItemIndex = 0; break;
                    case HorizonBasedAmbientOcclusion.QualityType.MiddleQuality : quality.ItemIndex = 1; break;
                    case HorizonBasedAmbientOcclusion.QualityType.HighQuality   : quality.ItemIndex = 2; break;
                }
            };

            #endregion

            var numberSteps = CommonControls.SliderNumericInt("Number Steps", groupGeneral, asset.NumberSteps, false, true, 0, 36, asset, "NumberSteps");
            var numberDirections = CommonControls.SliderNumericInt("Number Directions", groupGeneral, asset.NumberDirections, false, true, 0, 36, asset, "NumberDirections");
            var contrast = CommonControls.SliderNumericFloat("Contrast", groupGeneral, asset.Contrast, true, true, 0, 2, asset, "Contrast");
            var lineAttenuation = CommonControls.SliderNumericFloat("LineAttenuation", groupGeneral, asset.LineAttenuation, false, false, 0, 2, asset, "LineAttenuation");
            var radius = CommonControls.SliderNumericFloat("Radius", groupGeneral, asset.Radius, false, false, 0, 0.5f, asset, "Radius");
            var angleBias = CommonControls.SliderNumericFloat("AngleBias", groupGeneral, asset.AngleBias, false, false, 0, 90, asset, "AngleBias");

            groupGeneral.AdjustHeightFromChildren();

        } // AddControls       
コード例 #2
0
        } // GetParameters

        #endregion

        #region Render

        /// <summary>
        /// Generate ambient occlusion texture.
        /// </summary>
        internal RenderTarget Render(RenderTarget depthTexture, RenderTarget normalTexture, HorizonBasedAmbientOcclusion hbao, float fieldOfView, Size destinationSize, RenderTarget fullscreenDepthTexture)
        {
            try
            {
                // I decided to work with Color format for a number of reasons.
                // First, this format is very used so chances are that I can reuse it latter in another shader.
                // Second, GPUs tend to work faster in non-floating point render targets.
                // Third, I can blur it with linear sampling.
                // Last, I could need to return a color if I use directional occlusion.
                // The main disadvantage is that I am wasting three channels (or just one in SSDO).
                // A single 8 bit channel render target is not available in XNA 4.0 and I have two options for 16 bits render targets.
                // First, the compressed 4 channels formats, the compression is visible and the results are not satisfactory.
                // Last we have the half single format, it is a good option but I prefer to have linear sampling.
                // Alternatively, I can pack several shadows result in only one texture and blurred fourth results at the same time.
                // But I will do it only for shadows. I want to leave this shader simple. At least until a heavy optimization task needs to be performed.
                RenderTarget ambientOcclusionTexture = RenderTarget.Fetch(depthTexture.Size, SurfaceFormat.Color, DepthFormat.None, RenderTarget.AntialiasingType.NoAntialiasing);

                // Set shader atributes
                SetNormalTexture(normalTexture);
                SetDepthTexture(depthTexture);
                // It works a the depth texture resolution. Use a downsampled version of the G-Buffer.
                SetResolution(new Vector2(depthTexture.Width, depthTexture.Height));
                SetInverseResolution(new Vector2(1 / (float)depthTexture.Width, 1 / (float)depthTexture.Height));
                SetNumberSteps(hbao.NumberSteps);
                SetNumberDirections(hbao.NumberDirections);
                SetContrast(hbao.Contrast / (1.0f - (float)Math.Sin(hbao.AngleBias * (float)Math.PI / 180f)));
                SetLineAttenuation(hbao.LineAttenuation);
                SetRadius(hbao.Radius);
                SetSquareRadius(hbao.Radius * hbao.Radius);
                SetInverseRadius(1 / hbao.Radius);
                SetHalfPixel(new Vector2(-0.5f / (ambientOcclusionTexture.Width / 2), 0.5f / (ambientOcclusionTexture.Height / 2)));
                Vector2 focalLen = new Vector2
                {
                    X = 1.0f / (float)Math.Tan(fieldOfView * (Math.PI / 180) * 0.5f) * (float)ambientOcclusionTexture.Height / (float)ambientOcclusionTexture.Width,
                    Y = 1.0f / (float)Math.Tan(fieldOfView * (Math.PI / 180) * 0.5f)
                };
                SetFocalLength(focalLen);
                SetInverseFocalLength(new Vector2(1 / focalLen.X, 1 / focalLen.Y));
                SetAngleBias(hbao.AngleBias * (float)Math.PI / 180f);
                SetTanAngleBias((float)Math.Tan(hbao.AngleBias * (float)Math.PI / 180f));

                switch (hbao.Quality)
                {
                case HorizonBasedAmbientOcclusion.QualityType.LowQuality: Resource.CurrentTechnique = Resource.Techniques["LowQuality"]; break;

                case HorizonBasedAmbientOcclusion.QualityType.MiddleQuality: Resource.CurrentTechnique = Resource.Techniques["MiddleQuality"]; break;

                case HorizonBasedAmbientOcclusion.QualityType.HighQuality: Resource.CurrentTechnique = Resource.Techniques["HighQuality"]; break;
                }

                // Set Render States.
                EngineManager.Device.BlendState        = BlendState.Opaque;
                EngineManager.Device.DepthStencilState = DepthStencilState.None;
                EngineManager.Device.RasterizerState   = RasterizerState.CullCounterClockwise;
                EngineManager.Device.SamplerStates[3]  = SamplerState.PointWrap;

                // Render
                ambientOcclusionTexture.EnableRenderTarget();
                ambientOcclusionTexture.Clear(Color.White);
                Resource.CurrentTechnique.Passes[0].Apply();
                RenderScreenPlane();
                ambientOcclusionTexture.DisableRenderTarget();

                // The blured texture has fullscreen size to improve the quality.
                // This pass is a lot cheaper than the ambient occlusion pass so the performance penalty is acceptable.
                RenderTarget bluredAmbientOcclusionTexture = RenderTarget.Fetch(destinationSize, ambientOcclusionTexture.SurfaceFormat,
                                                                                DepthFormat.None, RenderTarget.AntialiasingType.NoAntialiasing);
                BilateralBlurShader.Instance.Filter(ambientOcclusionTexture, bluredAmbientOcclusionTexture, depthTexture, 10, 10);
                RenderTarget.Release(ambientOcclusionTexture);
                return(bluredAmbientOcclusionTexture);
            }
            catch (Exception e)
            {
                throw new InvalidOperationException("Horizon Based Ambient Occlusion Shader: Unable to render.", e);
            }
        } // Render