Example #1
0
        private void CalculateWaterShaderMap(Scene3D scene, RenderContext context, CommandList commandList, RenderItem renderItem, ResourceSet forwardPassResourceSet)
        {
            _waterMapRenderer.RenderWaterShaders(
                scene,
                context.GraphicsDevice,
                commandList,
                (reflectionFramebuffer, refractionFramebuffer) =>
            {
                var camera                   = scene.Camera;
                var clippingOffset           = scene.Waters.ClippingOffset;
                var originalFarPlaneDistance = camera.FarPlaneDistance;
                var pivot = renderItem.World.Translation.Y;

                if (refractionFramebuffer != null)
                {
                    commandList.PushDebugGroup("Refraction");
                    camera.FarPlaneDistance = scene.Waters.RefractionRenderDistance;

                    var clippingPlaneTop = new Plane(-Vector3.UnitZ, pivot + clippingOffset);

                    var transparentWaterDepth = scene.AssetLoadContext.AssetStore.WaterTransparency.Current.TransparentWaterDepth;
                    var clippingPlaneBottom   = new Plane(Vector3.UnitZ, -pivot + transparentWaterDepth);

                    // Render normal scene for water refraction shader
                    _globalShaderResourceData.UpdateGlobalConstantBuffers(commandList, context, camera.ViewProjection, clippingPlaneTop.AsVector4(), clippingPlaneBottom.AsVector4());

                    commandList.SetFramebuffer(refractionFramebuffer);

                    commandList.ClearColorTarget(0, ClearColor);
                    commandList.ClearDepthStencil(1);

                    commandList.SetFullViewports();

                    RenderedObjectsOpaque += DoRenderPass(context, commandList, _renderList.Opaque, camera.BoundingFrustum, forwardPassResourceSet, clippingPlaneTop, clippingPlaneBottom);
                    commandList.PopDebugGroup();
                }

                if (reflectionFramebuffer != null)
                {
                    commandList.PushDebugGroup("Reflection");
                    camera.FarPlaneDistance = scene.Waters.ReflectionRenderDistance;
                    var clippingPlane       = new Plane(Vector3.UnitZ, -pivot - clippingOffset);

                    // TODO: Improve rendering speed somehow?
                    // ------------------- Used for creating stencil mask -------------------
                    _globalShaderResourceData.UpdateGlobalConstantBuffers(commandList, context, camera.ViewProjection, clippingPlane.AsVector4(), null);

                    commandList.SetFramebuffer(reflectionFramebuffer);
                    commandList.ClearColorTarget(0, ClearColor);
                    commandList.ClearDepthStencil(1);

                    // -----------------------------------------------------------------------

                    // Render inverted scene for water reflection shader
                    camera.SetMirrorX(pivot);
                    _globalShaderResourceData.UpdateGlobalConstantBuffers(commandList, context, camera.ViewProjection, clippingPlane.AsVector4(), null);

                    //commandList.SetFramebuffer(reflectionFramebuffer);
                    commandList.ClearColorTarget(0, ClearColor);
                    //commandList.ClearDepthStencil(1);

                    commandList.SetFullViewports();

                    RenderedObjectsOpaque += DoRenderPass(context, commandList, _renderList.Opaque, camera.BoundingFrustum, forwardPassResourceSet, clippingPlane);

                    camera.SetMirrorX(pivot);
                    commandList.PopDebugGroup();
                }

                if (reflectionFramebuffer != null || refractionFramebuffer != null)
                {
                    camera.FarPlaneDistance = originalFarPlaneDistance;
                    _globalShaderResourceData.UpdateGlobalConstantBuffers(commandList, context, camera.ViewProjection, null, null);

                    // Reset the render item pipeline
                    commandList.SetFramebuffer(_intermediateFramebuffer);
                    commandList.InsertDebugMarker("Setting pipeline");
                    commandList.SetPipeline(renderItem.Material.Pipeline);
                }
            });
        }