Add utility Packing.hlsl shader for colors and vectors packing
This commit is contained in:
68
Source/Shaders/Packing.hlsl
Normal file
68
Source/Shaders/Packing.hlsl
Normal file
@@ -0,0 +1,68 @@
|
||||
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
|
||||
|
||||
#ifndef __PACKING__
|
||||
#define __PACKING__
|
||||
|
||||
// https://github.com/turanszkij/WickedEngine/blob/4a6171fdd584fcf9d41045e6dd2a13c03fa2e4d9/WickedEngine/shaders/globals.hlsli#L1103-L1118
|
||||
inline uint PackUnitVector(in float3 value)
|
||||
{
|
||||
uint result = 0;
|
||||
result |= (uint)((value.x * 0.5 + 0.5) * 255.0) << 0u;
|
||||
result |= (uint)((value.y * 0.5 + 0.5) * 255.0) << 8u;
|
||||
result |= (uint)((value.z * 0.5 + 0.5) * 255.0) << 16u;
|
||||
return result;
|
||||
}
|
||||
inline float3 UnpackUnitVector(in uint value)
|
||||
{
|
||||
float3 result;
|
||||
result.x = (float)((value >> 0u) & 0xFF) / 255.0 * 2 - 1;
|
||||
result.y = (float)((value >> 8u) & 0xFF) / 255.0 * 2 - 1;
|
||||
result.z = (float)((value >> 16u) & 0xFF) / 255.0 * 2 - 1;
|
||||
return result;
|
||||
}
|
||||
|
||||
// https://github.com/turanszkij/WickedEngine/blob/4a6171fdd584fcf9d41045e6dd2a13c03fa2e4d9/WickedEngine/shaders/PixelPacking_RGBE.hlsli
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
|
||||
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
|
||||
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
|
||||
// Developed by Minigraph
|
||||
// Author: James Stanard
|
||||
// RGBE, aka R9G9B9E5_SHAREDEXP, is an unsigned float HDR pixel format where red, green,
|
||||
// and blue all share the same exponent. The color channels store a 9-bit value ranging
|
||||
// from [0/512, 511/512] which multiplies by 2^Exp and Exp ranges from [-15, 16].
|
||||
// Floating point specials are not encoded.
|
||||
uint PackRGBE(float3 rgb)
|
||||
{
|
||||
// To determine the shared exponent, we must clamp the channels to an expressible range
|
||||
const float kMaxVal = asfloat(0x477F8000); // 1.FF x 2^+15
|
||||
const float kMinVal = asfloat(0x37800000); // 1.00 x 2^-16
|
||||
|
||||
// Non-negative and <= kMaxVal
|
||||
rgb = clamp(rgb, 0, kMaxVal);
|
||||
|
||||
// From the maximum channel we will determine the exponent. We clamp to a min value
|
||||
// so that the exponent is within the valid 5-bit range.
|
||||
float MaxChannel = max(max(kMinVal, rgb.r), max(rgb.g, rgb.b));
|
||||
|
||||
// 'Bias' has to have the biggest exponent plus 15 (and nothing in the mantissa). When
|
||||
// added to the three channels, it shifts the explicit '1' and the 8 most significant
|
||||
// mantissa bits into the low 9 bits. IEEE rules of float addition will round rather
|
||||
// than truncate the discarded bits. Channels with smaller natural exponents will be
|
||||
// shifted further to the right (discarding more bits).
|
||||
float Bias = asfloat((asuint(MaxChannel) + 0x07804000) & 0x7F800000);
|
||||
|
||||
// Shift bits into the right places
|
||||
uint3 RGB = asuint(rgb + Bias);
|
||||
uint E = (asuint(Bias) << 4) + 0x10000000;
|
||||
return E | RGB.b << 18 | RGB.g << 9 | (RGB.r & 0x1FF);
|
||||
}
|
||||
float3 UnpackRGBE(uint p)
|
||||
{
|
||||
float3 rgb = uint3(p, p >> 9, p >> 18) & 0x1FF;
|
||||
return ldexp(rgb, (int)(p >> 27) - 24);
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user