シェーダについて学んでいると、テクスチャに色以外のデータを保持する必要が出てくるケースが多々ある。
そんなとき目にするのが、通常のfloatの値を8bitのRGBAそれぞれに格納する、という方法。
こちらの記事の計算を参考に、JSに書き直してみました。
(実際に動くサンプルをjsdo.itに上げてあります)
function floatToInt(floatValue) {
var toFixed = 255.0 / 256;
return {
r: frac(floatValue * toFixed * 1),
g: frac(floatValue * toFixed * 255),
b: frac(floatValue * toFixed * 255 * 255),
a: frac(floatValue * toFixed * 255 * 255 * 255)
};
}
function intToFloat(intValue) {
var fromFixed = 256.0 / 255;
return (intValue.r * fromFixed / (1)
+ intValue.g * fromFixed / (255)
+ intValue.b * fromFixed / (255 * 255)
+ intValue.a * fromFixed / (255 * 255 * 255));
}
function frac(x) {
return x - Math.floor(x);
// Instead you can use below.
// return x % 1;
}
toFixed
は固定小数点の精度に変換するための計算を事前に行っているところ。
(しっかりとした理由はまだ理解しきれていないのだけど・・・)
要は、この「固定小数点」へ変換する処理を行い、RGBAそれぞれの成分に保存している、ということだと思う。
変換と復元はやっている処理を逆転しているだけ。
ちなみに、この処理は0.0〜1.0
の間の数値を想定している。
シェーダでは-1.0〜1.0
の間で数値がやりとりされ、特に色などは0.0〜1.0
の間での計算となるため、シェーダで使われる手法なんだと思います。