You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
112 lines
4.5 KiB
112 lines
4.5 KiB
// This file is part of the FidelityFX SDK.
|
|
//
|
|
// Copyright (c) 2023 Advanced Micro Devices, Inc. All rights reserved.
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
// of this software and associated documentation files (the "Software"), to deal
|
|
// in the Software without restriction, including without limitation the rights
|
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
// copies of the Software, and to permit persons to whom the Software is
|
|
// furnished to do so, subject to the following conditions:
|
|
// The above copyright notice and this permission notice shall be included in
|
|
// all copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
// THE SOFTWARE.
|
|
|
|
|
|
// packing/unpacking for edges; 2 bits per edge mean 4 gradient values (0, 0.33, 0.66, 1) for smoother transitions!
|
|
FfxFloat32 FFX_CACAO_PackEdges(FfxFloat32x4 edgesLRTB)
|
|
{
|
|
edgesLRTB = round(ffxSaturate(edgesLRTB) * 3.05);
|
|
return dot(edgesLRTB, FfxFloat32x4(64.0 / 255.0, 16.0 / 255.0, 4.0 / 255.0, 1.0 / 255.0));
|
|
}
|
|
|
|
FfxFloat32x4 FFX_CACAO_UnpackEdges(FfxFloat32 _packedVal)
|
|
{
|
|
FfxUInt32 packedVal = FfxUInt32(_packedVal * 255.5);
|
|
FfxFloat32x4 edgesLRTB;
|
|
edgesLRTB.x = FfxFloat32((packedVal >> 6) & 0x03) / 3.0; // there's really no need for mask (as it's an 8 bit input) but I'll leave it in so it doesn't cause any trouble in the future
|
|
edgesLRTB.y = FfxFloat32((packedVal >> 4) & 0x03) / 3.0;
|
|
edgesLRTB.z = FfxFloat32((packedVal >> 2) & 0x03) / 3.0;
|
|
edgesLRTB.w = FfxFloat32((packedVal >> 0) & 0x03) / 3.0;
|
|
|
|
return ffxSaturate(edgesLRTB + InvSharpness());
|
|
}
|
|
|
|
FfxFloat32 FFX_CACAO_ScreenSpaceToViewSpaceDepth(FfxFloat32 screenDepth)
|
|
{
|
|
#if UNITY_REVERSED_Z == 1
|
|
screenDepth = 1.0 - screenDepth;
|
|
#endif
|
|
|
|
FfxFloat32 depthLinearizeMul = DepthUnpackConsts().x;
|
|
FfxFloat32 depthLinearizeAdd = DepthUnpackConsts().y;
|
|
|
|
return depthLinearizeMul * ffxInvertSafe(depthLinearizeAdd - screenDepth);
|
|
}
|
|
|
|
FfxFloat32x4 FFX_CACAO_ScreenSpaceToViewSpaceDepth(FfxFloat32x4 screenDepth)
|
|
{
|
|
#if UNITY_REVERSED_Z == 1
|
|
screenDepth = 1.0 - screenDepth;
|
|
#endif
|
|
|
|
FfxFloat32 depthLinearizeMul = DepthUnpackConsts().x;
|
|
FfxFloat32 depthLinearizeAdd = DepthUnpackConsts().y;
|
|
|
|
return depthLinearizeMul * ffxInvertSafe(depthLinearizeAdd - screenDepth);
|
|
}
|
|
|
|
FfxFloat32x4 FFX_CACAO_CalculateEdges(const FfxFloat32 centerZ, const FfxFloat32 leftZ, const FfxFloat32 rightZ, const FfxFloat32 topZ, const FfxFloat32 bottomZ)
|
|
{
|
|
// slope-sensitive depth-based edge detection
|
|
FfxFloat32x4 edgesLRTB = FfxFloat32x4(leftZ, rightZ, topZ, bottomZ) - centerZ;
|
|
FfxFloat32x4 edgesLRTBSlopeAdjusted = edgesLRTB + edgesLRTB.yxwz;
|
|
edgesLRTB = min(abs(edgesLRTB), abs(edgesLRTBSlopeAdjusted));
|
|
return ffxSaturate((1.3 - edgesLRTB / (centerZ * 0.040)));
|
|
}
|
|
|
|
FfxFloat32x3 FFX_CACAO_NDCToViewSpace(FfxFloat32x2 pos, FfxFloat32 viewspaceDepth)
|
|
{
|
|
FfxFloat32x3 ret;
|
|
|
|
ret.xy = (NDCToViewMul() * pos.xy + NDCToViewAdd()) * viewspaceDepth;
|
|
|
|
ret.z = viewspaceDepth;
|
|
|
|
return ret;
|
|
}
|
|
|
|
FfxFloat32x3 FFX_CACAO_DepthBufferUVToViewSpace(FfxFloat32x2 pos, FfxFloat32 viewspaceDepth)
|
|
{
|
|
FfxFloat32x3 ret;
|
|
ret.xy = (DepthBufferUVToViewMul() * pos.xy + DepthBufferUVToViewAdd()) * viewspaceDepth;
|
|
ret.z = viewspaceDepth;
|
|
return ret;
|
|
}
|
|
|
|
FfxFloat32x3 FFX_CACAO_CalculateNormal(const FfxFloat32x4 edgesLRTB, FfxFloat32x3 pixCenterPos, FfxFloat32x3 pixLPos, FfxFloat32x3 pixRPos, FfxFloat32x3 pixTPos, FfxFloat32x3 pixBPos)
|
|
{
|
|
// Get this pixel's viewspace normal
|
|
FfxFloat32x4 acceptedNormals = FfxFloat32x4(edgesLRTB.x*edgesLRTB.z, edgesLRTB.z*edgesLRTB.y, edgesLRTB.y*edgesLRTB.w, edgesLRTB.w*edgesLRTB.x);
|
|
|
|
pixLPos = normalize(pixLPos - pixCenterPos);
|
|
pixRPos = normalize(pixRPos - pixCenterPos);
|
|
pixTPos = normalize(pixTPos - pixCenterPos);
|
|
pixBPos = normalize(pixBPos - pixCenterPos);
|
|
|
|
FfxFloat32x3 pixelNormal = FfxFloat32x3(0, 0, -0.0005);
|
|
pixelNormal += (acceptedNormals.x) * cross(pixLPos, pixTPos);
|
|
pixelNormal += (acceptedNormals.y) * cross(pixTPos, pixRPos);
|
|
pixelNormal += (acceptedNormals.z) * cross(pixRPos, pixBPos);
|
|
pixelNormal += (acceptedNormals.w) * cross(pixBPos, pixLPos);
|
|
pixelNormal = normalize(pixelNormal);
|
|
|
|
return pixelNormal;
|
|
}
|