Added RGBM encoding in GTC_packing #420

This commit is contained in:
Christophe Riccio 2016-10-16 16:40:49 +02:00
parent 9d4f0ba758
commit e4c559b29b
4 changed files with 61 additions and 2 deletions

View File

@ -451,6 +451,8 @@ namespace glm
/// The first vector component specifies the 11 least-significant bits of the result;
/// the last component specifies the 10 most-significant bits.
///
/// packF3x9_E1x5 allows encoding into RGBE / RGB9E5 format
///
/// @see gtc_packing
/// @see vec3 unpackF3x9_E1x5(uint32 const & p)
GLM_FUNC_DECL uint32 packF3x9_E1x5(vec3 const & v);
@ -460,11 +462,34 @@ namespace glm
///
/// The first component of the returned vector will be extracted from the least significant bits of the input;
/// the last component will be extracted from the most significant bits.
///
///
/// unpackF3x9_E1x5 allows decoding RGBE / RGB9E5 data
///
/// @see gtc_packing
/// @see uint32 packF3x9_E1x5(vec3 const & v)
GLM_FUNC_DECL vec3 unpackF3x9_E1x5(uint32 p);
/// Returns an unsigned integer vector obtained by converting the components of a floating-point vector
/// to the 16-bit floating-point representation found in the OpenGL Specification.
/// The first vector component specifies the 16 least-significant bits of the result;
/// the forth component specifies the 16 most-significant bits.
///
/// @see gtc_packing
/// @see tvec3<T, P> unpackRGBM(tvec4<T, P> const & p)
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions</a>
template <typename T, precision P>
GLM_FUNC_DECL tvec4<T, P> packRGBM(tvec3<T, P> const & rgb);
/// Returns a floating-point vector with components obtained by reinterpreting an integer vector as 16-bit floating-point numbers and converting them to 32-bit floating-point values.
/// The first component of the vector is obtained from the 16 least-significant bits of v;
/// the forth component is obtained from the 16 most-significant bits of v.
///
/// @see gtc_packing
/// @see tvec4<T, P> packRGBM(tvec3<float, P> const & v)
/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions</a>
template <typename T, precision P>
GLM_FUNC_DECL tvec3<T, P> unpackRGBM(tvec4<T, P> const & rgbm);
/// Returns an unsigned integer vector obtained by converting the components of a floating-point vector
/// to the 16-bit floating-point representation found in the OpenGL Specification.
/// The first vector component specifies the 16 least-significant bits of the result;

View File

@ -639,6 +639,22 @@ namespace detail
return vec3(Unpack.data.x, Unpack.data.y, Unpack.data.z) * pow(2.0f, Unpack.data.w - 15.f - 9.f);
}
// From http://graphicrants.blogspot.fr/2009/04/rgbm-color-encoding.html
template <typename T, precision P>
GLM_FUNC_QUALIFIER tvec4<T, P> packRGBM(tvec3<T, P> const & rgb)
{
tvec3<T, P> const Color(rgb * static_cast<T>(1.0 / 6.0));
T Alpha = clamp(max(max(Color.x, Color.y), max(Color.z, static_cast<T>(1e-6))), static_cast<T>(0), static_cast<T>(1));
Alpha = ceil(Alpha * static_cast<T>(255.0)) / static_cast<T>(255.0);
return tvec4<T, P>(Color / Alpha, Alpha);
}
template <typename T, precision P>
GLM_FUNC_QUALIFIER tvec3<T, P> unpackRGBM(tvec4<T, P> const & rgbm)
{
return tvec3<T, P>(rgbm.x, rgbm.y, rgbm.z) * rgbm.w * static_cast<T>(6);
}
template <precision P, template <typename, precision> class vecType>
GLM_FUNC_QUALIFIER vecType<uint16, P> packHalf(vecType<float, P> const & v)
{

View File

@ -53,6 +53,7 @@ glm::mat4 camera(float Translate, glm::vec2 const & Rotate)
#### [GLM 0.9.9.0](https://github.com/g-truc/glm/releases/latest) - 2017-XX-XX
##### Features:
- Added RGBM encoding in GTC_packing #420
- Added GTC_color_encoding extension
##### Improvements:

View File

@ -239,7 +239,7 @@ int test_F3x9_E1x5()
Tests.push_back(glm::vec3(0.5f));
Tests.push_back(glm::vec3(0.9f));
for (std::size_t i = 0; i < Tests.size(); ++i)
for(std::size_t i = 0; i < Tests.size(); ++i)
{
glm::uint32 p0 = glm::packF3x9_E1x5(Tests[i]);
glm::vec3 v0 = glm::unpackF3x9_E1x5(p0);
@ -251,6 +251,22 @@ int test_F3x9_E1x5()
return Error;
}
int test_RGBM()
{
int Error = 0;
for(std::size_t i = 0; i < 1024; ++i)
{
glm::vec3 const Color(i);
glm::vec4 const RGBM = glm::packRGBM(Color);
glm::vec3 const Result= glm::unpackRGBM(RGBM);
Error += glm::all(glm::epsilonEqual(Color, Result, 0.01f)) ? 0 : 1;
}
return Error;
}
int test_packUnorm1x16()
{
int Error = 0;
@ -671,6 +687,7 @@ int main()
Error += test_F2x11_1x10();
Error += test_F3x9_E1x5();
Error += test_RGBM();
Error += test_Snorm3x10_1x2();
Error += test_Unorm3x10_1x2();
Error += test_I3x10_1x2();