【发布时间】:2018-01-07 23:17:00
【问题描述】:
内置的 Unity 着色器支持将 32 位 RGBA 值编码和解码为 32 位浮点数的技术。这可以通过简单地将每个通道与之前通道的最高可能值相乘来完成。由于它存储在浮点数中,因此预计会损失一些精度。
着色器显然有一些优化,我正在努力理解。
UnityCG.cginc 代码中的着色器如下所示:
// Encoding/decoding [0..1) floats into 8 bit/channel RGBA. Note that 1.0 will not be encoded properly.
inline float4 EncodeFloatRGBA( float v )
{
float4 kEncodeMul = float4(1.0, 255.0, 65025.0, 16581375.0);
float kEncodeBit = 1.0/255.0;
float4 enc = kEncodeMul * v;
enc = frac (enc);
enc -= enc.yzww * kEncodeBit;
return enc;
}
inline float DecodeFloatRGBA( float4 enc )
{
float4 kDecodeDot = float4(1.0, 1/255.0, 1/65025.0, 1/16581375.0);
return dot( enc, kDecodeDot );
}
所以我的问题:
- 为什么G通道乘以255而不是256(2^8=256),B通道乘以65025而不是65536(2^16=65536),A通道16581375而不是16777216(2^ 24=16777216)。
- 点积似乎与分数相乘,因此
f = R + 255 * G + 65025 * B + 16581375 * A不会给出兼容的结果。为什么选择这个?
【问题讨论】:
-
据我了解 255 * 255 = 65025,它可能会为您提供第一个问题的线索,但我不明白第二个问题:D
-
对,但是每个通道有 256 种颜色——不是 255 种。:)
-
正如我所说,我看到它乘以 255 而不是 256。 :P
-
好的,stanlo's answer here 应该可以帮助您。我猜这是因为您可以解释的 8 位最大数字是 255,因此它们的每个通道的范围从 0 到 255(总共 256 个阴影)。甚至 unity 的颜色选择器工具的范围都是 [0, 255]。
-
但在底部的同一个线程中,您可以在公式中看到使用 256 的计算,这可以正常工作,完全搞砸了我的观点:D