SHA256
Document Render Core And API
This commit is contained in:
1 parent
354c42fdd9
commit
8deb64fd4d
22 files changed
+1241
-27
No files matched your search
+69
-9
@@ -18,6 +18,21 @@ namespace ADOFAIRenderer.API;
|
||||
/// When <c>RenderFPS</c> exceeds <c>VideoFPS</c>, intermediate game rendering frames are skipped and the hook
|
||||
/// will <b>not</b> be invoked on every rendered game frame.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// <b>Ping-pong model:</b> the renderer owns two RenderTextures with the size and format of the game frame.
|
||||
/// <see cref="Source"/> is the current frame, <see cref="Destination"/> is the buffer the next pass writes.
|
||||
/// A pass draws from <see cref="Source"/> into <see cref="Destination"/> and then calls <see cref="Swap"/>, which makes
|
||||
/// the written buffer the new <see cref="Source"/>. <see cref="Blit(Material, int)"/>, and by default
|
||||
/// <see cref="DrawToDestination"/> and <see cref="ExecuteCommandBuffer"/>, swap automatically. The texture in
|
||||
/// <see cref="Current"/> after the last hook is encoded. When no hook swaps or replaces the frame, the game frame is
|
||||
/// encoded unchanged. The first <see cref="Source"/> of every frame is the game's own frame texture
|
||||
/// (<see cref="OriginalSource"/>); do not write into it.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// <b>Threading and lifetime:</b> hooks run on the main Unity thread at the end of the frame, after the game has
|
||||
/// rendered. The textures are valid only during the hook call: do not keep references to <see cref="Source"/>,
|
||||
/// <see cref="Destination"/> or the context. <c>RenderTexture.active</c> is restored after all hooks have run.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
[SuppressMessage("ReSharper", "UnusedType.Global")]
|
||||
[SuppressMessage("ReSharper", "UnusedMember.Global")]
|
||||
@@ -25,12 +40,22 @@ namespace ADOFAIRenderer.API;
|
||||
[SuppressMessage("ReSharper", "UnusedAutoPropertyAccessor.Global")]
|
||||
public class FrameHookContext
|
||||
{
|
||||
/// <summary>Game frame of this capture (camera quad texture); never written by the context.</summary>
|
||||
private RenderTexture _originalSource = null!;
|
||||
|
||||
/// <summary>First ping-pong buffer, owned by FrameHookPipeline.</summary>
|
||||
private RenderTexture _pingRT = null!;
|
||||
|
||||
/// <summary>Second ping-pong buffer, owned by FrameHookPipeline.</summary>
|
||||
private RenderTexture _pongRT = null!;
|
||||
|
||||
/// <summary>Current frame: the original source, a ping-pong buffer, or a texture set by ReplaceCurrent.</summary>
|
||||
private RenderTexture _currentSource = null!;
|
||||
|
||||
/// <summary>Buffer the next pass writes: always the ping or pong buffer.</summary>
|
||||
private RenderTexture _currentDestination = null!;
|
||||
|
||||
/// <summary>True after the first Swap or ReplaceCurrent of this frame.</summary>
|
||||
private bool _hasModified;
|
||||
|
||||
/// <summary>
|
||||
@@ -45,6 +70,7 @@ public class FrameHookContext
|
||||
|
||||
/// <summary>
|
||||
/// The active <see cref="RenderTexture"/> representing the current state of the modified frame.
|
||||
/// Same texture as <see cref="Source"/>; after the last hook it is the frame that gets encoded.
|
||||
/// </summary>
|
||||
public RenderTexture Current => _currentSource;
|
||||
|
||||
@@ -59,7 +85,7 @@ public class FrameHookContext
|
||||
public bool HasModified => _hasModified;
|
||||
|
||||
/// <summary>
|
||||
/// The sequential 0-based index of the video frame currently being encoded.
|
||||
/// The sequential 0-based index of the video frame currently being captured (its position in the output video).
|
||||
/// </summary>
|
||||
public long FrameIndex { get; private set; }
|
||||
|
||||
@@ -69,12 +95,13 @@ public class FrameHookContext
|
||||
public long VideoFrameIndex => FrameIndex;
|
||||
|
||||
/// <summary>
|
||||
/// The sequential 0-based index of the game render frame.
|
||||
/// The sequential 0-based index of the game render frame, counted from the start of capture.
|
||||
/// With <c>RenderFPS</c> above the video frame rate it advances by more than one between hook calls.
|
||||
/// </summary>
|
||||
public long RenderFrameIndex { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The timestamp of the current frame in seconds relative to video start.
|
||||
/// The timestamp of the current frame in seconds relative to video start (<see cref="FrameIndex"/> / <see cref="VideoFPS"/>).
|
||||
/// </summary>
|
||||
public double VideoTime { get; private set; }
|
||||
|
||||
@@ -84,30 +111,32 @@ public class FrameHookContext
|
||||
public double DeltaTime => VideoFPS > 0 ? 1.0 / VideoFPS : 0.0;
|
||||
|
||||
/// <summary>
|
||||
/// The width of the frame in pixels.
|
||||
/// The width of the frame in pixels (width of the current <see cref="Source"/>).
|
||||
/// </summary>
|
||||
public int Width => _currentSource.width;
|
||||
|
||||
/// <summary>
|
||||
/// The height of the frame in pixels.
|
||||
/// The height of the frame in pixels (height of the current <see cref="Source"/>).
|
||||
/// </summary>
|
||||
public int Height => _currentSource.height;
|
||||
|
||||
/// <summary>
|
||||
/// The configured render frames per second.
|
||||
/// The configured render frames per second (game frames simulated per second of render time).
|
||||
/// </summary>
|
||||
public double RenderFPS { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The output video frames per second.
|
||||
/// The output video frames per second: the effective rate, min(configured <c>VideoFPS</c>, <see cref="RenderFPS"/>).
|
||||
/// </summary>
|
||||
public double VideoFPS { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The number of successful modification passes completed for the current frame.
|
||||
/// The number of modification passes completed for the current frame (calls of <see cref="Swap"/> and
|
||||
/// <see cref="ReplaceCurrent"/>, including the automatic swaps of the helper methods). 0 at the start of every frame.
|
||||
/// </summary>
|
||||
public int PassCount { get; private set; }
|
||||
|
||||
/// <summary>Creates a context for the first frame; see <see cref="Reset"/> for the parameters.</summary>
|
||||
internal FrameHookContext(
|
||||
RenderTexture originalSource,
|
||||
RenderTexture pingRT,
|
||||
@@ -122,6 +151,10 @@ public class FrameHookContext
|
||||
Reset(originalSource, pingRT, pongRT, firstDestination, frameIndex, renderFrameIndex, videoTime, renderFps, videoFps);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Prepares the context for a new frame: Source = <paramref name="originalSource"/>, Destination =
|
||||
/// <paramref name="firstDestination"/> (ping or pong), not modified, PassCount 0, and the frame metadata.
|
||||
/// </summary>
|
||||
internal void Reset(
|
||||
RenderTexture originalSource,
|
||||
RenderTexture pingRT,
|
||||
@@ -152,6 +185,11 @@ public class FrameHookContext
|
||||
/// <summary>
|
||||
/// Blits from <see cref="Source"/> to <see cref="Destination"/> using the specified <see cref="Material"/> and automatically swaps ping-pong buffers.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Uses <c>Graphics.Blit</c>, which binds <see cref="Source"/> as the material's <c>_MainTex</c> and changes
|
||||
/// <c>RenderTexture.active</c>.
|
||||
/// Reference: https://docs.unity3d.com/ScriptReference/Graphics.Blit.html
|
||||
/// </remarks>
|
||||
/// <param name="material">The material containing the shader to apply, or <c>null</c> for a standard copy.</param>
|
||||
/// <param name="pass">The shader pass index to use, or -1 to execute all passes.</param>
|
||||
public void Blit(Material? material = null, int pass = -1)
|
||||
@@ -174,6 +212,10 @@ public class FrameHookContext
|
||||
/// <summary>
|
||||
/// Blits from a custom source <see cref="Texture"/> to <see cref="Destination"/> using the specified <see cref="Material"/> and automatically swaps ping-pong buffers.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The current <see cref="Source"/> is not read; the result replaces the frame. <paramref name="customSource"/> is
|
||||
/// stretched to the size of <see cref="Destination"/>.
|
||||
/// </remarks>
|
||||
/// <param name="customSource">The custom source texture to blit from.</param>
|
||||
/// <param name="material">The material containing the shader to apply, or <c>null</c> for a standard copy.</param>
|
||||
/// <param name="pass">The shader pass index to use, or -1 to execute all passes.</param>
|
||||
@@ -200,6 +242,7 @@ public class FrameHookContext
|
||||
/// <summary>
|
||||
/// Copies the contents of <see cref="Source"/> into <see cref="Destination"/> without swapping buffers.
|
||||
/// Call this before drawing custom overlays into <see cref="Destination"/> if you wish to preserve the background.
|
||||
/// Does not count as a modification; call <see cref="Swap"/> after drawing to make the result the current frame.
|
||||
/// </summary>
|
||||
public void Copy()
|
||||
{
|
||||
@@ -207,7 +250,8 @@ public class FrameHookContext
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears <see cref="Destination"/> with the specified color.
|
||||
/// Clears <see cref="Destination"/> with the specified color (color only; no depth buffer is cleared).
|
||||
/// Does not swap; the previous <c>RenderTexture.active</c> is restored.
|
||||
/// </summary>
|
||||
/// <param name="clearColor">The color to clear with, or <c>null</c> for <see cref="Color.clear"/>.</param>
|
||||
public void ClearDestination(Color? clearColor = null)
|
||||
@@ -261,6 +305,11 @@ public class FrameHookContext
|
||||
/// <summary>
|
||||
/// Executes a <see cref="CommandBuffer"/> against the GPU and optionally swaps buffers.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The context does not set a render target for the command buffer: the commands must render into
|
||||
/// <see cref="Destination"/> themselves (for example with <c>SetRenderTarget</c> or <c>Blit(Source, Destination)</c>),
|
||||
/// so build or update the buffer inside the hook with the current <see cref="Source"/> and <see cref="Destination"/>.
|
||||
/// </remarks>
|
||||
/// <param name="commandBuffer">The command buffer to execute.</param>
|
||||
/// <param name="autoSwap">If <c>true</c> (default), automatically calls <see cref="Swap"/> after execution.</param>
|
||||
/// <exception cref="ArgumentNullException">Thrown when <paramref name="commandBuffer"/> is null.</exception>
|
||||
@@ -278,6 +327,11 @@ public class FrameHookContext
|
||||
/// Swaps the active <see cref="Source"/> and <see cref="Destination"/> ping-pong buffers.
|
||||
/// Call this after manually writing or rendering into <see cref="Destination"/> so that subsequent hooks or the video encoder read the updated frame.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// After the call, <see cref="Source"/> is the buffer that was <see cref="Destination"/>, and <see cref="Destination"/>
|
||||
/// is the other ping-pong buffer (its content is left over from an earlier pass or frame; the next pass overwrites it).
|
||||
/// A texture set by <see cref="ReplaceCurrent"/> is dropped by a swap.
|
||||
/// </remarks>
|
||||
public void Swap()
|
||||
{
|
||||
_hasModified = true;
|
||||
@@ -291,6 +345,12 @@ public class FrameHookContext
|
||||
/// <summary>
|
||||
/// Replaces the current modified frame texture with a custom <see cref="RenderTexture"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The texture becomes <see cref="Source"/> / <see cref="Current"/>; <see cref="Destination"/> is unchanged.
|
||||
/// The texture is read back for encoding when it is still current after the last hook, so it must stay alive and
|
||||
/// unchanged until the end of the hook chain, and it should have the frame's width, height and a format the capture
|
||||
/// can read: the capture sizes its buffers from the texture, and the encoder expects the render resolution.
|
||||
/// </remarks>
|
||||
/// <param name="customTexture">The custom texture to set as the active frame.</param>
|
||||
/// <exception cref="ArgumentNullException">Thrown when <paramref name="customTexture"/> is null.</exception>
|
||||
public void ReplaceCurrent(RenderTexture customTexture)
|
||||
|
||||
Reference in new issue
Block a user