Float data loaded from host to gpu texture gets values clipped to range [0...1]
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.
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.
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.
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.
Is it as simple as if TextureFloat1D is not None: ...?
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.
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.
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?
I think command-line.
Here's a summary of options:
- Automatic: bind texture according to GL version;
- Manual: don't bind unless explicit in command line. Something like ''clamp_float_textures".
You decide @rougier :)
Maybe manual would be the most prudent moves, else, it might break a bunch of demo. This where unit tests would be useful.