165 lines
8.4 KiB
C#
165 lines
8.4 KiB
C#
|
|
using System;
|
||
|
|
using UnityEngine.Rendering.RenderGraphModule;
|
||
|
|
using System.Runtime.CompilerServices; // AggressiveInlining
|
||
|
|
|
||
|
|
namespace UnityEngine.Rendering.Universal
|
||
|
|
{
|
||
|
|
internal sealed class UpscalerPostProcessPass : PostProcessPass
|
||
|
|
{
|
||
|
|
public const string k_UpscaledColorTargetName = "_CameraColorUpscaled";
|
||
|
|
Texture2D[] m_BlueNoise16LTex;
|
||
|
|
bool m_IsValid;
|
||
|
|
|
||
|
|
public UpscalerPostProcessPass(Texture2D[] blueNoise16LTex)
|
||
|
|
{
|
||
|
|
this.renderPassEvent = RenderPassEvent.AfterRenderingPostProcessing - 1;
|
||
|
|
this.profilingSampler = null; // Use default name
|
||
|
|
m_BlueNoise16LTex = blueNoise16LTex;
|
||
|
|
|
||
|
|
m_IsValid = m_BlueNoise16LTex != null && m_BlueNoise16LTex.Length > 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
public override void Dispose()
|
||
|
|
{
|
||
|
|
m_IsValid = false;
|
||
|
|
}
|
||
|
|
|
||
|
|
public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameData)
|
||
|
|
{
|
||
|
|
#if ENABLE_UPSCALER_FRAMEWORK
|
||
|
|
if (!m_IsValid)
|
||
|
|
return;
|
||
|
|
|
||
|
|
UniversalCameraData cameraData = frameData.Get<UniversalCameraData>();
|
||
|
|
UniversalResourceData resourceData = frameData.Get<UniversalResourceData>();
|
||
|
|
UniversalPostProcessingData postProcessingData = frameData.Get<UniversalPostProcessingData>();
|
||
|
|
|
||
|
|
var sourceTexture = resourceData.cameraColor;
|
||
|
|
var srcDesc = sourceTexture.GetDescriptor(renderGraph);
|
||
|
|
|
||
|
|
// Create a context item containing upscaling inputs
|
||
|
|
UpscalingIO io = frameData.Create<UpscalingIO>();
|
||
|
|
io.cameraColor = sourceTexture;
|
||
|
|
io.cameraDepth = resourceData.cameraDepth;
|
||
|
|
io.motionVectorColor = resourceData.motionVectorColor;
|
||
|
|
io.motionVectorDomain = UpscalingIO.MotionVectorDomain.NDC;
|
||
|
|
io.motionVectorDirection = UpscalingIO.MotionVectorDirection.PreviousFrameToCurrentFrame;
|
||
|
|
io.jitteredMotionVectors = false; // URP has no jittering in MVs
|
||
|
|
// io.exposureTexture; // TODO: set exposure texture when available
|
||
|
|
io.preExposureValue = 1.0f; // TODO: set if exposure value is pre-multiplied
|
||
|
|
io.hdrDisplayInformation = cameraData.isHDROutputActive ? cameraData.hdrDisplayInformation : new HDROutputUtils.HDRDisplayInformation(-1, -1, -1, 160.0f);
|
||
|
|
io.preUpscaleResolution = new Vector2Int(
|
||
|
|
cameraData.cameraTargetDescriptor.width,
|
||
|
|
cameraData.cameraTargetDescriptor.height
|
||
|
|
);
|
||
|
|
io.previousPreUpscaleResolution = io.preUpscaleResolution; // URP doesn't support Dynamic Resolution Scaling (DRS).
|
||
|
|
io.postUpscaleResolution = new Vector2Int(cameraData.pixelWidth, cameraData.pixelHeight);
|
||
|
|
io.motionVectorTextureSize = io.preUpscaleResolution;
|
||
|
|
io.enableTexArray = cameraData.xr.enabled && cameraData.xr.singlePassEnabled;
|
||
|
|
|
||
|
|
MotionVectorsPersistentData motionData = null;
|
||
|
|
{
|
||
|
|
cameraData.camera.TryGetComponent<UniversalAdditionalCameraData>(out var additionalCameraData);
|
||
|
|
Debug.Assert(additionalCameraData != null);
|
||
|
|
motionData = additionalCameraData.motionVectorsPersistentData;
|
||
|
|
Debug.Assert(motionData != null);
|
||
|
|
}
|
||
|
|
io.cameraInstanceID = cameraData.camera.GetEntityId();
|
||
|
|
io.nearClipPlane = cameraData.camera.nearClipPlane;
|
||
|
|
io.farClipPlane = cameraData.camera.farClipPlane;
|
||
|
|
io.fieldOfViewDegrees = cameraData.camera.fieldOfView;
|
||
|
|
io.invertedDepth = SystemInfo.usesReversedZBuffer;
|
||
|
|
io.flippedY = SystemInfo.graphicsUVStartsAtTop;
|
||
|
|
io.flippedX = false;
|
||
|
|
io.hdrInput = Experimental.Rendering.GraphicsFormatUtility.IsHDRFormat(srcDesc.format);
|
||
|
|
io.numActiveViews = cameraData.xr.enabled ? cameraData.xr.viewCount : 1;
|
||
|
|
io.eyeIndex = (cameraData.xr.enabled && !cameraData.xr.singlePassEnabled) ? cameraData.xr.multipassId : 0;
|
||
|
|
io.worldSpaceCameraPositions = new Vector3[io.numActiveViews];
|
||
|
|
io.previousWorldSpaceCameraPositions = new Vector3[io.numActiveViews];
|
||
|
|
io.previousPreviousWorldSpaceCameraPositions = new Vector3[io.numActiveViews];
|
||
|
|
for (int i = 0; i < io.numActiveViews; i++)
|
||
|
|
{
|
||
|
|
io.worldSpaceCameraPositions[i] = motionData.worldSpaceCameraPos;
|
||
|
|
io.previousWorldSpaceCameraPositions[i] = motionData.previousWorldSpaceCameraPos;
|
||
|
|
io.previousPreviousWorldSpaceCameraPositions[i] = motionData.previousPreviousWorldSpaceCameraPos;
|
||
|
|
}
|
||
|
|
io.projectionMatrices = motionData.projectionStereo;
|
||
|
|
io.previousProjectionMatrices = motionData.previousProjectionStereo;
|
||
|
|
io.previousPreviousProjectionMatrices = motionData.previousPreviousProjectionStereo;
|
||
|
|
io.viewMatrices = motionData.viewStereo;
|
||
|
|
io.previousViewMatrices = motionData.previousViewStereo;
|
||
|
|
io.previousPreviousViewMatrices = motionData.previousPreviousViewStereo;
|
||
|
|
io.resetHistory = cameraData.resetHistory;
|
||
|
|
// TODO (Apoorva): Maybe we want to support this?
|
||
|
|
// URP supports adding an offset value to the TAA frame index for testing determinism as follows:
|
||
|
|
// io.frameIndex = Time.frameCount + settings.jitterFrameCountOffset;
|
||
|
|
io.frameIndex = Time.frameCount;
|
||
|
|
io.deltaTime = motionData.deltaTime;
|
||
|
|
io.previousDeltaTime = motionData.lastDeltaTime;
|
||
|
|
io.blueNoiseTextureSet = m_BlueNoise16LTex;
|
||
|
|
|
||
|
|
// The motion scaling feature is only active outside of test environments. If we allowed it to run
|
||
|
|
// during automated graphics tests, the results of each test run would be dependent on system
|
||
|
|
// performance.
|
||
|
|
#if LWRP_DEBUG_STATIC_POSTFX
|
||
|
|
io.enableMotionScaling = false;
|
||
|
|
#else
|
||
|
|
io.enableMotionScaling = true;
|
||
|
|
#endif
|
||
|
|
io.enableHwDrs = false; // URP doesn't support hardware dynamic resolution scaling
|
||
|
|
// Insert the active upscaler's render graph passes
|
||
|
|
postProcessingData.activeUpscaler.RecordRenderGraph(renderGraph, frameData);
|
||
|
|
|
||
|
|
// Update the camera resolution to reflect the upscaled size
|
||
|
|
var dstDesc = io.cameraColor.GetDescriptor(renderGraph);
|
||
|
|
UpdateCameraResolution(renderGraph, cameraData, new Vector2Int(dstDesc.width, dstDesc.height));
|
||
|
|
|
||
|
|
// Use the output texture of upscaling
|
||
|
|
resourceData.cameraColor = io.cameraColor;
|
||
|
|
#endif
|
||
|
|
}
|
||
|
|
|
||
|
|
private class UpdateCameraResolutionPassData
|
||
|
|
{
|
||
|
|
internal Vector2Int newCameraTargetSize;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Updates render target descriptors and shader constants to reflect a new render size
|
||
|
|
// This should be called immediately after the resolution changes mid-frame (typically after an upscaling operation).
|
||
|
|
static internal void UpdateCameraResolution(RenderGraph renderGraph, UniversalCameraData cameraData, Vector2Int newCameraTargetSize)
|
||
|
|
{
|
||
|
|
// Update the camera data descriptor to reflect post-upscaled sizes
|
||
|
|
cameraData.cameraTargetDescriptor.width = newCameraTargetSize.x;
|
||
|
|
cameraData.cameraTargetDescriptor.height = newCameraTargetSize.y;
|
||
|
|
|
||
|
|
// Update the shader constants to reflect the new camera resolution
|
||
|
|
using (var builder = renderGraph.AddUnsafePass<UpdateCameraResolutionPassData>("Update Camera Resolution", out var passData))
|
||
|
|
{
|
||
|
|
passData.newCameraTargetSize = newCameraTargetSize;
|
||
|
|
|
||
|
|
// This pass only modifies shader constants
|
||
|
|
builder.AllowGlobalStateModification(true);
|
||
|
|
|
||
|
|
// Wrap constant modification into a pass to force graph execution timeline.
|
||
|
|
builder.SetRenderFunc(static (UpdateCameraResolutionPassData data, UnsafeGraphContext ctx) =>
|
||
|
|
{
|
||
|
|
ctx.cmd.SetGlobalVector(
|
||
|
|
ShaderPropertyId.screenSize,
|
||
|
|
new Vector4(
|
||
|
|
data.newCameraTargetSize.x,
|
||
|
|
data.newCameraTargetSize.y,
|
||
|
|
1.0f / data.newCameraTargetSize.x,
|
||
|
|
1.0f / data.newCameraTargetSize.y
|
||
|
|
)
|
||
|
|
);
|
||
|
|
});
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Precomputed shader ids to same some CPU cycles (mostly affects mobile)
|
||
|
|
public static class ShaderConstants
|
||
|
|
{
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|