阶段性完成
This commit is contained in:
48
Assets/PotaToon/Shaders/OIT/LinkedListCreation.hlsl
Normal file
48
Assets/PotaToon/Shaders/OIT/LinkedListCreation.hlsl
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* 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. Change to use _ScreenSize
|
||||
*/
|
||||
|
||||
#ifndef OIT_LINKED_LIST_INCLUDED
|
||||
#define OIT_LINKED_LIST_INCLUDED
|
||||
|
||||
#include "./OitUtils.hlsl"
|
||||
|
||||
struct FragmentAndLinkBuffer_STRUCT
|
||||
{
|
||||
uint pixelColor;
|
||||
uint uDepthSampleIdx;
|
||||
uint next;
|
||||
};
|
||||
|
||||
float Linear01Depth_(float depth)
|
||||
{
|
||||
return 1.0 / (_ZBufferParams.x * depth + _ZBufferParams.y);
|
||||
}
|
||||
|
||||
RWStructuredBuffer<FragmentAndLinkBuffer_STRUCT> FLBuffer;
|
||||
RWByteAddressBuffer StartOffsetBuffer;
|
||||
|
||||
void createFragmentEntry(float4 col, float3 pos, uint uSampleIdx) {
|
||||
//Retrieve current Pixel count and increase counter
|
||||
uint uPixelCount = FLBuffer.IncrementCounter();
|
||||
|
||||
//calculate bufferAddress
|
||||
uint uStartOffsetAddress = 4 * (_ScreenSize.x * (pos.y - 0.5) + (pos.x - 0.5));
|
||||
uint uOldStartOffset;
|
||||
StartOffsetBuffer.InterlockedExchange(uStartOffsetAddress, uPixelCount, uOldStartOffset);
|
||||
|
||||
//add new Fragment Entry in FragmentAndLinkBuffer
|
||||
FragmentAndLinkBuffer_STRUCT Element;
|
||||
Element.pixelColor = PackRGBA(col);
|
||||
Element.uDepthSampleIdx = PackDepthSampleIdx(Linear01Depth_(pos.z), uSampleIdx);
|
||||
Element.next = uOldStartOffset;
|
||||
FLBuffer[uPixelCount] = Element;
|
||||
}
|
||||
|
||||
#endif // OIT_LINKED_LIST_INCLUDED
|
||||
14
Assets/PotaToon/Shaders/OIT/LinkedListCreation.hlsl.meta
Normal file
14
Assets/PotaToon/Shaders/OIT/LinkedListCreation.hlsl.meta
Normal file
@@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a040255d2a73ca74ab6c02e35eddeb6e
|
||||
ShaderIncludeImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 316069
|
||||
packageName: PotaToon
|
||||
packageVersion: 1.3.6
|
||||
assetPath: Assets/PotaToon/Shaders/OIT/LinkedListCreation.hlsl
|
||||
uploadId: 814994
|
||||
89
Assets/PotaToon/Shaders/OIT/LinkedListRendering.hlsl
Normal file
89
Assets/PotaToon/Shaders/OIT/LinkedListRendering.hlsl
Normal file
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* 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
|
||||
14
Assets/PotaToon/Shaders/OIT/LinkedListRendering.hlsl.meta
Normal file
14
Assets/PotaToon/Shaders/OIT/LinkedListRendering.hlsl.meta
Normal file
@@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1796a2bca62e9a24eb001b6e1c5b25b4
|
||||
ShaderIncludeImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 316069
|
||||
packageName: PotaToon
|
||||
packageVersion: 1.3.6
|
||||
assetPath: Assets/PotaToon/Shaders/OIT/LinkedListRendering.hlsl
|
||||
uploadId: 814994
|
||||
59
Assets/PotaToon/Shaders/OIT/OITFullscreenRender.shader
Normal file
59
Assets/PotaToon/Shaders/OIT/OITFullscreenRender.shader
Normal file
@@ -0,0 +1,59 @@
|
||||
Shader "PotaToon/Hidden/OITFullscreenRender"
|
||||
{
|
||||
Properties
|
||||
{
|
||||
}
|
||||
SubShader
|
||||
{
|
||||
Tags { "RenderPipeline" = "UniversalPipeline" }
|
||||
Pass
|
||||
{
|
||||
ZTest Always
|
||||
ZWrite Off
|
||||
Cull Off
|
||||
// Blend One One
|
||||
Blend One OneMinusSrcAlpha
|
||||
|
||||
HLSLPROGRAM
|
||||
#pragma vertex OITVert
|
||||
#pragma fragment OITFrag
|
||||
#pragma target 5.0
|
||||
// #pragma require randomwrite
|
||||
|
||||
#pragma multi_compile_local_fragment _ _OIT_ADDITIVE
|
||||
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blit.hlsl"
|
||||
#include "./LinkedListRendering.hlsl"
|
||||
|
||||
SAMPLER(sampler_BlitTexture);
|
||||
|
||||
Varyings OITVert(Attributes input)
|
||||
{
|
||||
Varyings output;
|
||||
|
||||
#if SHADER_API_GLES
|
||||
float4 pos = input.positionOS;
|
||||
float2 uv = input.uv;
|
||||
#else
|
||||
float4 pos = GetFullScreenTriangleVertexPosition(input.vertexID);
|
||||
float2 uv = GetFullScreenTriangleTexCoord(input.vertexID);
|
||||
#endif
|
||||
|
||||
output.positionCS = pos;
|
||||
output.texcoord = uv;
|
||||
return output;
|
||||
}
|
||||
|
||||
//Pixel function returns a solid color for each point.
|
||||
float4 OITFrag(Varyings i, uint uSampleIndex : SV_SampleIndex) : SV_Target
|
||||
{
|
||||
// Retrieve current color from background texture
|
||||
float4 color = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_BlitTexture, i.texcoord);
|
||||
float4 finalColor = renderLinkedList(color, i.positionCS.xy, uSampleIndex);
|
||||
return finalColor;
|
||||
}
|
||||
ENDHLSL
|
||||
}
|
||||
}
|
||||
}
|
||||
16
Assets/PotaToon/Shaders/OIT/OITFullscreenRender.shader.meta
Normal file
16
Assets/PotaToon/Shaders/OIT/OITFullscreenRender.shader.meta
Normal file
@@ -0,0 +1,16 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ac3451dac5b085a459c6bc742bfdc8ef
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 316069
|
||||
packageName: PotaToon
|
||||
packageVersion: 1.3.6
|
||||
assetPath: Assets/PotaToon/Shaders/OIT/OITFullscreenRender.shader
|
||||
uploadId: 814994
|
||||
16
Assets/PotaToon/Shaders/OIT/OITOutlineUtils.hlsl
Normal file
16
Assets/PotaToon/Shaders/OIT/OITOutlineUtils.hlsl
Normal file
@@ -0,0 +1,16 @@
|
||||
#ifndef OIT_OUTLINE_UTILS_INCLUDED
|
||||
#define OIT_OUTLINE_UTILS_INCLUDED
|
||||
|
||||
TEXTURE2D(_OITDepthTexture);
|
||||
SAMPLER(sampler_OITDepthTexture);
|
||||
|
||||
bool SampleOITDepth(float2 uv, float z)
|
||||
{
|
||||
#if UNITY_REVERSED_Z
|
||||
return SAMPLE_TEXTURE2D(_OITDepthTexture, sampler_OITDepthTexture, uv).r > z;
|
||||
#else
|
||||
return SAMPLE_TEXTURE2D(_OITDepthTexture, sampler_OITDepthTexture, uv).r < z;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // OIT_OUTLINE_UTILS_INCLUDED
|
||||
14
Assets/PotaToon/Shaders/OIT/OITOutlineUtils.hlsl.meta
Normal file
14
Assets/PotaToon/Shaders/OIT/OITOutlineUtils.hlsl.meta
Normal file
@@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 975b81cda3479744eb65d27a408af820
|
||||
ShaderIncludeImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 316069
|
||||
packageName: PotaToon
|
||||
packageVersion: 1.3.6
|
||||
assetPath: Assets/PotaToon/Shaders/OIT/OITOutlineUtils.hlsl
|
||||
uploadId: 814994
|
||||
42
Assets/PotaToon/Shaders/OIT/OitUtils.hlsl
Normal file
42
Assets/PotaToon/Shaders/OIT/OitUtils.hlsl
Normal file
@@ -0,0 +1,42 @@
|
||||
#ifndef OIT_UTILS_INCLUDED
|
||||
#define OIT_UTILS_INCLUDED
|
||||
|
||||
// Unity's HLSL seems not to support dynamic array size, so we can only set this before compilation
|
||||
#define MAX_SORTED_PIXELS 8
|
||||
|
||||
//https://github.com/GameTechDev/AOIT-Update/blob/master/OIT_DX11/AOIT%20Technique/AOIT.hlsl
|
||||
// UnpackRGBA takes a uint value and converts it to a float4
|
||||
float4 UnpackRGBA(uint packedInput)
|
||||
{
|
||||
float4 unpackedOutput;
|
||||
uint4 p = uint4((packedInput & 0xFFUL),
|
||||
(packedInput >> 8UL) & 0xFFUL,
|
||||
(packedInput >> 16UL) & 0xFFUL,
|
||||
(packedInput >> 24UL));
|
||||
|
||||
unpackedOutput = ((float4)p) / 255;
|
||||
return unpackedOutput;
|
||||
}
|
||||
|
||||
// PackRGBA takes a float4 value and packs it into a UINT (8 bits / float)
|
||||
uint PackRGBA(float4 unpackedInput)
|
||||
{
|
||||
uint4 u = (uint4)(saturate(unpackedInput) * 255 + 0.5);
|
||||
uint packedOutput = (u.w << 24UL) | (u.z << 16UL) | (u.y << 8UL) | u.x;
|
||||
return packedOutput;
|
||||
}
|
||||
|
||||
float UnpackDepth(uint uDepthSampleIdx) {
|
||||
return (float)(uDepthSampleIdx >> 8UL) / (pow(2, 24) - 1);
|
||||
}
|
||||
|
||||
uint UnpackSampleIdx(uint uDepthSampleIdx) {
|
||||
return uDepthSampleIdx & 0xFFUL;
|
||||
}
|
||||
|
||||
uint PackDepthSampleIdx(float depth, uint uSampleIdx) {
|
||||
uint d = (uint)(saturate(depth) * (pow(2, 24) - 1));
|
||||
return d << 8UL | uSampleIdx;
|
||||
}
|
||||
|
||||
#endif // OIT_UTILS_INCLUDED
|
||||
14
Assets/PotaToon/Shaders/OIT/OitUtils.hlsl.meta
Normal file
14
Assets/PotaToon/Shaders/OIT/OitUtils.hlsl.meta
Normal file
@@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dc4d82347e26b3448bd198f3149567df
|
||||
ShaderIncludeImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 316069
|
||||
packageName: PotaToon
|
||||
packageVersion: 1.3.6
|
||||
assetPath: Assets/PotaToon/Shaders/OIT/OitUtils.hlsl
|
||||
uploadId: 814994
|
||||
Reference in New Issue
Block a user