kya*_*bal 4 opengl-es webgl glsles
这个问题与这里的问题非常相关(如何将vec4 rgba值转换为浮点数?).
已经有一些与此问题相关的文章或问题,但我想知道大多数文章都没有确定哪种类型的浮动值.只要我能想到,下面有一些浮动值包装/拆包公式.
然而,实际上这只是两个案例.其他包装/拆包可以通过这两种方法处理.
我想将已签名的浮动值打包并解压缩到vec3或vec2中.
对于我的情况,浮动值不能确保标准化,所以我不能使用简单的位移方式.
如果您知道要存储的最大值范围,比如说+5到-5,那么最简单的方法就是选择一些转换范围为0到1的值.将它扩展为您拥有的位数和然后把它分成几部分.
vec2 packFloatInto8BitVec2(float v, float min, float max) {
float zeroToOne = (v - min) / (max - min);
float zeroTo16Bit = zeroToOne * 256.0 * 255.0;
return vec2(mod(zeroToOne, 256.0), zeroToOne / 256.0);
}
Run Code Online (Sandbox Code Playgroud)
要把它放回去,你会做相反的事情.组装零件,除以返回零到一个值,然后按范围扩展.
float unpack8BitVec2IntoFloat(vec2 v, float min, float max) {
float zeroTo16Bit = v.x + v.y * 256.0;
float zeroToOne = zeroTo16Bit / 256.0 / 255.0;
return zeroToOne * (max - min) + min;
}
Run Code Online (Sandbox Code Playgroud)
对于vec3,只需扩展它
vec3 packFloatInto8BitVec3(float v, float min, float max) {
float zeroToOne = (v - min) / (max - min);
float zeroTo24Bit = zeroToOne * 256.0 * 256.0 * 255.0;
return vec3(mod(zeroToOne, 256.0), mod(zeroToOne / 256.0, 256.0), zeroToOne / 256.0 / 256.0);
}
float unpack8BitVec3IntoFloat(vec3 v, float min, float max) {
float zeroTo24Bit = v.x + v.y * 256.0 + v.z * 256.0 * 256.0;
float zeroToOne = zeroTo24Bit / 256.0 / 256.0 / 256.0;
return zeroToOne * (max - min) + min;
}
Run Code Online (Sandbox Code Playgroud)
几天前我用 shadertoy 写了一个小例子:https ://www.shadertoy.com/view/XdK3Dh
它将浮点数存储为 RGB 或从像素加载浮点数。还有一个测试函数是精确的逆函数(我见过的许多其他函数由于精度差而在某些范围内存在错误)。
整个示例假设您想将值保存在缓冲区中并在下一次绘制时将其读回。只有 256 种颜色,它限制您获得 16777216 个不同的值。大多数时候我不需要更大的规模。我还将它转移到在区间 <-8388608;8388608> 中插入的签名浮点数。
float color2float(in vec3 c) {
c *= 255.;
c = floor(c); // without this value could be shifted for some intervals
return c.r*256.*256. + c.g*256. + c.b - 8388608.;
}
// values out of <-8388608;8388608> are stored as min/max values
vec3 float2color(in float val) {
val += 8388608.; // this makes values signed
if(val < 0.) {
return vec3(0.);
}
if(val > 16777216.) {
return vec3(1.);
}
vec3 c = vec3(0.);
c.b = mod(val, 256.);
val = floor(val/256.);
c.g = mod(val, 256.);
val = floor(val/256.);
c.r = mod(val, 256.);
return c/255.;
}
Run Code Online (Sandbox Code Playgroud)
还有一件事,溢出的值将四舍五入为最小值/最大值。
归档时间: |
|
查看次数: |
4622 次 |
最近记录: |