Possible to pass params to shader when creating new geometry?

Jun 12, 2012 at 4:29am

Possible to pass params to shader when creating new geometry?

I’ve got a shader that selects a letter in a font atlas (.png file) texture depending on the input of an ascii code integer pass along in Max.

When I create a new gridshape (plane), I assign it the texture and shader.

What I would like to do, is instantiate a whole bunch of gridshapes (via javascript) and assign the same shader and texture but pass along the shader parameter to change the letter.

Right now, if I change the integer directly on the shader, it will update the texture on all of the objects that have been assigned the shader.

Is it possible to send params to the shader of a gridshape instance? Can it work that way?

If not, what are my options? Do I have to instantiate new shaders for each gridshape? Shouldn’t I be able to pass along shader parameters to different instances of geometry?

Thanks for your help in advance!

#46651
Jun 12, 2012 at 11:17am

You could change the parameter for every instance you’re drawing.
Though I do not know how it works if you would want to use jit.gl.multiple.

– Pasted Max Patch, click to expand. –
#167843
Jun 12, 2012 at 12:40pm

Thanks! That’s what I was looking for.

Does anyone else know how to do the above with jit.gl.multiple?

#167844
Jun 12, 2012 at 2:46pm

below is patch that uses jit.gl.multiple to display letters from a font atlas on each shape in a 16×16 grid, using the tex_plane_s/t parameters.

– Pasted Max Patch, click to expand. –
#167845
Jul 23, 2012 at 11:26pm

Finally getting back to you on this….

Robert, in your patcher, you’re not actually using a shader to display the letters but rather remapping the texture.
This solution will not work for me because my shader does more for than just map the texture to the correct letter, it also creates a colored background based on a passed parameter as well. I also plan on adding other instance specific shader params.

Essentially, I want to have the ability to pass shader parameters for each gridshape in jit.gl.multiple. Is it at all possible to do this with jit.gl.multiple? jit.gl.multiple provides an enormous performance improvement over iterating gridshapes in javascript.

Currently, I’m using javascript to loop through an array of letter objects and then drawing them individually while passing shader parameters to each. Each gridshape texture has the potential of being displayed differently via shader params. I’m hoping to find a way to improve the performance and jit.gl.multiple is the obvious way of doing this. With my current strategy, only a couple hundred gridshapes cause a significant loss of fps.

I’ve scoured the forums, and haven’t found other viable options for drawing many instances of geometry. Any other ideas that I should explore?

Any help would be much appreciated!!!!

#167846
Jul 24, 2012 at 4:20am

