public void Render( RenderContext rc, SceneContext sc, RenderPasses pass, BoundingFrustum frustum, Comparer <RenderItemIndex> comparer = null) { _renderQueue.Clear(); _cullableStage.Clear(); CollectVisibleObjects(ref frustum, pass, _cullableStage); _renderQueue.AddRange(_cullableStage, _camera.Position); _renderableStage.Clear(); CollectFreeObjects(pass, _renderableStage); _renderQueue.AddRange(_renderableStage, _camera.Position); if (comparer == null) { _renderQueue.Sort(); } else { _renderQueue.Sort(comparer); } foreach (Renderable renderable in _renderQueue) { renderable.Render(rc, sc, pass); } }
public void Render( GraphicsDevice gd, CommandList rc, SceneContext sc, RenderPasses pass, BoundingFrustum frustum, RenderQueue renderQueue, List <CullRenderable> cullRenderableList, List <Renderable> renderableList, Comparer <RenderItemIndex> comparer, bool threaded) { renderQueue.Clear(); cullRenderableList.Clear(); CollectVisibleObjects(ref frustum, pass, cullRenderableList); renderQueue.AddRange(cullRenderableList, _camera.Position); renderableList.Clear(); CollectFreeObjects(pass, renderableList); renderQueue.AddRange(renderableList, _camera.Position); if (comparer == null) { renderQueue.Sort(); } else { renderQueue.Sort(comparer); } foreach (Renderable renderable in renderQueue) { renderable.Render(gd, rc, sc, pass); } if (threaded) { foreach (CullRenderable thing in cullRenderableList) { _allPerFrameRenderablesConcurrentBag.Add(thing); } foreach (Renderable thing in renderableList) { _allPerFrameRenderablesConcurrentBag.Add(thing); } } else { foreach (CullRenderable thing in cullRenderableList) { _allPerFrameRenderablesSet.Add(thing); } foreach (Renderable thing in renderableList) { _allPerFrameRenderablesSet.Add(thing); } } }
public virtual void CreateDeviceObjects(GraphicsDevice gd, CommandList cl, SceneContext sc) { ResourceFactory factory = gd.ResourceFactory; ProjectionMatrixBuffer = factory.CreateUniformBuffer(new BufferDescription(64)); ViewMatrixBuffer = factory.CreateUniformBuffer(new BufferDescription(64)); LightViewProjectionBuffer0 = factory.CreateUniformBuffer(new BufferDescription(64, true)); gd.SetResourceName(LightViewProjectionBuffer0, "LightViewProjectionBuffer0"); LightViewProjectionBuffer1 = factory.CreateUniformBuffer(new BufferDescription(64, true)); gd.SetResourceName(LightViewProjectionBuffer1, "LightViewProjectionBuffer1"); LightViewProjectionBuffer2 = factory.CreateUniformBuffer(new BufferDescription(64, true)); gd.SetResourceName(LightViewProjectionBuffer2, "LightViewProjectionBuffer2"); DepthLimitsBuffer = factory.CreateUniformBuffer(new BufferDescription((uint)Unsafe.SizeOf <DepthCascadeLimits>())); LightInfoBuffer = factory.CreateUniformBuffer(new BufferDescription((uint)Unsafe.SizeOf <DirectionalLightInfo>())); CameraInfoBuffer = factory.CreateUniformBuffer(new BufferDescription((uint)Unsafe.SizeOf <CameraInfo>())); if (Camera != null) { UpdateCameraBuffers(cl); } PointLightsBuffer = factory.CreateUniformBuffer(new BufferDescription((uint)Unsafe.SizeOf <PointLightsInfo.Blittable>())); PointLightsInfo pli = new PointLightsInfo(); pli.NumActiveLights = 4; pli.PointLights = new PointLightInfo[4] { new PointLightInfo { Color = new Vector3(1f, 1f, 1f), Position = new Vector3(-50, 5, 0), Range = 75f }, new PointLightInfo { Color = new Vector3(1f, .75f, .9f), Position = new Vector3(0, 5, 0), Range = 100f }, new PointLightInfo { Color = new Vector3(1f, 1f, 0.6f), Position = new Vector3(50, 5, 0), Range = 40f }, new PointLightInfo { Color = new Vector3(0.75f, 0.75f, 1f), Position = new Vector3(25, 5, 45), Range = 150f }, }; cl.UpdateBuffer(PointLightsBuffer, 0, pli.GetBlittable()); NearShadowMapTexture = factory.CreateTexture(new TextureDescription(2048, 2048, 1, 1, 1, PixelFormat.R16_UNorm, TextureUsage.DepthStencil | TextureUsage.Sampled)); gd.SetResourceName(NearShadowMapTexture, "Near Shadow Map"); NearShadowMapView = factory.CreateTextureView(new TextureViewDescription(NearShadowMapTexture)); NearShadowMapFramebuffer = factory.CreateFramebuffer(new FramebufferDescription(NearShadowMapTexture)); MidShadowMapTexture = factory.CreateTexture(new TextureDescription(2048, 2048, 1, 1, 1, PixelFormat.R16_UNorm, TextureUsage.DepthStencil | TextureUsage.Sampled)); MidShadowMapView = factory.CreateTextureView(new TextureViewDescription(MidShadowMapTexture)); MidShadowMapFramebuffer = factory.CreateFramebuffer(new FramebufferDescription(MidShadowMapTexture)); FarShadowMapTexture = factory.CreateTexture(new TextureDescription(4096, 4096, 1, 1, 1, PixelFormat.R16_UNorm, TextureUsage.DepthStencil | TextureUsage.Sampled)); FarShadowMapView = factory.CreateTextureView(new TextureViewDescription(FarShadowMapTexture)); FarShadowMapFramebuffer = factory.CreateFramebuffer(new FramebufferDescription(FarShadowMapTexture)); }
public void RenderAllStages(GraphicsDevice gd, CommandList cl, SceneContext sc) { if (ThreadedRendering) { RenderAllMultiThreaded(gd, cl, sc); } else { RenderAllSingleThread(gd, cl, sc); } }
public override void CreateDeviceObjects(GraphicsDevice gd, CommandList cl, SceneContext sc) { if (_imguiRenderer == null) { _imguiRenderer = new ImGuiRenderer(gd, cl, gd.SwapchainFramebuffer.OutputDescription, _width, _height); } else { _imguiRenderer.CreateDeviceResources(gd, cl, gd.SwapchainFramebuffer.OutputDescription); } }
public override void CreateDeviceObjects(GraphicsDevice gd, CommandList cl, SceneContext sc) { if (_imguiRenderer == null) { _imguiRenderer = new ImGuiRenderer(gd, sc.MainSceneFramebuffer.OutputDescription, _width, _height, ColorSpaceHandling.Linear); } else { _imguiRenderer.CreateDeviceResources(gd, sc.MainSceneFramebuffer.OutputDescription, ColorSpaceHandling.Linear); } }
internal void CreateAllDeviceObjects(GraphicsDevice gd, CommandList cl, SceneContext sc) { _cullableStage[0].Clear(); _octree.GetAllContainedObjects(_cullableStage[0]); foreach (CullRenderable cr in _cullableStage[0]) { cr.CreateDeviceObjects(gd, cl, sc); } foreach (Renderable r in _freeRenderables) { r.CreateDeviceObjects(gd, cl, sc); } _resourceUpdateCL = gd.ResourceFactory.CreateCommandList(); _resourceUpdateCL.Name = "Scene Resource Update Command List"; }
private Matrix4x4 UpdateDirectionalLightMatrices( SceneContext sc, float near, float far, int shadowMapWidth, out BoundingFrustum lightFrustum) { Vector3 lightDir = sc.DirectionalLight.Direction; Vector3 viewDir = sc.Camera.LookDirection; Vector3 viewPos = sc.Camera.Position; Vector3 unitY = Vector3.UnitY; FrustumHelpers.ComputePerspectiveFrustumCorners( ref viewPos, ref viewDir, ref unitY, sc.Camera.FieldOfView, near, far, sc.Camera.AspectRatio, out FrustumCorners cameraCorners); // Approach used: http://alextardif.com/ShadowMapping.html Vector3 frustumCenter = Vector3.Zero; frustumCenter += cameraCorners.NearTopLeft; frustumCenter += cameraCorners.NearTopRight; frustumCenter += cameraCorners.NearBottomLeft; frustumCenter += cameraCorners.NearBottomRight; frustumCenter += cameraCorners.FarTopLeft; frustumCenter += cameraCorners.FarTopRight; frustumCenter += cameraCorners.FarBottomLeft; frustumCenter += cameraCorners.FarBottomRight; frustumCenter /= 8f; float radius = (cameraCorners.NearTopLeft - cameraCorners.FarBottomRight).Length() / 2.0f; float texelsPerUnit = shadowMapWidth / (radius * 2.0f); Matrix4x4 scalar = Matrix4x4.CreateScale(texelsPerUnit, texelsPerUnit, texelsPerUnit); Vector3 baseLookAt = -lightDir; Matrix4x4 lookat = Matrix4x4.CreateLookAt(Vector3.Zero, baseLookAt, Vector3.UnitY); lookat = scalar * lookat; Matrix4x4.Invert(lookat, out Matrix4x4 lookatInv); frustumCenter = Vector3.Transform(frustumCenter, lookat); frustumCenter.X = (int)frustumCenter.X; frustumCenter.Y = (int)frustumCenter.Y; frustumCenter = Vector3.Transform(frustumCenter, lookatInv); Vector3 lightPos = frustumCenter - (lightDir * radius * 2f); Matrix4x4 lightView = Matrix4x4.CreateLookAt(lightPos, frustumCenter, Vector3.UnitY); Matrix4x4 lightProjection = Matrix4x4.CreateOrthographicOffCenter( -radius * _lScale, radius * _rScale, -radius * _bScale, radius * _tScale, -radius * _nScale, radius * _fScale); Matrix4x4 viewProjectionMatrix = lightView * lightProjection; lightFrustum = new BoundingFrustum(lightProjection); return(viewProjectionMatrix); }
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); }
public override void UpdatePerFrameResources(GraphicsDevice gd, CommandList cl, SceneContext sc) { }
public override void Render(RenderContext rc, SceneContext sc, RenderPasses renderPass) { Debug.Assert(renderPass == RenderPasses.Overlay); _imguiRenderer.Render(rc); }
public abstract void Render(GraphicsDevice gd, CommandList cl, SceneContext sc, RenderPasses renderPass);
public abstract void UpdatePerFrameResources(GraphicsDevice gd, CommandList cl, SceneContext sc);
public abstract void CreateDeviceObjects(GraphicsDevice gd, CommandList cl, SceneContext sc);
private void RenderAllSingleThread(GraphicsDevice gd, CommandList cl, SceneContext sc) { 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()); // Near Matrix4x4 viewProj0 = UpdateDirectionalLightMatrices( sc, Camera.NearDistance, _nearCascadeLimit, sc.NearShadowMapTexture.Width, out BoundingFrustum lightFrustum); cl.UpdateBuffer(sc.LightViewProjectionBuffer0, 0, ref viewProj0); cl.SetFramebuffer(sc.NearShadowMapFramebuffer); cl.SetViewport(0, new Viewport(0, 0, sc.NearShadowMapTexture.Width, sc.NearShadowMapTexture.Height, 0, 1)); cl.SetScissorRect(0, 0, 0, sc.NearShadowMapTexture.Width, sc.NearShadowMapTexture.Height); cl.ClearDepthTarget(01f); Render(gd, cl, sc, RenderPasses.ShadowMapNear, lightFrustum, _renderQueues[0], _cullableStage[0], _renderableStage[0], null, false); // Mid Matrix4x4 viewProj1 = UpdateDirectionalLightMatrices( sc, _nearCascadeLimit, _midCascadeLimit, sc.MidShadowMapTexture.Width, out lightFrustum); cl.UpdateBuffer(sc.LightViewProjectionBuffer1, 0, ref viewProj1); cl.SetFramebuffer(sc.MidShadowMapFramebuffer); cl.SetViewport(0, new Viewport(0, 0, sc.MidShadowMapTexture.Width, sc.MidShadowMapTexture.Height, 0, 1)); cl.SetScissorRect(0, 0, 0, sc.MidShadowMapTexture.Width, sc.MidShadowMapTexture.Height); cl.ClearDepthTarget(1f); Render(gd, cl, sc, RenderPasses.ShadowMapMid, lightFrustum, _renderQueues[0], _cullableStage[0], _renderableStage[0], null, false); // Far Matrix4x4 viewProj2 = UpdateDirectionalLightMatrices( sc, _midCascadeLimit, _farCascadeLimit, sc.FarShadowMapTexture.Width, out lightFrustum); cl.UpdateBuffer(sc.LightViewProjectionBuffer2, 0, ref viewProj2); cl.SetFramebuffer(sc.FarShadowMapFramebuffer); cl.SetViewport(0, new Viewport(0, 0, sc.FarShadowMapTexture.Width, sc.FarShadowMapTexture.Height, 0, 1)); cl.SetScissorRect(0, 0, 0, sc.FarShadowMapTexture.Width, sc.FarShadowMapTexture.Height); cl.ClearDepthTarget(1f); Render(gd, cl, sc, RenderPasses.ShadowMapFar, lightFrustum, _renderQueues[0], _cullableStage[0], _renderableStage[0], null, false); cl.SetFramebuffer(gd.SwapchainFramebuffer); float scWidth = gd.SwapchainFramebuffer.Width; float scHeight = gd.SwapchainFramebuffer.Height; cl.SetViewport(0, new Viewport(0, 0, scWidth, scHeight, 0, 1)); cl.SetScissorRect(0, 0, 0, (uint)scWidth, (uint)scHeight); cl.ClearColorTarget(0, RgbaFloat.CornflowerBlue); cl.ClearDepthTarget(1f); BoundingFrustum cameraFrustum = new BoundingFrustum(_camera.ViewMatrix * _camera.ProjectionMatrix); Render(gd, cl, sc, RenderPasses.Standard, cameraFrustum, _renderQueues[0], _cullableStage[0], _renderableStage[0], null, false); Render(gd, cl, sc, RenderPasses.AlphaBlend, cameraFrustum, _renderQueues[0], _cullableStage[0], _renderableStage[0], null, false); Render(gd, cl, sc, RenderPasses.Overlay, cameraFrustum, _renderQueues[0], _cullableStage[0], _renderableStage[0], null, false); _resourceUpdateCL.Begin(); foreach (Renderable renderable in _allPerFrameRenderablesSet) { renderable.UpdatePerFrameResources(gd, _resourceUpdateCL, sc); } _resourceUpdateCL.End(); gd.ExecuteCommands(_resourceUpdateCL); }
public void RenderAllStages(RenderContext rc, SceneContext sc) { 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); sc.DepthLimitsBuffer.SetData(new DepthCascadeLimits { NearLimit = nearLimitCS.Z, MidLimit = midLimitCS.Z, FarLimit = farLimitCS.Z }); sc.LightInfoBuffer.SetData(sc.DirectionalLight.GetInfo()); // Near Matrix4x4 viewProj0 = UpdateDirectionalLightMatrices( sc, Camera.NearDistance, _nearCascadeLimit, sc.NearShadowMapTexture.Width, out BoundingFrustum lightFrustum); sc.LightViewProjectionBuffer0.SetData(ref viewProj0); sc.CurrentLightViewProjectionBuffer = sc.LightViewProjectionBuffer0; rc.SetFramebuffer(sc.NearShadowMapFramebuffer); rc.SetViewport(0, 0, sc.NearShadowMapTexture.Width, sc.NearShadowMapTexture.Height); rc.ClearBuffer(); Render(rc, sc, RenderPasses.ShadowMap, lightFrustum, null); // Mid Matrix4x4 viewProj1 = UpdateDirectionalLightMatrices( sc, _nearCascadeLimit, _midCascadeLimit, sc.MidShadowMapTexture.Width, out lightFrustum); sc.LightViewProjectionBuffer1.SetData(ref viewProj1); sc.CurrentLightViewProjectionBuffer = sc.LightViewProjectionBuffer1; rc.SetFramebuffer(sc.MidShadowMapFramebuffer); rc.SetViewport(0, 0, sc.MidShadowMapTexture.Width, sc.MidShadowMapTexture.Height); rc.ClearBuffer(); Render(rc, sc, RenderPasses.ShadowMap, lightFrustum, null); // Far Matrix4x4 viewProj2 = UpdateDirectionalLightMatrices( sc, _midCascadeLimit, _farCascadeLimit, sc.FarShadowMapTexture.Width, out lightFrustum); sc.LightViewProjectionBuffer2.SetData(ref viewProj2); sc.CurrentLightViewProjectionBuffer = sc.LightViewProjectionBuffer2; rc.SetFramebuffer(sc.FarShadowMapFramebuffer); rc.SetViewport(0, 0, sc.FarShadowMapTexture.Width, sc.FarShadowMapTexture.Height); rc.ClearBuffer(); Render(rc, sc, RenderPasses.ShadowMap, lightFrustum, null); rc.SetDefaultFramebuffer(); rc.SetViewport(0, 0, rc.CurrentFramebuffer.Width, rc.CurrentFramebuffer.Height); BoundingFrustum cameraFrustum = new BoundingFrustum(_camera.ViewMatrix * _camera.ProjectionMatrix); Render(rc, sc, RenderPasses.Standard, cameraFrustum, null); Render(rc, sc, RenderPasses.AlphaBlend, cameraFrustum, null); Render(rc, sc, RenderPasses.Overlay, cameraFrustum, null); }
public abstract void Render(RenderContext rc, SceneContext sc, RenderPasses renderPass);
public override void Render(GraphicsDevice gd, CommandList cl, SceneContext sc, RenderPasses renderPass) { Debug.Assert(renderPass == RenderPasses.Overlay); _imguiRenderer.Render(gd, cl); }
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); }
public virtual void CreateDeviceObjects(GraphicsDevice gd, CommandList cl, SceneContext sc) { ResourceFactory factory = gd.ResourceFactory; ProjectionMatrixBuffer = factory.CreateBuffer(new BufferDescription(64, BufferUsage.UniformBuffer | BufferUsage.Dynamic)); ViewMatrixBuffer = factory.CreateBuffer(new BufferDescription(64, BufferUsage.UniformBuffer | BufferUsage.Dynamic)); LightViewProjectionBuffer0 = factory.CreateBuffer(new BufferDescription(64, BufferUsage.UniformBuffer | BufferUsage.Dynamic)); LightViewProjectionBuffer0.Name = "LightViewProjectionBuffer0"; LightViewProjectionBuffer1 = factory.CreateBuffer(new BufferDescription(64, BufferUsage.UniformBuffer | BufferUsage.Dynamic)); LightViewProjectionBuffer1.Name = "LightViewProjectionBuffer1"; LightViewProjectionBuffer2 = factory.CreateBuffer(new BufferDescription(64, BufferUsage.UniformBuffer | BufferUsage.Dynamic)); LightViewProjectionBuffer2.Name = "LightViewProjectionBuffer2"; DepthLimitsBuffer = factory.CreateBuffer(new BufferDescription((uint)Unsafe.SizeOf <DepthCascadeLimits>(), BufferUsage.UniformBuffer | BufferUsage.Dynamic)); LightInfoBuffer = factory.CreateBuffer(new BufferDescription((uint)Unsafe.SizeOf <DirectionalLightInfo>(), BufferUsage.UniformBuffer | BufferUsage.Dynamic)); CameraInfoBuffer = factory.CreateBuffer(new BufferDescription((uint)Unsafe.SizeOf <CameraInfo>(), BufferUsage.UniformBuffer | BufferUsage.Dynamic)); if (Camera != null) { UpdateCameraBuffers(cl); } PointLightsBuffer = factory.CreateBuffer(new BufferDescription((uint)Unsafe.SizeOf <PointLightsInfo.Blittable>(), BufferUsage.UniformBuffer)); PointLightsInfo pli = new PointLightsInfo(); pli.NumActiveLights = 4; pli.PointLights = new PointLightInfo[4] { new PointLightInfo { Color = new Vector3(1f, 1f, 1f), Position = new Vector3(-50, 5, 0), Range = 75f }, new PointLightInfo { Color = new Vector3(1f, .75f, .9f), Position = new Vector3(0, 5, 0), Range = 100f }, new PointLightInfo { Color = new Vector3(1f, 1f, 0.6f), Position = new Vector3(50, 5, 0), Range = 40f }, new PointLightInfo { Color = new Vector3(0.75f, 0.75f, 1f), Position = new Vector3(25, 5, 45), Range = 150f }, }; cl.UpdateBuffer(PointLightsBuffer, 0, pli.GetBlittable()); TextureSamplerResourceLayout = factory.CreateResourceLayout(new ResourceLayoutDescription( new ResourceLayoutElementDescription("SourceTexture", ResourceKind.TextureReadOnly, ShaderStages.Fragment), new ResourceLayoutElementDescription("SourceSampler", ResourceKind.Sampler, ShaderStages.Fragment))); uint ReflectionMapSize = 2048; ReflectionColorTexture = factory.CreateTexture(TextureDescription.Texture2D(ReflectionMapSize, ReflectionMapSize, 1, 1, PixelFormat.R8_G8_B8_A8_UNorm, TextureUsage.RenderTarget | TextureUsage.Sampled)); ReflectionDepthTexture = factory.CreateTexture(TextureDescription.Texture2D(ReflectionMapSize, ReflectionMapSize, 1, 1, PixelFormat.R16_UNorm, TextureUsage.DepthStencil)); ReflectionColorView = factory.CreateTextureView(ReflectionColorTexture); ReflectionFramebuffer = factory.CreateFramebuffer(new FramebufferDescription(ReflectionDepthTexture, ReflectionColorTexture)); ReflectionViewProjBuffer = factory.CreateBuffer(new BufferDescription(64, BufferUsage.UniformBuffer | BufferUsage.Dynamic)); MirrorClipPlaneBuffer = factory.CreateBuffer(new BufferDescription(32, BufferUsage.UniformBuffer)); gd.UpdateBuffer(MirrorClipPlaneBuffer, 0, new ClipPlaneInfo(MirrorMesh.Plane, true)); NoClipPlaneBuffer = factory.CreateBuffer(new BufferDescription(32, BufferUsage.UniformBuffer)); gd.UpdateBuffer(NoClipPlaneBuffer, 0, new ClipPlaneInfo()); RecreateWindowSizedResources(gd, cl); ShadowMaps.CreateDeviceResources(gd); }
private void RenderAllMultiThreaded(GraphicsDevice gd, SceneContext sc) { 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); _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()); _allPerFrameRenderablesConcurrentBag.Clear(); _tasks[0] = Task.Run(() => { // Near Matrix4x4 viewProj0 = UpdateDirectionalLightMatrices( sc, Camera.NearDistance, _nearCascadeLimit, sc.NearShadowMapTexture.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.NearShadowMapTexture.Width, sc.NearShadowMapTexture.Height, 0, 1)); cls[1].SetScissorRect(0, 0, 0, sc.NearShadowMapTexture.Width, sc.NearShadowMapTexture.Height); cls[1].ClearDepthTarget(1f); Render(gd, cls[1], sc, RenderPasses.ShadowMapNear, lightFrustum0, _renderQueues[0], _cullableStage[0], _renderableStage[0], null, true); }); _tasks[1] = Task.Run(() => { // Mid Matrix4x4 viewProj1 = UpdateDirectionalLightMatrices( sc, _nearCascadeLimit, _midCascadeLimit, sc.MidShadowMapTexture.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.MidShadowMapTexture.Width, sc.MidShadowMapTexture.Height, 0, 1)); cls[2].SetScissorRect(0, 0, 0, sc.MidShadowMapTexture.Width, sc.MidShadowMapTexture.Height); cls[2].ClearDepthTarget(1f); Render(gd, cls[2], sc, RenderPasses.ShadowMapMid, lightFrustum1, _renderQueues[1], _cullableStage[1], _renderableStage[1], null, true); }); _tasks[2] = Task.Run(() => { // Far Matrix4x4 viewProj2 = UpdateDirectionalLightMatrices( sc, _midCascadeLimit, _farCascadeLimit, sc.FarShadowMapTexture.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.FarShadowMapTexture.Width, sc.FarShadowMapTexture.Height, 0, 1)); cls[3].SetScissorRect(0, 0, 0, sc.FarShadowMapTexture.Width, sc.FarShadowMapTexture.Height); cls[3].ClearDepthTarget(1f); Render(gd, cls[3], sc, RenderPasses.ShadowMapFar, lightFrustum2, _renderQueues[2], _cullableStage[2], _renderableStage[2], null, true); }); _tasks[3] = Task.Run(() => { cls[4].SetFramebuffer(gd.SwapchainFramebuffer); float scWidth = gd.SwapchainFramebuffer.Width; float scHeight = gd.SwapchainFramebuffer.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].ClearDepthTarget(1f); BoundingFrustum cameraFrustum = new BoundingFrustum(_camera.ViewMatrix * _camera.ProjectionMatrix); Render(gd, cls[4], sc, RenderPasses.Standard, cameraFrustum, _renderQueues[3], _cullableStage[3], _renderableStage[3], null, true); Render(gd, cls[4], sc, RenderPasses.AlphaBlend, cameraFrustum, _renderQueues[3], _cullableStage[3], _renderableStage[3], null, true); Render(gd, cls[4], sc, RenderPasses.Overlay, cameraFrustum, _renderQueues[3], _cullableStage[3], _renderableStage[3], null, true); }); Task.WaitAll(_tasks); foreach (Renderable renderable in _allPerFrameRenderablesConcurrentBag.ToHashSet()) { renderable.UpdatePerFrameResources(gd, _resourceUpdateCL, sc); } _resourceUpdateCL.End(); gd.ExecuteCommands(_resourceUpdateCL); for (int i = 0; i < cls.Length; i++) { cls[i].End(); gd.ExecuteCommands(cls[i]); cls[i].Dispose(); } }