-
Notifications
You must be signed in to change notification settings - Fork 1
Conversation
davepagurek
commented
Nov 12, 2017
•
edited
Loading
edited
src/shaderpipeline.ts
Outdated
@@ -1,11 +1,149 @@ | |||
import Shader from './shader'; | |||
import Qualifier from './qualifier'; | |||
import Set from './util/set'; | |||
import InterfaceVariable from './interface'; |
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.
Nitpick: could you do these imports alphabetically, please? (just a convention I like)
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.
Some of my comments refer to #36, in case that gets merged first. I don't mind either way, but we should talk about how to resolve the merge conflicts beforehand, since both PRs are pretty large.
src/interface.ts
Outdated
@@ -23,4 +23,20 @@ export default class InterfaceVariable implements Hashable { | |||
public hashCode(): string { | |||
return this.declaration(); | |||
} | |||
|
|||
public wrapAttributeValue(value: any[]): any { |
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.
Can you rename wrapAttributeValue
to something more descriptive, like wrapAttributeBufferInTypedArray
? It took a while to figure out what this was actually doing.
src/shader.ts
Outdated
@@ -22,18 +22,21 @@ export default class Shader { | |||
.join('\n'); | |||
} | |||
|
|||
public inputs(): Set<Variable> { | |||
public inputs(): Set<InterfaceVariable> { |
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.
In my pending PR for adding local variables, I remove dependencies and just use inputs()
and outputs()
to get VariableSource
s (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 InterfaceVariable
s, so maybe there should be InterfaceVariableDeclaration
and LocalVariableDeclaration
nodes?)
src/shaderpipeline.ts
Outdated
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 attribute
s to the map?
this.createBuffers(); | ||
} | ||
|
||
public setAttribute(input: string, value: any[], usage: GLenum = this.gl.STATIC_DRAW) { |
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.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Out of curiosity, why do we want variadic args?
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.
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
src/shaderpipelinebuilder.ts
Outdated
@@ -15,13 +17,13 @@ export default class ShaderPipelineBuilder { | |||
|
|||
// Vertex shader outputs must be a superset of fragment shader inputs. | |||
// 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My pending PR will redefine inputs
and outputs
to return what you want here, so you won't need a map.
src/type.ts
Outdated
@@ -31,4 +31,85 @@ export default class Type { | |||
|
|||
return true; | |||
} | |||
|
|||
public wrapAttributeValue(value: any[]): any { |
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.
Same comment as above: can you rename to wrapAttributeBufferInTypedArray
?
7dcc8d3
to
d0d2e48
Compare
src/shaderpipeline.ts
Outdated
.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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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:
|
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.
@@ -8,6 +8,7 @@ export default class EqualAssignment extends AssignmentExpression { | |||
} | |||
|
|||
public source(): string { | |||
console.log(this); |
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.
Remove this console.log
?