Path: blob/master/thirdparty/amd-fsr2/shaders/ffx_fsr2_common.h
9917 views
// This file is part of the FidelityFX SDK.1//2// Copyright (c) 2022-2023 Advanced Micro Devices, Inc. All rights reserved.3//4// Permission is hereby granted, free of charge, to any person obtaining a copy5// of this software and associated documentation files (the "Software"), to deal6// in the Software without restriction, including without limitation the rights7// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell8// copies of the Software, and to permit persons to whom the Software is9// furnished to do so, subject to the following conditions:10// The above copyright notice and this permission notice shall be included in11// all copies or substantial portions of the Software.12//13// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR14// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,15// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE16// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER17// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,18// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN19// THE SOFTWARE.2021#if !defined(FFX_FSR2_COMMON_H)22#define FFX_FSR2_COMMON_H2324#if defined(FFX_CPU) || defined(FFX_GPU)25//Locks26#define LOCK_LIFETIME_REMAINING 027#define LOCK_TEMPORAL_LUMA 128#endif // #if defined(FFX_CPU) || defined(FFX_GPU)2930#if defined(FFX_GPU)31FFX_STATIC const FfxFloat32 FSR2_FP16_MIN = 6.10e-05f;32FFX_STATIC const FfxFloat32 FSR2_FP16_MAX = 65504.0f;33FFX_STATIC const FfxFloat32 FSR2_EPSILON = 1e-03f;34FFX_STATIC const FfxFloat32 FSR2_TONEMAP_EPSILON = 1.0f / FSR2_FP16_MAX;35FFX_STATIC const FfxFloat32 FSR2_FLT_MAX = 3.402823466e+38f;36FFX_STATIC const FfxFloat32 FSR2_FLT_MIN = 1.175494351e-38f;3738// treat vector truncation warnings as errors39#pragma warning(error: 3206)4041// suppress warnings42#pragma warning(disable: 3205) // conversion from larger type to smaller43#pragma warning(disable: 3571) // in ffxPow(f, e), f could be negative4445// Reconstructed depth usage46FFX_STATIC const FfxFloat32 fReconstructedDepthBilinearWeightThreshold = 0.01f;4748// Accumulation49FFX_STATIC const FfxFloat32 fUpsampleLanczosWeightScale = 1.0f / 12.0f;50FFX_STATIC const FfxFloat32 fMaxAccumulationLanczosWeight = 1.0f;51FFX_STATIC const FfxFloat32 fAverageLanczosWeightPerFrame = 0.74f * fUpsampleLanczosWeightScale; // Average lanczos weight for jitter accumulated samples52FFX_STATIC const FfxFloat32 fAccumulationMaxOnMotion = 3.0f * fUpsampleLanczosWeightScale;5354// Auto exposure55FFX_STATIC const FfxFloat32 resetAutoExposureAverageSmoothing = 1e8f;5657struct AccumulationPassCommonParams58{59FfxInt32x2 iPxHrPos;60FfxFloat32x2 fHrUv;61FfxFloat32x2 fLrUv_HwSampler;62FfxFloat32x2 fMotionVector;63FfxFloat32x2 fReprojectedHrUv;64FfxFloat32 fHrVelocity;65FfxFloat32 fDepthClipFactor;66FfxFloat32 fDilatedReactiveFactor;67FfxFloat32 fAccumulationMask;6869FfxBoolean bIsResetFrame;70FfxBoolean bIsExistingSample;71FfxBoolean bIsNewSample;72};7374struct LockState75{76FfxBoolean NewLock; //Set for both unique new and re-locked new77FfxBoolean WasLockedPrevFrame; //Set to identify if the pixel was already locked (relock)78};7980void InitializeNewLockSample(FFX_PARAMETER_OUT FfxFloat32x2 fLockStatus)81{82fLockStatus = FfxFloat32x2(0, 0);83}8485#if FFX_HALF86void InitializeNewLockSample(FFX_PARAMETER_OUT FFX_MIN16_F2 fLockStatus)87{88fLockStatus = FFX_MIN16_F2(0, 0);89}90#endif919293void KillLock(FFX_PARAMETER_INOUT FfxFloat32x2 fLockStatus)94{95fLockStatus[LOCK_LIFETIME_REMAINING] = 0;96}9798#if FFX_HALF99void KillLock(FFX_PARAMETER_INOUT FFX_MIN16_F2 fLockStatus)100{101fLockStatus[LOCK_LIFETIME_REMAINING] = FFX_MIN16_F(0);102}103#endif104105struct RectificationBox106{107FfxFloat32x3 boxCenter;108FfxFloat32x3 boxVec;109FfxFloat32x3 aabbMin;110FfxFloat32x3 aabbMax;111FfxFloat32 fBoxCenterWeight;112};113#if FFX_HALF114struct RectificationBoxMin16115{116FFX_MIN16_F3 boxCenter;117FFX_MIN16_F3 boxVec;118FFX_MIN16_F3 aabbMin;119FFX_MIN16_F3 aabbMax;120FFX_MIN16_F fBoxCenterWeight;121};122#endif123124void RectificationBoxReset(FFX_PARAMETER_INOUT RectificationBox rectificationBox)125{126rectificationBox.fBoxCenterWeight = FfxFloat32(0);127128rectificationBox.boxCenter = FfxFloat32x3(0, 0, 0);129rectificationBox.boxVec = FfxFloat32x3(0, 0, 0);130rectificationBox.aabbMin = FfxFloat32x3(FSR2_FLT_MAX, FSR2_FLT_MAX, FSR2_FLT_MAX);131rectificationBox.aabbMax = -FfxFloat32x3(FSR2_FLT_MAX, FSR2_FLT_MAX, FSR2_FLT_MAX);132}133#if FFX_HALF134void RectificationBoxReset(FFX_PARAMETER_INOUT RectificationBoxMin16 rectificationBox)135{136rectificationBox.fBoxCenterWeight = FFX_MIN16_F(0);137138rectificationBox.boxCenter = FFX_MIN16_F3(0, 0, 0);139rectificationBox.boxVec = FFX_MIN16_F3(0, 0, 0);140rectificationBox.aabbMin = FFX_MIN16_F3(FSR2_FP16_MAX, FSR2_FP16_MAX, FSR2_FP16_MAX);141rectificationBox.aabbMax = -FFX_MIN16_F3(FSR2_FP16_MAX, FSR2_FP16_MAX, FSR2_FP16_MAX);142}143#endif144145void RectificationBoxAddInitialSample(FFX_PARAMETER_INOUT RectificationBox rectificationBox, const FfxFloat32x3 colorSample, const FfxFloat32 fSampleWeight)146{147rectificationBox.aabbMin = colorSample;148rectificationBox.aabbMax = colorSample;149150FfxFloat32x3 weightedSample = colorSample * fSampleWeight;151rectificationBox.boxCenter = weightedSample;152rectificationBox.boxVec = colorSample * weightedSample;153rectificationBox.fBoxCenterWeight = fSampleWeight;154}155156void RectificationBoxAddSample(FfxBoolean bInitialSample, FFX_PARAMETER_INOUT RectificationBox rectificationBox, const FfxFloat32x3 colorSample, const FfxFloat32 fSampleWeight)157{158if (bInitialSample) {159RectificationBoxAddInitialSample(rectificationBox, colorSample, fSampleWeight);160} else {161rectificationBox.aabbMin = ffxMin(rectificationBox.aabbMin, colorSample);162rectificationBox.aabbMax = ffxMax(rectificationBox.aabbMax, colorSample);163164FfxFloat32x3 weightedSample = colorSample * fSampleWeight;165rectificationBox.boxCenter += weightedSample;166rectificationBox.boxVec += colorSample * weightedSample;167rectificationBox.fBoxCenterWeight += fSampleWeight;168}169}170#if FFX_HALF171void RectificationBoxAddInitialSample(FFX_PARAMETER_INOUT RectificationBoxMin16 rectificationBox, const FFX_MIN16_F3 colorSample, const FFX_MIN16_F fSampleWeight)172{173rectificationBox.aabbMin = colorSample;174rectificationBox.aabbMax = colorSample;175176FFX_MIN16_F3 weightedSample = colorSample * fSampleWeight;177rectificationBox.boxCenter = weightedSample;178rectificationBox.boxVec = colorSample * weightedSample;179rectificationBox.fBoxCenterWeight = fSampleWeight;180}181182void RectificationBoxAddSample(FfxBoolean bInitialSample, FFX_PARAMETER_INOUT RectificationBoxMin16 rectificationBox, const FFX_MIN16_F3 colorSample, const FFX_MIN16_F fSampleWeight)183{184if (bInitialSample) {185RectificationBoxAddInitialSample(rectificationBox, colorSample, fSampleWeight);186} else {187rectificationBox.aabbMin = ffxMin(rectificationBox.aabbMin, colorSample);188rectificationBox.aabbMax = ffxMax(rectificationBox.aabbMax, colorSample);189190FFX_MIN16_F3 weightedSample = colorSample * fSampleWeight;191rectificationBox.boxCenter += weightedSample;192rectificationBox.boxVec += colorSample * weightedSample;193rectificationBox.fBoxCenterWeight += fSampleWeight;194}195}196#endif197198void RectificationBoxComputeVarianceBoxData(FFX_PARAMETER_INOUT RectificationBox rectificationBox)199{200rectificationBox.fBoxCenterWeight = (abs(rectificationBox.fBoxCenterWeight) > FfxFloat32(FSR2_EPSILON) ? rectificationBox.fBoxCenterWeight : FfxFloat32(1.f));201rectificationBox.boxCenter /= rectificationBox.fBoxCenterWeight;202rectificationBox.boxVec /= rectificationBox.fBoxCenterWeight;203FfxFloat32x3 stdDev = sqrt(abs(rectificationBox.boxVec - rectificationBox.boxCenter * rectificationBox.boxCenter));204rectificationBox.boxVec = stdDev;205}206#if FFX_HALF207void RectificationBoxComputeVarianceBoxData(FFX_PARAMETER_INOUT RectificationBoxMin16 rectificationBox)208{209rectificationBox.fBoxCenterWeight = (abs(rectificationBox.fBoxCenterWeight) > FFX_MIN16_F(FSR2_EPSILON) ? rectificationBox.fBoxCenterWeight : FFX_MIN16_F(1.f));210rectificationBox.boxCenter /= rectificationBox.fBoxCenterWeight;211rectificationBox.boxVec /= rectificationBox.fBoxCenterWeight;212FFX_MIN16_F3 stdDev = sqrt(abs(rectificationBox.boxVec - rectificationBox.boxCenter * rectificationBox.boxCenter));213rectificationBox.boxVec = stdDev;214}215#endif216217FfxFloat32x3 SafeRcp3(FfxFloat32x3 v)218{219return (all(FFX_NOT_EQUAL(v, FfxFloat32x3(0, 0, 0)))) ? (FfxFloat32x3(1, 1, 1) / v) : FfxFloat32x3(0, 0, 0);220}221#if FFX_HALF222FFX_MIN16_F3 SafeRcp3(FFX_MIN16_F3 v)223{224return (all(FFX_NOT_EQUAL(v, FFX_MIN16_F3(0, 0, 0)))) ? (FFX_MIN16_F3(1, 1, 1) / v) : FFX_MIN16_F3(0, 0, 0);225}226#endif227228FfxFloat32 MinDividedByMax(const FfxFloat32 v0, const FfxFloat32 v1)229{230const FfxFloat32 m = ffxMax(v0, v1);231return m != 0 ? ffxMin(v0, v1) / m : 0;232}233234#if FFX_HALF235FFX_MIN16_F MinDividedByMax(const FFX_MIN16_F v0, const FFX_MIN16_F v1)236{237const FFX_MIN16_F m = ffxMax(v0, v1);238return m != FFX_MIN16_F(0) ? ffxMin(v0, v1) / m : FFX_MIN16_F(0);239}240#endif241242FfxFloat32x3 YCoCgToRGB(FfxFloat32x3 fYCoCg)243{244FfxFloat32x3 fRgb;245246fRgb = FfxFloat32x3(247fYCoCg.x + fYCoCg.y - fYCoCg.z,248fYCoCg.x + fYCoCg.z,249fYCoCg.x - fYCoCg.y - fYCoCg.z);250251return fRgb;252}253#if FFX_HALF254FFX_MIN16_F3 YCoCgToRGB(FFX_MIN16_F3 fYCoCg)255{256FFX_MIN16_F3 fRgb;257258fRgb = FFX_MIN16_F3(259fYCoCg.x + fYCoCg.y - fYCoCg.z,260fYCoCg.x + fYCoCg.z,261fYCoCg.x - fYCoCg.y - fYCoCg.z);262263return fRgb;264}265#endif266267FfxFloat32x3 RGBToYCoCg(FfxFloat32x3 fRgb)268{269FfxFloat32x3 fYCoCg;270271fYCoCg = FfxFloat32x3(2720.25f * fRgb.r + 0.5f * fRgb.g + 0.25f * fRgb.b,2730.5f * fRgb.r - 0.5f * fRgb.b,274-0.25f * fRgb.r + 0.5f * fRgb.g - 0.25f * fRgb.b);275276return fYCoCg;277}278#if FFX_HALF279FFX_MIN16_F3 RGBToYCoCg(FFX_MIN16_F3 fRgb)280{281FFX_MIN16_F3 fYCoCg;282283fYCoCg = FFX_MIN16_F3(2840.25 * fRgb.r + 0.5 * fRgb.g + 0.25 * fRgb.b,2850.5 * fRgb.r - 0.5 * fRgb.b,286-0.25 * fRgb.r + 0.5 * fRgb.g - 0.25 * fRgb.b);287288return fYCoCg;289}290#endif291292FfxFloat32 RGBToLuma(FfxFloat32x3 fLinearRgb)293{294return dot(fLinearRgb, FfxFloat32x3(0.2126f, 0.7152f, 0.0722f));295}296#if FFX_HALF297FFX_MIN16_F RGBToLuma(FFX_MIN16_F3 fLinearRgb)298{299return dot(fLinearRgb, FFX_MIN16_F3(0.2126f, 0.7152f, 0.0722f));300}301#endif302303FfxFloat32 RGBToPerceivedLuma(FfxFloat32x3 fLinearRgb)304{305FfxFloat32 fLuminance = RGBToLuma(fLinearRgb);306307FfxFloat32 fPercievedLuminance = 0;308if (fLuminance <= 216.0f / 24389.0f) {309fPercievedLuminance = fLuminance * (24389.0f / 27.0f);310}311else {312fPercievedLuminance = ffxPow(fLuminance, 1.0f / 3.0f) * 116.0f - 16.0f;313}314315return fPercievedLuminance * 0.01f;316}317#if FFX_HALF318FFX_MIN16_F RGBToPerceivedLuma(FFX_MIN16_F3 fLinearRgb)319{320FFX_MIN16_F fLuminance = RGBToLuma(fLinearRgb);321322FFX_MIN16_F fPercievedLuminance = FFX_MIN16_F(0);323if (fLuminance <= FFX_MIN16_F(216.0f / 24389.0f)) {324fPercievedLuminance = fLuminance * FFX_MIN16_F(24389.0f / 27.0f);325}326else {327fPercievedLuminance = ffxPow(fLuminance, FFX_MIN16_F(1.0f / 3.0f)) * FFX_MIN16_F(116.0f) - FFX_MIN16_F(16.0f);328}329330return fPercievedLuminance * FFX_MIN16_F(0.01f);331}332#endif333334FfxFloat32x3 Tonemap(FfxFloat32x3 fRgb)335{336return fRgb / (ffxMax(ffxMax(0.f, fRgb.r), ffxMax(fRgb.g, fRgb.b)) + 1.f).xxx;337}338339FfxFloat32x3 InverseTonemap(FfxFloat32x3 fRgb)340{341return fRgb / ffxMax(FSR2_TONEMAP_EPSILON, 1.f - ffxMax(fRgb.r, ffxMax(fRgb.g, fRgb.b))).xxx;342}343344#if FFX_HALF345FFX_MIN16_F3 Tonemap(FFX_MIN16_F3 fRgb)346{347return fRgb / (ffxMax(ffxMax(FFX_MIN16_F(0.f), fRgb.r), ffxMax(fRgb.g, fRgb.b)) + FFX_MIN16_F(1.f)).xxx;348}349350FFX_MIN16_F3 InverseTonemap(FFX_MIN16_F3 fRgb)351{352return fRgb / ffxMax(FFX_MIN16_F(FSR2_TONEMAP_EPSILON), FFX_MIN16_F(1.f) - ffxMax(fRgb.r, ffxMax(fRgb.g, fRgb.b))).xxx;353}354#endif355356FfxInt32x2 ClampLoad(FfxInt32x2 iPxSample, FfxInt32x2 iPxOffset, FfxInt32x2 iTextureSize)357{358FfxInt32x2 result = iPxSample + iPxOffset;359result.x = (iPxOffset.x < 0) ? ffxMax(result.x, 0) : result.x;360result.x = (iPxOffset.x > 0) ? ffxMin(result.x, iTextureSize.x - 1) : result.x;361result.y = (iPxOffset.y < 0) ? ffxMax(result.y, 0) : result.y;362result.y = (iPxOffset.y > 0) ? ffxMin(result.y, iTextureSize.y - 1) : result.y;363return result;364365// return ffxMed3(iPxSample + iPxOffset, FfxInt32x2(0, 0), iTextureSize - FfxInt32x2(1, 1));366}367#if FFX_HALF368FFX_MIN16_I2 ClampLoad(FFX_MIN16_I2 iPxSample, FFX_MIN16_I2 iPxOffset, FFX_MIN16_I2 iTextureSize)369{370FFX_MIN16_I2 result = iPxSample + iPxOffset;371result.x = (iPxOffset.x < 0) ? ffxMax(result.x, FFX_MIN16_I(0)) : result.x;372result.x = (iPxOffset.x > 0) ? ffxMin(result.x, iTextureSize.x - FFX_MIN16_I(1)) : result.x;373result.y = (iPxOffset.y < 0) ? ffxMax(result.y, FFX_MIN16_I(0)) : result.y;374result.y = (iPxOffset.y > 0) ? ffxMin(result.y, iTextureSize.y - FFX_MIN16_I(1)) : result.y;375return result;376377// return ffxMed3Half(iPxSample + iPxOffset, FFX_MIN16_I2(0, 0), iTextureSize - FFX_MIN16_I2(1, 1));378}379#endif380381FfxFloat32x2 ClampUv(FfxFloat32x2 fUv, FfxInt32x2 iTextureSize, FfxInt32x2 iResourceSize)382{383const FfxFloat32x2 fSampleLocation = fUv * iTextureSize;384const FfxFloat32x2 fClampedLocation = ffxMax(FfxFloat32x2(0.5f, 0.5f), ffxMin(fSampleLocation, FfxFloat32x2(iTextureSize) - FfxFloat32x2(0.5f, 0.5f)));385const FfxFloat32x2 fClampedUv = fClampedLocation / FfxFloat32x2(iResourceSize);386387return fClampedUv;388}389390FfxBoolean IsOnScreen(FfxInt32x2 pos, FfxInt32x2 size)391{392return all(FFX_LESS_THAN(FfxUInt32x2(pos), FfxUInt32x2(size)));393}394#if FFX_HALF395FfxBoolean IsOnScreen(FFX_MIN16_I2 pos, FFX_MIN16_I2 size)396{397return all(FFX_LESS_THAN(FFX_MIN16_U2(pos), FFX_MIN16_U2(size)));398}399#endif400401FfxFloat32 ComputeAutoExposureFromLavg(FfxFloat32 Lavg)402{403Lavg = exp(Lavg);404405const FfxFloat32 S = 100.0f; //ISO arithmetic speed406const FfxFloat32 K = 12.5f;407FfxFloat32 ExposureISO100 = log2((Lavg * S) / K);408409const FfxFloat32 q = 0.65f;410FfxFloat32 Lmax = (78.0f / (q * S)) * ffxPow(2.0f, ExposureISO100);411412return 1 / Lmax;413}414#if FFX_HALF415FFX_MIN16_F ComputeAutoExposureFromLavg(FFX_MIN16_F Lavg)416{417Lavg = exp(Lavg);418419const FFX_MIN16_F S = FFX_MIN16_F(100.0f); //ISO arithmetic speed420const FFX_MIN16_F K = FFX_MIN16_F(12.5f);421const FFX_MIN16_F ExposureISO100 = log2((Lavg * S) / K);422423const FFX_MIN16_F q = FFX_MIN16_F(0.65f);424const FFX_MIN16_F Lmax = (FFX_MIN16_F(78.0f) / (q * S)) * ffxPow(FFX_MIN16_F(2.0f), ExposureISO100);425426return FFX_MIN16_F(1) / Lmax;427}428#endif429430FfxInt32x2 ComputeHrPosFromLrPos(FfxInt32x2 iPxLrPos)431{432FfxFloat32x2 fSrcJitteredPos = FfxFloat32x2(iPxLrPos) + 0.5f - Jitter();433FfxFloat32x2 fLrPosInHr = (fSrcJitteredPos / RenderSize()) * DisplaySize();434FfxInt32x2 iPxHrPos = FfxInt32x2(floor(fLrPosInHr));435return iPxHrPos;436}437#if FFX_HALF438FFX_MIN16_I2 ComputeHrPosFromLrPos(FFX_MIN16_I2 iPxLrPos)439{440FFX_MIN16_F2 fSrcJitteredPos = FFX_MIN16_F2(iPxLrPos) + FFX_MIN16_F(0.5f) - FFX_MIN16_F2(Jitter());441FFX_MIN16_F2 fLrPosInHr = (fSrcJitteredPos / FFX_MIN16_F2(RenderSize())) * FFX_MIN16_F2(DisplaySize());442FFX_MIN16_I2 iPxHrPos = FFX_MIN16_I2(floor(fLrPosInHr));443return iPxHrPos;444}445#endif446447FfxFloat32x2 ComputeNdc(FfxFloat32x2 fPxPos, FfxInt32x2 iSize)448{449return fPxPos / FfxFloat32x2(iSize) * FfxFloat32x2(2.0f, -2.0f) + FfxFloat32x2(-1.0f, 1.0f);450}451452FfxFloat32 GetViewSpaceDepth(FfxFloat32 fDeviceDepth)453{454const FfxFloat32x4 fDeviceToViewDepth = DeviceToViewSpaceTransformFactors();455456// fDeviceToViewDepth details found in ffx_fsr2.cpp457return (fDeviceToViewDepth[1] / (fDeviceDepth - fDeviceToViewDepth[0]));458}459460FfxFloat32 GetViewSpaceDepthInMeters(FfxFloat32 fDeviceDepth)461{462return GetViewSpaceDepth(fDeviceDepth) * ViewSpaceToMetersFactor();463}464465FfxFloat32x3 GetViewSpacePosition(FfxInt32x2 iViewportPos, FfxInt32x2 iViewportSize, FfxFloat32 fDeviceDepth)466{467const FfxFloat32x4 fDeviceToViewDepth = DeviceToViewSpaceTransformFactors();468469const FfxFloat32 Z = GetViewSpaceDepth(fDeviceDepth);470471const FfxFloat32x2 fNdcPos = ComputeNdc(iViewportPos, iViewportSize);472const FfxFloat32 X = fDeviceToViewDepth[2] * fNdcPos.x * Z;473const FfxFloat32 Y = fDeviceToViewDepth[3] * fNdcPos.y * Z;474475return FfxFloat32x3(X, Y, Z);476}477478FfxFloat32x3 GetViewSpacePositionInMeters(FfxInt32x2 iViewportPos, FfxInt32x2 iViewportSize, FfxFloat32 fDeviceDepth)479{480return GetViewSpacePosition(iViewportPos, iViewportSize, fDeviceDepth) * ViewSpaceToMetersFactor();481}482483FfxFloat32 GetMaxDistanceInMeters()484{485#if FFX_FSR2_OPTION_INVERTED_DEPTH486return GetViewSpaceDepth(0.0f) * ViewSpaceToMetersFactor();487#else488return GetViewSpaceDepth(1.0f) * ViewSpaceToMetersFactor();489#endif490}491492FfxFloat32x3 PrepareRgb(FfxFloat32x3 fRgb, FfxFloat32 fExposure, FfxFloat32 fPreExposure)493{494fRgb /= fPreExposure;495fRgb *= fExposure;496497fRgb = clamp(fRgb, 0.0f, FSR2_FP16_MAX);498499return fRgb;500}501502FfxFloat32x3 UnprepareRgb(FfxFloat32x3 fRgb, FfxFloat32 fExposure)503{504fRgb /= fExposure;505fRgb *= PreExposure();506507return fRgb;508}509510511struct BilinearSamplingData512{513FfxInt32x2 iOffsets[4];514FfxFloat32 fWeights[4];515FfxInt32x2 iBasePos;516};517518BilinearSamplingData GetBilinearSamplingData(FfxFloat32x2 fUv, FfxInt32x2 iSize)519{520BilinearSamplingData data;521522FfxFloat32x2 fPxSample = (fUv * iSize) - FfxFloat32x2(0.5f, 0.5f);523data.iBasePos = FfxInt32x2(floor(fPxSample));524FfxFloat32x2 fPxFrac = ffxFract(fPxSample);525526data.iOffsets[0] = FfxInt32x2(0, 0);527data.iOffsets[1] = FfxInt32x2(1, 0);528data.iOffsets[2] = FfxInt32x2(0, 1);529data.iOffsets[3] = FfxInt32x2(1, 1);530531data.fWeights[0] = (1 - fPxFrac.x) * (1 - fPxFrac.y);532data.fWeights[1] = (fPxFrac.x) * (1 - fPxFrac.y);533data.fWeights[2] = (1 - fPxFrac.x) * (fPxFrac.y);534data.fWeights[3] = (fPxFrac.x) * (fPxFrac.y);535536return data;537}538539struct PlaneData540{541FfxFloat32x3 fNormal;542FfxFloat32 fDistanceFromOrigin;543};544545PlaneData GetPlaneFromPoints(FfxFloat32x3 fP0, FfxFloat32x3 fP1, FfxFloat32x3 fP2)546{547PlaneData plane;548549FfxFloat32x3 v0 = fP0 - fP1;550FfxFloat32x3 v1 = fP0 - fP2;551plane.fNormal = normalize(cross(v0, v1));552plane.fDistanceFromOrigin = -dot(fP0, plane.fNormal);553554return plane;555}556557FfxFloat32 PointToPlaneDistance(PlaneData plane, FfxFloat32x3 fPoint)558{559return abs(dot(plane.fNormal, fPoint) + plane.fDistanceFromOrigin);560}561562#endif // #if defined(FFX_GPU)563564#endif //!defined(FFX_FSR2_COMMON_H)565566567