Using NaN in attributes

Hi all!
There was a question on SO:
https://stackoverflow.com/q/48960680/4045502
The author came up with using NaN values in an attribute for positions.
Is it a good practice to use NaN in attributes?
Specifically for that case with lines in one geometry I used a custom attribute for visibility + THREE.ShaderMaterial() and discard on visibility condition in the fragment shader.

https://jsfiddle.net/prisoner849/51swmaLy/

Geometry_of_lines

No, you should avoid NaN values. The problem is that typed arrays handled NaN values differently. If you pass a NaN value to a Uint8Array(), it is interpreted as 0. If you do the same test with Float32Array, the NaN value is preserved and passed to the shader.

see Edit fiddle - JSFiddle - Code Playground

Besides, NaN values in attributes like position will break certain three.js features like view frustum culling since the engine expects valid numerical data.

1 Like

Since the beginning, that idea with NaN seemed doubtful for me :slight_smile:
Thanks for explanation :beers:

The frustrum culling and similar features should disregard NaN values instead of failing on them. NaN values are valid OpenGL according to spec, used for this very purpose.

1 Like

NaN values are valid OpenGL according to spec

We’re using WebGL. The spec may be different. But more importantly, we’re feeding WebGL data using JavaScript and must deal with the peculiarities of that language along the way.

Well, of course, NaN is a floating point value. It can’t be represented by a Uint8. That behavior could be surprising for some users, though. On the other hand, using non-float typed arrays in THREE is a bit advanced, so anyone that would run into this behavior would also be likely to understand what NaN is.

My two cents is that this approach is perfectly fine and that I agree with @jadware that THREE should be more forgiving of NaN (if possible without adding a lot of complexity). The workaround in the answer is also interesting.

Here is another approach.
No NaNs, no shaders. Just THREE.LineSegments() with a single indexed THREE.BufferGeometry():
https://jsfiddle.net/prisoner849/1j131tnt/
Single_geometry_of_curves_wo_NaNs

For the reference:
https://threejs.org/examples/?q=line#webgl_buffergeometry_lines_indexed