Esempio n. 1
0
        private void RenderAllSingleThread(GraphicsDevice gd, CommandList cl, SceneContext sc)
        {
            float     depthClear  = gd.IsDepthRangeZeroToOne ? 0f : 1f;
            Matrix4x4 cameraProj  = Camera.ProjectionMatrix;
            Vector4   nearLimitCS = Vector4.Transform(new Vector3(0, 0, -_nearCascadeLimit), cameraProj);
            Vector4   midLimitCS  = Vector4.Transform(new Vector3(0, 0, -_midCascadeLimit), cameraProj);
            Vector4   farLimitCS  = Vector4.Transform(new Vector3(0, 0, -_farCascadeLimit), cameraProj);

            cl.UpdateBuffer(sc.DepthLimitsBuffer, 0, new DepthCascadeLimits
            {
                NearLimit = nearLimitCS.Z,
                MidLimit  = midLimitCS.Z,
                FarLimit  = farLimitCS.Z
            });

            cl.UpdateBuffer(sc.LightInfoBuffer, 0, sc.DirectionalLight.GetInfo());

            Vector3 lightPos = sc.DirectionalLight.Transform.Position - sc.DirectionalLight.Direction * 1000f;

            // Near
            cl.PushDebugGroup("Shadow Map - Near Cascade");
            Matrix4x4 viewProj0 = UpdateDirectionalLightMatrices(
                gd,
                sc,
                Camera.NearDistance,
                _nearCascadeLimit,
                sc.ShadowMapTexture.Width,
                out BoundingFrustum lightFrustum);

            cl.UpdateBuffer(sc.LightViewProjectionBuffer0, 0, ref viewProj0);
            cl.SetFramebuffer(sc.NearShadowMapFramebuffer);
            cl.SetFullViewports();
            cl.ClearDepthStencil(depthClear);
            Render(gd, cl, sc, RenderPasses.ShadowMapNear, lightFrustum, lightPos, _renderQueues[0], _cullableStage[0], _renderableStage[0], null, false);
            cl.PopDebugGroup();

            // Mid
            cl.PushDebugGroup("Shadow Map - Mid Cascade");
            Matrix4x4 viewProj1 = UpdateDirectionalLightMatrices(
                gd,
                sc,
                _nearCascadeLimit,
                _midCascadeLimit,
                sc.ShadowMapTexture.Width,
                out lightFrustum);

            cl.UpdateBuffer(sc.LightViewProjectionBuffer1, 0, ref viewProj1);
            cl.SetFramebuffer(sc.MidShadowMapFramebuffer);
            cl.SetFullViewports();
            cl.ClearDepthStencil(depthClear);
            Render(gd, cl, sc, RenderPasses.ShadowMapMid, lightFrustum, lightPos, _renderQueues[0], _cullableStage[0], _renderableStage[0], null, false);
            cl.PopDebugGroup();

            // Far
            cl.PushDebugGroup("Shadow Map - Far Cascade");
            Matrix4x4 viewProj2 = UpdateDirectionalLightMatrices(
                gd,
                sc,
                _midCascadeLimit,
                _farCascadeLimit,
                sc.ShadowMapTexture.Width,
                out lightFrustum);

            cl.UpdateBuffer(sc.LightViewProjectionBuffer2, 0, ref viewProj2);
            cl.SetFramebuffer(sc.FarShadowMapFramebuffer);
            cl.SetFullViewports();
            cl.ClearDepthStencil(depthClear);
            Render(gd, cl, sc, RenderPasses.ShadowMapFar, lightFrustum, lightPos, _renderQueues[0], _cullableStage[0], _renderableStage[0], null, false);
            cl.PopDebugGroup();

            // Reflections
            cl.PushDebugGroup("Planar Reflection Map");
            cl.SetFramebuffer(sc.ReflectionFramebuffer);
            float fbWidth  = sc.ReflectionFramebuffer.Width;
            float fbHeight = sc.ReflectionFramebuffer.Height;

            cl.SetViewport(0, new Viewport(0, 0, fbWidth, fbHeight, 0, 1));
            cl.SetFullViewports();
            cl.SetFullScissorRects();
            cl.ClearColorTarget(0, RgbaFloat.Black);
            cl.ClearDepthStencil(depthClear);

            // Render reflected scene.
            Matrix4x4  planeReflectionMatrix = Matrix4x4.CreateReflection(MirrorMesh.Plane);
            CameraInfo camInfo = new CameraInfo();

            camInfo.CameraLookDirection       = Vector3.Normalize(Vector3.Reflect(_camera.LookDirection, MirrorMesh.Plane.Normal));
            camInfo.CameraPosition_WorldSpace = Vector3.Transform(_camera.Position, planeReflectionMatrix);
            cl.UpdateBuffer(sc.CameraInfoBuffer, 0, ref camInfo);

            Matrix4x4 view = sc.Camera.ViewMatrix;

            view = planeReflectionMatrix * view;
            cl.UpdateBuffer(sc.ViewMatrixBuffer, 0, view);

            Matrix4x4 projection = _camera.ProjectionMatrix;

            cl.UpdateBuffer(sc.ReflectionViewProjBuffer, 0, view * projection);

            BoundingFrustum cameraFrustum = new BoundingFrustum(view * projection);

            Render(gd, cl, sc, RenderPasses.ReflectionMap, cameraFrustum, _camera.Position, _renderQueues[0], _cullableStage[0], _renderableStage[0], null, false);

            cl.GenerateMipmaps(sc.ReflectionColorTexture);
            cl.PopDebugGroup();

            // Main scene
            cl.PushDebugGroup("Main Scene Pass");
            cl.SetFramebuffer(sc.MainSceneFramebuffer);
            fbWidth  = sc.MainSceneFramebuffer.Width;
            fbHeight = sc.MainSceneFramebuffer.Height;
            cl.SetViewport(0, new Viewport(0, 0, fbWidth, fbHeight, 0, 1));
            cl.SetFullViewports();
            cl.SetFullScissorRects();
            cl.ClearDepthStencil(depthClear);
            sc.UpdateCameraBuffers(cl); // Re-set because reflection step changed it.
            cameraFrustum = new BoundingFrustum(_camera.ViewMatrix * _camera.ProjectionMatrix);
            Render(gd, cl, sc, RenderPasses.Standard, cameraFrustum, _camera.Position, _renderQueues[0], _cullableStage[0], _renderableStage[0], null, false);
            cl.PopDebugGroup();
            cl.PushDebugGroup("Transparent Pass");
            Render(gd, cl, sc, RenderPasses.AlphaBlend, cameraFrustum, _camera.Position, _renderQueues[0], _cullableStage[0], _renderableStage[0], null, false);
            cl.PopDebugGroup();
            cl.PushDebugGroup("Overlay");
            Render(gd, cl, sc, RenderPasses.Overlay, cameraFrustum, _camera.Position, _renderQueues[0], _cullableStage[0], _renderableStage[0], null, false);
            cl.PopDebugGroup();

            if (sc.MainSceneColorTexture.SampleCount != TextureSampleCount.Count1)
            {
                cl.ResolveTexture(sc.MainSceneColorTexture, sc.MainSceneResolvedColorTexture);
            }

            cl.PushDebugGroup("Duplicator");
            cl.SetFramebuffer(sc.DuplicatorFramebuffer);
            fbWidth  = sc.DuplicatorFramebuffer.Width;
            fbHeight = sc.DuplicatorFramebuffer.Height;
            cl.SetFullViewports();
            Render(gd, cl, sc, RenderPasses.Duplicator, new BoundingFrustum(), _camera.Position, _renderQueues[0], _cullableStage[0], _renderableStage[0], null, false);
            cl.PopDebugGroup();

            cl.PushDebugGroup("Swapchain Pass");
            cl.SetFramebuffer(gd.SwapchainFramebuffer);
            fbWidth  = gd.SwapchainFramebuffer.Width;
            fbHeight = gd.SwapchainFramebuffer.Height;
            cl.SetFullViewports();
            Render(gd, cl, sc, RenderPasses.SwapchainOutput, new BoundingFrustum(), _camera.Position, _renderQueues[0], _cullableStage[0], _renderableStage[0], null, false);
            cl.PopDebugGroup();

            cl.End();

            _resourceUpdateCL.Begin();
            foreach (Renderable renderable in _allPerFrameRenderablesSet)
            {
                renderable.UpdatePerFrameResources(gd, _resourceUpdateCL, sc);
            }
            _resourceUpdateCL.End();

            gd.SubmitCommands(_resourceUpdateCL);
            gd.SubmitCommands(cl);
        }
