ExtractLumaCS.hlsl 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. // RUN: %dxc -E main -T cs_6_0 %s | FileCheck %s
  2. // CHECK: threadId
  3. // CHECK: sampleLevel
  4. // CHECK: sampleLevel
  5. // CHECK: sampleLevel
  6. // CHECK: sampleLevel
  7. // CHECK: dot3
  8. // CHECK: FMax
  9. // CHECK: Log
  10. // CHECK: Round_ne
  11. // CHECK: UMin
  12. //
  13. // Copyright (c) Microsoft. All rights reserved.
  14. // This code is licensed under the MIT License (MIT).
  15. // THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
  16. // ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
  17. // IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
  18. // PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
  19. //
  20. // Developed by Minigraph
  21. //
  22. // Author: James Stanard
  23. //
  24. // The CS for extracting bright pixels and saving a log-luminance map (quantized to 8 bits). This
  25. // is then used to generate an 8-bit histogram.
  26. #include "ShaderUtility.hlsli"
  27. #include "PostEffectsRS.hlsli"
  28. SamplerState BiLinearClamp : register( s0 );
  29. Texture2D<float3> SourceTex : register( t0 );
  30. RWTexture2D<uint> LumaResult : register( u0 );
  31. cbuffer cb0
  32. {
  33. float2 g_inverseOutputSize;
  34. }
  35. [RootSignature(PostEffects_RootSig)]
  36. [numthreads( 8, 8, 1 )]
  37. void main( uint3 DTid : SV_DispatchThreadID )
  38. {
  39. // We need the scale factor and the size of one pixel so that our four samples are right in the middle
  40. // of the quadrant they are covering.
  41. float2 uv = DTid.xy * g_inverseOutputSize;
  42. float2 offset = g_inverseOutputSize * 0.25f;
  43. // Use 4 bilinear samples to guarantee we don't undersample when downsizing by more than 2x
  44. float3 color1 = SourceTex.SampleLevel( BiLinearClamp, uv + float2(-offset.x, -offset.y), 0 );
  45. float3 color2 = SourceTex.SampleLevel( BiLinearClamp, uv + float2( offset.x, -offset.y), 0 );
  46. float3 color3 = SourceTex.SampleLevel( BiLinearClamp, uv + float2(-offset.x, offset.y), 0 );
  47. float3 color4 = SourceTex.SampleLevel( BiLinearClamp, uv + float2( offset.x, offset.y), 0 );
  48. // Compute average luminance
  49. float luma = RGBToLuminance(color1 + color2 + color3 + color4) * 0.25;
  50. // Logarithmically compress the range [2^-12, 2^4) to [0, 255]
  51. float logLuma = log2( max(1.0 / 4096.0, luma) ) + 12.0;
  52. uint quantizedLog = min(255, (uint)round(logLuma * 16.0));
  53. // Store result
  54. LumaResult[DTid.xy] = quantizedLog;
  55. }