Procedural Shader Cost/Draw Calls

Really quick question (I hope).

I’m challenging myself to try and do all the materials for my game in the shader (ie. no or few textures allowed, and I’m leaning towards only allowing auxiliary textures, like AO or position, nothing so visible as an Albedo or metallic rough map).

My question has to do with using the same shader for multiple objects, and the render cost that incurs. For example, I have a shader which blends between two colors based on a position map, and a custom voronoi function. The voronoi function takes into account object position via a mul(_Object2World, float4(0, 0, 0, 1) ) call. This means that for each object, I get a different return on the voronoi diagram (or any kind of noise function), meaning each looks distinct.

My understanding is that because I created one material from this shader, and applied it to multiple objects in my scene, that this is one draw call. Is this accurate? Or am I going to hit a wall later on by doing this again in multiple other shaders?


No, that wouldn’t work ^^. Yes, if all objects use the same material they could be batched into a single drawcall. Read the documentation on batching carefully as only certain condition will lead to batching.

Your problems is that batching means all objects that are batched together will behave like a single object. Batching actually transforms the vertices into the same space before it’s send to the GPU. So technically it transforms multiple objects into a single one. So you only have one single matrix in the shader which only has a single position.

If you want to support batching you would have to encode the object position into the actual vertex data. So that each vertex has an additional position (stored as color / texcoords / …) which represents the object position. So all vertices of a single object would have the same position stored in that vertex attribute. So in the shader this position will represent the object position.