The issue is that the CHOP length (n ) can change at runtime, but the uniform array allocation in GLSL cannot. To work around this, I tried allocating the arrays with more elements than I’d ever need, and then limiting the number of points drawn using:
int numPoints = n;
for (int i = 0; i < numPoints; i++) {
if (i >= numPoints){
break;
}
// ...draw points...
}
Problems I’m seeing:
Allocating more memory than needed seems to cause problems. numPoints is ignored, and points are drawn at y=0 or at seemingly random positions. The x values mostly work as expected.
I understand that uninitialized memory can be garbage or zero, depending on the hardware, driver, or memory state. I tried padding my CHOPs with some value, but that didn’t solve the issue.
I’m also aware there are size limits on allocations, but the behavior seems inconsistent. For example, in my example tox:
When drawing 50 points, I can allocate up to 4096 points without problems.
When drawing realworld data with 3000+ points, even allocating the exact size needed for the array doesn’t seem to work.
I’m sure i can find a solution to get this to work via CHOP->TOP and using it as a 2D sampler - but i’ve been fighting this issue for some time now and would really like to understand whats going on here.
You should use a texture buffer instead of a uniform array for this usage case. The size can be variable for texture buffer, and the size limitations are far large (usually 2GB+)
Hopefully we’ll have better access to storage buffers in the future for this kind of use case.
I’d note that in either case, the shader could be improved. You’re doing 5000 iterations per fragment which is a very inefficient way to render this data. I’m not sure if this is a representation of what you’re actually trying to do, but you’d likely be better served by instancing some geometry and then using the position data to displace the instances (either by using TD’s Geo COMP or manually in the vertex shader). Your example project is running at 60fps on my computer so maybe not an issue for your use case but thought I’d point that out. As alway, profile on your real project before taking performance advice from strangers.
Also, at least on my computer, your reference data and the two “unexpected” GLSL shaders all look the same. Which does suggest you’re running into some driver wonkiness, if I’m interpreting the network corectly.
Thank you malcolm and also Tim from yfx who helped me on the discord with this.
I wasn’t aware that chops can be used as a texture buffer. Its written in the documentation but my mind didn’t really comprehent CHOPS and texturebuffers together.
For future reference for anyone to stumble upon:
Instead of
uniform float xPoints[n];
uniform float yPoints[n];
//.....
float x = xPoints[i];
float y = yPoints[i];
change the ‘Array Type’ on the array page to Texture buffer and use
uniform samplerBuffer xPoints;
uniform samplerBuffer yPoints;
//.....
float x = texelFetch(xPoints, i).x;
float y = texelFetch(yPoints, i).x;
When set to vec2, the data can also be sampled from a single chop
Happy to help. Note that you’ll likely want to only use one texelFetch() call for that, rather than two. Depending on driver/optimizer, you may get much better performance by reducing the calls.