You're breathtaking!
This commit is contained in:
89
Source/Shaders/Histogram.shader
Normal file
89
Source/Shaders/Histogram.shader
Normal file
@@ -0,0 +1,89 @@
|
||||
// Copyright (c) 2012-2020 Wojciech Figat. All rights reserved.
|
||||
|
||||
#include "./Flax/Common.hlsl"
|
||||
|
||||
// Those defines must match the C++
|
||||
#define THREADGROUP_SIZE_X 16
|
||||
#define THREADGROUP_SIZE_Y 16
|
||||
#define HISTOGRAM_SIZE 64
|
||||
|
||||
META_CB_BEGIN(0, Data)
|
||||
|
||||
uint2 InputSize;
|
||||
float HistogramMul;
|
||||
float HistogramAdd;
|
||||
|
||||
META_CB_END
|
||||
|
||||
#ifdef _CS_ClearHistogram
|
||||
|
||||
RWStructuredBuffer<uint> HistogramBuffer : register(u0);
|
||||
|
||||
// Clears the histogram
|
||||
META_CS(true, FEATURE_LEVEL_SM5)
|
||||
[numthreads(THREADGROUP_SIZE_X, 1, 1)]
|
||||
void CS_ClearHistogram(uint dispatchThreadId : SV_DispatchThreadID)
|
||||
{
|
||||
if (dispatchThreadId < HISTOGRAM_SIZE)
|
||||
HistogramBuffer[dispatchThreadId] = 0u;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef _CS_GenerateHistogram
|
||||
|
||||
Texture2D<float4> Input : register(t0);
|
||||
|
||||
RWStructuredBuffer<uint> HistogramBuffer : register(u0);
|
||||
|
||||
float ComputeHistogramPositionFromLuminance(float luminance)
|
||||
{
|
||||
return log2(luminance) * HistogramMul + HistogramAdd;
|
||||
}
|
||||
|
||||
groupshared uint SharedHistogram[HISTOGRAM_SIZE];
|
||||
|
||||
// Generates the histogram
|
||||
META_CS(true, FEATURE_LEVEL_SM5)
|
||||
[numthreads(THREADGROUP_SIZE_X, THREADGROUP_SIZE_Y, 1)]
|
||||
void CS_GenerateHistogram(uint3 groupId : SV_GroupID, uint3 dispatchThreadId : SV_DispatchThreadID, uint3 groupThreadId : SV_GroupThreadID, uint groupIndex : SV_GroupIndex)
|
||||
{
|
||||
const uint localThreadId = groupThreadId.y * THREADGROUP_SIZE_X + groupThreadId.x;
|
||||
|
||||
// Clear the histogram
|
||||
if (localThreadId < HISTOGRAM_SIZE)
|
||||
SharedHistogram[localThreadId] = 0u;
|
||||
|
||||
GroupMemoryBarrierWithGroupSync();
|
||||
|
||||
// Gather local group histogram
|
||||
if (dispatchThreadId.x < InputSize.x && dispatchThreadId.y < InputSize.y)
|
||||
{
|
||||
uint weight = 1u;
|
||||
|
||||
// Vignette weighting to add more focus on the center of the screen
|
||||
#if 0
|
||||
{
|
||||
float2 uv = float2(dispatchThreadId.xy) / float2(InputSize.x, InputSize.y);
|
||||
float2 d = abs(uv - (0.5).xx);
|
||||
float factor = saturate(1.0 - dot(d, d));
|
||||
factor *= factor;
|
||||
weight = (uint)(64.0 * factor);
|
||||
}
|
||||
#endif
|
||||
|
||||
float3 color = Input[dispatchThreadId.xy].xyz;
|
||||
float luminance = Luminance(color);
|
||||
float logLuminance = ComputeHistogramPositionFromLuminance(luminance);
|
||||
uint idx = (uint)(saturate(logLuminance) * (HISTOGRAM_SIZE - 1u));
|
||||
InterlockedAdd(SharedHistogram[idx], weight);
|
||||
}
|
||||
|
||||
GroupMemoryBarrierWithGroupSync();
|
||||
|
||||
// Merge everything
|
||||
if (localThreadId < HISTOGRAM_SIZE)
|
||||
InterlockedAdd(HistogramBuffer[localThreadId], SharedHistogram[localThreadId]);
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user