Hey All,
I came across this post and saw the PR and related discussion on github which seems to be ending in a limbo.
I created this post to hopefully discuss possible solution that would be inline with current three.js setup (mainly it’s caching mechanisms). I have spent some time thinking how this feature could be interweaved in current three.js setup and here are some bullet points how I would see it.
By no means this is a ready solution but it gives some starting point for the discussion to move this topic forward.
I would appreciate your feedback on proposed solution and to know if there is anything going on in this matter? Last post from @Mugen87 on GitHub points out some idea but not sure if this has been crystallised in a form of code? (branch?)
Below some principles of my idea:
- include transform feedback object ( TFO, result of gl.createTransformFeedback() ) as part of WebGLBindingState (similar to current object property (VAO)),
- augment
BufferAttribute
with a property, for exampletransformFeedbackVaryingName
of type string, which would be indication that the attribute should have corresponding TF buffer created. User would callbufferAttribute.transformFeedbackVaryingName.set('myVarying')
when creating BufferAttribute and setting the name as defined in the shader (assuming ShaderMaterial usage here), this could be ‘automated’ further when parsing shaders from chunk maybe, -
BufferGeometry
would keep track of the names of its attribute TF Varyings (ie. by defining gettertfVaryingNames
with some clever caching maybe) - augment
WebGLProgram
with conditionally executed code:
gl.transformFeedbackVaryings(
program,
parameters.tfVaryingNames,
gl.SEPARATE_ATTRIBS // additional parameter would define this?
);
if parameters.tfVaryingNames is present (the parameter would be defined in WebGLPrograms from geometry.tfVaryingNames
) as other parameters there,
- augment
WebGLAttributes
createBuffer
output to contain additionaltfBuffer
property, similarly tobuffer
but here data would be written to by GPU, - when calling bindingStates.setup in WebGLRenderer there would be additional call, while looping the attributes (same as it is doing now for vao to set vertexAttribPointer etc.),
gl.bindBufferBase(
gl.TRANSFORM_FEEDBACK_BUFFER,
program.location,
tfBuffer
);
- (optional) create separate transformFeedbackRenderer, that would wrap gl[begin / end ]TransformFeedback around drawArrays call, the renderer would be set similarly as currently
indexedBufferRenderer
is set - create flipping mechanism that would allow switching read/write from/to
buffer
ortfBuffer
so the actual transform feedback can be utilised (in WebGLBindingStates which would providetick
function used by WebGLRenderer to flip buffers.
Here I have some performance consideration:
is it better (three.js context, performance-wise) to flip buffers only (as described above) and allowing the WebGLRenderer to re-bind and re-configure each attribute in the binding state VAO / TFO ? Does this not contradict the idea of VAO which was created so we don’t need to rebind each buffer?