@Simeon I think I’ve worked out what was causing the black mesh issue in build 60+ of 2.3.2 and managed to fix it. I no longer think it’s a bug, but there does seem to be a change in how shaders are attached to meshes.
It’s a bit complex, but I’ll try to explain.
Say I have a 3D scene with a bunch of procedurally generated meshes for the scenery. Each mesh is unique, ie is only drawn once, and is held in a table, scenery = {}
. Each mesh is lit with a diffuse lighting shader.
Here’s the part that seems to have changed in 2.3.2. Let’s say I define the shader only once, in setup (as apparently defining lots of shader objects does take up some resources. I think I read that in Apple guidelines):
diffuseShader = {
vert = [[ //blah ]],
frag = [[ //blah ]]
}
function setup()
diffuse = shader(diffuseShader.vert, diffuseShader.frag)
then, I have lots of scenery meshes, each one has the pre-defined shader attached:
for i =1, #scenery do
scenery[i].mesh = mesh()
scenery[i].mesh.shader = diffuse
then, in the course of the game, I update various uniforms on the shader:
scenery[i].mesh.shader.lightDirection = position
or whatever.
This sort of set up used to work. Even though the shader object is only defined once, by attaching it to lots of separate mesh objects you seemed to create separate instances of the shader, whose custom uniform variables could be set independently.
With 2.3.2 however, if you try this, you only have one shader object. So the line:
scenery[i].mesh.shader.lightDirection = position
sets the lightDirection
uniform not just for scenery[i].mesh
, but for every single mesh that has the pre-defined diffuse
shader.
Fixing this is very very easy (but has taken me weeks to figure out!). Instead of defining a global shader object, redefine the shader object for every single instance of the mesh, like this:
for i =1, #scenery do
scenery[i].mesh = mesh()
scenery[i].mesh.shader = shader(diffuseShader.vert, diffuseShader.frag) --NEW in 2.3.2: redefine shader object
This ensures you have independent shader objects capable of remembering independent uniform variables.
This fixed the black mesh issue I was having.
@Simeon are you able to confirm this change in how shaders are bound to mesh objects?
This only really comes up with unique geometry that isn’t being recycled across the scene. It’s not an issue if you’re reusing a model (eg an NPC tank or whatever), as when you’re drawing the same mesh in multiple locations you’d set/reset the shader uniforms before each instance’s draw
command anyway.
So it’s a fairly narrow set of circumstances where people will notice a change with 2.3.2, but I thought it was worth posting about it, in case anyone else has run into this.