Mesh Instancing problems

I’m trying to play with mesh instancing and I’m getting really odd visual artifacts if I go over maybe 200 or so instances. Am I misunderstanding how this works or is there a bug somewhere?

function setup()
    width = 50
    height = 50
    numInstances = width * height
    
    m = mesh()
    m.shader = shader(vert, frag)
    
    m:addRect(0,0,5,5)
    m:setColors(color(255,200,0))

    transform = m:buffer("transform")
    transform:resize(numInstances)
    transform.instanced = true
    
    for i=0,(numInstances-1) do
        local x = i % width
        local y = math.floor(i / width)
        transform[i+1] = matrix():translate(6 + x*6, 6 + y*6)
    end

end

function draw()
    background(40, 40, 50)
    m:draw(numInstances)
end

vert=[[
#version 300 es

uniform mat4 modelViewProjection;

in mat4 transform;
in vec4 position;
in vec4 color;

out lowp vec4 vColor;

void main()
{
    vColor = color;
    gl_Position = modelViewProjection * (transform * position);
}
]]

frag=[[
#version 300 es

in lowp vec4 vColor;
out lowp vec4 fragColor;

void main()
{
    fragColor = vColor;
}
]]

@BigZaphod Each time I run your code, I get something different. What are you trying to accomplish.

Well it shouldn’t be different every time and that’s the problem here.

There should just be 50x50 yellow rectangles. If you drop the width and height down to 10 or so, it works fine every time.

if you use the following syntax:

![](https://codea.io/talk/uploads/editor/ra/pdoautru7bgd.png)

you will get your image displayed in the forum:

Here’s an example showing an array of meshes with a texture.

function setup()
    size=20
    m=mesh()
    for x=1,WIDTH/size do
        for y=1,HEIGHT/size do
            m:addRect(x*size,y*size,size,size*2)
        end
    end
    m.texture="Planet Cute:Character Cat Girl"
end

function draw()
    background(40, 40, 50)
    m:draw()
end

That’s the same visual result I’m going for, yes, but not the purpose of this experiment. I’m trying to use instancing in order to do the same thing and it’s glitching out. What I don’t know is if I’m instancing wrong or if Codea has a bug.

Here’s an example of instancing in only one direction.

function setup()
    m = mesh()
    m:addRect(0,0,10,10)
    m:setColors(color(255,255,0))
    m.shader = shader(vert, frag)
    numInstances = 40
    xVal=30
end

function draw()
    background(40, 40, 50)
    m.shader.xVal=xVal
    m:draw(numInstances)
end

vert=[[
    #extension GL_EXT_draw_instanced: enable     
    uniform mat4 modelViewProjection;
    attribute vec4 position;
    attribute vec4 color;    
    varying lowp vec4 vColor;
    uniform highp float xVal;
    void main()
    {   vColor = color;
        float xOffset = xVal;
        float yOffset = float (gl_InstanceIDEXT) * 12.+100.;
        vec4 offset = vec4(xOffset, yOffset, 0, 0);
        gl_Position = modelViewProjection * (position+offset);
    }
    ]]

frag=[[    
    varying lowp vec4 vColor;
    void main()
    {   gl_FragColor = vColor;
    }
    ]]

I did some more experimenting and it looks like there’s a bug or limitation somewhere. Any more than 256 instances will start corrupting the visuals. Perhaps internally Codea is storing the instance count as a byte?

I dind’t try your code but maybe you’re having issues with vertices count.
Try increase the initial buffer size of the mesh!

....
m = mesh()
m:resize(5000)
...

I don’t think vertex count is the issue - there are only 6 in the mesh. Instancing is a technique for telling the GPU to redraw the same mesh some number of times in order to avoid using a lot of vertices in the mesh itself or needing so many draw calls.

@BigZaphod Here’s 185,000 meshes (370x500). There are 370 rects being drawn 500 numinstances.

supportedOrientations(PORTRAIT_ANY)
displayMode(FULLSCREEN)

function setup()
    print(370*500)
    m = mesh()
    for z=1,370 do
        m:addRect(z*2,0,1,1)
    end
    m:setColors(color(255,255,0))
    m.shader = shader(vert, frag)
    numInstances = 500
    xVal=10
end

function draw()
    background(40, 40, 50)
    m.shader.xVal=xVal
    m:draw(numInstances)
end

vert=[[
    #extension GL_EXT_draw_instanced: enable     
    uniform mat4 modelViewProjection;
    attribute vec4 position;
    attribute vec4 color;    
    varying lowp vec4 vColor;
    uniform highp float xVal;
    void main()
    {   vColor = color;
        float xOffset = xVal;
        float yOffset = float (gl_InstanceIDEXT) * 2.+10.;
        vec4 offset = vec4(xOffset, yOffset, 0, 0);
        gl_Position = modelViewProjection * (position+offset);
    }
    ]]

frag=[[    
    varying lowp vec4 vColor;
    void main()
    {   gl_FragColor = vColor;
    }
    ]]

Errmeger!! Incidentally was just doing some inital tests with instancing.
Really cool start points @dave1707 Good work!

@BigZaphod in the code you had initially posted, you have not enabled the instancing extension, reference the first line of both of the vert shaders @dave1707 posted:

    #extension GL_EXT_draw_instanced: enable     

you also need to then use the built in gl_InstanceIDEXT attribute to access the instance number (Dave uses this in the yOffset float in his shaders)