Webgl passing a big Int32 uniform is difficult
See original GitHub issueIs your feature request related to a problem? Please describe. I’m trying to pass a big Uint32 as uniform. The max value of that int can be a 9-digit number. It is used in my case to compare a specific id to the id of the geometry object currently being rendered.
The problem is that an uniform can only be a float32 (or a vector of float, which is not of interest here) Float can have at most a 7-digit precision or up to 2^23. So trying to pass a 9-digit number to my shaders failed for my use case.
As an alternative, I tried to trick that limitation by passing my integer as a Float32, relying on the underlying bits. In the uniform callback, it looks like that:
const focusArrayBuffer = new ArrayBuffer(Float32Array.BYTES_PER_ELEMENT);
const selectedFeature = new DataView(focusArrayBuffer);
selectedFeature.setInt32(0, someInt32Value);
const uniforms = {
u_selectedId: function(framestate){
return selectedFeature.getFloat32(0);
}
}
I thought I had it, until I tested a default value of 0. And unfortunately, a few other geometry with non-zero ids reacted to that.
In particular the values 2339002
or 2339006
. Despite the fact that:
b = new ArrayBuffer(Float32Array.BYTES_PER_ELEMENT);
v = new DataView(b,0);
v.setUint32(0,2339002)
v.getFloat32(0) // output: 3.277639910652676e-39
v.setUint32(0,2339006)
v.getFloat32(0) // output: 3.277645515846533e-39
The output here are different from 0 or from each other but they seem to be passed with the same value to the shaders.
And the precision in the shaders are precision highp float
for both of them.
So I don’t get why that failed to pass the proper value to the shaders…
Describe the solution you’d like Being able to pass a int32 instead of a float would be much simpler here.
Issue Analytics
- State:
- Created 3 years ago
- Comments:5 (2 by maintainers)
Top GitHub Comments
Well in theory, I think I should be able to trick it. After all, a float32 is just 32 bits in memory. If
3.277639910652676e-39
is different from2339002
, they both have the same binary representation. So that’s what I’m trying to do here, passing a float32 to the shaders that have the same binary representation as a big int32.My end goal is to represent around 100 000 vectors in Openlayers. That is fairly lower than 2^23. However, those 100 000 vectors might get reloaded periodically and
2^23 / 100000 = 83.89...
Which means I can have at most 83 reloads before hitting the float limit and entering the bug zone. So usingol_uid
won’t work for me here and I need to use my own smaller identifier I guess.Considering the use case above, there might be a (very) rare bug in the hit detection once the 2^23 id is reached.
Au passage: salut de la part d’un autre Olivier Guyot 😉
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.