等效于此 GLSL 函数的 C++

C++ equivalent to this GLSL functions

有人能告诉我这两个 GLSL 函数的 Cpp 等价物是什么吗? (首选组件明智的解决方案)。

vec4 pack( float v ) {
  vec4 enc = vec4(1.0, 255.0, 65025.0, 160581375.0) * v;
  enc = fract(enc);
  enc -= enc.yzww * vec4(1.0/255.0,1.0/255.0,1.0/255.0,0.0);
  return enc;
}


float unpack( vec4 rgba ) {
  return dot( rgba, vec4(1.0, 1/255.0, 1/65025.0, 1/160581375.0) );
}

来源:Source of the code above

如果您知道所有内置函数的工作原理,这真的不难。 fract (...) returns 浮点数的小数部分和点积只是乘积的分量和。

唯一不寻常的是 yzww 调配,但这很容易实现:

// C++ offers `modf (...)`, which does the same thing, but this is simpler.
float fract (float f) {
  return f-(long)f;
}

void pack (float v, float* enc) {
  enc [0] = fract (1.0f         * v);
  enc [1] = fract (255.0f       * v);
  enc [2] = fract (65025.0f     * v);
  enc [3] = fract (160581375.0f * v);

  enc [0] -= enc [1] * 1.0f/255.0f;
  enc [1] -= enc [2] * 1.0f/255.0f;
  enc [2] -= enc [3] * 1.0f/255.0f;

  return enc;
}

float unpack (const float* rgba) {
  float dot = rgba [0] * 1.0f               +  rgba [1] * (1.0f / 255.0f)  +
              rgba [2] * (1.0f / 65025.0f)  +  rgba [3] * (1.0f / 160581375.0f);
  return dot;
}

我冒昧地更改 pack (...) 以接受一个存储结果的数组,而不是 return 在堆栈上创建一个数组。这是 C 语言中更常见的做法,但如果你有一些 C++ class 用于存储 4D 向量,你可以 return 一个它的实例。

如果您使用 GLM 模板库,所有这些都可以变得更加简单。它在 C++ 中尽可能地反映了 GLSL 的类型和运算符。