Are 2d position attributes supported in three.js?
We have very old inherited code that uses them, which used to work cleanly but now reports an error.
The failure reports itself as
THREE.BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The “position” attribute is likely to have NaN values.
The code still works as the later tests against the NaN values have appropriate results.
The reason behind the error is that Vector3.fromBufferAttribute() and attribute.getZ() assume the (position) attribute given has itemWidth at least 3.
If 2d attributes are not supported it will be fairly easy for us to correct.
It would be helpful in that case if the documentation was clearer, and the error reporting was more timely;
eg at setAttribute, and/or in attribute.getZ.
The library is called “Three”, the core class is called Object"3D". I think it’s perfectly clear.
You can always
Object3D as a 2D object by just ignoring the
z axis, keeping it at 0, or treating it like a sort of CSS
z-index —that’s a trick many 3D engines use. But I wouldn’t mess with the
position attribute too much. There’s a bunch of internal stuff assuming it’s dealing with three axes, and things like
computeBoundingBox are just the tip of the iceberg. It gets messy if you start tweaking the basic setup.
In addition to what fennec said…
You can probably simply bind your 2d position attribute to a different channel, for instance “position2d” or something, leaving the main 3d position channel full of zeroes… then handle in the shader how you want to derive the correct data you need.
Thank you both for the replies.
I’ve arranged to convert the 2d attributes to 3d as needed. That was easier than trying to fix the very old inherited underlying code that generated the 2d positions in the first place.
A second all zeros position attribute wouldn’t help. It wasn’t the shader code that failed; the shader was creating the correct result. It was the three.js use of bounding sphere for culling and ray hits; that depends on a properly populated 3d position attribute.
Given how much three.js relies on the position attribute it would be good if setAttribute checked for an inappropriate attribute buffer. It would mean special case code in setAttribute, but the position attribute is already a very special case. On the other hand, I know three doesn’t want to bloat itself too much with argument and other user error checking; though it does have the attribute is likely to have NaN values checks
aside: we’ve had problems before with three.js demanding a position attribute where it wasn’t needed for procedural geometry shaders. We’ve had a workaround, but I should check if that is now resolved within three.js itself.
Ahh yeah that all makes sense and sounds like the way to go. I forgot about hte bounding box computation. Glad you figured it out.
Alternative could be to extend the class
THREE.BufferGeometry overwriting the methods that cause you issues. This avoids wasting memory with 0-es.
True. In our particular case the buffers are pretty small with around 30 items, so the extra 0’s don’t matter too much. The extra code would be larger than the extra 0’s, though of course my existing workaround is also taking code space to generate those extra 0’s as well.