"Computed radius is NaN." Can you help me debug this issue?

First off, I’m aware that similar questions have been asked before and I have referenced them but I couldn’t find the solution for my problem in those.

What I’m trying to do is draw circle billboards using an InstancedGeometry. The code seems to be rendering fine but I am getting a pesky error in the console, stating that:

THREE.BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The “position” attribute is likely to have NaN values.

However, I can’t see how the position attribute would have NaN values. And indeed, the fact that my fragment shader is working correctly is completely dependent on my vertex shader (posted below) sending the position value to the fragment shader (via the line coord2d = position;).

Here is my code.

    renderer.setSize(window.innerWidth, window.innerHeight);
    // two triangles of a square
    const position: number[] = [ -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0];
    const geometry = new THREE.InstancedBufferGeometry();
    geometry.setAttribute(
        "position",
        new THREE.Float32BufferAttribute(position, 2).setUsage(
            THREE.StaticDrawUsage,
        ),
    );
    const material = new THREE.RawShaderMaterial({
        glslVersion: THREE.GLSL3,
        vertexShader: circlesVtxSource,
        fragmentShader: circlesFragSource,
        uniforms: {
            aspect: { value: aspect },
            radius: { value: 0.1 },
            center: { value: new THREE.Vector2(0.0, 0) },
            color: { value: new THREE.Color(1, 1, 0) },
        },
    });
    let positions = [...Array(5)].map((_) => {
        return { x: Math.random(), y: Math.random() };
    });
    let number = positions.length * 2;
    const translateArray = new Float32Array(number);
    positions.forEach((position, index) => {
        let positionIndex = index * 2;
        translateArray[positionIndex] = position.x;
        translateArray[positionIndex + 1] = position.y;
    });
    geometry.setAttribute(
        "translate",
        new THREE.InstancedBufferAttribute(translateArray, 2),
    );

and the relevant vertex shader:


in vec2 position;
in vec2 translate;

uniform float aspect;
uniform float radius;
uniform vec2 center;
uniform vec3 color;


out vec2 coord2d;
out vec3 fragColor;



void main(void){
    coord2d = position;
    gl_Position = vec4(translate + radius * coord2d, 0.0, 1.0);
    gl_Position.x /= aspect;
    fragColor = color;
}

computeBoundingSphere works on Vector3 data, while your position attribute contains coordinates of Vector2 data. My hypothesis is that because of this discrepancy, computeBoundingSphere is trying to access data beyond the end of your position data and fails.

To check whether this is the case, make your position buffer to contain 3 coordinates per vertex (set the extra coordinate to 0).

3 Likes

Thanks, Pavel! I’ll have a go at that.