Material Question?

I have a question about Caching material or not?

From what I see the only have to pass parameters to a shader is through the Material class. So caching material does not work, if some of those parameters needs to be unique to the model the material is assigned to, even though the shader, textures and 99% of all other parameters are the same, but I need to add a couple of unique parameters that relate to a specific Quad.

Only way I can see doing this is not caching the material and for each Quad you their own material class or clone the main one and then I can assign unique parameters to the material so they get to the shader.

If there is another way, please let me know? Does it hurt to have up 64x64x4 different materials so I can pass those couple of unique parameters that apply to that quad only.

Also, what is the best way during update to update all those materials? so they render correctly.

Right now, I have a material manager that is an AppState that loops through the materials to update them.

In my own engine, the Geometry, had a function called before rendering so you can update parameters for geometry so the shader gets the correct value.

Thanks.

The important things like textures and stuff will be shared, memory-wise… as will the compiled shaders themselves. But having 16,000 different materials is going to be a problem whether they are the same instance or not… because that means 16,000 different Geometries, 16,000 different draw calls, etc…

That’s a lot of separate quads. What is different about each one of them? Maybe you can have one material and just use additional vertex buffers for this other data and get it down to just one mesh.

2 Likes

Right now, I batch many of the Quad into one mesh, end up creating only about 300 meshes. But only have around 10 materials due to caching that I’m using.

But I do not see a way to get parameters that CHANGE all the time that relate to these Quads.

I don’t see an option inside JME to be able to pass parameters related to specific Geometries.

I’m not sure what numbers we are actually talking about. So I don’t know what to tell you. If it’s only 300. Then ok. If it’s 16,000 then not ok.

You can set material parameter overrides on the spatials.

I still encourage you to look into vertex attributes. They can “change all the time” as needed. That’s what bone animation does after all (when not using hardware skinning).

1 Like

Example.
I have 3 textures.

1st. normal texture to draw for a Quad.
2nd. is a blend texture to be able to blend with the first Quad.
3rd. is the bump map on what areas to blend.

Those are static, but what I need to pass in a UNIQUE variable to this QUAD. I have about 30 Quads like this. Over time the blend gets worse and worse. But the blend on all 30 Quads are not the same, the changed over time unequally.

Only option I see is to have 30 materials??? This is my first time using an engine, I wrote my own and works great. Just wanted something, so I didn’t have to maintain the engine and focus on just the game only.

If someone can help me with this, because I have hundreds of different Quads that have unique values that alter the rendering process in the shader and I can’t see to find the best way to do this.

Thought about overwriting the Material class and using my own class.

    public void render(Geometry geometry, LightList lights, RenderManager renderManager) {

to override this function and when it calls to update the parameters for the shader, to call my OWN Geometry function for an update on the parameter. I don’t know if something like this would work. I’ve not completely traced the function if this is the correct spot.

Any help would be nice.

Not sure whether this is the correct way, but I only use my own materials (in a deferred pipeline) and I encode geometry specific information into one of these buffers:
https://javadoc.jmonkeyengine.org/v3.3.0-beta2/com/jme3/scene/VertexBuffer.Type.html

I guess you could do the same.

Custom material + vertex attributes is the way I’d do it.

Thanks I will look into that. I used this style method when doing instance rendering in my own engine, pass all the needed values to the shader down though this method, like (Color, position, atlas position and etc… for each instance).

I render instances in chunks, that way I do not do 20,000 at one time, I batch them up and send it over in batches for the instances. This way I can’t render over a ton of particle effects and take no hit on the performance.

JME is really flexible with vertex buffers. The only unflexible part is that you can’t choose your own names for them. But any of them can be whatever type you want, basically (ie: no need to put vec2 into texture coordinates, you could put floats or vec4 or whatever). Color is a common one to coopt.

That is what I was thinking, select one not being used and assign it data.

Thanks for your help.

1 Like