Esempio n. 2
0
        private void RenderAllMultiThreaded(GraphicsDevice gd, CommandList cl, SceneContext sc)
        {
            float     depthClear  = gd.IsDepthRangeZeroToOne ? 0f : 1f;
            Matrix4x4 cameraProj  = Camera.ProjectionMatrix;
            Vector4   nearLimitCS = Vector4.Transform(new Vector3(0, 0, -_nearCascadeLimit), cameraProj);
            Vector4   midLimitCS  = Vector4.Transform(new Vector3(0, 0, -_midCascadeLimit), cameraProj);
            Vector4   farLimitCS  = Vector4.Transform(new Vector3(0, 0, -_farCascadeLimit), cameraProj);
            Vector3   lightPos    = sc.DirectionalLight.Transform.Position - sc.DirectionalLight.Direction * 1000f;

            _resourceUpdateCL.Begin();
            CommandList[] cls = new CommandList[5];
            for (int i = 0; i < cls.Length; i++)
            {
                cls[i] = gd.ResourceFactory.CreateCommandList(); cls[i].Begin();
            }

            _resourceUpdateCL.UpdateBuffer(sc.DepthLimitsBuffer, 0, new DepthCascadeLimits
            {
                NearLimit = nearLimitCS.Z,
                MidLimit  = midLimitCS.Z,
                FarLimit  = farLimitCS.Z
            });

            _resourceUpdateCL.UpdateBuffer(sc.LightInfoBuffer, 0, sc.DirectionalLight.GetInfo());

            _allPerFrameRenderablesSet.Clear();
            _tasks[0] = Task.Run(() =>
            {
                // Near
                Matrix4x4 viewProj0 = UpdateDirectionalLightMatrices(
                    gd,
                    sc,
                    Camera.NearDistance,
                    _nearCascadeLimit,
                    sc.ShadowMapTexture.Width,
                    out BoundingFrustum lightFrustum0);
                cls[1].UpdateBuffer(sc.LightViewProjectionBuffer0, 0, ref viewProj0);

                cls[1].SetFramebuffer(sc.NearShadowMapFramebuffer);
                cls[1].SetViewport(0, new Viewport(0, 0, sc.ShadowMapTexture.Width, sc.ShadowMapTexture.Height, 0, 1));
                cls[1].SetScissorRect(0, 0, 0, sc.ShadowMapTexture.Width, sc.ShadowMapTexture.Height);
                cls[1].ClearDepthStencil(depthClear);
                Render(gd, cls[1], sc, RenderPasses.ShadowMapNear, lightFrustum0, lightPos, _renderQueues[0], _cullableStage[0], _renderableStage[0], null, true);
            });

            _tasks[1] = Task.Run(() =>
            {
                // Mid
                Matrix4x4 viewProj1 = UpdateDirectionalLightMatrices(
                    gd,
                    sc,
                    _nearCascadeLimit,
                    _midCascadeLimit,
                    sc.ShadowMapTexture.Width,
                    out var lightFrustum1);
                cls[2].UpdateBuffer(sc.LightViewProjectionBuffer1, 0, ref viewProj1);

                cls[2].SetFramebuffer(sc.MidShadowMapFramebuffer);
                cls[2].SetViewport(0, new Viewport(0, 0, sc.ShadowMapTexture.Width, sc.ShadowMapTexture.Height, 0, 1));
                cls[2].SetScissorRect(0, 0, 0, sc.ShadowMapTexture.Width, sc.ShadowMapTexture.Height);
                cls[2].ClearDepthStencil(depthClear);
                Render(gd, cls[2], sc, RenderPasses.ShadowMapMid, lightFrustum1, lightPos, _renderQueues[1], _cullableStage[1], _renderableStage[1], null, true);
            });

            _tasks[2] = Task.Run(() =>
            {
                // Far
                Matrix4x4 viewProj2 = UpdateDirectionalLightMatrices(
                    gd,
                    sc,
                    _midCascadeLimit,
                    _farCascadeLimit,
                    sc.ShadowMapTexture.Width,
                    out var lightFrustum2);
                cls[3].UpdateBuffer(sc.LightViewProjectionBuffer2, 0, ref viewProj2);

                cls[3].SetFramebuffer(sc.FarShadowMapFramebuffer);
                cls[3].SetViewport(0, new Viewport(0, 0, sc.ShadowMapTexture.Width, sc.ShadowMapTexture.Height, 0, 1));
                cls[3].SetScissorRect(0, 0, 0, sc.ShadowMapTexture.Width, sc.ShadowMapTexture.Height);
                cls[3].ClearDepthStencil(depthClear);
                Render(gd, cls[3], sc, RenderPasses.ShadowMapFar, lightFrustum2, lightPos, _renderQueues[2], _cullableStage[2], _renderableStage[2], null, true);
            });

            _tasks[3] = Task.Run(() =>
            {
                // Reflections
                cls[4].SetFramebuffer(sc.ReflectionFramebuffer);
                float scWidth  = sc.ReflectionFramebuffer.Width;
                float scHeight = sc.ReflectionFramebuffer.Height;
                cls[4].SetViewport(0, new Viewport(0, 0, scWidth, scHeight, 0, 1));
                cls[4].SetFullViewports();
                cls[4].SetFullScissorRects();
                cls[4].ClearColorTarget(0, RgbaFloat.Black);
                cls[4].ClearDepthStencil(depthClear);

                // Render reflected scene.
                Matrix4x4 planeReflectionMatrix = Matrix4x4.CreateReflection(MirrorMesh.Plane);
                CameraInfo camInfo                = new CameraInfo();
                camInfo.CameraLookDirection       = Vector3.Normalize(Vector3.Reflect(_camera.LookDirection, MirrorMesh.Plane.Normal));
                camInfo.CameraPosition_WorldSpace = Vector3.Transform(_camera.Position, planeReflectionMatrix);
                cls[4].UpdateBuffer(sc.CameraInfoBuffer, 0, ref camInfo);

                Matrix4x4 view = sc.Camera.ViewMatrix;
                view           = planeReflectionMatrix * view;
                cls[4].UpdateBuffer(sc.ViewMatrixBuffer, 0, view);

                Matrix4x4 projection = _camera.ProjectionMatrix;
                cls[4].UpdateBuffer(sc.ReflectionViewProjBuffer, 0, view * projection);

                BoundingFrustum cameraFrustum = new BoundingFrustum(view * projection);
                Render(gd, cls[4], sc, RenderPasses.ReflectionMap, cameraFrustum, _camera.Position, _renderQueues[3], _cullableStage[3], _renderableStage[3], null, true);

                cl.GenerateMipmaps(sc.ReflectionColorTexture);

                // Main scene
                cls[4].SetFramebuffer(sc.MainSceneFramebuffer);
                scWidth  = sc.MainSceneFramebuffer.Width;
                scHeight = sc.MainSceneFramebuffer.Height;
                cls[4].SetViewport(0, new Viewport(0, 0, scWidth, scHeight, 0, 1));
                cls[4].SetScissorRect(0, 0, 0, (uint)scWidth, (uint)scHeight);
                cls[4].ClearColorTarget(0, RgbaFloat.Black);
                cls[4].ClearDepthStencil(depthClear);
                sc.UpdateCameraBuffers(cls[4]);
                cameraFrustum = new BoundingFrustum(_camera.ViewMatrix * _camera.ProjectionMatrix);
                Render(gd, cls[4], sc, RenderPasses.Standard, cameraFrustum, _camera.Position, _renderQueues[3], _cullableStage[3], _renderableStage[3], null, true);
                Render(gd, cls[4], sc, RenderPasses.AlphaBlend, cameraFrustum, _camera.Position, _renderQueues[3], _cullableStage[3], _renderableStage[3], null, true);
                Render(gd, cls[4], sc, RenderPasses.Overlay, cameraFrustum, _camera.Position, _renderQueues[3], _cullableStage[3], _renderableStage[3], null, true);
            });

            Task.WaitAll(_tasks);

            foreach (Renderable renderable in _allPerFrameRenderablesSet)
            {
                renderable.UpdatePerFrameResources(gd, _resourceUpdateCL, sc);
            }
            _resourceUpdateCL.End();
            gd.SubmitCommands(_resourceUpdateCL);

            for (int i = 0; i < cls.Length; i++)
            {
                cls[i].End(); gd.SubmitCommands(cls[i]); cls[i].Dispose();
            }

            if (sc.MainSceneColorTexture.SampleCount != TextureSampleCount.Count1)
            {
                cl.ResolveTexture(sc.MainSceneColorTexture, sc.MainSceneResolvedColorTexture);
            }

            cl.SetFramebuffer(sc.DuplicatorFramebuffer);
            uint fbWidth  = sc.DuplicatorFramebuffer.Width;
            uint fbHeight = sc.DuplicatorFramebuffer.Height;

            cl.SetViewport(0, new Viewport(0, 0, fbWidth, fbHeight, 0, 1));
            cl.SetViewport(1, new Viewport(0, 0, fbWidth, fbHeight, 0, 1));
            cl.SetScissorRect(0, 0, 0, fbWidth, fbHeight);
            cl.SetScissorRect(1, 0, 0, fbWidth, fbHeight);
            Render(gd, cl, sc, RenderPasses.Duplicator, new BoundingFrustum(), _camera.Position, _renderQueues[0], _cullableStage[0], _renderableStage[0], null, false);

            cl.SetFramebuffer(gd.SwapchainFramebuffer);
            fbWidth  = gd.SwapchainFramebuffer.Width;
            fbHeight = gd.SwapchainFramebuffer.Height;
            cl.SetViewport(0, new Viewport(0, 0, fbWidth, fbHeight, 0, 1));
            cl.SetScissorRect(0, 0, 0, fbWidth, fbHeight);
            Render(gd, cl, sc, RenderPasses.SwapchainOutput, new BoundingFrustum(), _camera.Position, _renderQueues[0], _cullableStage[0], _renderableStage[0], null, false);

            cl.End();
            gd.SubmitCommands(cl);
        }