Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/amd-fsr2/shaders/ffx_fsr2_common.h
9917 views
1
// This file is part of the FidelityFX SDK.
2
//
3
// Copyright (c) 2022-2023 Advanced Micro Devices, Inc. All rights reserved.
4
//
5
// Permission is hereby granted, free of charge, to any person obtaining a copy
6
// of this software and associated documentation files (the "Software"), to deal
7
// in the Software without restriction, including without limitation the rights
8
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
// copies of the Software, and to permit persons to whom the Software is
10
// furnished to do so, subject to the following conditions:
11
// The above copyright notice and this permission notice shall be included in
12
// all copies or substantial portions of the Software.
13
//
14
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
// THE SOFTWARE.
21
22
#if !defined(FFX_FSR2_COMMON_H)
23
#define FFX_FSR2_COMMON_H
24
25
#if defined(FFX_CPU) || defined(FFX_GPU)
26
//Locks
27
#define LOCK_LIFETIME_REMAINING 0
28
#define LOCK_TEMPORAL_LUMA 1
29
#endif // #if defined(FFX_CPU) || defined(FFX_GPU)
30
31
#if defined(FFX_GPU)
32
FFX_STATIC const FfxFloat32 FSR2_FP16_MIN = 6.10e-05f;
33
FFX_STATIC const FfxFloat32 FSR2_FP16_MAX = 65504.0f;
34
FFX_STATIC const FfxFloat32 FSR2_EPSILON = 1e-03f;
35
FFX_STATIC const FfxFloat32 FSR2_TONEMAP_EPSILON = 1.0f / FSR2_FP16_MAX;
36
FFX_STATIC const FfxFloat32 FSR2_FLT_MAX = 3.402823466e+38f;
37
FFX_STATIC const FfxFloat32 FSR2_FLT_MIN = 1.175494351e-38f;
38
39
// treat vector truncation warnings as errors
40
#pragma warning(error: 3206)
41
42
// suppress warnings
43
#pragma warning(disable: 3205) // conversion from larger type to smaller
44
#pragma warning(disable: 3571) // in ffxPow(f, e), f could be negative
45
46
// Reconstructed depth usage
47
FFX_STATIC const FfxFloat32 fReconstructedDepthBilinearWeightThreshold = 0.01f;
48
49
// Accumulation
50
FFX_STATIC const FfxFloat32 fUpsampleLanczosWeightScale = 1.0f / 12.0f;
51
FFX_STATIC const FfxFloat32 fMaxAccumulationLanczosWeight = 1.0f;
52
FFX_STATIC const FfxFloat32 fAverageLanczosWeightPerFrame = 0.74f * fUpsampleLanczosWeightScale; // Average lanczos weight for jitter accumulated samples
53
FFX_STATIC const FfxFloat32 fAccumulationMaxOnMotion = 3.0f * fUpsampleLanczosWeightScale;
54
55
// Auto exposure
56
FFX_STATIC const FfxFloat32 resetAutoExposureAverageSmoothing = 1e8f;
57
58
struct AccumulationPassCommonParams
59
{
60
FfxInt32x2 iPxHrPos;
61
FfxFloat32x2 fHrUv;
62
FfxFloat32x2 fLrUv_HwSampler;
63
FfxFloat32x2 fMotionVector;
64
FfxFloat32x2 fReprojectedHrUv;
65
FfxFloat32 fHrVelocity;
66
FfxFloat32 fDepthClipFactor;
67
FfxFloat32 fDilatedReactiveFactor;
68
FfxFloat32 fAccumulationMask;
69
70
FfxBoolean bIsResetFrame;
71
FfxBoolean bIsExistingSample;
72
FfxBoolean bIsNewSample;
73
};
74
75
struct LockState
76
{
77
FfxBoolean NewLock; //Set for both unique new and re-locked new
78
FfxBoolean WasLockedPrevFrame; //Set to identify if the pixel was already locked (relock)
79
};
80
81
void InitializeNewLockSample(FFX_PARAMETER_OUT FfxFloat32x2 fLockStatus)
82
{
83
fLockStatus = FfxFloat32x2(0, 0);
84
}
85
86
#if FFX_HALF
87
void InitializeNewLockSample(FFX_PARAMETER_OUT FFX_MIN16_F2 fLockStatus)
88
{
89
fLockStatus = FFX_MIN16_F2(0, 0);
90
}
91
#endif
92
93
94
void KillLock(FFX_PARAMETER_INOUT FfxFloat32x2 fLockStatus)
95
{
96
fLockStatus[LOCK_LIFETIME_REMAINING] = 0;
97
}
98
99
#if FFX_HALF
100
void KillLock(FFX_PARAMETER_INOUT FFX_MIN16_F2 fLockStatus)
101
{
102
fLockStatus[LOCK_LIFETIME_REMAINING] = FFX_MIN16_F(0);
103
}
104
#endif
105
106
struct RectificationBox
107
{
108
FfxFloat32x3 boxCenter;
109
FfxFloat32x3 boxVec;
110
FfxFloat32x3 aabbMin;
111
FfxFloat32x3 aabbMax;
112
FfxFloat32 fBoxCenterWeight;
113
};
114
#if FFX_HALF
115
struct RectificationBoxMin16
116
{
117
FFX_MIN16_F3 boxCenter;
118
FFX_MIN16_F3 boxVec;
119
FFX_MIN16_F3 aabbMin;
120
FFX_MIN16_F3 aabbMax;
121
FFX_MIN16_F fBoxCenterWeight;
122
};
123
#endif
124
125
void RectificationBoxReset(FFX_PARAMETER_INOUT RectificationBox rectificationBox)
126
{
127
rectificationBox.fBoxCenterWeight = FfxFloat32(0);
128
129
rectificationBox.boxCenter = FfxFloat32x3(0, 0, 0);
130
rectificationBox.boxVec = FfxFloat32x3(0, 0, 0);
131
rectificationBox.aabbMin = FfxFloat32x3(FSR2_FLT_MAX, FSR2_FLT_MAX, FSR2_FLT_MAX);
132
rectificationBox.aabbMax = -FfxFloat32x3(FSR2_FLT_MAX, FSR2_FLT_MAX, FSR2_FLT_MAX);
133
}
134
#if FFX_HALF
135
void RectificationBoxReset(FFX_PARAMETER_INOUT RectificationBoxMin16 rectificationBox)
136
{
137
rectificationBox.fBoxCenterWeight = FFX_MIN16_F(0);
138
139
rectificationBox.boxCenter = FFX_MIN16_F3(0, 0, 0);
140
rectificationBox.boxVec = FFX_MIN16_F3(0, 0, 0);
141
rectificationBox.aabbMin = FFX_MIN16_F3(FSR2_FP16_MAX, FSR2_FP16_MAX, FSR2_FP16_MAX);
142
rectificationBox.aabbMax = -FFX_MIN16_F3(FSR2_FP16_MAX, FSR2_FP16_MAX, FSR2_FP16_MAX);
143
}
144
#endif
145
146
void RectificationBoxAddInitialSample(FFX_PARAMETER_INOUT RectificationBox rectificationBox, const FfxFloat32x3 colorSample, const FfxFloat32 fSampleWeight)
147
{
148
rectificationBox.aabbMin = colorSample;
149
rectificationBox.aabbMax = colorSample;
150
151
FfxFloat32x3 weightedSample = colorSample * fSampleWeight;
152
rectificationBox.boxCenter = weightedSample;
153
rectificationBox.boxVec = colorSample * weightedSample;
154
rectificationBox.fBoxCenterWeight = fSampleWeight;
155
}
156
157
void RectificationBoxAddSample(FfxBoolean bInitialSample, FFX_PARAMETER_INOUT RectificationBox rectificationBox, const FfxFloat32x3 colorSample, const FfxFloat32 fSampleWeight)
158
{
159
if (bInitialSample) {
160
RectificationBoxAddInitialSample(rectificationBox, colorSample, fSampleWeight);
161
} else {
162
rectificationBox.aabbMin = ffxMin(rectificationBox.aabbMin, colorSample);
163
rectificationBox.aabbMax = ffxMax(rectificationBox.aabbMax, colorSample);
164
165
FfxFloat32x3 weightedSample = colorSample * fSampleWeight;
166
rectificationBox.boxCenter += weightedSample;
167
rectificationBox.boxVec += colorSample * weightedSample;
168
rectificationBox.fBoxCenterWeight += fSampleWeight;
169
}
170
}
171
#if FFX_HALF
172
void RectificationBoxAddInitialSample(FFX_PARAMETER_INOUT RectificationBoxMin16 rectificationBox, const FFX_MIN16_F3 colorSample, const FFX_MIN16_F fSampleWeight)
173
{
174
rectificationBox.aabbMin = colorSample;
175
rectificationBox.aabbMax = colorSample;
176
177
FFX_MIN16_F3 weightedSample = colorSample * fSampleWeight;
178
rectificationBox.boxCenter = weightedSample;
179
rectificationBox.boxVec = colorSample * weightedSample;
180
rectificationBox.fBoxCenterWeight = fSampleWeight;
181
}
182
183
void RectificationBoxAddSample(FfxBoolean bInitialSample, FFX_PARAMETER_INOUT RectificationBoxMin16 rectificationBox, const FFX_MIN16_F3 colorSample, const FFX_MIN16_F fSampleWeight)
184
{
185
if (bInitialSample) {
186
RectificationBoxAddInitialSample(rectificationBox, colorSample, fSampleWeight);
187
} else {
188
rectificationBox.aabbMin = ffxMin(rectificationBox.aabbMin, colorSample);
189
rectificationBox.aabbMax = ffxMax(rectificationBox.aabbMax, colorSample);
190
191
FFX_MIN16_F3 weightedSample = colorSample * fSampleWeight;
192
rectificationBox.boxCenter += weightedSample;
193
rectificationBox.boxVec += colorSample * weightedSample;
194
rectificationBox.fBoxCenterWeight += fSampleWeight;
195
}
196
}
197
#endif
198
199
void RectificationBoxComputeVarianceBoxData(FFX_PARAMETER_INOUT RectificationBox rectificationBox)
200
{
201
rectificationBox.fBoxCenterWeight = (abs(rectificationBox.fBoxCenterWeight) > FfxFloat32(FSR2_EPSILON) ? rectificationBox.fBoxCenterWeight : FfxFloat32(1.f));
202
rectificationBox.boxCenter /= rectificationBox.fBoxCenterWeight;
203
rectificationBox.boxVec /= rectificationBox.fBoxCenterWeight;
204
FfxFloat32x3 stdDev = sqrt(abs(rectificationBox.boxVec - rectificationBox.boxCenter * rectificationBox.boxCenter));
205
rectificationBox.boxVec = stdDev;
206
}
207
#if FFX_HALF
208
void RectificationBoxComputeVarianceBoxData(FFX_PARAMETER_INOUT RectificationBoxMin16 rectificationBox)
209
{
210
rectificationBox.fBoxCenterWeight = (abs(rectificationBox.fBoxCenterWeight) > FFX_MIN16_F(FSR2_EPSILON) ? rectificationBox.fBoxCenterWeight : FFX_MIN16_F(1.f));
211
rectificationBox.boxCenter /= rectificationBox.fBoxCenterWeight;
212
rectificationBox.boxVec /= rectificationBox.fBoxCenterWeight;
213
FFX_MIN16_F3 stdDev = sqrt(abs(rectificationBox.boxVec - rectificationBox.boxCenter * rectificationBox.boxCenter));
214
rectificationBox.boxVec = stdDev;
215
}
216
#endif
217
218
FfxFloat32x3 SafeRcp3(FfxFloat32x3 v)
219
{
220
return (all(FFX_NOT_EQUAL(v, FfxFloat32x3(0, 0, 0)))) ? (FfxFloat32x3(1, 1, 1) / v) : FfxFloat32x3(0, 0, 0);
221
}
222
#if FFX_HALF
223
FFX_MIN16_F3 SafeRcp3(FFX_MIN16_F3 v)
224
{
225
return (all(FFX_NOT_EQUAL(v, FFX_MIN16_F3(0, 0, 0)))) ? (FFX_MIN16_F3(1, 1, 1) / v) : FFX_MIN16_F3(0, 0, 0);
226
}
227
#endif
228
229
FfxFloat32 MinDividedByMax(const FfxFloat32 v0, const FfxFloat32 v1)
230
{
231
const FfxFloat32 m = ffxMax(v0, v1);
232
return m != 0 ? ffxMin(v0, v1) / m : 0;
233
}
234
235
#if FFX_HALF
236
FFX_MIN16_F MinDividedByMax(const FFX_MIN16_F v0, const FFX_MIN16_F v1)
237
{
238
const FFX_MIN16_F m = ffxMax(v0, v1);
239
return m != FFX_MIN16_F(0) ? ffxMin(v0, v1) / m : FFX_MIN16_F(0);
240
}
241
#endif
242
243
FfxFloat32x3 YCoCgToRGB(FfxFloat32x3 fYCoCg)
244
{
245
FfxFloat32x3 fRgb;
246
247
fRgb = FfxFloat32x3(
248
fYCoCg.x + fYCoCg.y - fYCoCg.z,
249
fYCoCg.x + fYCoCg.z,
250
fYCoCg.x - fYCoCg.y - fYCoCg.z);
251
252
return fRgb;
253
}
254
#if FFX_HALF
255
FFX_MIN16_F3 YCoCgToRGB(FFX_MIN16_F3 fYCoCg)
256
{
257
FFX_MIN16_F3 fRgb;
258
259
fRgb = FFX_MIN16_F3(
260
fYCoCg.x + fYCoCg.y - fYCoCg.z,
261
fYCoCg.x + fYCoCg.z,
262
fYCoCg.x - fYCoCg.y - fYCoCg.z);
263
264
return fRgb;
265
}
266
#endif
267
268
FfxFloat32x3 RGBToYCoCg(FfxFloat32x3 fRgb)
269
{
270
FfxFloat32x3 fYCoCg;
271
272
fYCoCg = FfxFloat32x3(
273
0.25f * fRgb.r + 0.5f * fRgb.g + 0.25f * fRgb.b,
274
0.5f * fRgb.r - 0.5f * fRgb.b,
275
-0.25f * fRgb.r + 0.5f * fRgb.g - 0.25f * fRgb.b);
276
277
return fYCoCg;
278
}
279
#if FFX_HALF
280
FFX_MIN16_F3 RGBToYCoCg(FFX_MIN16_F3 fRgb)
281
{
282
FFX_MIN16_F3 fYCoCg;
283
284
fYCoCg = FFX_MIN16_F3(
285
0.25 * fRgb.r + 0.5 * fRgb.g + 0.25 * fRgb.b,
286
0.5 * fRgb.r - 0.5 * fRgb.b,
287
-0.25 * fRgb.r + 0.5 * fRgb.g - 0.25 * fRgb.b);
288
289
return fYCoCg;
290
}
291
#endif
292
293
FfxFloat32 RGBToLuma(FfxFloat32x3 fLinearRgb)
294
{
295
return dot(fLinearRgb, FfxFloat32x3(0.2126f, 0.7152f, 0.0722f));
296
}
297
#if FFX_HALF
298
FFX_MIN16_F RGBToLuma(FFX_MIN16_F3 fLinearRgb)
299
{
300
return dot(fLinearRgb, FFX_MIN16_F3(0.2126f, 0.7152f, 0.0722f));
301
}
302
#endif
303
304
FfxFloat32 RGBToPerceivedLuma(FfxFloat32x3 fLinearRgb)
305
{
306
FfxFloat32 fLuminance = RGBToLuma(fLinearRgb);
307
308
FfxFloat32 fPercievedLuminance = 0;
309
if (fLuminance <= 216.0f / 24389.0f) {
310
fPercievedLuminance = fLuminance * (24389.0f / 27.0f);
311
}
312
else {
313
fPercievedLuminance = ffxPow(fLuminance, 1.0f / 3.0f) * 116.0f - 16.0f;
314
}
315
316
return fPercievedLuminance * 0.01f;
317
}
318
#if FFX_HALF
319
FFX_MIN16_F RGBToPerceivedLuma(FFX_MIN16_F3 fLinearRgb)
320
{
321
FFX_MIN16_F fLuminance = RGBToLuma(fLinearRgb);
322
323
FFX_MIN16_F fPercievedLuminance = FFX_MIN16_F(0);
324
if (fLuminance <= FFX_MIN16_F(216.0f / 24389.0f)) {
325
fPercievedLuminance = fLuminance * FFX_MIN16_F(24389.0f / 27.0f);
326
}
327
else {
328
fPercievedLuminance = ffxPow(fLuminance, FFX_MIN16_F(1.0f / 3.0f)) * FFX_MIN16_F(116.0f) - FFX_MIN16_F(16.0f);
329
}
330
331
return fPercievedLuminance * FFX_MIN16_F(0.01f);
332
}
333
#endif
334
335
FfxFloat32x3 Tonemap(FfxFloat32x3 fRgb)
336
{
337
return fRgb / (ffxMax(ffxMax(0.f, fRgb.r), ffxMax(fRgb.g, fRgb.b)) + 1.f).xxx;
338
}
339
340
FfxFloat32x3 InverseTonemap(FfxFloat32x3 fRgb)
341
{
342
return fRgb / ffxMax(FSR2_TONEMAP_EPSILON, 1.f - ffxMax(fRgb.r, ffxMax(fRgb.g, fRgb.b))).xxx;
343
}
344
345
#if FFX_HALF
346
FFX_MIN16_F3 Tonemap(FFX_MIN16_F3 fRgb)
347
{
348
return fRgb / (ffxMax(ffxMax(FFX_MIN16_F(0.f), fRgb.r), ffxMax(fRgb.g, fRgb.b)) + FFX_MIN16_F(1.f)).xxx;
349
}
350
351
FFX_MIN16_F3 InverseTonemap(FFX_MIN16_F3 fRgb)
352
{
353
return fRgb / ffxMax(FFX_MIN16_F(FSR2_TONEMAP_EPSILON), FFX_MIN16_F(1.f) - ffxMax(fRgb.r, ffxMax(fRgb.g, fRgb.b))).xxx;
354
}
355
#endif
356
357
FfxInt32x2 ClampLoad(FfxInt32x2 iPxSample, FfxInt32x2 iPxOffset, FfxInt32x2 iTextureSize)
358
{
359
FfxInt32x2 result = iPxSample + iPxOffset;
360
result.x = (iPxOffset.x < 0) ? ffxMax(result.x, 0) : result.x;
361
result.x = (iPxOffset.x > 0) ? ffxMin(result.x, iTextureSize.x - 1) : result.x;
362
result.y = (iPxOffset.y < 0) ? ffxMax(result.y, 0) : result.y;
363
result.y = (iPxOffset.y > 0) ? ffxMin(result.y, iTextureSize.y - 1) : result.y;
364
return result;
365
366
// return ffxMed3(iPxSample + iPxOffset, FfxInt32x2(0, 0), iTextureSize - FfxInt32x2(1, 1));
367
}
368
#if FFX_HALF
369
FFX_MIN16_I2 ClampLoad(FFX_MIN16_I2 iPxSample, FFX_MIN16_I2 iPxOffset, FFX_MIN16_I2 iTextureSize)
370
{
371
FFX_MIN16_I2 result = iPxSample + iPxOffset;
372
result.x = (iPxOffset.x < 0) ? ffxMax(result.x, FFX_MIN16_I(0)) : result.x;
373
result.x = (iPxOffset.x > 0) ? ffxMin(result.x, iTextureSize.x - FFX_MIN16_I(1)) : result.x;
374
result.y = (iPxOffset.y < 0) ? ffxMax(result.y, FFX_MIN16_I(0)) : result.y;
375
result.y = (iPxOffset.y > 0) ? ffxMin(result.y, iTextureSize.y - FFX_MIN16_I(1)) : result.y;
376
return result;
377
378
// return ffxMed3Half(iPxSample + iPxOffset, FFX_MIN16_I2(0, 0), iTextureSize - FFX_MIN16_I2(1, 1));
379
}
380
#endif
381
382
FfxFloat32x2 ClampUv(FfxFloat32x2 fUv, FfxInt32x2 iTextureSize, FfxInt32x2 iResourceSize)
383
{
384
const FfxFloat32x2 fSampleLocation = fUv * iTextureSize;
385
const FfxFloat32x2 fClampedLocation = ffxMax(FfxFloat32x2(0.5f, 0.5f), ffxMin(fSampleLocation, FfxFloat32x2(iTextureSize) - FfxFloat32x2(0.5f, 0.5f)));
386
const FfxFloat32x2 fClampedUv = fClampedLocation / FfxFloat32x2(iResourceSize);
387
388
return fClampedUv;
389
}
390
391
FfxBoolean IsOnScreen(FfxInt32x2 pos, FfxInt32x2 size)
392
{
393
return all(FFX_LESS_THAN(FfxUInt32x2(pos), FfxUInt32x2(size)));
394
}
395
#if FFX_HALF
396
FfxBoolean IsOnScreen(FFX_MIN16_I2 pos, FFX_MIN16_I2 size)
397
{
398
return all(FFX_LESS_THAN(FFX_MIN16_U2(pos), FFX_MIN16_U2(size)));
399
}
400
#endif
401
402
FfxFloat32 ComputeAutoExposureFromLavg(FfxFloat32 Lavg)
403
{
404
Lavg = exp(Lavg);
405
406
const FfxFloat32 S = 100.0f; //ISO arithmetic speed
407
const FfxFloat32 K = 12.5f;
408
FfxFloat32 ExposureISO100 = log2((Lavg * S) / K);
409
410
const FfxFloat32 q = 0.65f;
411
FfxFloat32 Lmax = (78.0f / (q * S)) * ffxPow(2.0f, ExposureISO100);
412
413
return 1 / Lmax;
414
}
415
#if FFX_HALF
416
FFX_MIN16_F ComputeAutoExposureFromLavg(FFX_MIN16_F Lavg)
417
{
418
Lavg = exp(Lavg);
419
420
const FFX_MIN16_F S = FFX_MIN16_F(100.0f); //ISO arithmetic speed
421
const FFX_MIN16_F K = FFX_MIN16_F(12.5f);
422
const FFX_MIN16_F ExposureISO100 = log2((Lavg * S) / K);
423
424
const FFX_MIN16_F q = FFX_MIN16_F(0.65f);
425
const FFX_MIN16_F Lmax = (FFX_MIN16_F(78.0f) / (q * S)) * ffxPow(FFX_MIN16_F(2.0f), ExposureISO100);
426
427
return FFX_MIN16_F(1) / Lmax;
428
}
429
#endif
430
431
FfxInt32x2 ComputeHrPosFromLrPos(FfxInt32x2 iPxLrPos)
432
{
433
FfxFloat32x2 fSrcJitteredPos = FfxFloat32x2(iPxLrPos) + 0.5f - Jitter();
434
FfxFloat32x2 fLrPosInHr = (fSrcJitteredPos / RenderSize()) * DisplaySize();
435
FfxInt32x2 iPxHrPos = FfxInt32x2(floor(fLrPosInHr));
436
return iPxHrPos;
437
}
438
#if FFX_HALF
439
FFX_MIN16_I2 ComputeHrPosFromLrPos(FFX_MIN16_I2 iPxLrPos)
440
{
441
FFX_MIN16_F2 fSrcJitteredPos = FFX_MIN16_F2(iPxLrPos) + FFX_MIN16_F(0.5f) - FFX_MIN16_F2(Jitter());
442
FFX_MIN16_F2 fLrPosInHr = (fSrcJitteredPos / FFX_MIN16_F2(RenderSize())) * FFX_MIN16_F2(DisplaySize());
443
FFX_MIN16_I2 iPxHrPos = FFX_MIN16_I2(floor(fLrPosInHr));
444
return iPxHrPos;
445
}
446
#endif
447
448
FfxFloat32x2 ComputeNdc(FfxFloat32x2 fPxPos, FfxInt32x2 iSize)
449
{
450
return fPxPos / FfxFloat32x2(iSize) * FfxFloat32x2(2.0f, -2.0f) + FfxFloat32x2(-1.0f, 1.0f);
451
}
452
453
FfxFloat32 GetViewSpaceDepth(FfxFloat32 fDeviceDepth)
454
{
455
const FfxFloat32x4 fDeviceToViewDepth = DeviceToViewSpaceTransformFactors();
456
457
// fDeviceToViewDepth details found in ffx_fsr2.cpp
458
return (fDeviceToViewDepth[1] / (fDeviceDepth - fDeviceToViewDepth[0]));
459
}
460
461
FfxFloat32 GetViewSpaceDepthInMeters(FfxFloat32 fDeviceDepth)
462
{
463
return GetViewSpaceDepth(fDeviceDepth) * ViewSpaceToMetersFactor();
464
}
465
466
FfxFloat32x3 GetViewSpacePosition(FfxInt32x2 iViewportPos, FfxInt32x2 iViewportSize, FfxFloat32 fDeviceDepth)
467
{
468
const FfxFloat32x4 fDeviceToViewDepth = DeviceToViewSpaceTransformFactors();
469
470
const FfxFloat32 Z = GetViewSpaceDepth(fDeviceDepth);
471
472
const FfxFloat32x2 fNdcPos = ComputeNdc(iViewportPos, iViewportSize);
473
const FfxFloat32 X = fDeviceToViewDepth[2] * fNdcPos.x * Z;
474
const FfxFloat32 Y = fDeviceToViewDepth[3] * fNdcPos.y * Z;
475
476
return FfxFloat32x3(X, Y, Z);
477
}
478
479
FfxFloat32x3 GetViewSpacePositionInMeters(FfxInt32x2 iViewportPos, FfxInt32x2 iViewportSize, FfxFloat32 fDeviceDepth)
480
{
481
return GetViewSpacePosition(iViewportPos, iViewportSize, fDeviceDepth) * ViewSpaceToMetersFactor();
482
}
483
484
FfxFloat32 GetMaxDistanceInMeters()
485
{
486
#if FFX_FSR2_OPTION_INVERTED_DEPTH
487
return GetViewSpaceDepth(0.0f) * ViewSpaceToMetersFactor();
488
#else
489
return GetViewSpaceDepth(1.0f) * ViewSpaceToMetersFactor();
490
#endif
491
}
492
493
FfxFloat32x3 PrepareRgb(FfxFloat32x3 fRgb, FfxFloat32 fExposure, FfxFloat32 fPreExposure)
494
{
495
fRgb /= fPreExposure;
496
fRgb *= fExposure;
497
498
fRgb = clamp(fRgb, 0.0f, FSR2_FP16_MAX);
499
500
return fRgb;
501
}
502
503
FfxFloat32x3 UnprepareRgb(FfxFloat32x3 fRgb, FfxFloat32 fExposure)
504
{
505
fRgb /= fExposure;
506
fRgb *= PreExposure();
507
508
return fRgb;
509
}
510
511
512
struct BilinearSamplingData
513
{
514
FfxInt32x2 iOffsets[4];
515
FfxFloat32 fWeights[4];
516
FfxInt32x2 iBasePos;
517
};
518
519
BilinearSamplingData GetBilinearSamplingData(FfxFloat32x2 fUv, FfxInt32x2 iSize)
520
{
521
BilinearSamplingData data;
522
523
FfxFloat32x2 fPxSample = (fUv * iSize) - FfxFloat32x2(0.5f, 0.5f);
524
data.iBasePos = FfxInt32x2(floor(fPxSample));
525
FfxFloat32x2 fPxFrac = ffxFract(fPxSample);
526
527
data.iOffsets[0] = FfxInt32x2(0, 0);
528
data.iOffsets[1] = FfxInt32x2(1, 0);
529
data.iOffsets[2] = FfxInt32x2(0, 1);
530
data.iOffsets[3] = FfxInt32x2(1, 1);
531
532
data.fWeights[0] = (1 - fPxFrac.x) * (1 - fPxFrac.y);
533
data.fWeights[1] = (fPxFrac.x) * (1 - fPxFrac.y);
534
data.fWeights[2] = (1 - fPxFrac.x) * (fPxFrac.y);
535
data.fWeights[3] = (fPxFrac.x) * (fPxFrac.y);
536
537
return data;
538
}
539
540
struct PlaneData
541
{
542
FfxFloat32x3 fNormal;
543
FfxFloat32 fDistanceFromOrigin;
544
};
545
546
PlaneData GetPlaneFromPoints(FfxFloat32x3 fP0, FfxFloat32x3 fP1, FfxFloat32x3 fP2)
547
{
548
PlaneData plane;
549
550
FfxFloat32x3 v0 = fP0 - fP1;
551
FfxFloat32x3 v1 = fP0 - fP2;
552
plane.fNormal = normalize(cross(v0, v1));
553
plane.fDistanceFromOrigin = -dot(fP0, plane.fNormal);
554
555
return plane;
556
}
557
558
FfxFloat32 PointToPlaneDistance(PlaneData plane, FfxFloat32x3 fPoint)
559
{
560
return abs(dot(plane.fNormal, fPoint) + plane.fDistanceFromOrigin);
561
}
562
563
#endif // #if defined(FFX_GPU)
564
565
#endif //!defined(FFX_FSR2_COMMON_H)
566
567