glumpy icon indicating copy to clipboard operation
glumpy copied to clipboard

Float data loaded from host to gpu texture gets values clipped to range [0...1]

Open jstreibel opened this issue 4 years ago • 9 comments

This behavior is OpenGL default (to clamp floats uploaded to texture). I just though since Glumpy is used for scientific visualization, it would be common for people to upload float data to texture in range beyond [0...1]. Especially because classes named TextureFloat*D which solve this are implemented already.

The I found was to change a line in file variable.py (in gloo), in the method set_data of class Uniform, lines 226 and 227.

The line changed was

    (...)
                if data.dtype in [np.float16, np.float32, np.float64]:
                    self._data = data.astype(np.float32).view(Texture1D)

and became

    (...)
                if data.dtype in [np.float16, np.float32, np.float64]:
                    self._data = data.astype(np.float32).view(TextureFloat1D)

EDIT: if its the case to make this change or somehow allow for the user to choose whether to clamp values, then changes to the Texture2D case should also be implemented.

jstreibel avatar Jun 21 '21 03:06 jstreibel

Thanks for the report. Glumpy is trying to stick to Open GL ES 2.0 (which is quite old now) that does not offer natively float texture and this is the reason I'm using Texture1D only. But I agree it would make sense to have an option to use float texure. Not sure on the best way to do that.

rougier avatar Jun 21 '21 11:06 rougier

No worries.

In terms of user interface my guess is that the simplest way is to have in gloo.Program.__init__ an option to clamp_texture_float_values or similar. __init__ would then pass this information to gloo.Program._build_uniforms, which then would setup the uniforms accordingly. In this case, class Uniform should keep track on whether to use Texture1D or TextureFloat1D for float arrays.

jstreibel avatar Jun 21 '21 15:06 jstreibel

Or we can check if TextureFloat1D / TextureFloat2D are bounded (i..e not equal to None) and use them when available. If you use the default configuration, they shoudl be equal to None but if you specify a GL 3.2 context, that should work.

rougier avatar Jun 29 '21 08:06 rougier

Is it as simple as if TextureFloat1D is not None: ...?

jstreibel avatar Jul 06 '21 15:07 jstreibel

Maybe even more simpler: Texture1D = TextureFloat1D or Texture1D. But the question is whether this would break things, i.e. shaders that assume implicitely that values are bound between 0 and 1.

rougier avatar Jul 12 '21 12:07 rougier

It would likely break something somewhere. Also, it could be counter intuitive to have different behavior for different GL context version. Say you make a program with default GL context then at some point move to a newer version. In this case, (my opinion is that) the least different everything looks and behaves, the better.

OTOH I particularly use them unclamped 99% of time.

Design-wise: because it's already been running clamped, I suggest make it optional (where compatible) and clamped by default.

jstreibel avatar Jul 12 '21 21:07 jstreibel

Sorry for the delay. I think you're right and I don't see an automatic solution. Question is then how to offer the option for unbounded texture. Maybe a command line argument?

rougier avatar Jul 26 '21 08:07 rougier

I think command-line.

Here's a summary of options:

  1. Automatic: bind texture according to GL version;
  2. Manual: don't bind unless explicit in command line. Something like ''clamp_float_textures".

You decide @rougier :)

jstreibel avatar Jul 27 '21 19:07 jstreibel

Maybe manual would be the most prudent moves, else, it might break a bunch of demo. This where unit tests would be useful.

rougier avatar Aug 19 '21 07:08 rougier