-
-
Notifications
You must be signed in to change notification settings - Fork 3.5k
Open
0 / 10 of 1 issue completedOpen
0 / 10 of 1 issue completed
Copy link
Milestone
Description
Topic
I was working on this sketch https://openprocessing.org/sketch/2664809 and instanceID() / 10
gives a type error, but 0.1 * instanceID()
does not. For consistency and to reduce the number of times a programmer has to manually convert between numeric types, do you think we should just auto-convert instanceID()
to a float behind the scenes?
Sub-issues
Collapse Sub-issuesSub-issues
- Manage this item control⌃ shift⇧ uU
To pick up a draggable item, press the space bar.
While dragging, use the arrow keys to move the item.
Press space again to drop the item in its new position, or press escape to cancel.
Metadata
Metadata
Assignees
Type
Projects
Status
Ready for Work
Milestone
Relationships
Development
Select code repository
Activity
perminder-17 commentedon Jun 1, 2025
Hi @davepagurek, thanks for bringing this up. It’s a great discussion. I haven’t used p5.strands, but
instanceID()
corresponds togl_InstanceID
, which is declared as anint
. According to the OpenGL spec, gl_InstanceID contains the index of the current primitive in an instanced draw call.It says ;
Since array indexing requires an integer, dynamic lookups must be done with an int. Integer IDs remain useful for indexing arrays or performing lookups, If we auto-converted
instanceID()
to afloat
, the user would still have to cast it back to anint
whenever they needed, which is inconvenient.Also, with very large draw calls, a
32-bit float
loses exact integer precision beyond a certain threshold.I don't know these two points still an issue here but if it matters, without chainging
instanceID()
tofloat
behind the scene, how about creating a new one namedinstanceIDf()
whose type isfloat
and let theinstanceID()
one remainint
.If these are not the concern users gonna use, we can convert
instanceID()
tofloat
I think.davepagurek commentedon Jun 2, 2025
While those are true, I think it might be worth compromising on those more advanced features for the sake of ease of use.
Another thought: for array indexing, we could make our
array[n]
operator in JavaScript convert toarray[int(n)]
when converting to GLSL whenever we add support for arrays. We might want to shift the mental model from being "operators behave differently on different numeric types" to something like "there are separate operators for int and float." So we could maybe treat numbers all as floats, soa * b
always does float multiplication, but add a JavaScript method likea.intDivide(b)
that translates toint(a) * int(b)
in GLSL.davepagurek commentedon Jun 2, 2025
also cc @lukeplowden in case you have thoughts!
perminder-17 commentedon Jun 2, 2025
Aah, yes. That's sounds great. I agree that prioritizing ease of use over more complex features is sensible. This approach makes a lot of sense and we could do that after making
instanceID()
tofloat
.lukeplowden commentedon Jun 3, 2025
Firstly, this is actually a bug coming from here:
FunctionCallNode
This is the error
It infers
genType
to be anint
, when really those should only befloat
orvec2/3/4
types. The error thrown does stop the GLSL code from generating which would be invalid code, but it is really a bug in the p5.strands compiler. As a separate issue, we should definitely make function calls convert fromint
tofloat
type.On the actual topic of this issue, this does raise some other issues:
0.1 * instanceID()
0.1000 * float(gl_InstanceID)
instanceID() * 0.1
float(gl_InstanceID * 0)
instanceID() / 10
float((gl_InstanceID / 10))
0.1 * instanceID()
works how you wouldexpectwant it to, because it wraps 0.1 intodynamicNode(0.1)
and that function always makes floats from single values. I think the left-hand operand takes precedent for determining type, which is a bit strange for sure.I do basically agree that everything could be converted to float, and I like the mental model of "there are separate operators for int and float". For the most part, we do always use floats at least in vertex and fragment shaders. I think though, for compute (which may be added in the future) there are generally more integer operations. At least for now, I think it's better to presume that all binary operations using
* / + -
in JavaScript, are on float/vec typesdavepagurek commentedon Jun 3, 2025
Does it go through
FunctionCallNode
for multiplication/division, or is that all throughBinaryExpressionNode
'sdetermineType
?Initially I was thinking the fix might be in here:
p5.js/src/webgl/ShaderGenerator.js
Lines 1385 to 1387 in 2606c21
Possibly returning something like
new FloatNode(variableConstructor('gl_InstanceID', 'int'))
.lukeplowden commentedon Jun 3, 2025
That would also fix it, but
genType
should also never be anint
, and the actual error comes from calls topow
andfloor
receiving (and accepting) anIntNode
as arguments, which isn't a valid signature. If I change theFunctionCallNode
:Then it does properly cast the type to float, and handle the error. It does leave the weirdness from the table above, where different syntaxes for the same operation currently give different results. It will just render unexpectedly, instead of not compiling as GLSL or throwing the type error about function signatures.
BinaryExpressionNode
should also be changed to stop the confusion of the different outputs based on what's on the left or right hand side of the operation.There are a few different options as you've highlighted, about whether to just assume all scalars are floats (which can already be cast to vecs easily). That way we can cast back to int if needed.
Otherwise, I suppose the compiler would have to be a bit smarter about knowing what type something should be based on what it's used in... maybe nodes could be duplicated if used in different contexts? This is probably unnecessary though...
Your change would definitely work for
instanceID()
in this case though, and give a consistent output. If we make all scalars floats, this would be necessary.davepagurek commentedon Jun 3, 2025
got it, thanks for the explanation! That works too.
I'm going to mark this one as "help wanted" in case any contributors want to try tackling this based on this discussion.