-
Notifications
You must be signed in to change notification settings - Fork 43
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Performance: draw all lines in a single buffer geometry #31
Comments
heres the extracted BufferGeometry usage. simply updating vertices would not require recreating the geometry. function createGeometry () {
const geometry = new THREE.BufferGeometry();
const vertices = [];
// populate vertices
// start
// vertices.push( vertex.x, vertex.y, vertex.z );
// end
// vertices.push( vertex.x, vertex.y, vertex.z );
geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) );
return geometry;
}
const material = new THREE.LineBasicMaterial({
// color: p[ 1 ],
// opacity: p[ 2 ]
});
const line = new THREE.LineSegments( createGeometry(), material );
scene.add( line );
// update geometry after some change
line.geometry.dispose();
line.geometry = createGeometry(); |
ok got it working. performance improvement is significant! const graph = new ThreeForceGraph()
.graphData(packageData)
.linkThreeObject((link) => {
// create dummy object
return new Object3D()
})
.linkPositionUpdate((linkObject, { start, end }, link) => {
lineController.setLine(link.id, [start.x, start.y, start.z], [end.x, end.y, end.z])
// override link position update
return true
})
import { LineSegments, LineBasicMaterial, BufferGeometry, Float32BufferAttribute } from 'three'
export class LineSegmentsController {
constructor ({ lineCapacity = 1000, color = '#f0f0f0', opacity = 0.2 } = {}) {
this.lineToIndex = new Map()
this.material = new LineBasicMaterial({
color,
opacity,
transparent: opacity < 1,
depthWrite: opacity >= 1
})
this.geometry = new BufferGeometry()
this.lineCapacity = 0
this.vertices = new Float32Array(0)
this.setLineCapacity(lineCapacity)
this.object = new LineSegments(this.geometry, this.material)
this.object.renderOrder = 10
}
setLine (id, start, end) {
if (this.lineToIndex.has(id)) {
const positions = this.geometry.attributes.position.array
// existing line, update entry
const index = this.lineToIndex.get(id)
positions.set(start, index)
positions.set(end, index + 3)
} else {
// new line, add new entry
const lineCount = this.lineToIndex.size
const index = lineCount * 2 * 3
this.lineToIndex.set(id, index)
// double line capacity if expired
if (lineCount >= this.lineCapacity) {
this.setLineCapacity(this.lineCapacity * 2)
}
const positions = this.geometry.attributes.position.array
positions.set(start, index)
positions.set(end, index + 3)
this.geometry.setDrawRange(0, (lineCount + 1) * 2)
}
// mark for update
this.geometry.attributes.position.needsUpdate = true
// this.geometry.computeBoundingBox()
// this.geometry.computeBoundingSphere()
}
setLineCapacity (newLineCapacity) {
// lineCapacity * 2 point/line * 3 floats/point
const newVertices = new Float32Array(newLineCapacity * 2 * 3)
// only run this when its not the first time
if (this.lineCapacity > 0) {
const positions = this.geometry.attributes.position.array
newVertices.set(positions)
}
this.vertices = newVertices
this.geometry.setAttribute('position', new Float32BufferAttribute(this.vertices, 3))
this.lineCapacity = newLineCapacity
}
} |
with this change alone i went 3 fps -> 15 fps on quest 2 vr headset |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Is your feature request related to a problem? Please describe.
drawing graphs with many links has poor performance on constrained devices
Describe the solution you'd like
option to render all lines as part of a single buffer geometry
Describe alternatives you've considered
not drawing the lines at all 😿
Additional context
example of many line segments in a buffer geometry
each is 1500 line segments
https://github.com/mrdoob/three.js/blob/master/examples/webgl_lines_sphere.html#L112-L128
primary challenge seems to be the expectation of 1 link matches 1 three object
The text was updated successfully, but these errors were encountered: