11 changed files with 404 additions and 0 deletions
-
1Packages/com.unity.postprocessing@3.2.2/PostProcessing/PostProcessResources.asset
-
2Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling.cs
-
3Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/PS5.meta
-
BINPackages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/PS5/PSSRPlugin.prx
-
77Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/PS5/PSSRPlugin.prx.meta
-
230Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/PSSRUpscaler.cs
-
3Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/PSSRUpscaler.cs.meta
-
49Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/Upscaler.cs
-
5Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/PostProcessResources.cs
-
27Packages/com.unity.postprocessing@3.2.2/PostProcessing/Shaders/Builtins/PrepareInputs.compute
-
7Packages/com.unity.postprocessing@3.2.2/PostProcessing/Shaders/Builtins/PrepareInputs.compute.meta
@ -0,0 +1,3 @@ |
|||||
|
fileFormatVersion: 2 |
||||
|
guid: 32c5585f0ac1473aaa942ede8bc01712 |
||||
|
timeCreated: 1730718066 |
||||
@ -0,0 +1,77 @@ |
|||||
|
fileFormatVersion: 2 |
||||
|
guid: 82cb3c505a5252e4db0b661d9ccd67cb |
||||
|
PluginImporter: |
||||
|
externalObjects: {} |
||||
|
serializedVersion: 2 |
||||
|
iconMap: {} |
||||
|
executionOrder: {} |
||||
|
defineConstraints: [] |
||||
|
isPreloaded: 1 |
||||
|
isOverridable: 1 |
||||
|
isExplicitlyReferenced: 0 |
||||
|
validateReferences: 1 |
||||
|
platformData: |
||||
|
- first: |
||||
|
: Any |
||||
|
second: |
||||
|
enabled: 0 |
||||
|
settings: |
||||
|
Exclude Editor: 1 |
||||
|
Exclude GameCoreScarlett: 1 |
||||
|
Exclude GameCoreXboxOne: 1 |
||||
|
Exclude Linux64: 1 |
||||
|
Exclude OSXUniversal: 1 |
||||
|
Exclude PS4: 1 |
||||
|
Exclude PS5: 0 |
||||
|
Exclude Win: 1 |
||||
|
Exclude Win64: 1 |
||||
|
- first: |
||||
|
Any: |
||||
|
second: |
||||
|
enabled: 0 |
||||
|
settings: {} |
||||
|
- first: |
||||
|
Editor: Editor |
||||
|
second: |
||||
|
enabled: 0 |
||||
|
settings: |
||||
|
CPU: AnyCPU |
||||
|
DefaultValueInitialized: true |
||||
|
OS: AnyOS |
||||
|
- first: |
||||
|
PS4: PS4 |
||||
|
second: |
||||
|
enabled: 0 |
||||
|
settings: {} |
||||
|
- first: |
||||
|
PS5: PS5 |
||||
|
second: |
||||
|
enabled: 1 |
||||
|
settings: {} |
||||
|
- first: |
||||
|
Standalone: Linux64 |
||||
|
second: |
||||
|
enabled: 0 |
||||
|
settings: |
||||
|
CPU: AnyCPU |
||||
|
- first: |
||||
|
Standalone: OSXUniversal |
||||
|
second: |
||||
|
enabled: 0 |
||||
|
settings: |
||||
|
CPU: AnyCPU |
||||
|
- first: |
||||
|
Standalone: Win |
||||
|
second: |
||||
|
enabled: 0 |
||||
|
settings: |
||||
|
CPU: AnyCPU |
||||
|
- first: |
||||
|
Standalone: Win64 |
||||
|
second: |
||||
|
enabled: 0 |
||||
|
settings: |
||||
|
CPU: AnyCPU |
||||
|
userData: |
||||
|
assetBundleName: |
||||
|
assetBundleVariant: |
||||
@ -0,0 +1,230 @@ |
|||||
|
using System; |
||||
|
using System.Runtime.InteropServices; |
||||
|
using UnityEngine.Experimental.Rendering; |
||||
|
|
||||
|
namespace UnityEngine.Rendering.PostProcessing |
||||
|
{ |
||||
|
internal class PSSRUpscaler : Upscaler |
||||
|
{ |
||||
|
#if UNITY_PS5
|
||||
|
public static bool IsSupported => UnityEngine.PS5.Utility.isTrinityMode; |
||||
|
|
||||
|
private PSSRPlugin.DispatchParams _dispatchParams; |
||||
|
private IntPtr _dispatchParamsBuffer; |
||||
|
|
||||
|
private RenderTexture _inputColor; |
||||
|
private RenderTexture _inputDepth; |
||||
|
private RenderTexture _outputColor; |
||||
|
private Texture2D _outputIntermediate; |
||||
|
|
||||
|
private bool _pluginInitialized; |
||||
|
private bool _contextInitialized; |
||||
|
|
||||
|
public override void CreateContext(PostProcessRenderContext context, Upscaling config) |
||||
|
{ |
||||
|
if (!PSSRPlugin.InitPssr()) |
||||
|
{ |
||||
|
Debug.LogError("Failed to initialize PSSR plugin!"); |
||||
|
_pluginInitialized = false; |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
_pluginInitialized = true; |
||||
|
|
||||
|
PSSRPlugin.InitParams initParams; |
||||
|
initParams.displayWidth = (uint)config.UpscaleSize.x; |
||||
|
initParams.displayHeight = (uint)config.UpscaleSize.y; |
||||
|
initParams.maxRenderWidth = (uint)config.MaxRenderSize.x; |
||||
|
initParams.maxRenderHeight = (uint)config.MaxRenderSize.y; |
||||
|
|
||||
|
CreateRenderTexture(ref _inputColor, "PSSR Input Color", config.MaxRenderSize, context.sourceFormat, true); |
||||
|
CreateRenderTexture(ref _inputDepth, "PSSR Input Depth", config.MaxRenderSize, GraphicsFormat.R32_SFloat, true); |
||||
|
CreateRenderTexture(ref _outputColor, "PSSR Output Color", config.UpscaleSize, RenderTextureFormat.RGB111110Float); |
||||
|
|
||||
|
if (PSSRPlugin.CreatePssrContext(ref initParams, out IntPtr outputColorTexturePtr) >= 0 && outputColorTexturePtr != IntPtr.Zero) |
||||
|
{ |
||||
|
// PSSR requires an output color texture in a very particular format (k11_11_10Float with kStandard256B tile mode and a specific alignment) that Unity cannot create directly.
|
||||
|
// So instead we let the plugin create that texture and then import it into Unity as a generic 32bpp texture from a native pointer.
|
||||
|
_outputIntermediate = Texture2D.CreateExternalTexture(config.UpscaleSize.x, config.UpscaleSize.y, TextureFormat.RGBA32, false, true, outputColorTexturePtr); |
||||
|
_dispatchParamsBuffer = Marshal.AllocHGlobal(Marshal.SizeOf<PSSRPlugin.DispatchParams>()); |
||||
|
_contextInitialized = true; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public override void DestroyContext() |
||||
|
{ |
||||
|
base.DestroyContext(); |
||||
|
|
||||
|
// TODO: this still race conditions sometimes
|
||||
|
if (_contextInitialized) |
||||
|
{ |
||||
|
var cmd = new CommandBuffer(); |
||||
|
cmd.IssuePluginEventAndData(PSSRPlugin.GetRenderEventAndDataFunc(), 2, IntPtr.Zero); |
||||
|
Graphics.ExecuteCommandBuffer(cmd); |
||||
|
cmd.Release(); |
||||
|
|
||||
|
_contextInitialized = false; |
||||
|
} |
||||
|
|
||||
|
DestroyRenderTexture(ref _outputColor); |
||||
|
DestroyRenderTexture(ref _inputDepth); |
||||
|
DestroyRenderTexture(ref _inputColor); |
||||
|
|
||||
|
if (_dispatchParamsBuffer != IntPtr.Zero) |
||||
|
{ |
||||
|
Marshal.FreeHGlobal(_dispatchParamsBuffer); |
||||
|
_dispatchParamsBuffer = IntPtr.Zero; |
||||
|
} |
||||
|
|
||||
|
if (_pluginInitialized) |
||||
|
{ |
||||
|
PSSRPlugin.ReleasePssr(); |
||||
|
_pluginInitialized = false; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private static readonly int CameraMotionVectorsTexture = Shader.PropertyToID("_CameraMotionVectorsTexture"); |
||||
|
|
||||
|
public override void Render(PostProcessRenderContext context, Upscaling config) |
||||
|
{ |
||||
|
var cmd = context.command; |
||||
|
if (!_pluginInitialized || !_contextInitialized) |
||||
|
{ |
||||
|
cmd.BlitFullscreenTriangle(context.source, context.destination); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
cmd.BeginSample("PSSR"); |
||||
|
|
||||
|
// TODO: if PSSR needs a copy of the previous depth and motion vectors anyway, why not just double-buffer those resources ourselves and make good use of these otherwise dumb copies?
|
||||
|
PrepareInputs(cmd, context, config, _inputColor, _inputDepth); |
||||
|
|
||||
|
_dispatchParams.color = ToNativePtr(_inputColor); |
||||
|
_dispatchParams.depth = ToNativePtr(_inputDepth); |
||||
|
_dispatchParams.motionVectors = ToNativePtr(Shader.GetGlobalTexture(CameraMotionVectorsTexture)); |
||||
|
_dispatchParams.exposure = ToNativePtr(config.exposureSource switch |
||||
|
{ |
||||
|
Upscaling.ExposureSource.Manual when config.exposure != null => config.exposure, |
||||
|
Upscaling.ExposureSource.Unity => context.autoExposureTexture, |
||||
|
_ => null, |
||||
|
}); |
||||
|
_dispatchParams.reactiveMask = ToNativePtr(config.reactiveMask); |
||||
|
_dispatchParams.outputColor = ToNativePtr(_outputIntermediate); |
||||
|
|
||||
|
var scaledRenderSize = config.GetScaledRenderSize(context.camera); |
||||
|
_dispatchParams.renderWidth = (uint)scaledRenderSize.x; |
||||
|
_dispatchParams.renderHeight = (uint)scaledRenderSize.y; |
||||
|
_dispatchParams.jitter = config.JitterOffset; // TODO: may need to scale this (should be jitter in render pixels apparently)
|
||||
|
_dispatchParams.motionVectorScale = new Vector2(-scaledRenderSize.x, -scaledRenderSize.y); |
||||
|
_dispatchParams.FromCamera(context.camera); |
||||
|
_dispatchParams.preExposure = config.preExposure; |
||||
|
_dispatchParams.resetHistory = config.Reset ? 1u : 0u; |
||||
|
|
||||
|
Marshal.StructureToPtr(_dispatchParams, _dispatchParamsBuffer, false); |
||||
|
cmd.IssuePluginEventAndData(PSSRPlugin.GetRenderEventAndDataFunc(), 1, _dispatchParamsBuffer); |
||||
|
|
||||
|
// Convert the native texture into Unity-land using a blind texture data copy
|
||||
|
cmd.CopyTexture(_outputIntermediate, _outputColor); |
||||
|
|
||||
|
// TODO: optional sharpening
|
||||
|
cmd.BlitFullscreenTriangle(_outputColor, context.destination); |
||||
|
|
||||
|
cmd.EndSample("PSSR"); |
||||
|
} |
||||
|
|
||||
|
private static IntPtr ToNativePtr(Texture texture) |
||||
|
{ |
||||
|
return texture != null ? texture.GetNativeTexturePtr() : IntPtr.Zero; |
||||
|
} |
||||
|
|
||||
|
private static class PSSRPlugin |
||||
|
{ |
||||
|
private const string LibraryName = "PSSRPlugin.prx"; |
||||
|
|
||||
|
[DllImport(LibraryName)] |
||||
|
public static extern IntPtr GetRenderEventAndDataFunc(); |
||||
|
|
||||
|
[DllImport(LibraryName)] |
||||
|
public static extern bool InitPssr(); |
||||
|
|
||||
|
[DllImport(LibraryName)] |
||||
|
public static extern void ReleasePssr(); |
||||
|
|
||||
|
[DllImport(LibraryName)] |
||||
|
public static extern int CreatePssrContext(ref InitParams initParams, out IntPtr outputColorTexturePtr); |
||||
|
|
||||
|
[Serializable, StructLayout(LayoutKind.Sequential)] |
||||
|
public struct InitParams |
||||
|
{ |
||||
|
public uint displayWidth; |
||||
|
public uint displayHeight; |
||||
|
public uint maxRenderWidth; |
||||
|
public uint maxRenderHeight; |
||||
|
} |
||||
|
|
||||
|
[Serializable, StructLayout(LayoutKind.Sequential)] |
||||
|
public struct DispatchParams |
||||
|
{ |
||||
|
public IntPtr color; |
||||
|
public IntPtr depth; |
||||
|
public IntPtr motionVectors; |
||||
|
public IntPtr exposure; |
||||
|
public IntPtr reactiveMask; |
||||
|
public IntPtr outputColor; |
||||
|
|
||||
|
public uint renderWidth; |
||||
|
public uint renderHeight; |
||||
|
|
||||
|
public Vector2 jitter; |
||||
|
public Vector2 motionVectorScale; |
||||
|
|
||||
|
public Matrix4x4 camProjection; |
||||
|
public Vector3 camForward; |
||||
|
public Vector3 camUp; |
||||
|
public Vector3 camRight; |
||||
|
public double camPositionX; |
||||
|
public double camPositionY; |
||||
|
public double camPositionZ; |
||||
|
public float pad; |
||||
|
|
||||
|
public float camNear; |
||||
|
public float camFar; |
||||
|
public float preExposure; |
||||
|
public uint resetHistory; |
||||
|
|
||||
|
public void FromCamera(Camera cam) |
||||
|
{ |
||||
|
camProjection = cam.projectionMatrix; |
||||
|
camForward = cam.transform.forward; |
||||
|
camUp = cam.transform.up; |
||||
|
camRight = cam.transform.right; |
||||
|
camPositionX = cam.transform.position.x; |
||||
|
camPositionY = cam.transform.position.y; |
||||
|
camPositionZ = cam.transform.position.z; |
||||
|
pad = 0f; |
||||
|
|
||||
|
camNear = cam.nearClipPlane; |
||||
|
camFar = cam.farClipPlane; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
#else
|
||||
|
public static bool IsSupported => false; |
||||
|
|
||||
|
public override void CreateContext(PostProcessRenderContext context, Upscaling config) |
||||
|
{ |
||||
|
throw new NotImplementedException(); |
||||
|
} |
||||
|
|
||||
|
public override void DestroyContext() |
||||
|
{ |
||||
|
base.DestroyContext(); |
||||
|
} |
||||
|
|
||||
|
public override void Render(PostProcessRenderContext context, Upscaling config) |
||||
|
{ |
||||
|
throw new NotImplementedException(); |
||||
|
} |
||||
|
#endif
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,3 @@ |
|||||
|
fileFormatVersion: 2 |
||||
|
guid: dfe32e853f4042ab8ce14f5cdc3c3151 |
||||
|
timeCreated: 1730636826 |
||||
@ -0,0 +1,27 @@ |
|||||
|
#pragma kernel CS |
||||
|
|
||||
|
Texture2D InColor: register(t0); |
||||
|
Texture2D<float> InDepth: register(t1); |
||||
|
//Texture2D<float2> InMotionVectors: register(t2); |
||||
|
|
||||
|
RWTexture2D<float4> OutColor: register(u0); |
||||
|
RWTexture2D<float> OutDepth: register(u1); |
||||
|
//RWTexture2D<float2> OutMotionVectors: register(u2); |
||||
|
|
||||
|
cbuffer Params: register(b0) |
||||
|
{ |
||||
|
int prepareColor; |
||||
|
int prepareDepth; |
||||
|
int prepareMotionVectors; |
||||
|
int pad; |
||||
|
}; |
||||
|
|
||||
|
[numthreads(8, 8, 1)] |
||||
|
void CS(uint2 GroupId: SV_GroupID, uint2 GroupThreadId: SV_GroupThreadID) |
||||
|
{ |
||||
|
uint2 InputPos = GroupId * uint2(8, 8) + GroupThreadId; |
||||
|
|
||||
|
if (prepareColor) OutColor[InputPos] = InColor[InputPos]; |
||||
|
if (prepareDepth) OutDepth[InputPos] = InDepth[InputPos]; |
||||
|
//if (prepareMotionVectors) OutMotionVectors[InputPos] = InMotionVectors[InputPos]; |
||||
|
} |
||||
@ -0,0 +1,7 @@ |
|||||
|
fileFormatVersion: 2 |
||||
|
guid: d27c88814f02b424088b06503e1bc9d5 |
||||
|
ComputeShaderImporter: |
||||
|
externalObjects: {} |
||||
|
userData: |
||||
|
assetBundleName: |
||||
|
assetBundleVariant: |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue