Files
Cielonos/Assets/PotaToon/Shaders/OIT/LinkedListRendering.hlsl
SoulliesOfficial f7af60351b 阶段性完成
2025-12-08 05:27:53 -05:00

89 lines
2.6 KiB
HLSL
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* This file includes modifications to original work licensed under the Apache License, Version 2.0.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Modified by: mseon
* Date: 2025-04-06
* Changes:
* 1. Add Additive blending mode.
* 2. Change to use _ScreenSize
*/
#ifndef OIT_LINKED_LIST_RENDERING_INCLUDED
#define OIT_LINKED_LIST_RENDERING_INCLUDED
#include "./OitUtils.hlsl"
struct FragmentAndLinkBuffer_STRUCT
{
uint pixelColor;
uint uDepthSampleIdx;
uint next;
};
Buffer<FragmentAndLinkBuffer_STRUCT> FLBuffer;
ByteAddressBuffer StartOffsetBuffer;
float4 renderLinkedList(float4 col, float2 pos, uint uSampleIndex)
{
// Fetch offset of first fragment for current pixel
uint uStartOffsetAddress = 4 * (_ScreenSize.x * (pos.y - 0.5) + (pos.x - 0.5));
uint uOffset = StartOffsetBuffer.Load(uStartOffsetAddress);
FragmentAndLinkBuffer_STRUCT SortedPixels[MAX_SORTED_PIXELS];
// Parse linked list for all pixels at this position
// and store them into temp array for later sorting
int nNumPixels = 0;
while (uOffset != 0)
{
// Retrieve pixel at current offset
FragmentAndLinkBuffer_STRUCT Element = FLBuffer[uOffset];
uint uSampleIdx = UnpackSampleIdx(Element.uDepthSampleIdx);
if (uSampleIdx == uSampleIndex)
{
SortedPixels[nNumPixels] = Element;
nNumPixels += 1;
}
uOffset = (nNumPixels >= MAX_SORTED_PIXELS) ? 0 : FLBuffer[uOffset].next;
}
// Sort pixels in depth
for (int i = 0; i < nNumPixels - 1; i++)
{
for (int j = i + 1; j > 0; j--)
{
float depth = UnpackDepth(SortedPixels[j].uDepthSampleIdx);
float previousElementDepth = UnpackDepth(SortedPixels[j - 1].uDepthSampleIdx);
if (previousElementDepth < depth)
{
FragmentAndLinkBuffer_STRUCT temp = SortedPixels[j - 1];
SortedPixels[j - 1] = SortedPixels[j];
SortedPixels[j] = temp;
}
}
}
// Rendering pixels
for (int k = 0; k < nNumPixels; k++)
{
// Retrieve next unblended furthermost pixel
float4 vPixColor = UnpackRGBA(SortedPixels[k].pixelColor);
// Manual blending between current fragment and previous one
#if _OIT_ADDITIVE
col.rgb += lerp(0, vPixColor.rgb, vPixColor.a);
#else
col.rgb = lerp(col.rgb, vPixColor.rgb, vPixColor.a);
#endif
}
#if _OIT_ADDITIVE
col.rgb = saturate(col.rgb);
#endif
return col;
}
#endif // OIT_LINKED_LIST_RENDERING_INCLUDED