maybe you could try with poly~-but not sure about speed issue with many instances… (i didn’t found out about how to bang the instances in the correct order, that’s why i always prepended the target $1 – it works this way, but should be solved more elegant. maybe somebody can help?

attachment in next post…

#167847
Jul 24, 2012 at 4:33am

here:

Attachments:
  1. Archive.zip
#167848
Jul 24, 2012 at 12:02pm

ok, here one more try with 100 instances of poly…

Attachments:
  1. poly100.zip
#167849
Jul 24, 2012 at 1:01pm

Thanks tobiasros, I will look at your examples ASAP and get back.

I’ve posted my js drawing function below so that you can see the logic.

From more reading, I understand that the draw function resets the opengl stack every time and this is the source of my slowdown. (http://cycling74.com/forums/topic.php?id=9013)

Also, I know that jit.gl.multiple won’t work for me unless there is some undocumented way of passing shader params to each instance of the gridshape multiplied by jit.gl.multiple.

I’ve also read into a bit of jit.gl.lua and it seems that it might be worth trying out. However, I haven’t been able to find an example that shows how to pass different shader params for each instance. Is there a jit.gl.lua expert who could give me an example?

My most basic question is:

1. Is it possible to achieve what I’m trying to do with either JS or LUA? I want to set up the position, rotation, texture and pass shader params for each instance of a basic gridshape (plane) (and I think somehow use drawraw to get good performance??) The texture and the shader are the same for each gridshape, but the shader params change.

You can ignore most of the code below, it is just to show you that I’m looping to set position, rotation, shader params and then draw already generated gridshapes

function drawGlyphs() {

	// Loop through all Code Blocks

	for (var i = 0; i < myglobal.codeBlockObjArray.length; i++) {

		// Loop through each row of each Code Block

		for (var r = 0; r < myglobal.codeBlockObjArray[i].codeBlockArray.length; r++) {

			var downVector = myglobal.codeBlockObjArray[i].downVector.multiply(r * 1.5);

			for (var c = 0; c < myglobal.codeBlockObjArray[i].codeBlockArray[r].length; c++) {

				var rightVector = myglobal.codeBlockObjArray[i].rightVector.multiply(c);

				var resultVector = rightVector.add(downVector);

				var targetVector = myglobal.codeBlockObjArray[i].position.add(resultVector);

				myglobal.codeBlockObjArray[i].codeBlockArray[r][c].gridShape.position = [targetVector.elements[0], targetVector.elements[1], targetVector.elements[2]];

				myglobal.codeBlockObjArray[i].codeBlockArray[r][c].gridShape.rotate = [myglobal.codeBlockObjArray[i].cameraRotation[0], myglobal.codeBlockObjArray[i].cameraRotation[1], myglobal.codeBlockObjArray[i].cameraRotation[2], myglobal.codeBlockObjArray[i].cameraRotation[3]];				

				charShader.param("glyph", myglobal.codeBlockObjArray[i].codeBlockArray[r][c].charID);

				charShader.param("dimensions", (16, 16));

				if (myglobal.codeBlockObjArray[i].beatCodeIndexArray[myglobal.codeBlockObjArray[i].currentBeatCodeIndex] === r) {

					charShader.param("bgcolor", [1., 0., 0., .5]);

				} else {

					charShader.param("bgcolor", [0., 0., 0., 0.]);

				}

				var eventMatch = false;

				for (var e = 0; e < myglobal.codeBlockObjArray[i].eventCodeIndexArray.length; e++) {

					if (myglobal.codeBlockObjArray[i].eventCodeIndexArray[e] === r) {

						//post("EVENT MATCH");

						eventMatch = true;

						break;

					}

				}

				if (eventMatch == true) {

					charShader.param("bgcolor", [0., 0., 1., .5]);

				}

				myglobal.codeBlockObjArray[i].codeBlockArray[r][c].gridShape.draw();

			}

		}

	}

}
#167850
Jul 24, 2012 at 5:14pm

hi tobiasros,

I looked at your poly examples and they too suffer from the same problem as my JS method, which is that the OpenGL stack is reset at each draw call. I upped the number from 100 to 500 and I have just about the same fps as with JS (somewhere below 25fps). I’m currently exploring jit.gl.lua but I still am not certain if/how to pass shader params to each instance.

#167851
Jul 24, 2012 at 6:52pm

You best bet is to do the following:

// pseudo-code
for each object do
   shader.param(name, value)
   shader.bind()
   object.drawraw()
   shader.unbind()
end

If you’re drawing a gridshape, set @displaylist 1 for speed.

#167852
Jul 24, 2012 at 10:56pm

another option is to use the jit.gl.multiple shader parameter feature.
you can set arbitrary shader parameters per instance with jit.gl.multiple by specifying the parameter name in the @glparams arg list like this:
@glparams shader.param-name (where param-name is the name of the shader parameter you’d like to affect).

the patch below demonstrates this:

– Pasted Max Patch, click to expand. –
#167853
Jul 27, 2012 at 1:38am

Thanks Wesley and Robert!

I’ve attached 3 Max patchers with 3 different methods. 2 with js using jit.gl.multiple and iterating in js and one with jit.gl.lua.

the jit.gl.multiple seems to have the performance edge. with jit.gl.lua I haven’t been able to figure out how to set non-relative positions.
and with the iterating in js, I haven’t figured out how to draw the gridshapes any more efficiently.

My finding is that jit.gl.multiple outperforms anything else I’ve tried.

A few questions stem from this exploration:

1. Is there a way to incorporate the jit.gl.multiple directly into my JS and still pass shader params? Could someone show me how to do this?
2. For future reference, is there any better way of drawing gridshapes through iteration than the way I’m doing in the iteration patch?
3. With jit.gl.lua, can you set discrete positioning using the method I was using?

and…

4. I’ve seen lots of references to getting more performance out of Max/Jitter using lower level languages…C and Java? What kind of difference could I expect if I eventually explore that route? I basically want to know how many discrete pieces of geometry I can drive through Jitter and maintain 30-60fps. By going the C or Java route, can I expect to be able to throw thousands of gridshapes??? Are there examples out there using C and Java that essentially show off what is possible?

Any comments on improving my max/js/lua code would be appreciated.

Thanks!

#167854
Jul 27, 2012 at 2:25am

1. Is there a way to incorporate the jit.gl.multiple directly into my JS and still pass shader params? Could someone show me how to do this?

I had a look, and I don’t think there is right now. I’ve made a feature request.

2. For future reference, is there any better way of drawing gridshapes through iteration than the way I’m doing in the iteration patch?

Looks like you’re doing the right things to me.

3. With jit.gl.lua, can you set discrete positioning using the method I was using?

I’m not sure what you mean here. You can do anything in jit.gl.lua that you can do in JS. If you post the code snippet you’re referring to, I could help better.

You might also want to look into using jit.gen. For generating the various matrices for use with jit.gl.multiple, jit.gen is going to give you really good performance, particularly once you get into the 100s of objects. Looks like right now, you could simply use jit.noise for most of your calculations. Using setcell is going to be quite slow in comparison.

#167855
Jul 27, 2012 at 2:54am

I’m not sure what you mean here. You can do anything in jit.gl.lua that you can do in JS. If you post the code snippet you’re referring to, I could help better.

So, these patchers were just for testing performance. My intention in my actual project is not to randomly generate values for everything but rather to place gridshapes at different locations in 3D. What I’m wondering if how I could place a gridshape with an x,y,z value using an efficient drawing method in jit.lua (and same with my js iteration). (so how to place gridshapes when using drawraw?)

#167856
Jul 27, 2012 at 3:31am

use a position matrix with jit.gl.multiple

#167857

You must be logged in to reply to this topic.