[SOLVED] Batching overrides any custom Shader Chunk


I’ve been trying to set up my grass shader seen here:

Trying to get it to work with batching. Because obviously the draw calls get too big either way.

If I set the grass blade entity to a batching group, the shader animation stops working - as if the code was using the default shader chunk.

I’ve searched a lot into this topic but didn’t see any solution. Is there any way of making Batching work with custom shader chunks?

Here is the public project I set up to test this up: https://playcanvas.com/editor/scene/710968


Don’t have code ready, but if you study how the batcher system works you will see that it just creates grouped meshInstances.

I think you will find a reference to them on the batch group object.

From there you will need to override their material, set the custom shader chunk and update it.

I feel that will work.

Looking at your code might be even simpler, if you don’t clone the original material, and just override it, you might not need to find the batched mesh instances and reassign the material.

I’ve tried that but it doesn’t work (I think).

I’m currently trying to find the Batch. I see that you can get the Batch Group using app.batcher.getGroupByName BUT, that doesn’t reference the Batch in any way, it’s just the Batch Group that you create using the editor.

No idea how to find the actual batch and access its meshInstance.

So, doing console.log(this.app.batcher) I can see all of the properties of BatchManager, which some aren’t listed in https://developer.playcanvas.com/en/api/pc.BatchManager.html

I need to access _batchList which I can access with the Chrome Dev Tools but not from a script for some reason (it returns an empty array).

Totally lost right now, undocumented properties… then empty arrays when clearly it’s not empty.

If you are accessing them in the initialize() method most likely they are empty because batches haven’t been generated yet.

I will let you know if I find something.

Yeah, i’ve progressed a tad after that post. But still got nowhere tbh.

I set the console log to delay by 1 second, then I could access the properties. HOWEVER, setting the material shader params like I would set it on the individual mesh Instances material, doesn’t seem to work, it doesn’t do anything.

The material that the batch uses is correct and has the custom shader chunks, but still it doesn’t get the parameter updates.

Actually, the transformVS (vertex shader chunk) isn’t correct, it has been overriden to default.

When I try to set it directly on the batch meshInstance, the mesh disappears from the scene.
When I try to set it to a temporary material and then set the material to the batch meshInstance, the same happens…

So confusing and frustrating :’)

Ooooookay I fixed it, phew!

So apparently checking “Dynamic” in the Batch Group is only for Skinned Meshes, that’s why it was crashing and disappearing when I placed my grass vertex shader.

I thought “Dynamic” was to be set for all moving objects.

1 Like

So hmm not fully fixed, when not “Dynamic”, the meshes can’t even look at the camera, they’re static.

Gonna see how to fix…

Tired for today. It works when “dynamic” is disabled. Crashes with “dynamic” enabled.

I guess i’ll have to do the billboarding in the vertex shader to avoid having to use lookAt.

So apparently checking “Dynamic” in the Batch Group is only for Skinned Meshes

Batching doesn’t currently support skinned meshes.

Dynamic must mean something else.

That is pretty weird.

So I still don’t know why my vertex shader crashes when checking as “Dynamic”. I will continue testing and researching today.

Worst case is we can’t use Dynamic batching with custom shader chunks, and have to do all of the orientation stuff on the vertex shader, also have to research how to do that.

Okay this time it’s 100% fixed. Grass is running on Dynamic batching and I’m still doing billboarding with lookAt instead of doing it in the vertex shader.

However I have to figure out how to do billboarding in the vertex shader because the lookAt function is taking a lot of time with thousands and thousands of grass quads.

Before, rendering 500 grass quads would result in very bad framerate. now 5000 is still playable.

Gonna keep improving, let’s see if doing billboarding on the shader lets me up that number even more.

1 Like

With @Mr_F’s help I made it to +500k grass with playable performance!

Current grass project only generates 15k thought, no need for more to see a beautiful grass field.


Applied the result to one of my current projects (with some improvements that are not in the public grass project):

(twitter’s video compression really hurt the little visual details…)


@devMidgard This project is awesome, can you assign a license to it? I would like to use it, but I wanna be sure about the license first

Hey, you’re free to use this “as is”. It was an experiment and it includes:

  • Procedural mesh generation.
  • Shader animation.

I don’t think you’ll be able to use it easily because it’s all kinda hacked together in a messy way. But if it can educate you into how to approach grass with this engine, you’re completely free to fork, study the code, and do whatever you please with it :slight_smile:

I have plans of eventually releasing a proper grass system plugin when the PlayCanvas Team updates the Asset Store to allow for more stuff to be in etc.

1 Like

Hi @devMidgard I was looking for a grass shader, would you mind sharing your public project, as the above link is broken.


Sure, i’ve made the project public again. Sorry for that.