diff --git a/data/shaders/hlsl/oit/color.frag b/data/shaders/hlsl/oit/color.frag new file mode 100644 index 00000000..d50c1150 --- /dev/null +++ b/data/shaders/hlsl/oit/color.frag @@ -0,0 +1,64 @@ +// Copyright 2020 Sascha Willems + +#define MAX_FRAGMENT_COUNT 128 + +struct VSOutput +{ + float4 Pos : SV_POSITION; +}; + +struct Node +{ + float4 color; + float depth; + uint next; +}; + +RWTexture2D headIndexImage : register(u0); + +struct Particle +{ + float2 pos; + float2 vel; + float4 gradientPos; +}; + +// Binding 0 : Position storage buffer +RWStructuredBuffer nodes : register(u1); + +float4 main(VSOutput input) : SV_TARGET +{ + Node fragments[MAX_FRAGMENT_COUNT]; + int count = 0; + + uint nodeIdx = headIndexImage[uint2(input.Pos.xy)].r; + + while (nodeIdx != 0xffffffff && count < MAX_FRAGMENT_COUNT) + { + fragments[count] = nodes[nodeIdx]; + nodeIdx = fragments[count].next; + ++count; + } + + // Do the insertion sort + for (uint i = 1; i < count; ++i) + { + Node insert = fragments[i]; + uint j = i; + while (j > 0 && insert.depth > fragments[j - 1].depth) + { + fragments[j] = fragments[j-1]; + --j; + } + fragments[j] = insert; + } + + // Do blending + float4 color = float4(0.025, 0.025, 0.025, 1.0f); + for (uint f = 0; f < count; ++f) + { + color = lerp(color, fragments[f].color, fragments[f].color.a); + } + + return color; +} \ No newline at end of file diff --git a/data/shaders/hlsl/oit/color.frag.spv b/data/shaders/hlsl/oit/color.frag.spv new file mode 100644 index 00000000..7e2e62e9 Binary files /dev/null and b/data/shaders/hlsl/oit/color.frag.spv differ diff --git a/data/shaders/hlsl/oit/color.vert b/data/shaders/hlsl/oit/color.vert new file mode 100644 index 00000000..609b3606 --- /dev/null +++ b/data/shaders/hlsl/oit/color.vert @@ -0,0 +1,14 @@ +// Copyright 2020 Sascha Willems + +struct VSOutput +{ + float4 Pos : SV_POSITION; +}; + +VSOutput main(uint VertexIndex : SV_VertexID) +{ + VSOutput output = (VSOutput)0; + float2 UV = float2((VertexIndex << 1) & 2, VertexIndex & 2); + output.Pos = float4(UV * 2.0f - 1.0f, 0.0f, 1.0f); + return output; +} \ No newline at end of file diff --git a/data/shaders/hlsl/oit/color.vert.spv b/data/shaders/hlsl/oit/color.vert.spv new file mode 100644 index 00000000..03158809 Binary files /dev/null and b/data/shaders/hlsl/oit/color.vert.spv differ diff --git a/data/shaders/hlsl/oit/geometry.frag b/data/shaders/hlsl/oit/geometry.frag new file mode 100644 index 00000000..296fd37d --- /dev/null +++ b/data/shaders/hlsl/oit/geometry.frag @@ -0,0 +1,56 @@ +// Copyright 2020 Sascha Willems + +#define MAX_FRAGMENT_COUNT 75 + +struct VSOutput +{ + float4 Pos : SV_POSITION; +}; + +struct Node +{ + float4 color; + float depth; + uint next; +}; + +struct ObjectUBO +{ + float4x4 model; + float4 color; +}; + +cbuffer ubo : register(b1) { ObjectUBO objectUBO; } + +struct GeometrySBO +{ + uint count; + uint maxNodeCount; +}; +// Binding 0 : Position storage buffer +RWStructuredBuffer geometrySBO : register(u2); + +RWTexture2D headIndexImage : register(u3); + +RWStructuredBuffer nodes : register(u4); + +[earlydepthstencil] +void main(VSOutput input) +{ + // Increase the node count + uint nodeIdx; + InterlockedAdd(geometrySBO[0].count, 1, nodeIdx); + + // Check LinkedListSBO is full + if (nodeIdx < geometrySBO[0].maxNodeCount) + { + // Exchange new head index and previous head index + uint prevHeadIdx; + InterlockedExchange(headIndexImage[uint2(input.Pos.xy)], nodeIdx, prevHeadIdx); + + // Store node data + nodes[nodeIdx].color = objectUBO.color; + nodes[nodeIdx].depth = input.Pos.z; + nodes[nodeIdx].next = prevHeadIdx; + } +} \ No newline at end of file diff --git a/data/shaders/hlsl/oit/geometry.frag.spv b/data/shaders/hlsl/oit/geometry.frag.spv new file mode 100644 index 00000000..3fd22787 Binary files /dev/null and b/data/shaders/hlsl/oit/geometry.frag.spv differ diff --git a/data/shaders/hlsl/oit/geometry.vert b/data/shaders/hlsl/oit/geometry.vert new file mode 100644 index 00000000..f4b5c940 --- /dev/null +++ b/data/shaders/hlsl/oit/geometry.vert @@ -0,0 +1,34 @@ +// Copyright 2020 Sascha Willems + +struct VSInput +{ +[[vk::location(0)]] float4 Pos : POSITION0; +}; + +struct RenderPassUBO +{ + float4x4 projection; + float4x4 view; +}; + +cbuffer renderPassUBO : register(b0) { RenderPassUBO renderPassUBO; } + +struct ObjectUBO +{ + float4x4 model; + float4 color; +}; + +cbuffer objectUBO : register(b1) { ObjectUBO objectUBO; } + +struct VSOutput +{ + float4 Pos : SV_POSITION; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput)0; + output.Pos = mul(renderPassUBO.projection, mul(renderPassUBO.view, mul(objectUBO.model, input.Pos))); + return output; +} diff --git a/data/shaders/hlsl/oit/geometry.vert.spv b/data/shaders/hlsl/oit/geometry.vert.spv new file mode 100644 index 00000000..9ff7f93a Binary files /dev/null and b/data/shaders/hlsl/oit/geometry.vert.spv differ