Shaders: print to console from .jxs file?

Cassie Smith's icon

I'm trying to find a way to print to console or equivalent from within a shader .jxs file. I'm not super familiar with C, but it seems like printf() is the standard print to console method. Unfortunately it's doing nothing.

I just want to debug and track the logic step-by-step as I would in any scripting language, including logging local variables that run calculations within the main loop. So, using objects to look at global parameters on the Max side isn't really useful.

Any thoughts? Worst case maybe there is a useful set of externals I don't know about? Thanks!



Rob Ramirez's icon

JXS files are wrappers around glsl shaders that run on your GPU, and therefore there is no way to print to the console. This is not a Max issue, but simply a reality of computer hardware.

Shader programming takes some getting used to for those coming from general purpose cpu programming backgrounds, but the way one typically debugs is by writing to the color output (gl_FragColor). Keep in mind the output of a jit.gl.slab can be easily viewed while debugging by sending to a jit.matrix, and then to a jit.cellblock (or jit.print).

pliskin's icon

Hi, I think my current puzzle is related to this - I want to output a value from the shader back into max as it is running - sending values and automating the shader is great, but there are cool operations that i'd like to hook into. I assume this requires an output value to be defined and accessed from the slab object running the shader? so essentially you have 2 layers coming out of the slab? Super clunky, but seems doable?

Federico-AmazingMaxStuff's icon

You can only output textures from a shader or write into a GPU buffer.
You can then transform this texture into a matrix to access the values from it, but is an expensive operation computationally speaking.

pliskin's icon

thanks for the confirmation, Federico.
If cost is not important - what is a way of outputting a float from the fragment program? It would have to still be a vec4, I assume, and how do you point that to a second output of the jit.gl.slab?

Federico-AmazingMaxStuff's icon

Unfortunately it can only come out in the form of a texture. If you just need a single number and for some reason you need to make the calculation on the GPU, you can also create a texture with dimensions 1 1.
In any case it comes out as a texture, where every cell contains a vec4 of data, which then you can bring on the CPU realm by transforming it into a matrix and then read it.
You can point to several texture targets from within the shader in this form:
- in GL3:

out vec3 [3] output;

void main() {
output[0] = Something
output[1] =
Something
output[2] =
Something
}


And then associate the shader to a node with @capture set to 2 or 3, depends from how many targets you need.

- in GL2:

gl_FragData[0] = vec4(something);
gl_FragData[1] = vec4(something);

Hope this helps!

pliskin's icon

IT WORKS! Truly Amazing stuff.
Thank you for the output formatting. This is super dumb but awesome haha.

Federico-AmazingMaxStuff's icon

Great that it worked! ^^

Matteo Marson's icon

Thanks so much Federico!
I didn't know how to translate the gl_FragData[i] thing into gl3