0

I have encoded floats into a texture (4 bytes of a float32 are stored as RBGA values). Now I need to decode them back into a single float.

Here's what I've tried so far and what didn't work for me:

    float rgbaToFloat(vec4 rgba) {
      uint r = uint(rgba.x*255.);
      uint g = uint(rgba.y*255.);
      uint b = uint(rgba.z*255.);
      uint a = uint(rgba.w*255.);

      return uintBitsToFloat((r << 24) | (g << 16) | (b << 8) | a);
    }

I pack floats into a texture image using the following snippet (python):

import numpy as np

data_flat = [...]  #floats

dim = int(np.sqrt(len(data_flat))) + 1
image = np.zeros((dim, dim, 4), dtype='uint8')
for i, d in enumerate(data_flat):
    image[i // dim, i % dim] = np.array([d], dtype=np.float32).view(np.uint8)

For a single floating-point value, it produces the following output:

d = 0.06797099858522415;
np.array([d], dtype=np.float32).view(np.uint8)
>>> array([ 97,  52, 139,  61], dtype=uint8)

Which seems to be correct, as binary representations match.

It seems to return overflowed values, hard to say, with the only debug way being comparing pictures, but it's certainly not what I expect it to output.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
Vladislav
  • 1,811
  • 1
  • 8
  • 10
  • 3
    Which code do you use to pack the float into the image? Also, wouldn't it be way easier to use a floating point texture? – BDL Jan 28 '20 at 12:59
  • 2
    note a 32-bit float can't represent all 32-bit integer values, it has only 24 bits of mantissa – moonshadow Jan 28 '20 at 13:00
  • @BDL, thank you for the fast reply! I convert uint8 into float32 using python, here's a snippet: `data_flat = [...]` `dim = int(np.sqrt(len(data_flat))) + 1` `image = np.zeros((dim, dim, 4), dtype='uint8')` `for i, d in enumerate(data_flat):` `image[i // dim, i % dim] = np.array([d], dtype=np.float32).view(np.uint8)` I'm not sure it's possible to use floating point texture on shadertoy (that's a requirement) if there's a way, I would appreciate you sharing it. – Vladislav Jan 28 '20 at 13:03
  • @moonshadow thank's for the reply! I'm not trying to represent 32-bit integers using 32-bit floats. What I am trying to do is pack a single float32 into 4 uint8 using python (successfully) and then unpack it back into float32 in glsl. – Vladislav Jan 28 '20 at 13:07
  • 3
    Why don't you just directly use floats in GLSL? – user253751 Jan 28 '20 at 13:12
  • @BDL I've updated the answer with code I use to convert floats into chars, for better readability. – Vladislav Jan 28 '20 at 13:12
  • @user253751 I need to use some kind of an asset, to load the data (it's too large to write it directly into the shader). The only way to do it in shadertoy seems to be via texture. I don't know if using floating point textures is possible there, though. If you can advise a way to do it, I'd be grateful. – Vladislav Jan 28 '20 at 13:14
  • I'm not sure what you're trying to do, but [this answer](https://stackoverflow.com/a/38039733/673852) seems relevant. – Ruslan Jan 28 '20 at 13:16
  • if what you want is a texture with four integer channels, why don't you just declare your texture as four GL_UNSIGNED_BYTE channels and write out the vec4 directly without any of the weird conversions? – moonshadow Jan 28 '20 at 13:36
  • @moonshadow, sorry, I'm not really fluent yet in OpenGL, would you please tell me how to do it exactly? – Vladislav Jan 28 '20 at 13:40
  • 2
    @Vladislav In shadertoy? I have no idea. Do you have to use shadertoy though? OpenGL itself supports single-channel float textures just fine. – user253751 Jan 28 '20 at 14:18
  • I'm confused. you show python so is this a WebGL quesiton or an OpenGL question? Python doesn't normally work with WebGL AFAIK. – gman Jan 28 '20 at 16:07
  • @gman I use python only to create texture. Then I export it and import into shader toy. – Vladislav Jan 28 '20 at 16:09
  • 1
    Maybe this is what you need: https://stackoverflow.com/questions/18453302/how-do-you-pack-one-32bit-int-into-4-8bit-ints-in-glsl-webgl/18454838#18454838 – LJᛃ Jan 29 '20 at 13:09
  • @LJᛃ thank's a lot, that works like magic! – Vladislav Jan 29 '20 at 17:45

1 Answers1

0

Thanks to @LJᛃ for referring me to this answer, it works like charm.

Vladislav
  • 1,811
  • 1
  • 8
  • 10