-
-
Notifications
You must be signed in to change notification settings - Fork 35.4k
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
Update InterleavedBufferAttribute API to allow shared WebGL buffer across different parameters #21656
base: dev
Are you sure you want to change the base?
Conversation
@@ -91,91 +82,109 @@ class InterleavedBufferAttribute { | |||
|
|||
setX( index, x ) { | |||
|
|||
this.data.array[ index * this.data.stride + this.offset ] = x; | |||
// Note: Assuming stride is multiple of type.BYTES_PER_ELEMENT |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's require (i.e. not attempt to support anything else) the requirements of glTF here, they are there for a reason:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, good to know that. I have overlooked that part in the spec. Yeah let's require unless other specs need.
|
||
this.name = ''; | ||
|
||
this.data = interleavedBuffer; | ||
this.data = buffer; | ||
this.array = new type( buffer.array.buffer, offset ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that in addition to the requirement that stride be a multiple of component size, this also requires that offset be a multiple of 4 I believe. May need to document these alignment requirements.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good to me unless other specs need.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Requirement of Float32Array constructor itself as well: https://stackoverflow.com/a/8638875/1314762
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, I didn't know that.
@@ -5,27 +5,18 @@ const _vector = new /*@__PURE__*/ Vector3(); | |||
|
|||
class InterleavedBufferAttribute { | |||
|
|||
constructor( interleavedBuffer, itemSize, offset, normalized ) { | |||
constructor( buffer, itemSize, type, normalized, stride, offset, count ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that I would swap the order of type
and normalized
, to match existing BufferAtribute constructors. In this case normalized
would be a required parameter; seems fine to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The number of parameters will be many so I thought making the order be same as gl.vertexAttribPointer()
parameters help users understand the order, but no strong opinion. Swapping them sounds ok to me.
I'm still on the fence about the need for a |
No strong opinion about it. |
Any other comments or feedbacks to this change? If no objection, I will switch this PR to "ready for review" after I reflect the review comments. |
@takahirox Are you still awaiting comments or feedback on this? Seems like a great change that I would really like to see it being merged. |
Yeah, I still want comments. If it looks good, I want to move it forward. |
@Mugen87 Can you take a look? 🙏 |
Sorry, but other issues and changes have a higher priority right now to me. In context of buffer attributes and buffer geometry I also vote to focus on #22874 first. |
We recently found that using interleaved buffers with attributes of different types leads to the creation of multiple buffers in WebGL, which duplicates data on the GPU and defeats the purpose of interleaving data in the first place. @donmccurdy was so kind to point me to this proposal, and I really like it. It would allow us to continue using interleaved attributes instead of migrating to non-interleaved attributes. @takahirox Is there any chance to pick this topic again anytime soon? |
Sorry for the delay, I just came back from vacation. @takahirox If I got it right, you're mostly waiting for feedback on the API changes, correct? @Mugen87 Any idea about when this proposal could make it onto the roadmap? I checked the other issue that you referred to above (#22874) and it seems to be mostly figured out by now. I'm happy to assist with code reviews if that helps. |
I’m looking forward to this PR merging. We have a use case where point cloud data is received in an interleaved format with mixed types. Currently, we iterate over the structure and create separate position and color attributes on the CPU before uploading to the GPU. Ideally we could upload the data as-is to the GPU and access it using interleaved attributes. |
@donmccurdy I'm a fan of this change and think it will get some perf wins, but I'm not sure the scale of those wins. In the app I've been profiling lately, the per-frame cost of this on the JS side is entirely hidden by VAOs - it just remains a single call to set the VAO after it's been setup. The additional complexity of what's actually referenced in those VAOs certainly has some overhead, but I'd have to grab this change (and update the GLTFLoader) to be able to quantify that. |
I would love to have this PR merged, can it be made possible anytime soon? |
Related issue: #17089
Description
In #17089 a problem was raised that the current
InterleavedBuffer
andInterleavedBufferAttribute
doesn't allow shared WebGL buffer across different parameters like type.We discussed it in that thread and it would be worth to enable shared WebGL buffer. But we need to change interleaved buffer APIs. So I opened this draft PR to get feedbacks from other devs if it's ok to change the API for the improvement.
New API suggestion:
InterleavedBuffer
which is just a buffer containing the contentsgl.vertexAttribPointer()
parameters inInterleavedBufferAttribute
.Example:
Pros:
GLTFLoader
users would get benefits without changing their code. (GLTFLoader
optimization is not in this PR. I would like to suggest to do that in another PR not to make this PR bigger.)Cons:
GLTFLoader
,IFCLoader
, and some other example modules but not so many (see the diff of this PR). Users can directly use interleaved buffer API likewebgl_buffergeometry_points_interleaved
example but perhaps it isn't main stream use case so I hope this change doesn't make a big bad impact.Changes:
InterleavedBuffer
because the corresponding WebGL buffer needs to be released when all the attributes referring to it are disposed.InterleavedBuffer
will be just a buffer and won't have type. So we may need to drop some methods relying on the type.Note:
stride
andoffset
in the newInterleavedBufferAttribute
are in bytes for flexibility. And I assumestride
bytes is multiple of multiple oftype.BYTES_PER_ELEMENT
for the efficient array accessor methods. Ifstride
isn'ttype.BYTES_PER_ELEMENT
aligned, the accessor methods may need to create data view for each call. Is this limitation good?Advanced topics:
BufferAttribute
andInterleavedAttribute
while keepingBufferAttribute
API for simpler API. I think it would be possible and sounds good to me. I would like to know your folks opinions about it. Even if we do it, I would like to suggest to make a separated PR because the changes will be in our center core codes, like renderer, so I want to carefully and incrementally proceed.