Example #1
0
        internal AmbientOcclusionTechnique(
            GBufferTechnique gbufferTechnique,
            ShaderProgram postVertProg, ShaderProgram aoFragProg, ShaderProgram boxBlurFragProg,
            RenderScene scene,
            Logger logger = null)
        {
            if (gbufferTechnique == null)
            {
                throw new NullReferenceException(nameof(gbufferTechnique));
            }
            if (postVertProg == null)
            {
                throw new ArgumentNullException(nameof(postVertProg));
            }
            if (aoFragProg == null)
            {
                throw new ArgumentNullException(nameof(aoFragProg));
            }
            if (boxBlurFragProg == null)
            {
                throw new ArgumentNullException(nameof(boxBlurFragProg));
            }
            if (scene == null)
            {
                throw new NullReferenceException(nameof(scene));
            }

            this.gbufferTechnique = gbufferTechnique;
            this.scene            = scene;
            this.logger           = logger;

            //Create renderer for rendering the ao texture
            renderer = new Renderer(scene, logger);
            renderer.AddSpecialization(scene.SwapchainCount);
            renderer.AddSpecialization(sampleKernelSize);
            renderer.AddSpecialization(sampleRadius);
            renderer.AddSpecialization(sampleBias);
            swapchainIndexPushDataBinding = renderer.AddPushData <int>();
            targetSizePushBinding         = renderer.AddPushData <Int2>();

            //Create random for generating the kernel and noise (using a arbitrary fixed seed)
            IRandom random = new ShiftRandom(seed: 1234);

            //Create the sample kernel
            Span <Float4> sampleKernel = stackalloc Float4[sampleKernelSize];

            GenerateSampleKernel(random, sampleKernel);
            sampleKernelBuffer = DeviceBuffer.UploadData <Float4>(
                sampleKernel, scene, BufferUsages.UniformBuffer);

            //Create the rotation noise texture
            Float4Texture rotationNoiseTexture = TextureUtils.CreateRandomFloatTexture(
                random, min: (-1f, -1f, 0f, 0f), max: (1f, 1f, 0f, 0f), size: (noiseSize, noiseSize));

            rotationNoiseSampler = new DeviceSampler(scene.LogicalDevice,
                                                     texture: DeviceTexture.UploadTexture(rotationNoiseTexture, scene),
                                                     repeat: true,
                                                     pointFilter: true);

            //Add full-screen object for drawing the composition
            renderObject = new AttributelessObject(scene, vertexCount: 3, new TextureInfo[0]);
            renderer.AddObject(renderObject, postVertProg, aoFragProg, debugName: "fullscreen");

            //Create a BlurTechnique for blurring the ao texture (to hide the ao sample pattern)
            blurTechnique = new BoxBlurTechnique(
                postVertProg,
                boxBlurFragProg,
                blurSampleRange,
                sampleScale: 1f,
                scene,
                logger);
        }