float-packing.ts 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. /**
  2. * Copyright (c) 2019-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
  3. *
  4. * @author Alexander Rose <alexander.rose@weirdbyte.de>
  5. */
  6. import { clamp } from '../mol-math/interpolate';
  7. import { fasterExp, fasterLog } from '../mol-math/approx';
  8. import { Vec3, Vec4 } from '../mol-math/linear-algebra';
  9. import { NumberArray } from './type-helpers';
  10. const maxFloat = 10000.0; // NOTE same constant is set in shaders
  11. const floatLogFactor = fasterLog(maxFloat + 1);
  12. /** encode float logarithmically */
  13. export function encodeFloatLog(value: number) { return fasterLog(value + 1) / floatLogFactor; }
  14. /** decode logarithmically encoded float */
  15. export function decodeFloatLog(value: number) { return fasterExp(value * floatLogFactor) - 1; }
  16. /** encode float as rgb triplet into array at offset */
  17. export function encodeFloatRGBtoArray(value: number, array: NumberArray, offset: number) {
  18. value = clamp(Math.round(value), 0, 16777216 - 1) + 1;
  19. array[offset + 2] = value % 256;
  20. value = Math.floor(value / 256);
  21. array[offset + 1] = value % 256;
  22. value = Math.floor(value / 256);
  23. array[offset] = value % 256;
  24. return array;
  25. }
  26. /** decode float encoded as rgb triplet */
  27. export function decodeFloatRGB(r: number, g: number, b: number) {
  28. return (Math.floor(r) * 256 * 256 + Math.floor(g) * 256 + Math.floor(b)) - 1;
  29. }
  30. const UnpackDownscale = 255 / 256; // 0..1 -> fraction (excluding 1)
  31. const PackFactors = Vec3.create(256 * 256 * 256, 256 * 256, 256);
  32. const UnpackFactors = Vec4.create(
  33. UnpackDownscale / PackFactors[0],
  34. UnpackDownscale / PackFactors[1],
  35. UnpackDownscale / PackFactors[2],
  36. UnpackDownscale / 1
  37. );
  38. const tmpDepthRGBA = Vec4();
  39. export function unpackRGBAToDepth(r: number, g: number, b: number, a: number) {
  40. Vec4.set(tmpDepthRGBA, r / 255, g / 255, b / 255, a / 255);
  41. return Vec4.dot(tmpDepthRGBA, UnpackFactors);
  42. }