【发布时间】:2011-06-16 05:20:25
【问题描述】:
我正在编写一个着色器 (HLSL),我需要将一个颜色值打包成 R32 格式。我发现了各种将浮点数打包成 R8G8B8A8 格式的代码,但它们似乎都没有反向工作。我的目标是 SM3.0,所以(afaik)位操作不是一个选项。
总而言之,我需要能够做到这一点:
float4 color = ...; // Where color ranges from 0 -> 1
float packedValue = pack(color);
有人知道怎么做吗?
更新
我已经取得了一些的进展...也许这将有助于澄清问题。
我的临时解决方案是这样的:
const int PRECISION = 64;
float4 unpack(float value)
{
float4 color;
color.a = value % PRECISION;
value = floor(value / PRECISION);
color.b = value % PRECISION;
value = floor(value / PRECISION);
color.g = value % PRECISION;
value = floor(value / PRECISION);
color.r = value;
return color / (PRECISION - 1);
}
float pack(float4 color)
{
int4 iVal = floor(color * (PRECISION - 1));
float output = 0;
output += iVal.r * PRECISION * PRECISION * PRECISION;
output += iVal.g * PRECISION * PRECISION;
output += iVal.b * PRECISION;
output += iVal.a;
return output;
}
我基本上......假装我正在使用整数类型:s
通过猜测和检查,64 是我可以使用的最高数字,同时仍保持 [0...1] 范围。不幸的是,这也意味着我失去了一些精度 - 6 位而不是 8 位。
【问题讨论】:
-
最终会被问到的,所以你不妨把它搞定:) 为什么你必须使用 R32 而不是整数格式?
-
嘿...我知道它会来,但仍然...实际上,我使用的是R32G32B32A32,我只说R32是为了简化。我只是想弄清楚如何将尽可能多的信息推送到单个渲染目标中。当然,我仍然需要进行一些测量,但我想将我的所有数据推送到单个渲染目标中比通过 MRT 使用四个要便宜一些。
-
我期待看到人们可以为这个问题提供什么答案。
-
我知道我没有帮助回答你的问题,但我怀疑通过将所有这些工作打包到一个大的渲染目标中而不是仅仅使用 MRT 是否会有所收获。更不用说一些旧硬件(如 Xbox 360)甚至不支持 R32G32B32A32。
-
这只是一个实验。此外,我讨厌 Xbox :D