# \[Solved\] Updating multiple attributes with instanced rendering

**URL:** <https://discourse.libcinder.org/t/solved-updating-multiple-attributes-with-instanced-rendering/1138>\
**Category:** Using Cinder\
**Created:** [April 24, 2018, 11:56pm UTC](https://discourse.libcinder.org/t/solved-updating-multiple-attributes-with-instanced-rendering/1138 "2018-04-24T23:56:57Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![DanFaraday](https://avatars.discourse-cdn.com/v4/letter/d/a5b964/32.png) [@DanFaraday](https://discourse.libcinder.org/u/DanFaraday)\
**Post date:** [April 24, 2018, 11:56pm UTC](https://discourse.libcinder.org/t/solved-updating-multiple-attributes-with-instanced-rendering/1138/1 "2018-04-24T23:56:57Z")

</div>

Hi Everyone,

I’m new to Cinder, coming from a webdev background. I’ve experimented with a bit of WebGL, but trying to expand my horizons.

I’m trying to learn about Instanced Rendering using the InstancedTeapots sample. I understand the general concept, but can’t quite translate that into practical changes to the code.

I want to assign each teapot a different color, but think I’m approaching it incorrectly.

My setup

```auto
 // Shader for the 3D instanced object
    mGlsl = ci::gl::GlslProg::create( ci::app::loadAsset( "shader.vert" ), ci::app::loadAsset( "shader.frag" ) );
    
    ci::gl::VboMeshRef mesh = ci::gl::VboMesh::create( ci::geom::Teapot() );
    
    // create an array of initial per-instance positions laid out in a 2D grid
    std::vector<ci::vec3> bufferData;
    bufferData.resize(2*(mNumX * mNumY));
    
    for( size_t potX = 0; potX < mNumX; ++potX ) {
        for( size_t potY = 0; potY < mNumY; ++potY ) {
            float instanceX = potX / (float)mNumX - 0.5f;
            float instanceY = potY / (float)mNumY - 0.5f;
            
            ci::vec3 pos;
            
            pos = ci::vec3( instanceX * mGridSpacing, 0 , instanceY * mGridSpacing);
            bufferData.push_back( pos );
            bufferData.push_back(ci::vec3(ci::randFloat(), ci::randFloat(), ci::randFloat() ));
        }
    }
    
    // create the VBO which will contain per-instance (rather than per-vertex) data
    mInstanceDataVbo = ci::gl::Vbo::create( GL_ARRAY_BUFFER, bufferData.size() * sizeof(ci::vec3), bufferData.data(), GL_DYNAMIC_DRAW );
    
    // we need a geom::BufferLayout to describe this data as mapping to the CUSTOM_0 semantic, and the 1 (rather than 0) as the last param indicates per-instance (rather than per-vertex)
    ci::geom::BufferLayout instanceDataLayout;
    instanceDataLayout.append( ci::geom::Attrib::CUSTOM_0, 3, sizeof(ci::vec3), 0, 1 /* per instance */ );
    
    // need to change the offset
    instanceDataLayout.append( ci::geom::Attrib::CUSTOM_1, 3, sizeof(ci::vec3), sizeof(ci::vec3), 1 /* per instance */ );
    
    
    // now add it to the VboMesh we already made of the Teapot
    mesh->appendVbo( instanceDataLayout, mInstanceDataVbo );
    
    // and finally, build our batch, mapping our CUSTOM_0 attribute to the "vInstancePosition" GLSL vertex attribute
    mInstanceBatch = ci::gl::Batch::create( mesh, mGlsl, { { ci::geom::Attrib::CUSTOM_0, "vInstancePosition" },
        { ci::geom::Attrib::CUSTOM_1, "vInstanceColor" }
    } );
    
    ci::gl::enableDepthWrite();
    ci::gl::enableDepthRead();
    
    
    // Shader for the 3D instanced object
    mGlsl = ci::gl::GlslProg::create( ci::app::loadAsset( "shader.vert" ), ci::app::loadAsset( "shader.frag" ) );

```

My Update:

```auto
 ci::vec3 *sphere = (ci::vec3*)mInstanceDataVbo->mapReplace();
    
     for( size_t potX = 0; potX < mNumX; ++potX ) {
         for( size_t potY = 0; potY < mNumY; ++potY ) {
                float instanceX = potX / (float)mNumX - 0.5f;
                float instanceY = potY / (float)mNumY - 0.5f;

                ci::vec3 newPos( instanceX * mGridSpacing, 0 , instanceY * mGridSpacing);
                *sphere++ = newPos;
                *sphere++ = ci::vec3(1.,1.,1.); // try resetting the color
         }
     }
     mInstanceDataVbo->unmap();

```

vert shader:

```auto
#version 150

uniform mat4 ciModelViewProjection;
uniform mat4 ciProjectionMatrix, ciViewMatrix;
uniform mat3 ciNormalMatrix;

in vec4 ciPosition;
in vec2 ciTexCoord0;
in vec3 ciNormal;
in vec4 ciColor;
in vec3 vInstancePosition; // per-instance position variable
in vec3 vInstanceColor;
out highp vec2 TexCoord;
out lowp vec4 Color;
out highp vec3 Normal;

void main( void )
{
    gl_Position = ciModelViewProjection * (ciPosition + vec4( vInstancePosition, 0 ) );
    Color = vec4(vInstanceColor, 1.f);
    TexCoord = ciTexCoord0;
    Normal = ciNormalMatrix * ciNormal;
}

```

Should I be separating the positions and colors into separate buffers? Or is there a different way to update the buffer instead of mapReplace()?

Thanks!

Dan

[Solved]

The StereoscopicRendering sample shows how to do this. Solution was to create a struct and reference the color and position using:

```auto
         data->position = newPos;
         data->color = newColor;

```

---

<div class="post-metadata">

**Author:** ![paul.houx](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/paul.houx/32/31_2.png) [@paul.houx](https://discourse.libcinder.org/u/paul.houx)\
**Post date:** [April 25, 2018, 6:15am UTC](https://discourse.libcinder.org/t/solved-updating-multiple-attributes-with-instanced-rendering/1138/2 "2018-04-25T06:15:31Z")

</div>

A quick note for future reference: try to structure your data in groups of 4 floats, so that it conforms to the so-called `std140` [memory layout](https://www.khronos.org/opengl/wiki/Interface_Block_(GLSL)#Memory_layout). This will avoid misaligned data and makes life a bit easier in most cases.

A 3D position and an RGBA color could be packed like this:

```auto
struct Data {
  vec3 position; // 3 floats
  float reserved; // 1 alignment float, not containing any meaningful data 
  vec4 color; // 4 floats
}

```

Some examples of valid groups of 4 floats:

```auto
struct Data {
  vec4 a; // obviously :)

  vec3 b; // 3 + 1 float
  float c; 

  vec2 d; // 2 + 2 floats
  vec2 e;

  vec2 f; // 2 + 1 + 1 float
  float g;
  float h;

  float i; // 1 + 1 + 1 + 1 float
  float j;
  float k;
  float l;

  vec3 m; // 3 + 1 32-bit integer
  int n; // 32-bit integers (int32_t) use the same number of bytes (4) as floats
}

```

Example of invalid packing:

```auto
struct Garbage {
  float a; // OpenGL will turn this float into a vec4(!)...
  vec3 b; // ...and will then turn this vec3 into a vec4!
}

```

As a rule of thumb: go from big to small.

-Paul

---

<div class="post-metadata">

**Author:** ![DanFaraday](https://avatars.discourse-cdn.com/v4/letter/d/a5b964/32.png) [@DanFaraday](https://discourse.libcinder.org/u/DanFaraday)\
**Post date:** [April 25, 2018, 2:35pm UTC](https://discourse.libcinder.org/t/solved-updating-multiple-attributes-with-instanced-rendering/1138/3 "2018-04-25T14:35:12Z")

</div>

Thank you @paul.houx, that’s very interesting! I read something about ‘padding’ buffer data, I assume this Is what you’re talking about?

One thing that still confuses me, is that I don’t have any alpha blending on, and I’ve enabled depthRead and depthWrite, but it still seems like the objects are drawing in the incorrect or, or have some sort of transparency…

 ![30%20AM](https://canada1.discourse-cdn.com/flex030/uploads/libcinder/original/1X/73f6851e4e94c551bd82e85aef54458008ce17ee.jpg)

---

<div class="post-metadata">

**Author:** ![paul.houx](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/paul.houx/32/31_2.png) [@paul.houx](https://discourse.libcinder.org/u/paul.houx)\
**Post date:** [April 25, 2018, 9:11pm UTC](https://discourse.libcinder.org/t/solved-updating-multiple-attributes-with-instanced-rendering/1138/4 "2018-04-25T21:11:21Z")

</div>

Possible fixes:

- Check your fragment shader to make sure you write `1` to the output alpha. If you’re outputting a `vec3`, use a `vec4` instead and set its 4th component to 1.
- Check if you do have a depth buffer. If you’re rendering to an `Fbo`, make sure its depth buffer is enabled and cleared.
- Try to explicitly set the blend mode to “no blending”. Perhaps the OpenGL state is dirty (the effect in the image looks like some kind of _subtractive_ blending, interesting).

---

<div class="post-metadata">

**Author:** ![DanFaraday](https://avatars.discourse-cdn.com/v4/letter/d/a5b964/32.png) [@DanFaraday](https://discourse.libcinder.org/u/DanFaraday)\
**Post date:** [May 1, 2018, 9:26pm UTC](https://discourse.libcinder.org/t/solved-updating-multiple-attributes-with-instanced-rendering/1138/5 "2018-05-01T21:26:21Z")

</div>

Hi Paul,

Sorry about the delayed response. Explicitly using gl::disableBlending() solved the problem. Not sure how the state got ‘dirty’, as you mentioned, as I have no other calls to blending in the app…

---

<div class="post-metadata">

**Author:** ![paul.houx](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/paul.houx/32/31_2.png) [@paul.houx](https://discourse.libcinder.org/u/paul.houx)\
**Post date:** [May 2, 2018, 5:51am UTC](https://discourse.libcinder.org/t/solved-updating-multiple-attributes-with-instanced-rendering/1138/6 "2018-05-02T05:51:54Z")

</div>

Hi Dan,

I would not be surprised if alpha blending is enabled by default. I seem to remember a discussion about it among the core Cinder devs. It used to be disabled by default, but then users were confused when their text rendering looked bad. Kind of the opposite of your use case 🙂

-Paul
