mirror of
https://github.com/id-Software/DOOM-3-BFG.git
synced 2025-04-24 10:38:53 +00:00
Implemented binary search for colors in HLSL
This commit is contained in:
parent
9e88365c59
commit
a589f3e6f0
1 changed files with 69 additions and 13 deletions
|
@ -50,22 +50,12 @@ struct PS_OUT
|
|||
// *INDENT-ON*
|
||||
|
||||
|
||||
float3 BlueNoise3( float2 n, float x )
|
||||
{
|
||||
float2 uv = n.xy * rpJitterTexOffset.xy;
|
||||
|
||||
float3 noise = t_BlueNoise.Sample( samp1, uv ).rgb;
|
||||
|
||||
noise = frac( noise + c_goldenRatioConjugate * rpJitterTexOffset.w * x );
|
||||
|
||||
return noise;
|
||||
}
|
||||
|
||||
#define RESOLUTION_DIVISOR 4.0
|
||||
#define NUM_COLORS 16
|
||||
|
||||
|
||||
// find nearest palette color using Euclidean distance
|
||||
float4 EuclidDist( float3 c, float3 pal[NUM_COLORS] )
|
||||
float4 LinearSearch( float3 c, float3 pal[NUM_COLORS] )
|
||||
{
|
||||
int idx = 0;
|
||||
float nd = distance( c, pal[0] );
|
||||
|
@ -84,6 +74,71 @@ float4 EuclidDist( float3 c, float3 pal[NUM_COLORS] )
|
|||
return float4( pal[idx], 1.0 );
|
||||
}
|
||||
|
||||
float3 GetClosest( float3 val1, float3 val2, float3 target )
|
||||
{
|
||||
if( distance( target, val1 ) >= distance( val2, target ) )
|
||||
{
|
||||
return val2;
|
||||
}
|
||||
else
|
||||
{
|
||||
return val1;
|
||||
}
|
||||
}
|
||||
|
||||
// find nearest palette color using Euclidean disntance and binary search
|
||||
// this requires an already sorted palette as input
|
||||
float3 BinarySearch( float3 target, float3 pal[NUM_COLORS] )
|
||||
{
|
||||
float targetY = PhotoLuma( target );
|
||||
|
||||
// left-side case
|
||||
if( targetY <= PhotoLuma( pal[0] ) )
|
||||
{
|
||||
return pal[0];
|
||||
}
|
||||
|
||||
// right-side case
|
||||
if( targetY >= PhotoLuma( pal[NUM_COLORS - 1] ) )
|
||||
{
|
||||
return pal[NUM_COLORS - 1];
|
||||
}
|
||||
|
||||
int i = 0, j = NUM_COLORS, mid = 0;
|
||||
while( i < j )
|
||||
{
|
||||
mid = ( i + j ) / 2;
|
||||
|
||||
if( distance( pal[mid], target ) < 0.01 )
|
||||
{
|
||||
return pal[mid];
|
||||
}
|
||||
|
||||
// if target is less than array element, then search in left
|
||||
if( targetY < PhotoLuma( pal[mid] ) )
|
||||
{
|
||||
// if target is greater than previous
|
||||
// to mid, return closest of two
|
||||
if( mid > 0 && targetY > PhotoLuma( pal[mid - 1] ) )
|
||||
{
|
||||
return GetClosest( pal[mid - 1], pal[mid], target );
|
||||
}
|
||||
j = mid;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( mid < ( NUM_COLORS - 1 ) && targetY < PhotoLuma( pal[mid + 1] ) )
|
||||
{
|
||||
return GetClosest( pal[mid], pal[mid + 1], target );
|
||||
}
|
||||
i = mid + 1;
|
||||
}
|
||||
}
|
||||
|
||||
// only single element left after search
|
||||
return pal[mid];
|
||||
}
|
||||
|
||||
|
||||
#define RGB(r, g, b) float3(float(r)/255.0, float(g)/255.0, float(b)/255.0)
|
||||
|
||||
|
@ -151,7 +206,8 @@ void main( PS_IN fragment, out PS_OUT result )
|
|||
#endif
|
||||
|
||||
// find closest color match from C64 color palette
|
||||
color = EuclidDist( color.rgb, palette );
|
||||
color = LinearSearch( color.rgb, palette );
|
||||
//color = float4( BinarySearch( color.rgb, palette ), 1.0 );
|
||||
|
||||
result.color = color;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue