Fat Lines: Setting geometry data does not work

Hi! it’s my first question, for my first project with three.js, i hope it’s not too simple, i already researched but with no success.
So i’m creating a Line2 because i need to control the fatness, so i followed this example (https://threejs.org/examples/?q=line#webgl_lines_fat) and it was working.

But then i saw that i also need to update the points of my geometry, so made some modifications following this example: https://threejs.org/docs/index.html#manual/en/introduction/How-to-update-things

And now my mesh it’s not showing anymore, here is a relevant code, i’m inside a vue component, so it has some different syntax.

//mounted()
this.arcGeometry1 = new LineGeometry()
// set maximum size for buffer of LineGeometry,
var positions = new Float32Array( MAX_POINTS * 3 ); // 3 vertices per point
this.arcGeometry1.setAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) ); //  the number of values of the array, not drawRange
this.matLine2 = new LineMaterial({
color: 0x000000,
linewidth: 3,
dashed: false
});
this.matLine2.resolution.set(( this.container.clientWidth, this.container.clientHeight ))
this.arcMesh = new Line2(this.arcGeometry1, this.matLine2 );
update()
init()
render()


//update()
var positions = this.arcMesh.geometry.attributes.position.array;
  for (let x = 0; x < arcPath.length; x++) {
    positions[x] = arcPath[x]
  }

  this.arcMesh.geometry.setDrawRange( 0, arcPath.length );
  this.arcMesh.geometry.computeBoundingSphere();
  //this.arcMesh.computeLineDistances();
  this.earthArcMesh.scale.set( 1, 1, 1 );

//init()
this.scene.add(this.arcMesh);

//render()
this.renderer.render(this.scene, this.camera);
this.arcMesh.geometry.computeBoundingSphere();
this.arcMesh.geometry.attributes.position.needsUpdate = true;

Since i implemented bufferGeometry the mesh is not showing in the render, but when i debug it, seems fine because the geometry points are correctly loaded

Line2 {…}
castShadow: (...)
children: (...)
frustumCulled: (...)
geometry: LineGeometry
    attributes: Object
        position: BufferAttribute
            array: Float32Array(135)
                [0 … 99]
                0: -148.2235870361328
                1: -17.804668426513672
                2: 0.0008591873338446021
                3: -147.93746948242188
                4: -20.358715057373047
                5: 0.0009825639426708221
                6: -147.60552978515625
                7: -22.92180633544922
                8: 0.0011064092395827174
                9: -147.22335815429688
                10: -25.517356872558594
                11: 0.0012318536173552275
                ...

boundingSphere: Sphere
    center: Vector3
    radius: 0

A hint may be that always in the console debugging i see that the bounding sphere has radius 0? Even if did compute it in the snippet before. Any help would be very appreciated, thanks

/cc

Is it possible for your to demonstrate the problem with a live example: https://jsfiddle.net/t1uwemLq/

In any event, you can’t define the geometry for LineGeometry like so:

You have to use a dedicated interface for this. Try it with LineGeometry.setPositions(). That is necessary since internally the geometry is instanced and interleaved.

Thanks, for the answer! I did use .setPositions() before and it was showing, but my problem is that i need to update the position data AND the number of points, and with setPositions() would throw this mistake, when the number of points was different from the initiated size:
On firefox:
WebGL warning: drawElementsInstanced: Instance fetch requires 14, but attribs only supply 13.
On Chrome:
GL ERROR :GL_INVALID_OPERATION : glDrawElementsInstancedANGLE: attempt to access out of range vertices in attribute 1

so i refactored following this example:
https://threejs.org/docs/index.html#manual/en/introduction/How-to-update-things

I’m having some trouble building the jsfiddle because it’ s from a big vue component but basically i’m wondering if it’s possible to modify this buffer example: http://jsfiddle.net/w67tzfhx/ by using the Line2() object from this example: https://github.com/mrdoob/three.js/blob/7c1424c5819ab622a346dd630ee4e6431388021e/examples/webgl_lines_fat.html instead of THREE.Line()

This is a general limitation of WebGL buffers since they are fixed sized. Once created you can’t just add additional elements like with an ordinary JavaScript array.

The general idea is to make buffers “large enough” for your app and then use BufferGeometry.drawRange or InstancedBufferGeometry.maxInstancedCount to control the final rendering.

Looking at your stackoverflow post, the provided answer is exactly the same like here.

I

That’s what I tried in the first post I used bufferGeometry to allocate a buffer large enough and drawRange but still it didn’t work. Now i’m trying to make a fiddle, but I’m stuck.

I want to modify this fiddle: http://jsfiddle.net/w67tzfhx/
but i can’t import three.js modules as in the same syntax as: https://jsfiddle.net/t1uwemLq/

Whenever I copy and paste the modules i need it stops rendering, any hint?

Try it with this fiddle: https://jsfiddle.net/tqkpbeh0/

When using modules, the code becomes automatically strict which can break apps like in the previous version of the fiddle.

Here i did the solutions i’m trying:
Line2() declared with LineMaterial and LineGeometry

But the Buffer set with setPositions() and drawRange()

https://jsfiddle.net/danieledep/9qk1mjht/6/
I don’t know what’s wrong…

BufferGeometry.setDrawRange() can’t be used with wide lines since it internally uses instanced rendering. Hence, you need to modulate InstancedBufferGeometry.maxInstancedCount:

https://jsfiddle.net/brLk6aud/1/

Thank you so much @Mugen87 , I made it work with your example, your help was very very very appreciated.

1 Like