Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Mesh Instancing problems

in Questions Posts: 30

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;
}
]]
IMG_0029.PNG 808.7K

Comments

  • dave1707dave1707 Mod
    Posts: 6,102

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

  • Posts: 30

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

  • Posts: 30

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

  • Jmv38Jmv38 Mod
    edited July 2 Posts: 3,268

    if you use the following syntax:

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

    you will get your image displayed in the forum:

  • dave1707dave1707 Mod
    Posts: 6,102

    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
    
  • Posts: 30

    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.

  • dave1707dave1707 Mod
    Posts: 6,102

    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;
        }
        ]]
    
  • Posts: 30

    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?

  • edited July 2 Posts: 448

    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)
    ...
    
  • Posts: 30

    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.

  • dave1707dave1707 Mod
    Posts: 6,102

    @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)

Sign In or Register to comment.