22 changed files with 885 additions and 4 deletions
-
4Packages/com.unity.postprocessing@3.2.2/PostProcessing/PostProcessResources.asset
-
8Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/SGSR2.meta
-
34Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/SGSR2/SGSR2.cs
-
11Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/SGSR2/SGSR2.cs.meta
-
8Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/SGSR2/Shaders.meta
-
3Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/SGSR2/Shaders/sgsr2_activate.compute
-
7Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/SGSR2/Shaders/sgsr2_activate.compute.meta
-
3Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/SGSR2/Shaders/sgsr2_convert.compute
-
7Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/SGSR2/Shaders/sgsr2_convert.compute.meta
-
3Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/SGSR2/Shaders/sgsr2_upscale.compute
-
7Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/SGSR2/Shaders/sgsr2_upscale.compute.meta
-
8Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/SGSR2/Shaders/shaders.meta
-
141Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/SGSR2/Shaders/shaders/sgsr2_activate.hlsl
-
7Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/SGSR2/Shaders/shaders/sgsr2_activate.hlsl.meta
-
127Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/SGSR2/Shaders/shaders/sgsr2_convert.hlsl
-
7Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/SGSR2/Shaders/shaders/sgsr2_convert.hlsl.meta
-
315Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/SGSR2/Shaders/shaders/sgsr2_upscale.hlsl
-
7Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/SGSR2/Shaders/shaders/sgsr2_upscale.hlsl.meta
-
142Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/SGSR2Upscaler.cs
-
3Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/SGSR2Upscaler.cs.meta
-
32Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/Upscaler.cs
-
5Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/PostProcessResources.cs
@ -0,0 +1,8 @@ |
|||||
|
fileFormatVersion: 2 |
||||
|
guid: 260875685c7ca5f4e9b3250dc54cefa5 |
||||
|
folderAsset: yes |
||||
|
DefaultImporter: |
||||
|
externalObjects: {} |
||||
|
userData: |
||||
|
assetBundleName: |
||||
|
assetBundleVariant: |
||||
@ -0,0 +1,34 @@ |
|||||
|
using System; |
||||
|
using System.Collections; |
||||
|
using System.Collections.Generic; |
||||
|
using UnityEngine; |
||||
|
|
||||
|
public class SGSR2 |
||||
|
{ |
||||
|
[Serializable] |
||||
|
public struct Params |
||||
|
{ |
||||
|
public Vector2Int renderSize; |
||||
|
public Vector2Int displaySize; |
||||
|
public Vector2 renderSizeRcp; |
||||
|
public Vector2 displaySizeRcp; |
||||
|
public Vector2 jitterOffset; |
||||
|
public Matrix4x4 clipToPrevClip; |
||||
|
public float preExposure; |
||||
|
public float cameraFovAngleHor; |
||||
|
public float cameraNear; |
||||
|
public float minLerpContribution; |
||||
|
public uint bSameCamera; |
||||
|
public uint reset; |
||||
|
} |
||||
|
|
||||
|
[Serializable] |
||||
|
public class Shaders |
||||
|
{ |
||||
|
public ComputeShader convert; |
||||
|
|
||||
|
public ComputeShader activate; |
||||
|
|
||||
|
public ComputeShader upscale; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,11 @@ |
|||||
|
fileFormatVersion: 2 |
||||
|
guid: 90947cc43979fe34a8d41922d0491528 |
||||
|
MonoImporter: |
||||
|
externalObjects: {} |
||||
|
serializedVersion: 2 |
||||
|
defaultReferences: [] |
||||
|
executionOrder: 0 |
||||
|
icon: {instanceID: 0} |
||||
|
userData: |
||||
|
assetBundleName: |
||||
|
assetBundleVariant: |
||||
@ -0,0 +1,8 @@ |
|||||
|
fileFormatVersion: 2 |
||||
|
guid: 6702adb1ba60ebd4cb3e577b586e6e23 |
||||
|
folderAsset: yes |
||||
|
DefaultImporter: |
||||
|
externalObjects: {} |
||||
|
userData: |
||||
|
assetBundleName: |
||||
|
assetBundleVariant: |
||||
@ -0,0 +1,3 @@ |
|||||
|
#pragma kernel CS |
||||
|
|
||||
|
#include "shaders/sgsr2_activate.hlsl" |
||||
@ -0,0 +1,7 @@ |
|||||
|
fileFormatVersion: 2 |
||||
|
guid: d7de362950af6fe4e90da7d6e32f9826 |
||||
|
ComputeShaderImporter: |
||||
|
externalObjects: {} |
||||
|
userData: |
||||
|
assetBundleName: |
||||
|
assetBundleVariant: |
||||
@ -0,0 +1,3 @@ |
|||||
|
#pragma kernel CS |
||||
|
|
||||
|
#include "shaders/sgsr2_convert.hlsl" |
||||
@ -0,0 +1,7 @@ |
|||||
|
fileFormatVersion: 2 |
||||
|
guid: a41757aacd8b70e42a4001d514bfbe53 |
||||
|
ComputeShaderImporter: |
||||
|
externalObjects: {} |
||||
|
userData: |
||||
|
assetBundleName: |
||||
|
assetBundleVariant: |
||||
@ -0,0 +1,3 @@ |
|||||
|
#pragma kernel CS |
||||
|
|
||||
|
#include "shaders/sgsr2_upscale.hlsl" |
||||
@ -0,0 +1,7 @@ |
|||||
|
fileFormatVersion: 2 |
||||
|
guid: 5d28d29787492b74aa736a21f70572c7 |
||||
|
ComputeShaderImporter: |
||||
|
externalObjects: {} |
||||
|
userData: |
||||
|
assetBundleName: |
||||
|
assetBundleVariant: |
||||
@ -0,0 +1,8 @@ |
|||||
|
fileFormatVersion: 2 |
||||
|
guid: 81bb130e0ef32fa4fb623a65d2f2116e |
||||
|
folderAsset: yes |
||||
|
DefaultImporter: |
||||
|
externalObjects: {} |
||||
|
userData: |
||||
|
assetBundleName: |
||||
|
assetBundleVariant: |
||||
@ -0,0 +1,141 @@ |
|||||
|
//============================================================================================================ |
||||
|
// |
||||
|
// |
||||
|
// Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved. |
||||
|
// SPDX-License-Identifier: BSD-3-Clause |
||||
|
// |
||||
|
//============================================================================================================ |
||||
|
|
||||
|
#define EPSILON 1.19e-07f |
||||
|
float DecodeColorY(uint sample32) |
||||
|
{ |
||||
|
uint x11 = sample32 >> 21u; |
||||
|
return float(x11) * (1.0 / 2047.5); |
||||
|
} |
||||
|
|
||||
|
uint packHalf2x16(float2 value) |
||||
|
{ |
||||
|
return f32tof16(value.x) | (f32tof16(value.y) << 16); |
||||
|
} |
||||
|
|
||||
|
float2 unpackHalf2x16(uint x) |
||||
|
{ |
||||
|
return f16tof32(uint2(x & 0xFFFF, x >> 16)); |
||||
|
} |
||||
|
|
||||
|
Texture2D<uint> PrevLumaHistory : register(t0); |
||||
|
Texture2D MotionDepthAlphaBuffer : register(t1); |
||||
|
Texture2D<uint> YCoCgColor : register(t2); |
||||
|
RWTexture2D<float4> MotionDepthClipAlphaBuffer : register(u0); |
||||
|
RWTexture2D<uint> LumaHistory : register(u1); |
||||
|
|
||||
|
cbuffer Params : register(b0) |
||||
|
{ |
||||
|
uint2 renderSize; |
||||
|
uint2 displaySize; |
||||
|
float2 ViewportSizeInverse; |
||||
|
float2 displaySizeRcp; |
||||
|
float2 jitterOffset; |
||||
|
float4 clipToPrevClip[4]; |
||||
|
float preExposure; |
||||
|
float cameraFovAngleHor; |
||||
|
float cameraNear; |
||||
|
float MinLerpContribution; |
||||
|
uint bSameCamera; |
||||
|
uint reset; |
||||
|
}; |
||||
|
|
||||
|
SamplerState s_PointClamp : register(s0); |
||||
|
SamplerState s_LinearClamp : register(s1); |
||||
|
|
||||
|
[numthreads(8, 8, 1)] |
||||
|
void CS(uint2 GroupId : SV_GroupID, uint2 GroupThreadId : SV_GroupThreadID) |
||||
|
{ |
||||
|
int2 sampleOffset[4] = { |
||||
|
int2(-1, -1), |
||||
|
int2(-1, +0), |
||||
|
int2(+0, -1), |
||||
|
int2(+0, +0) |
||||
|
}; |
||||
|
|
||||
|
uint2 InputPos = GroupId * uint2(8, 8) + GroupThreadId; |
||||
|
|
||||
|
float2 ViewportUV = (float2(InputPos) + 0.5f) * ViewportSizeInverse; |
||||
|
float2 gatherCoord = ViewportUV + 0.5f * ViewportSizeInverse; |
||||
|
uint luma_reference32 = YCoCgColor.GatherRed(s_PointClamp, gatherCoord).w; |
||||
|
float luma_reference = DecodeColorY(luma_reference32); |
||||
|
|
||||
|
float4 mda = MotionDepthAlphaBuffer[InputPos].xyzw; //motion depth alpha |
||||
|
float depth = mda.z; |
||||
|
float alphamask = mda.w; |
||||
|
float2 motion = mda.xy; |
||||
|
|
||||
|
#ifdef REQUEST_NDC_Y_UP |
||||
|
float2 PrevUV = float2(-0.5f * motion.x + ViewportUV.x, 0.5f * motion.y + ViewportUV.y); |
||||
|
#else |
||||
|
float2 PrevUV = float2(-0.5f * motion.x + ViewportUV.x, -0.5f * motion.y + ViewportUV.y); |
||||
|
#endif |
||||
|
float depthclip = 0.0; |
||||
|
|
||||
|
if (depth > 1.0e-05f) { |
||||
|
float2 Prevf_sample = PrevUV * float2(renderSize) - 0.5f; |
||||
|
float2 Prevfrac = Prevf_sample - floor(Prevf_sample); |
||||
|
float OneMinusPrevfacx = 1.0 - Prevfrac.x; |
||||
|
|
||||
|
float Bilinweights[4] = { |
||||
|
OneMinusPrevfacx - OneMinusPrevfacx * Prevfrac.y, |
||||
|
Prevfrac.x - Prevfrac.x * Prevfrac.y, |
||||
|
OneMinusPrevfacx * Prevfrac.y, |
||||
|
Prevfrac.x * Prevfrac.y |
||||
|
}; |
||||
|
|
||||
|
float diagonal_length = length(float2(renderSize)); |
||||
|
float Wdepth = 0.0; |
||||
|
float Wsum = 0.0; |
||||
|
float Ksep = 1.37e-05f; |
||||
|
float Kfov = cameraFovAngleHor; |
||||
|
float Ksep_Kfov_diagonal = Ksep * Kfov * diagonal_length; |
||||
|
for (int index = 0; index < 4; index+=2){ |
||||
|
float4 gPrevdepth = MotionDepthAlphaBuffer.GatherBlue(s_PointClamp, PrevUV, sampleOffset[index]); |
||||
|
float tdepth1 = min(gPrevdepth.x, gPrevdepth.y); |
||||
|
float tdepth2 = min(gPrevdepth.z, gPrevdepth.w); |
||||
|
float fPrevdepth = min(tdepth1, tdepth2); |
||||
|
|
||||
|
float Depthsep = Ksep_Kfov_diagonal * (1.0 - min(fPrevdepth, depth)); |
||||
|
float weight = Bilinweights[index]; |
||||
|
Wdepth += clamp(Depthsep / (abs(fPrevdepth - depth) + EPSILON), 0.0, 1.0) * weight; |
||||
|
|
||||
|
float2 gPrevdepth2 = MotionDepthAlphaBuffer.GatherBlue(s_PointClamp, PrevUV, sampleOffset[index + int(1)]).zw; |
||||
|
fPrevdepth = min(min(gPrevdepth2.x, gPrevdepth2.y), tdepth2); |
||||
|
Depthsep = Ksep_Kfov_diagonal * (1.0 - min(fPrevdepth, depth)); |
||||
|
weight = Bilinweights[index + int(1)]; |
||||
|
Wdepth += clamp(Depthsep / (abs(fPrevdepth - depth) + EPSILON), 0.0, 1.0) * weight; |
||||
|
} |
||||
|
depthclip = clamp(1.0f - Wdepth, 0.0, 1.0); |
||||
|
} |
||||
|
|
||||
|
float2 current_luma_diff; |
||||
|
uint prev_luma_diff_pack = PrevLumaHistory.GatherRed(s_PointClamp, PrevUV).w; |
||||
|
float2 prev_luma_diff; |
||||
|
prev_luma_diff.x = unpackHalf2x16(prev_luma_diff_pack >> 16u).x; |
||||
|
prev_luma_diff.y = unpackHalf2x16((prev_luma_diff_pack & uint(0xFFFF))).x; |
||||
|
|
||||
|
bool enable = false; |
||||
|
if (depthclip + float(reset) < 0.1) |
||||
|
{ |
||||
|
enable = (all(PrevUV >= 0.0f) && all(PrevUV <= 1.0f)); |
||||
|
} |
||||
|
float luma_diff = luma_reference - prev_luma_diff.x; |
||||
|
if (!enable) |
||||
|
{ |
||||
|
current_luma_diff.x = 0.0; |
||||
|
current_luma_diff.y = 0.0; |
||||
|
}else{ |
||||
|
current_luma_diff.x = luma_reference; |
||||
|
current_luma_diff.y = (prev_luma_diff.y != 0.0f) ? ((sign(luma_diff) == sign(prev_luma_diff.y)) ? (sign(luma_diff) * min(abs(prev_luma_diff.y), abs(luma_diff))) : prev_luma_diff.y) : luma_diff; |
||||
|
} |
||||
|
|
||||
|
alphamask = floor(alphamask) + 0.5f * float((current_luma_diff.x != 0.0f) && (abs(current_luma_diff.y) != abs(luma_diff))); |
||||
|
LumaHistory[InputPos] = (packHalf2x16(float2(current_luma_diff.x, 0.0)) << 16u) | packHalf2x16(float2(current_luma_diff.y, 0.0)); |
||||
|
MotionDepthClipAlphaBuffer[InputPos] = float4(motion, depthclip, alphamask); |
||||
|
} |
||||
@ -0,0 +1,7 @@ |
|||||
|
fileFormatVersion: 2 |
||||
|
guid: 503a58dfbaf241c4cbabb2b264d66f96 |
||||
|
ShaderIncludeImporter: |
||||
|
externalObjects: {} |
||||
|
userData: |
||||
|
assetBundleName: |
||||
|
assetBundleVariant: |
||||
@ -0,0 +1,127 @@ |
|||||
|
//============================================================================================================ |
||||
|
// |
||||
|
// |
||||
|
// Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved. |
||||
|
// SPDX-License-Identifier: BSD-3-Clause |
||||
|
// |
||||
|
//============================================================================================================ |
||||
|
|
||||
|
float2 decodeVelocityFromTexture(float2 ev) { |
||||
|
const float inv_div = 1.0f / (0.499f * 0.5f); |
||||
|
float2 dv; |
||||
|
dv.xy = ev.xy * inv_div - 32767.0f / 65535.0f * inv_div; |
||||
|
//dv.z = uintBitsToFloat((uint(round(ev.z * 65535.0f)) << 16) | uint(round(ev.w * 65535.0f))); |
||||
|
return dv; |
||||
|
} |
||||
|
|
||||
|
Texture2D InputOpaqueColor : register(t0); |
||||
|
Texture2D InputColor : register(t1); |
||||
|
Texture2D<float> InputDepth : register(t2); |
||||
|
Texture2D<float2> InputVelocity : register(t3); |
||||
|
RWTexture2D<float4> MotionDepthAlphaBuffer : register(u0); |
||||
|
RWTexture2D<uint> YCoCgColor : register(u1); |
||||
|
|
||||
|
cbuffer Params : register(b0) |
||||
|
{ |
||||
|
uint2 renderSize; |
||||
|
uint2 displaySize; |
||||
|
float2 ViewportSizeInverse; |
||||
|
float2 displaySizeRcp; |
||||
|
float2 jitterOffset; |
||||
|
float4 clipToPrevClip[4]; |
||||
|
float preExposure; |
||||
|
float cameraFovAngleHor; |
||||
|
float cameraNear; |
||||
|
float MinLerpContribution; |
||||
|
uint bSameCamera; |
||||
|
uint reset; |
||||
|
}; |
||||
|
|
||||
|
SamplerState s_PointClamp : register(s0); |
||||
|
SamplerState s_LinearClamp : register(s1); |
||||
|
|
||||
|
[numthreads(8, 8, 1)] |
||||
|
void CS(uint2 GroupId : SV_GroupID, uint2 GroupThreadId : SV_GroupThreadID) |
||||
|
{ |
||||
|
uint2 InputPos = GroupId * uint2(8, 8) + GroupThreadId; |
||||
|
|
||||
|
float2 gatherCoord = float2(InputPos) * ViewportSizeInverse; |
||||
|
float2 ViewportUV = gatherCoord + 0.5f * ViewportSizeInverse; |
||||
|
|
||||
|
//derived from ffx_fsr2_reconstruct_dilated_velocity_and_previous_depth.h |
||||
|
//FindNearestDepth |
||||
|
|
||||
|
int2 InputPosBtmRight = int2(1, 1) + int2(InputPos); |
||||
|
float NearestZ = InputDepth[InputPosBtmRight].x; |
||||
|
|
||||
|
float4 topleft = InputDepth.GatherRed(s_PointClamp, gatherCoord); |
||||
|
|
||||
|
NearestZ = max(topleft.x, NearestZ); |
||||
|
NearestZ = max(topleft.y, NearestZ); |
||||
|
NearestZ = max(topleft.z, NearestZ); |
||||
|
NearestZ = max(topleft.w, NearestZ); |
||||
|
|
||||
|
float2 v11 = float2(ViewportSizeInverse.x, 0.0); |
||||
|
float2 topRight = InputDepth.GatherRed(s_PointClamp, (gatherCoord + v11)).yz; |
||||
|
|
||||
|
NearestZ = max(topRight.x, NearestZ); |
||||
|
NearestZ = max(topRight.y, NearestZ); |
||||
|
|
||||
|
float2 v13 = float2(0.0, ViewportSizeInverse.y); |
||||
|
float2 bottomLeft = InputDepth.GatherRed(s_PointClamp, (gatherCoord + v13)).xy; |
||||
|
|
||||
|
NearestZ = max(bottomLeft.x, NearestZ); |
||||
|
NearestZ = max(bottomLeft.y, NearestZ); |
||||
|
|
||||
|
//refer to ue/fsr2 PostProcessFFX_FSR2ConvertVelocity.usf, and using nearest depth for dilated motion |
||||
|
|
||||
|
// TODO: wondering if this whole song and dance about decoding velocity is really necessary for Unity |
||||
|
float2 EncodedVelocity = InputVelocity[InputPos]; |
||||
|
|
||||
|
float2 motion; |
||||
|
if (EncodedVelocity.x > 0.0) |
||||
|
{ |
||||
|
motion = decodeVelocityFromTexture(EncodedVelocity.xy); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
#ifdef REQUEST_NDC_Y_UP |
||||
|
float2 ScreenPos = float2(2.0f * ViewportUV.x - 1.0f, 1.0f - 2.0f * ViewportUV.y); |
||||
|
#else |
||||
|
float2 ScreenPos = float2(2.0f * ViewportUV - 1.0f); |
||||
|
#endif |
||||
|
float3 Position = float3(ScreenPos, NearestZ); //this_clip |
||||
|
float4 PreClip = clipToPrevClip[3] + ((clipToPrevClip[2] * Position.z) + ((clipToPrevClip[1] * ScreenPos.y) + (clipToPrevClip[0] * ScreenPos.x))); |
||||
|
float2 PreScreen = PreClip.xy / PreClip.w; |
||||
|
motion = Position.xy - PreScreen; |
||||
|
} |
||||
|
|
||||
|
motion = EncodedVelocity; |
||||
|
|
||||
|
////////////compute luma |
||||
|
float3 Colorrgb = InputColor[InputPos].xyz; |
||||
|
|
||||
|
///simple tonemap |
||||
|
Colorrgb /= max(max(Colorrgb.x, Colorrgb.y), Colorrgb.z) + preExposure; |
||||
|
|
||||
|
float3 Colorycocg; |
||||
|
Colorycocg.x = 0.25 * (Colorrgb.x + 2.0 * Colorrgb.y + Colorrgb.z); |
||||
|
Colorycocg.y = clamp(0.5 * Colorrgb.x + 0.5 - 0.5 * Colorrgb.z, 0.0, 1.0); |
||||
|
Colorycocg.z = clamp(Colorycocg.x + Colorycocg.y - Colorrgb.x, 0.0, 1.0); |
||||
|
|
||||
|
//now color YCoCG all in the range of [0,1] |
||||
|
uint x11 = uint(Colorycocg.x * 2047.5); |
||||
|
uint y11 = uint(Colorycocg.y * 2047.5); |
||||
|
uint z10 = uint(Colorycocg.z * 1023.5); |
||||
|
|
||||
|
float3 Colorprergb = InputOpaqueColor[InputPos].xyz; |
||||
|
|
||||
|
///simple tonemap |
||||
|
Colorprergb /= max(max(Colorprergb.x, Colorprergb.y), Colorprergb.z) + preExposure; |
||||
|
float3 delta = abs(Colorrgb - Colorprergb); |
||||
|
float alpha_mask = max(delta.x, max(delta.y, delta.z)); |
||||
|
alpha_mask = (0.35f * 1000.0f) * alpha_mask; |
||||
|
|
||||
|
YCoCgColor[InputPos] = ((x11 << 21u) | (y11 << 10u)) | z10; |
||||
|
MotionDepthAlphaBuffer[InputPos] = float4(motion, NearestZ, alpha_mask); |
||||
|
} |
||||
@ -0,0 +1,7 @@ |
|||||
|
fileFormatVersion: 2 |
||||
|
guid: d980c2a95e08a894d96b558154687e24 |
||||
|
ShaderIncludeImporter: |
||||
|
externalObjects: {} |
||||
|
userData: |
||||
|
assetBundleName: |
||||
|
assetBundleVariant: |
||||
@ -0,0 +1,315 @@ |
|||||
|
//============================================================================================================ |
||||
|
// |
||||
|
// |
||||
|
// Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved. |
||||
|
// SPDX-License-Identifier: BSD-3-Clause |
||||
|
// |
||||
|
//============================================================================================================ |
||||
|
|
||||
|
float FastLanczos(float base) |
||||
|
{ |
||||
|
float y = base - 1.0f; |
||||
|
float y2 = y * y; |
||||
|
float y_temp = 0.75f * y + y2; |
||||
|
return y_temp * y2; |
||||
|
} |
||||
|
|
||||
|
float3 DecodeColor(uint sample32) |
||||
|
{ |
||||
|
uint x11 = sample32 >> 21u; |
||||
|
uint y11 = sample32 & (2047u << 10u); |
||||
|
uint z10 = sample32 & 1023u; |
||||
|
float3 samplecolor; |
||||
|
samplecolor.x = (float(x11) * (1.0 / 2047.5)); |
||||
|
samplecolor.y = (float(y11) * (4.76953602e-7)) - 0.5; |
||||
|
samplecolor.z = (float(z10) * (1.0 / 1023.5)) - 0.5; |
||||
|
|
||||
|
return samplecolor; |
||||
|
} |
||||
|
|
||||
|
Texture2D PrevHistoryOutput : register(t0); |
||||
|
Texture2D MotionDepthClipAlphaBuffer : register(t1); |
||||
|
Texture2D<uint> YCoCgColor : register(t2); |
||||
|
RWTexture2D<float4> SceneColorOutput : register(u0); |
||||
|
RWTexture2D<float4> HistoryOutput : register(u1); |
||||
|
|
||||
|
cbuffer Params : register(b0) |
||||
|
{ |
||||
|
uint2 renderSize; |
||||
|
uint2 displaySize; |
||||
|
float2 renderSizeRcp; |
||||
|
float2 displaySizeRcp; |
||||
|
float2 jitterOffset; |
||||
|
float4 clipToPrevClip[4]; |
||||
|
float preExposure; |
||||
|
float cameraFovAngleHor; |
||||
|
float cameraNear; |
||||
|
float MinLerpContribution; |
||||
|
uint bSameCamera; |
||||
|
uint reset; |
||||
|
}; |
||||
|
|
||||
|
SamplerState s_PointClamp : register(s0); |
||||
|
SamplerState s_LinearClamp : register(s1); |
||||
|
|
||||
|
[numthreads(8, 8, 1)] |
||||
|
void CS(uint2 GroupId : SV_GroupID, uint2 GroupThreadId : SV_GroupThreadID) |
||||
|
{ |
||||
|
uint2 InvocationID = GroupId * uint2(8, 8) + GroupThreadId; |
||||
|
|
||||
|
float Biasmax_viewportXScale = min(float(displaySize.x) / float(renderSize.x), 1.99); //Biasmax_viewportXScale |
||||
|
float scalefactor = min(20.0, pow((float(displaySize.x) / float(renderSize.x)) * (float(displaySize.y) / float(renderSize.y)), 3.0)); |
||||
|
float f2 = preExposure; //1.0; //preExposure |
||||
|
float2 HistoryInfoViewportSizeInverse = displaySizeRcp; |
||||
|
float2 HistoryInfoViewportSize = float2(displaySize); |
||||
|
float2 InputJitter = jitterOffset; |
||||
|
float2 InputInfoViewportSize = float2(renderSize); |
||||
|
float2 Hruv = (float2(InvocationID) + 0.5f) * HistoryInfoViewportSizeInverse; |
||||
|
float2 Jitteruv; |
||||
|
Jitteruv.x = clamp(Hruv.x + (InputJitter.x * HistoryInfoViewportSizeInverse.x), 0.0, 1.0); |
||||
|
Jitteruv.y = clamp(Hruv.y + (InputJitter.y * HistoryInfoViewportSizeInverse.y), 0.0, 1.0); |
||||
|
|
||||
|
int2 InputPos = int2(Jitteruv * InputInfoViewportSize); |
||||
|
|
||||
|
//float2 Motion = texelFetch(MotionDepthClipAlphaBuffer, InputPos, 0).xy; |
||||
|
float alphab = MotionDepthClipAlphaBuffer[InputPos].w; |
||||
|
float3 mda = MotionDepthClipAlphaBuffer.SampleLevel(s_LinearClamp, Jitteruv, 0).xyz; |
||||
|
float2 Motion = mda.xy; |
||||
|
|
||||
|
///ScreenPosToViewportScale&Bias |
||||
|
float2 PrevUV; |
||||
|
PrevUV.x = clamp(-0.5 * Motion.x + Hruv.x, 0.0, 1.0); |
||||
|
#ifdef REQUEST_NDC_Y_UP |
||||
|
PrevUV.y = clamp(0.5 * Motion.y + Hruv.y, 0.0, 1.0); |
||||
|
#else |
||||
|
PrevUV.y = clamp(-0.5 * Motion.y + Hruv.y, 0.0, 1.0); |
||||
|
#endif |
||||
|
|
||||
|
float depthfactor = mda.z; |
||||
|
float history_value = frac(alphab); // clamp(alpha, 0.0f, 1.0f); |
||||
|
float alphamask = (alphab - history_value) * 0.001f; |
||||
|
history_value *= 2.0; |
||||
|
|
||||
|
float4 History = PrevHistoryOutput.SampleLevel(s_LinearClamp, PrevUV, 0); |
||||
|
float3 HistoryColor = History.xyz; |
||||
|
float Historyw = History.w; |
||||
|
float Wfactor = max(clamp(abs(Historyw), 0.0, 1.0), alphamask); |
||||
|
|
||||
|
/////upsample and compute box |
||||
|
float4 Upsampledcw = 0.0f; |
||||
|
float kernelfactor = clamp(Wfactor + float(reset), 0.0, 1.0); |
||||
|
float biasmax = Biasmax_viewportXScale - Biasmax_viewportXScale * kernelfactor; |
||||
|
float biasmin = max(1.0f, 0.3 + 0.3 * biasmax); |
||||
|
float biasfactor = max(0.25f * depthfactor, kernelfactor); |
||||
|
float kernelbias = lerp(biasmax, biasmin, biasfactor); |
||||
|
float motion_viewport_len = length(Motion * HistoryInfoViewportSize); |
||||
|
float curvebias = lerp(-2.0, -3.0, clamp(motion_viewport_len * 0.02, 0.0, 1.0)); |
||||
|
|
||||
|
float3 rectboxcenter = 0.0f; |
||||
|
float3 rectboxvar = 0.0f; |
||||
|
float rectboxweight = 0.0; |
||||
|
float2 srcpos = float2(InputPos) + 0.5f - InputJitter; |
||||
|
float2 srcOutputPos = Hruv * InputInfoViewportSize; |
||||
|
|
||||
|
kernelbias *= 0.5f; |
||||
|
float kernelbias2 = kernelbias * kernelbias; |
||||
|
float2 srcpos_srcOutputPos = srcpos - srcOutputPos; |
||||
|
|
||||
|
int2 InputPosBtmRight = 1 + InputPos; |
||||
|
float2 gatherCoord = float2(InputPos) * renderSizeRcp; |
||||
|
uint btmRight = YCoCgColor[InputPosBtmRight].x; |
||||
|
uint4 topleft = YCoCgColor.GatherRed(s_PointClamp, gatherCoord); |
||||
|
uint2 topRight = YCoCgColor.GatherRed(s_PointClamp, gatherCoord + float2(renderSizeRcp.x, 0.0)).yz; |
||||
|
uint2 bottomLeft = YCoCgColor.GatherRed(s_PointClamp, gatherCoord + float2(0.0, renderSizeRcp.y)).xy; |
||||
|
|
||||
|
float3 rectboxmin; |
||||
|
float3 rectboxmax; |
||||
|
{ |
||||
|
rectboxmin = DecodeColor(btmRight); |
||||
|
float2 baseoffset = srcpos_srcOutputPos + float2(1.0, 1.0); |
||||
|
float baseoffset_dot = dot(baseoffset, baseoffset); |
||||
|
float base = clamp(baseoffset_dot * kernelbias2, 0.0, 1.0); |
||||
|
float weight = FastLanczos(base); |
||||
|
Upsampledcw += float4(rectboxmin * weight, weight); |
||||
|
float boxweight = exp(baseoffset_dot * curvebias); |
||||
|
rectboxmax = rectboxmin; |
||||
|
float3 wsample = rectboxmin * boxweight; |
||||
|
rectboxcenter = wsample; |
||||
|
rectboxvar = rectboxmin * wsample; |
||||
|
rectboxweight = boxweight; |
||||
|
} |
||||
|
{ |
||||
|
float3 samplecolor = DecodeColor(bottomLeft.x); |
||||
|
float2 baseoffset = srcpos_srcOutputPos + float2(-1.0, 1.0); |
||||
|
float baseoffset_dot = dot(baseoffset, baseoffset); |
||||
|
float base = clamp(baseoffset_dot * kernelbias2, 0.0f, 1.0f); |
||||
|
float weight = FastLanczos(base); |
||||
|
Upsampledcw += float4(samplecolor * weight, weight); |
||||
|
float boxweight = exp(baseoffset_dot * curvebias); |
||||
|
rectboxmin = min(rectboxmin, samplecolor); |
||||
|
rectboxmax = max(rectboxmax, samplecolor); |
||||
|
float3 wsample = samplecolor * boxweight; |
||||
|
rectboxcenter += wsample; |
||||
|
rectboxvar += (samplecolor * wsample); |
||||
|
rectboxweight += boxweight; |
||||
|
} |
||||
|
{ |
||||
|
float3 samplecolor = DecodeColor(bottomLeft.y); |
||||
|
float2 baseoffset = srcpos_srcOutputPos + float2(0.0, 1.0); |
||||
|
float baseoffset_dot = dot(baseoffset, baseoffset); |
||||
|
float base = clamp(baseoffset_dot * kernelbias2, 0.0f, 1.0f); |
||||
|
float weight = FastLanczos(base); |
||||
|
Upsampledcw += float4(samplecolor * weight, weight); |
||||
|
float boxweight = exp(baseoffset_dot * curvebias); |
||||
|
rectboxmin = min(rectboxmin, samplecolor); |
||||
|
rectboxmax = max(rectboxmax, samplecolor); |
||||
|
float3 wsample = samplecolor * boxweight; |
||||
|
rectboxcenter += wsample; |
||||
|
rectboxvar += (samplecolor * wsample); |
||||
|
rectboxweight += boxweight; |
||||
|
} |
||||
|
{ |
||||
|
float3 samplecolor = DecodeColor(topRight.x); |
||||
|
float2 baseoffset = srcpos_srcOutputPos + float2(1.0, 0.0); |
||||
|
float baseoffset_dot = dot(baseoffset, baseoffset); |
||||
|
float base = clamp(baseoffset_dot * kernelbias2, 0.0f, 1.0f); |
||||
|
float weight = FastLanczos(base); |
||||
|
Upsampledcw += float4(samplecolor * weight, weight); |
||||
|
float boxweight = exp(baseoffset_dot * curvebias); |
||||
|
rectboxmin = min(rectboxmin, samplecolor); |
||||
|
rectboxmax = max(rectboxmax, samplecolor); |
||||
|
float3 wsample = samplecolor * boxweight; |
||||
|
rectboxcenter += wsample; |
||||
|
rectboxvar += (samplecolor * wsample); |
||||
|
rectboxweight += boxweight; |
||||
|
} |
||||
|
{ |
||||
|
float3 samplecolor = DecodeColor(topRight.y); |
||||
|
float2 baseoffset = srcpos_srcOutputPos + float2(1.0, -1.0); |
||||
|
float baseoffset_dot = dot(baseoffset, baseoffset); |
||||
|
float base = clamp(baseoffset_dot * kernelbias2, 0.0f, 1.0f); |
||||
|
float weight = FastLanczos(base); |
||||
|
Upsampledcw += float4(samplecolor * weight, weight); |
||||
|
float boxweight = exp(baseoffset_dot * curvebias); |
||||
|
rectboxmin = min(rectboxmin, samplecolor); |
||||
|
rectboxmax = max(rectboxmax, samplecolor); |
||||
|
float3 wsample = samplecolor * boxweight; |
||||
|
rectboxcenter += wsample; |
||||
|
rectboxvar += (samplecolor * wsample); |
||||
|
rectboxweight += boxweight; |
||||
|
} |
||||
|
{ |
||||
|
float3 samplecolor = DecodeColor(topleft.x); |
||||
|
float2 baseoffset = srcpos_srcOutputPos + float2(-1.0, 0.0); |
||||
|
float baseoffset_dot = dot(baseoffset, baseoffset); |
||||
|
float base = clamp(baseoffset_dot * kernelbias2, 0.0f, 1.0f); |
||||
|
float weight = FastLanczos(base); |
||||
|
Upsampledcw += float4(samplecolor * weight, weight); |
||||
|
float boxweight = exp(baseoffset_dot * curvebias); |
||||
|
rectboxmin = min(rectboxmin, samplecolor); |
||||
|
rectboxmax = max(rectboxmax, samplecolor); |
||||
|
float3 wsample = samplecolor * boxweight; |
||||
|
rectboxcenter += wsample; |
||||
|
rectboxvar += (samplecolor * wsample); |
||||
|
rectboxweight += boxweight; |
||||
|
} |
||||
|
{ |
||||
|
float3 samplecolor = DecodeColor(topleft.y); |
||||
|
float2 baseoffset = srcpos_srcOutputPos; |
||||
|
float baseoffset_dot = dot(baseoffset, baseoffset); |
||||
|
float base = clamp(baseoffset_dot * kernelbias2, 0.0f, 1.0f); |
||||
|
float weight = FastLanczos(base); |
||||
|
Upsampledcw += float4(samplecolor * weight, weight); |
||||
|
float boxweight = exp(baseoffset_dot * curvebias); |
||||
|
rectboxmin = min(rectboxmin, samplecolor); |
||||
|
rectboxmax = max(rectboxmax, samplecolor); |
||||
|
float3 wsample = samplecolor * boxweight; |
||||
|
rectboxcenter += wsample; |
||||
|
rectboxvar += (samplecolor * wsample); |
||||
|
rectboxweight += boxweight; |
||||
|
} |
||||
|
{ |
||||
|
float3 samplecolor = DecodeColor(topleft.z); |
||||
|
float2 baseoffset = srcpos_srcOutputPos + float2(0.0, -1.0); |
||||
|
float baseoffset_dot = dot(baseoffset, baseoffset); |
||||
|
float base = clamp(baseoffset_dot * kernelbias2, 0.0f, 1.0f); |
||||
|
float weight = FastLanczos(base); |
||||
|
Upsampledcw += float4(samplecolor * weight, weight); |
||||
|
float boxweight = exp(baseoffset_dot * curvebias); |
||||
|
rectboxmin = min(rectboxmin, samplecolor); |
||||
|
rectboxmax = max(rectboxmax, samplecolor); |
||||
|
float3 wsample = samplecolor * boxweight; |
||||
|
rectboxcenter += wsample; |
||||
|
rectboxvar += (samplecolor * wsample); |
||||
|
rectboxweight += boxweight; |
||||
|
} |
||||
|
{ |
||||
|
float3 samplecolor = DecodeColor(topleft.w); |
||||
|
float2 baseoffset = srcpos_srcOutputPos + float2(-1.0, -1.0); |
||||
|
float baseoffset_dot = dot(baseoffset, baseoffset); |
||||
|
float base = clamp(baseoffset_dot * kernelbias2, 0.0f, 1.0f); |
||||
|
float weight = FastLanczos(base); |
||||
|
Upsampledcw += float4(samplecolor * weight, weight); |
||||
|
float boxweight = exp(baseoffset_dot * curvebias); |
||||
|
rectboxmin = min(rectboxmin, samplecolor); |
||||
|
rectboxmax = max(rectboxmax, samplecolor); |
||||
|
float3 wsample = samplecolor * boxweight; |
||||
|
rectboxcenter += wsample; |
||||
|
rectboxvar += (samplecolor * wsample); |
||||
|
rectboxweight += boxweight; |
||||
|
} |
||||
|
|
||||
|
rectboxweight = 1.0 / rectboxweight; |
||||
|
rectboxcenter *= rectboxweight; |
||||
|
rectboxvar *= rectboxweight; |
||||
|
rectboxvar = sqrt(abs(rectboxvar - rectboxcenter * rectboxcenter)); |
||||
|
|
||||
|
Upsampledcw.xyz = clamp(Upsampledcw.xyz / Upsampledcw.w, rectboxmin-0.05f, rectboxmax+0.05f); |
||||
|
Upsampledcw.w = Upsampledcw.w * (1.0f / 3.0f) ; |
||||
|
|
||||
|
float tcontribute = history_value * clamp(rectboxvar.x * 10.0f, 0.0, 1.0); |
||||
|
float OneMinusWfactor = 1.0f - Wfactor; |
||||
|
tcontribute = tcontribute * OneMinusWfactor; |
||||
|
|
||||
|
float baseupdate = OneMinusWfactor - OneMinusWfactor * depthfactor; |
||||
|
baseupdate = min(baseupdate, lerp(baseupdate, Upsampledcw.w *10.0f, clamp(10.0f* motion_viewport_len, 0.0, 1.0))); |
||||
|
baseupdate = min(baseupdate, lerp(baseupdate, Upsampledcw.w, clamp(motion_viewport_len *0.05f, 0.0, 1.0))); |
||||
|
float basealpha = baseupdate; |
||||
|
|
||||
|
const float EPSILON = 1.192e-07f; |
||||
|
float boxscale = max(depthfactor, clamp(motion_viewport_len * 0.05f, 0.0, 1.0)); |
||||
|
float boxsize = lerp(scalefactor, 1.0f, boxscale); |
||||
|
float3 sboxvar = rectboxvar * boxsize; |
||||
|
float3 boxmin = rectboxcenter - sboxvar; |
||||
|
float3 boxmax = rectboxcenter + sboxvar; |
||||
|
rectboxmax = min(rectboxmax, boxmax); |
||||
|
rectboxmin = max(rectboxmin, boxmin); |
||||
|
|
||||
|
float3 clampedcolor = clamp(HistoryColor, rectboxmin, rectboxmax); |
||||
|
float lerpcontribution = (any(rectboxmin > HistoryColor) || any(HistoryColor > rectboxmax)) ? tcontribute : 1.0f; |
||||
|
lerpcontribution = lerpcontribution - lerpcontribution * sqrt(alphamask); |
||||
|
HistoryColor = lerp(clampedcolor, HistoryColor, clamp(lerpcontribution, 0.0, 1.0)); |
||||
|
float basemin = min(basealpha, 0.1f); |
||||
|
basealpha = lerp(basemin, basealpha, clamp(lerpcontribution, 0.0, 1.0)); |
||||
|
|
||||
|
////blend color |
||||
|
float alphasum = max(EPSILON, basealpha + Upsampledcw.w); |
||||
|
float alpha = clamp(Upsampledcw.w / alphasum + float(reset), 0.0, 1.0); |
||||
|
Upsampledcw.xyz = lerp(HistoryColor, Upsampledcw.xyz, alpha); |
||||
|
|
||||
|
HistoryOutput[InvocationID.xy] = float4(Upsampledcw.xyz, Wfactor); |
||||
|
|
||||
|
////ycocg to grb |
||||
|
float x_z = Upsampledcw.x - Upsampledcw.z; |
||||
|
Upsampledcw.xyz = float3( |
||||
|
x_z + Upsampledcw.y, |
||||
|
Upsampledcw.x + Upsampledcw.z, |
||||
|
x_z - Upsampledcw.y); |
||||
|
|
||||
|
float compMax = max(Upsampledcw.x, Upsampledcw.y); |
||||
|
compMax = max(compMax, Upsampledcw.z); |
||||
|
float scale = preExposure / ((1.0f + 1.0f / 65504.0f) - compMax); //(1.0f + 1.0f / 65504.0f) = 1.000015e+00 |
||||
|
|
||||
|
Upsampledcw.xyz = Upsampledcw.xyz * scale; |
||||
|
SceneColorOutput[InvocationID.xy] = Upsampledcw; |
||||
|
} |
||||
@ -0,0 +1,7 @@ |
|||||
|
fileFormatVersion: 2 |
||||
|
guid: 5cde6f90c795fb841a38f37495375e6e |
||||
|
ShaderIncludeImporter: |
||||
|
externalObjects: {} |
||||
|
userData: |
||||
|
assetBundleName: |
||||
|
assetBundleVariant: |
||||
@ -0,0 +1,142 @@ |
|||||
|
using System.Runtime.InteropServices; |
||||
|
using FidelityFX; |
||||
|
using UnityEngine.Experimental.Rendering; |
||||
|
|
||||
|
namespace UnityEngine.Rendering.PostProcessing |
||||
|
{ |
||||
|
internal class SGSR2Upscaler: Upscaler |
||||
|
{ |
||||
|
public static bool IsSupported => SystemInfo.supportsComputeShaders; |
||||
|
|
||||
|
private RenderTexture _colorLuma; |
||||
|
private RenderTexture _motionDepthAlpha; |
||||
|
private RenderTexture _motionDepthClipAlpha; |
||||
|
private readonly RenderTexture[] _lumaHistory = new RenderTexture[2]; |
||||
|
private readonly RenderTexture[] _upscaleHistory = new RenderTexture[2]; |
||||
|
|
||||
|
private readonly ConstantsBuffer<SGSR2.Params> _paramsBuffer = new(); |
||||
|
|
||||
|
private uint _frameCount = 0; |
||||
|
|
||||
|
public override void CreateContext(PostProcessRenderContext context, Upscaling config) |
||||
|
{ |
||||
|
CreateRenderTexture(ref _colorLuma, "ColorLuma", config.MaxRenderSize, GraphicsFormat.R32_UInt, true); |
||||
|
CreateRenderTexture(ref _motionDepthAlpha, "MotionDepthAlpha", config.MaxRenderSize, GraphicsFormat.R16G16B16A16_SFloat, true); |
||||
|
CreateRenderTexture(ref _motionDepthClipAlpha, "MotionDepthClipAlpha", config.MaxRenderSize, GraphicsFormat.R16G16B16A16_SFloat, true); |
||||
|
CreateRenderTextureArray(_lumaHistory, "LumaHistory", config.MaxRenderSize, GraphicsFormat.R32_UInt, true); |
||||
|
CreateRenderTextureArray(_upscaleHistory, "History", config.UpscaleSize, context.sourceFormat, true); |
||||
|
|
||||
|
_paramsBuffer.Init(); |
||||
|
} |
||||
|
|
||||
|
public override void DestroyContext() |
||||
|
{ |
||||
|
base.DestroyContext(); |
||||
|
|
||||
|
_paramsBuffer.Destroy(); |
||||
|
|
||||
|
DestroyRenderTextureArray(_upscaleHistory); |
||||
|
DestroyRenderTextureArray(_lumaHistory); |
||||
|
DestroyRenderTexture(ref _motionDepthClipAlpha); |
||||
|
DestroyRenderTexture(ref _motionDepthAlpha); |
||||
|
DestroyRenderTexture(ref _colorLuma); |
||||
|
} |
||||
|
|
||||
|
public override void Render(PostProcessRenderContext context, Upscaling config) |
||||
|
{ |
||||
|
var cmd = context.command; |
||||
|
cmd.BeginSample("SGSR2"); |
||||
|
|
||||
|
ref var parms = ref _paramsBuffer.Value; |
||||
|
parms.renderSize = config.GetScaledRenderSize(context.camera); |
||||
|
parms.displaySize = config.UpscaleSize; |
||||
|
parms.renderSizeRcp = new Vector2(1.0f / parms.renderSize.x, 1.0f / parms.renderSize.y); |
||||
|
parms.displaySizeRcp = new Vector2(1.0f / parms.displaySize.x, 1.0f / parms.displaySize.y); |
||||
|
parms.jitterOffset = config.JitterOffset; |
||||
|
parms.clipToPrevClip = Matrix4x4.identity; // TODO: clipToPrevClip
|
||||
|
parms.preExposure = config.preExposure; |
||||
|
parms.cameraFovAngleHor = Mathf.Tan(context.camera.fieldOfView * Mathf.Deg2Rad * 0.5f) * (float)parms.renderSize.x / parms.renderSize.y; |
||||
|
parms.cameraNear = context.camera.nearClipPlane; |
||||
|
parms.minLerpContribution = 0f; |
||||
|
parms.bSameCamera = 0u; |
||||
|
parms.reset = config.Reset ? 1u : 0u; |
||||
|
_paramsBuffer.UpdateBufferData(cmd); |
||||
|
|
||||
|
if (_frameCount == 0 || config.Reset) |
||||
|
{ |
||||
|
cmd.SetRenderTarget(_lumaHistory[0]); |
||||
|
cmd.ClearRenderTarget(false, true, Color.clear); |
||||
|
cmd.SetRenderTarget(_lumaHistory[1]); |
||||
|
cmd.ClearRenderTarget(false, true, Color.clear); |
||||
|
cmd.SetRenderTarget(_upscaleHistory[0]); |
||||
|
cmd.ClearRenderTarget(false, true, Color.clear); |
||||
|
cmd.SetRenderTarget(_upscaleHistory[1]); |
||||
|
cmd.ClearRenderTarget(false, true, Color.clear); |
||||
|
} |
||||
|
|
||||
|
Convert(cmd, context, config); |
||||
|
Activate(cmd, context); |
||||
|
Upscale(cmd, context); |
||||
|
|
||||
|
cmd.EndSample("SGSR2"); |
||||
|
_frameCount++; |
||||
|
} |
||||
|
|
||||
|
private void Convert(CommandBuffer cmd, PostProcessRenderContext context, Upscaling config) |
||||
|
{ |
||||
|
var shader = context.resources.computeShaders.sgsr2Upscaler.convert; |
||||
|
int kernelIndex = shader.FindKernel("CS"); |
||||
|
|
||||
|
cmd.SetComputeConstantBufferParam(shader, "Params", _paramsBuffer, 0, Marshal.SizeOf<SGSR2.Params>()); |
||||
|
cmd.SetComputeTextureParam(shader, kernelIndex, "InputOpaqueColor", config.ColorOpaqueOnly); |
||||
|
cmd.SetComputeTextureParam(shader, kernelIndex, "InputColor", context.source); |
||||
|
cmd.SetComputeTextureParam(shader, kernelIndex, "InputDepth", BuiltinRenderTextureType.CameraTarget, 0, RenderTextureSubElement.Depth); |
||||
|
cmd.SetComputeTextureParam(shader, kernelIndex, "InputVelocity", BuiltinRenderTextureType.MotionVectors); |
||||
|
cmd.SetComputeTextureParam(shader, kernelIndex, "MotionDepthAlphaBuffer", _motionDepthAlpha); |
||||
|
cmd.SetComputeTextureParam(shader, kernelIndex, "YCoCgColor", _colorLuma); |
||||
|
|
||||
|
const int threadGroupWorkRegionDim = 8; |
||||
|
int dispatchSrcX = (_paramsBuffer.Value.renderSize.x + (threadGroupWorkRegionDim - 1)) / threadGroupWorkRegionDim; |
||||
|
int dispatchSrcY = (_paramsBuffer.Value.renderSize.y + (threadGroupWorkRegionDim - 1)) / threadGroupWorkRegionDim; |
||||
|
cmd.DispatchCompute(shader, kernelIndex, dispatchSrcX, dispatchSrcY, 1); |
||||
|
} |
||||
|
|
||||
|
private void Activate(CommandBuffer cmd, PostProcessRenderContext context) |
||||
|
{ |
||||
|
var shader = context.resources.computeShaders.sgsr2Upscaler.activate; |
||||
|
int kernelIndex = shader.FindKernel("CS"); |
||||
|
uint frameIndex = _frameCount % 2; |
||||
|
|
||||
|
cmd.SetComputeConstantBufferParam(shader, "Params", _paramsBuffer, 0, Marshal.SizeOf<SGSR2.Params>()); |
||||
|
cmd.SetComputeTextureParam(shader, kernelIndex, "PrevLumaHistory", _lumaHistory[frameIndex ^ 1]); |
||||
|
cmd.SetComputeTextureParam(shader, kernelIndex, "MotionDepthAlphaBuffer", _motionDepthAlpha); |
||||
|
cmd.SetComputeTextureParam(shader, kernelIndex, "YCoCgColor", _colorLuma); |
||||
|
cmd.SetComputeTextureParam(shader, kernelIndex, "MotionDepthClipAlphaBuffer", _motionDepthClipAlpha); |
||||
|
cmd.SetComputeTextureParam(shader, kernelIndex, "LumaHistory", _lumaHistory[frameIndex]); |
||||
|
|
||||
|
const int threadGroupWorkRegionDim = 8; |
||||
|
int dispatchSrcX = (_paramsBuffer.Value.renderSize.x + (threadGroupWorkRegionDim - 1)) / threadGroupWorkRegionDim; |
||||
|
int dispatchSrcY = (_paramsBuffer.Value.renderSize.y + (threadGroupWorkRegionDim - 1)) / threadGroupWorkRegionDim; |
||||
|
cmd.DispatchCompute(shader, kernelIndex, dispatchSrcX, dispatchSrcY, 1); |
||||
|
} |
||||
|
|
||||
|
private void Upscale(CommandBuffer cmd, PostProcessRenderContext context) |
||||
|
{ |
||||
|
var shader = context.resources.computeShaders.sgsr2Upscaler.upscale; |
||||
|
int kernelIndex = shader.FindKernel("CS"); |
||||
|
uint frameIndex = _frameCount % 2; |
||||
|
|
||||
|
cmd.SetComputeConstantBufferParam(shader, "Params", _paramsBuffer, 0, Marshal.SizeOf<SGSR2.Params>()); |
||||
|
cmd.SetComputeTextureParam(shader, kernelIndex, "PrevHistoryOutput", _upscaleHistory[frameIndex ^ 1]); |
||||
|
cmd.SetComputeTextureParam(shader, kernelIndex, "MotionDepthClipAlphaBuffer", _motionDepthClipAlpha); |
||||
|
cmd.SetComputeTextureParam(shader, kernelIndex, "YCoCgColor", _colorLuma); |
||||
|
cmd.SetComputeTextureParam(shader, kernelIndex, "SceneColorOutput", context.destination); |
||||
|
cmd.SetComputeTextureParam(shader, kernelIndex, "HistoryOutput", _upscaleHistory[frameIndex]); |
||||
|
|
||||
|
const int threadGroupWorkRegionDim = 8; |
||||
|
int dispatchDstX = (_paramsBuffer.Value.displaySize.x + (threadGroupWorkRegionDim - 1)) / threadGroupWorkRegionDim; |
||||
|
int dispatchDstY = (_paramsBuffer.Value.displaySize.y + (threadGroupWorkRegionDim - 1)) / threadGroupWorkRegionDim; |
||||
|
cmd.DispatchCompute(shader, kernelIndex, dispatchDstX, dispatchDstY, 1); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,3 @@ |
|||||
|
fileFormatVersion: 2 |
||||
|
guid: 50f119aeb4064ca88ed2cec1faf14969 |
||||
|
timeCreated: 1730405245 |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue