forked from Misaki/GhostEngine
Update rendering architecture and resource management
Added a new `Ref<T>` struct for reference semantics. Added the `RenderGraph` system for managing rendering passes. Added the `RenderTexture` class for encapsulating GPU resources. Added `GraphicsBuffer` class for effective GPU resource management. Changed `CommandList` methods from public to internal for visibility control. Changed `IRenderPass` interface from internal to public for accessibility. Changed `GetData<T>()` in `ComponentObject.cs` to return `CompRef<T>`. Changed `GetComponent<T>()` in `EntityManager.cs` to return `CompRef<T>`. Changed `GetSingleton<T>()` in `World.cs` to use `CompRef<T>`. Changed `IQueryTypeParameter` to use `CompRef<T>` for consistency. Changed `QueryItem<T0>` and related structs to use `CompRef<T>`. Changed `Material` class to support bindless textures. Changed `Shader` class to support bindless rendering. Changed `Mesh` class to support bindless vertex and index buffer access. Updated documentation to reflect the new bindless rendering architecture.
This commit is contained in:
230
Ghost.Graphics/Examples/RenderGraphExample.cs
Normal file
230
Ghost.Graphics/Examples/RenderGraphExample.cs
Normal file
@@ -0,0 +1,230 @@
|
||||
using Ghost.Graphics.Data;
|
||||
using Ghost.Graphics.RenderGraphModule;
|
||||
using System.Numerics;
|
||||
using Win32.Graphics.Direct3D12;
|
||||
using Win32.Graphics.Dxgi.Common;
|
||||
|
||||
namespace Ghost.Graphics.Examples;
|
||||
|
||||
/// <summary>
|
||||
/// Example demonstrating render graph usage with history buffers and multiple cameras
|
||||
/// </summary>
|
||||
public static class RenderGraphExample
|
||||
{
|
||||
// Example pass data structures
|
||||
public struct DepthPrePassData
|
||||
{
|
||||
public RGTextureHandle DepthBuffer;
|
||||
// Add other render targets, constants, etc.
|
||||
}
|
||||
|
||||
public struct GBufferPassData
|
||||
{
|
||||
public RGTextureHandle DepthBuffer;
|
||||
public RGTextureHandle AlbedoBuffer;
|
||||
public RGTextureHandle NormalBuffer;
|
||||
public RGTextureHandle MaterialBuffer;
|
||||
}
|
||||
|
||||
public struct LightingPassData
|
||||
{
|
||||
public RGTextureHandle DepthBuffer;
|
||||
public RGTextureHandle AlbedoBuffer;
|
||||
public RGTextureHandle NormalBuffer;
|
||||
public RGTextureHandle MaterialBuffer;
|
||||
public RGTextureHandle SceneColor;
|
||||
public RGTextureHandle PreviousFrameColor; // History buffer
|
||||
}
|
||||
|
||||
public struct PostProcessPassData
|
||||
{
|
||||
public RGTextureHandle SceneColor;
|
||||
public RGTextureHandle FinalColor;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Example camera/view state class to store history buffers (like Unreal's FViewState)
|
||||
/// </summary>
|
||||
public class CameraViewState
|
||||
{
|
||||
public TextureHandle? PreviousFrameColorBuffer;
|
||||
public TextureHandle? PreviousFrameDepthBuffer;
|
||||
public TextureHandle? VelocityBuffer;
|
||||
|
||||
public Matrix4x4 PreviousViewProjectionMatrix;
|
||||
}
|
||||
|
||||
public static void ExampleRenderGraph(CameraViewState viewState, TextureHandle backBuffer)
|
||||
{
|
||||
// Create render graph with optional descriptor
|
||||
var renderGraphDesc = new RenderGraphDesc(initialResourceCapacity: 512, initialPassCapacity: 128);
|
||||
using var renderGraph = new RenderGraph("MainRenderGraph", renderGraphDesc);
|
||||
|
||||
// Begin recording passes
|
||||
renderGraph.BeginRecord();
|
||||
|
||||
// Import external resources (backbuffer, history buffers)
|
||||
var backBufferHandle = renderGraph.ImportTexture(
|
||||
"BackBuffer",
|
||||
backBuffer,
|
||||
new TextureDescription(1920, 1080, 1, Format.R8G8B8A8Unorm, ResourceFlags.AllowRenderTarget));
|
||||
|
||||
// Import history buffer if available (for temporal effects like TAA)
|
||||
RGTextureHandle? previousFrameColorHandle = null;
|
||||
if (viewState.PreviousFrameColorBuffer.HasValue)
|
||||
{
|
||||
previousFrameColorHandle = renderGraph.ImportTexture(
|
||||
"PreviousFrameColor",
|
||||
viewState.PreviousFrameColorBuffer.Value,
|
||||
new TextureDescription(1920, 1080, 1, Format.R8G8B8A8Unorm));
|
||||
}
|
||||
|
||||
// Depth Pre-pass
|
||||
renderGraph.CreatePass<DepthPrePassData>("DepthPrePass")
|
||||
.Setup((ref DepthPrePassData data, RenderPassBuilder builder) =>
|
||||
{
|
||||
// Create depth buffer as transient resource
|
||||
data.DepthBuffer = builder.CreateTexture("DepthBuffer",
|
||||
new TextureDescription(1920, 1080, 1, Format.D32Float, ResourceFlags.AllowDepthStencil));
|
||||
|
||||
// Declare write access to depth buffer
|
||||
data.DepthBuffer = builder.WriteTexture(data.DepthBuffer);
|
||||
})
|
||||
.SetRenderFunc((ref DepthPrePassData data, RenderPassContext ctx) =>
|
||||
{
|
||||
// Render depth only
|
||||
// Use data.DepthBuffer for rendering
|
||||
})
|
||||
.Compile();
|
||||
|
||||
// G-Buffer Pass
|
||||
var gBufferOutputs = renderGraph.CreatePass<GBufferPassData>("GBufferPass")
|
||||
.Setup((ref GBufferPassData data, RenderPassBuilder builder) =>
|
||||
{
|
||||
// Read depth buffer from previous pass
|
||||
data.DepthBuffer = builder.ReadTexture(data.DepthBuffer); // This will be resolved during compilation
|
||||
|
||||
// Create G-Buffer targets
|
||||
data.AlbedoBuffer = builder.CreateTexture("AlbedoBuffer",
|
||||
new TextureDescription(1920, 1080, 1, Format.R8G8B8A8Unorm, ResourceFlags.AllowRenderTarget));
|
||||
data.NormalBuffer = builder.CreateTexture("NormalBuffer",
|
||||
new TextureDescription(1920, 1080, 1, Format.R8G8B8A8Snorm, ResourceFlags.AllowRenderTarget));
|
||||
data.MaterialBuffer = builder.CreateTexture("MaterialBuffer",
|
||||
new TextureDescription(1920, 1080, 1, Format.R8G8B8A8Unorm, ResourceFlags.AllowRenderTarget));
|
||||
|
||||
// Declare write access
|
||||
data.AlbedoBuffer = builder.WriteTexture(data.AlbedoBuffer);
|
||||
data.NormalBuffer = builder.WriteTexture(data.NormalBuffer);
|
||||
data.MaterialBuffer = builder.WriteTexture(data.MaterialBuffer);
|
||||
})
|
||||
.SetRenderFunc((ref GBufferPassData data, RenderPassContext ctx) =>
|
||||
{
|
||||
// Render geometry to G-Buffer
|
||||
// Use data.DepthBuffer, data.AlbedoBuffer, etc.
|
||||
});
|
||||
|
||||
gBufferOutputs.Compile();
|
||||
|
||||
// Lighting Pass
|
||||
var lightingOutput = renderGraph.CreatePass<LightingPassData>("LightingPass")
|
||||
.Setup((ref LightingPassData data, RenderPassBuilder builder) =>
|
||||
{
|
||||
// Read G-Buffer outputs
|
||||
data.DepthBuffer = builder.ReadTexture(data.DepthBuffer);
|
||||
data.AlbedoBuffer = builder.ReadTexture(data.AlbedoBuffer);
|
||||
data.NormalBuffer = builder.ReadTexture(data.NormalBuffer);
|
||||
data.MaterialBuffer = builder.ReadTexture(data.MaterialBuffer);
|
||||
|
||||
// Create scene color output
|
||||
data.SceneColor = builder.CreateTexture("SceneColor",
|
||||
new TextureDescription(1920, 1080, 1, Format.R16G16B16A16Float, ResourceFlags.AllowRenderTarget));
|
||||
data.SceneColor = builder.WriteTexture(data.SceneColor);
|
||||
|
||||
// Use previous frame color if available (for temporal effects)
|
||||
if (previousFrameColorHandle.HasValue)
|
||||
{
|
||||
data.PreviousFrameColor = builder.ReadTexture(previousFrameColorHandle.Value);
|
||||
}
|
||||
})
|
||||
.SetRenderFunc((ref LightingPassData data, RenderPassContext ctx) =>
|
||||
{
|
||||
// Perform deferred lighting
|
||||
// Can access previous frame color for temporal anti-aliasing, etc.
|
||||
});
|
||||
|
||||
lightingOutput.Compile();
|
||||
|
||||
// Post-Processing Pass
|
||||
renderGraph.CreatePass<PostProcessPassData>("PostProcessPass")
|
||||
.Setup((ref PostProcessPassData data, RenderPassBuilder builder) =>
|
||||
{
|
||||
// Read scene color from lighting pass
|
||||
data.SceneColor = builder.ReadTexture(data.SceneColor);
|
||||
|
||||
// Write to backbuffer
|
||||
data.FinalColor = builder.WriteTexture(backBufferHandle);
|
||||
})
|
||||
.SetRenderFunc((ref PostProcessPassData data, RenderPassContext ctx) =>
|
||||
{
|
||||
// Apply tone mapping, gamma correction, etc.
|
||||
// Copy to backbuffer
|
||||
});
|
||||
|
||||
// End recording
|
||||
renderGraph.EndRecord();
|
||||
|
||||
// Compile the render graph (dependency analysis, topological sort, resource lifetime analysis)
|
||||
renderGraph.Compile();
|
||||
|
||||
// Export resources for next frame (history buffers)
|
||||
if (lightingOutput != null) // In real implementation, you'd track the scene color handle
|
||||
{
|
||||
// viewState.PreviousFrameColorBuffer = renderGraph.ExportTexture(sceneColorHandle);
|
||||
}
|
||||
|
||||
// Execute the render graph
|
||||
renderGraph.Execute();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Example with multiple cameras rendering to different targets
|
||||
/// </summary>
|
||||
public static void MultiCameraExample(List<CameraViewState> cameras, List<TextureHandle> renderTargets)
|
||||
{
|
||||
using var renderGraph = new RenderGraph("MultiCameraRenderGraph");
|
||||
renderGraph.BeginRecord();
|
||||
|
||||
for (var i = 0; i < cameras.Count; i++)
|
||||
{
|
||||
var camera = cameras[i];
|
||||
var renderTarget = renderTargets[i];
|
||||
var cameraName = $"Camera{i}";
|
||||
|
||||
// Import render target
|
||||
var renderTargetHandle = renderGraph.ImportTexture(
|
||||
$"{cameraName}_RenderTarget",
|
||||
renderTarget,
|
||||
new TextureDescription(1920, 1080, 1, Format.R8G8B8A8Unorm, ResourceFlags.AllowRenderTarget));
|
||||
|
||||
// Camera-specific rendering passes
|
||||
renderGraph.CreatePass<DepthPrePassData>($"{cameraName}_DepthPrePass")
|
||||
.Setup((ref DepthPrePassData data, RenderPassBuilder builder) =>
|
||||
{
|
||||
data.DepthBuffer = builder.CreateTexture($"{cameraName}_DepthBuffer",
|
||||
new TextureDescription(1920, 1080, 1, Format.D32Float, ResourceFlags.AllowDepthStencil));
|
||||
data.DepthBuffer = builder.WriteTexture(data.DepthBuffer);
|
||||
})
|
||||
.SetRenderFunc((ref DepthPrePassData data, RenderPassContext ctx) =>
|
||||
{
|
||||
// Render with camera[i] view/projection matrices
|
||||
})
|
||||
.Compile();
|
||||
|
||||
// Additional passes for this camera...
|
||||
}
|
||||
|
||||
renderGraph.EndRecord();
|
||||
renderGraph.Compile();
|
||||
renderGraph.Execute();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user