Model/Meshes transparency and Model/Effect batching?

So I’m building Yet Another Voxel Engine. In my last post, JWollen pointed me in the right direction to use vertex colors. So I now get lighting and shadow maps working. My shader is pretty basic:

mixin ParadoxDefaultDeferredShader;
mixin compose albedoDiffuse = ComputerColorStream;

Every “chunk” is an Entity with a Model and two Meshes (one for solid vertices and one for transparent vertices). So one problem is that the transparent vertices are ignoring the alpha channel. I am flagging the transparent meshes with UseTransparent = true (and using deferred renderer), so I assumed the system was rendering solids first then transparents second, with the second time using an appropriate blend state. Is this not the case?

Second problem is that it seems like Paradox creates a new instance of a shader for every chunk, which slows things down dramatically. So if I have 10 chunks on screen, it seems to create 10 different shaders, and then a new shader every time a new chunk is created… My fears are confirmed in Graphics Diagnostics where I see a whole slew of setup commands run before every Draw of a chunk. Is there any way to batch models under a single effect? Or do I have to manage that by having a single Entity and Model and swapping in meshes on the fly?

You are right in that there will be two rendering passes, one deferred for opaque meshes, followed by a forward pass for transparent ones.
However, UseTransparent will not work when setting it on a Mesh. It will only work, if you set it on a mesh’s Material, so right now all your transparent meshes end up in the opaque pass.
I suggest you follow the material-based route from the other thread.

The reason for that is, that transparency requires a different shader and only Material-properties are considered when compiling/searching for shaders.

Concerning the second problem: As far as I can tell, there shouldn’t be any redundant shaders. Paradox caches compiled shaders by Material-properties and reuses them. Also, your model/mesh-organization shouldn’t matter. Models are mostly for logical/transformation purposes and meshes will be sorted by material/shader, no matter what.

Some state changes will still be necessary for each Draw-call, but for a reasonable number of chunks, that shouldn’t be a problem. What kind of performance problems are you experiencing/what API calls are you observing?

Hey, thanks for the reply! Actually, I am setting it on the Material, I’m using two materials:

var mixinSource = new ShaderMixinSource();
mixinSource.Mixins.Add(new ShaderClassSource("ComputeColorStream"));

SolidMaterial = new Material();
SolidMaterial.Parameters.Add(MaterialParameters.AlbedoDiffuse, mixinSource);
SolidMaterial.Parameters.Add(MaterialParameters.UseTransparent, false);

AlphaMaterial = new Material();
AlphaMaterial.Parameters.Add(MaterialParameters.AlbedoDiffuse, mixinSource);
AlphaMaterial.Parameters.Add(MaterialParameters.UseTransparent, true);

which then I apply on the mesh. But it still results in solid blocks which are defined with vertex colors having 0.5f alpha.

For the second thing, I can’t tell if it’s a problem yet or not.

Performance wise, when I did something similar to this under SharpDX, the perf just seemed so much faster (thousands of FPS for rather simple textureless block worlds with 1-2 million vertices).

I am guessing the shader used here is far more complex but then again the lighting and shadow mapping is far better than what I was able to do on my own, but I’m seeing FPS in the 50-100 range for similar vertex count.

I can optimize the vertex count much lower when I start run length encoding blocks together, so maybe it’s not a big deal.

I’m also not 100% sure that frustum culling (AddDefaultFrustumCulling) is actually doing anything.

To use AddDefaultFrustumCulling, you’ll have to set the bounding boxes in each Mesh instance.

Paradox does not calculate this automatically, but there’s a constructor for the BoundingBox class which takes a minimum and maximum Vector3, so it’s quite easy to set it yourself.

Also AddDefaultFrustumCulling seems to be using the Mesh’s TransformationKeys.World parameter, however this seems a bit weird to me as that does not get set automatically.
I changed the behavior of the AddDefaultFrustumCulling method to directly use the Entity’s world matrix, which works fine.