Buffer binding#35
Conversation
| import Shader from './shader'; | ||
| import Qualifier from './qualifier'; | ||
| import Set from './util/set'; | ||
| import InterfaceVariable from './interface'; |
There was a problem hiding this comment.
Nitpick: could you do these imports alphabetically, please? (just a convention I like)
| return this.declaration(); | ||
| } | ||
|
|
||
| public wrapAttributeValue(value: any[]): any { |
There was a problem hiding this comment.
Can you rename wrapAttributeValue to something more descriptive, like wrapAttributeBufferInTypedArray? It took a while to figure out what this was actually doing.
| } | ||
|
|
||
| public inputs(): Set<Variable> { | ||
| public inputs(): Set<InterfaceVariable> { |
There was a problem hiding this comment.
In my pending PR for adding local variables, I remove dependencies and just use inputs() and outputs() to get VariableSources (just the variable name and type). There are other fields inputDecls and outputDecls which contain VariableDeclaration[]s to use in code generation. If I submit first, you can change these to inputVars() and outputVars() and use them the way you are now (but you would need to cast to get back that they're InterfaceVariables, so maybe there should be InterfaceVariableDeclaration and LocalVariableDeclaration nodes?)
| this.attributeBuffers = new Map(); | ||
| this.uniformPositions = new Map(); | ||
| this.inputs = new Map(); | ||
| [...vertexShader.inputs().union(fragmentShader.inputs())].forEach(input => { |
There was a problem hiding this comment.
Do we expect there to be common inputs between vertex and fragment shaders? I think fragment shader inputs come from vertex shader outputs. We don't bind buffers for those inputs.
There was a problem hiding this comment.
This only does stuff for uniforms, which you get for both, and attributes, which should only be inputs for the vertex shader (but we don't check that), and currently ignores in and out variables. Haven't thought too much yet about those but there aren't buffers being made for them anyway.
There was a problem hiding this comment.
Right, that makes sense. Although I still don't understand the purpose of the inputs map, which takes inputs from both the fragment and vertex shader, and doesn't check whether or not those inputs are attributes. If you're only using it for attribute variables, can you
a) just get inputs from the vertex shader, and
b) filter by qualifier so that you only add attributes to the map?
| this.createBuffers(); | ||
| } | ||
|
|
||
| public setAttribute(input: string, value: any[], usage: GLenum = this.gl.STATIC_DRAW) { |
There was a problem hiding this comment.
It seems awkward to key input interface variables by their declaration string. Why can't we just iterate over the set of inputs?
Also, can we change the signature of this to take all input variables, and all buffers? Maybe something like this:
public setAttributes(inputVars: InterfaceVariable[], buffer: any[], usage: GLenum);If we do this, we can figure out the stride and offset for each attribute.
There was a problem hiding this comment.
This is for the end user to bind a value to a variable, which they may not want to do all at once, e.g. shader.bindAttribute('position', [1, -1, 0, ... ]). From the user's perspective, they'd be naming their variables by strings anyway, so wouldn't it be weird to make them pass in an object as a key?
There was a problem hiding this comment.
I thought the map was keyed by declaration for some reason, which is why I thought it was awkward. I'm okay with just variable names, because as you said, they're naming these variables with strings anyway.
Can we also support binding for multiple attributes at once (taking a string[] instead of InterfaceVariable[])? Binding separately in this way with multiple buffers will be less performant than interleaving the data if we want multiple attributes, so it's good to at least leave the option open.
Also, FWIW, I think we need to think more carefully about what buffer-related work we want users to do outside of our library. Right now, they have to gather each attribute's data in separate buffers, which is simple on their end, but leads to inefficient GPU cache use. On the other hand, they gather every attribute's data in a single buffer and pass it in to avoid cache problems, but this might be too restrictive to use. However, I'm fine with your current approach, and I'll make a separate issue for this.
| this.gl.enableVertexAttribArray(position); | ||
| } | ||
|
|
||
| // TODO: support variadic args |
There was a problem hiding this comment.
Out of curiosity, why do we want variadic args?
There was a problem hiding this comment.
We don't need to, but there are the non-v versions of all the uniform functions that maybe people want to call directly instead of wrapping in an array, so our call might mirror that. Definitely not a key feature or anything, just something that we might consider doing in the name of not limiting the library's usage
| // Might want to enforce equality (need to check the standard), but for now, this should be sufficient. | ||
| const inVars = this.fragmentShader.inputs(); | ||
| const outVars = this.vertexShader.outputs(); | ||
| const inVars = new Set<Variable>([...this.fragmentShader.inputs()].map(v => v.variable)); |
There was a problem hiding this comment.
My pending PR will redefine inputs and outputs to return what you want here, so you won't need a map.
| return true; | ||
| } | ||
|
|
||
| public wrapAttributeValue(value: any[]): any { |
There was a problem hiding this comment.
Same comment as above: can you rename to wrapAttributeBufferInTypedArray?
7dcc8d3 to
d0d2e48
Compare
| .filter(input => input.variable.qualifier == Qualifier.Attribute) | ||
| .forEach(input => this.attributes.set(input.variable.name(), input.variable)); | ||
| this.uniforms = new Set( | ||
| [...vertexShader.inputDecls] |
There was a problem hiding this comment.
This implies we're going to expect users to pass in uniforms to the inputs parameter in a Shader constructor. Would it be better to have a separate uniforms constructor parameter? Shader inputs and uniforms are used for different purposes (vertex/fragment-specific vs static for entire pipeline), so it could be less confusing to split them at the Shader level.
There was a problem hiding this comment.
I want to think about this more in another PR I think
d5d9495 to
cb211ce
Compare
851453d to
1366a7b
Compare
|
Ok so changes I made:
|
| } | ||
|
|
||
| public source(): string { | ||
| console.log(this); |
Uh oh!
There was an error while loading. Please reload this page.