Setting unique colours for entities with setCustomParameter

Anything and everything that's related to OGRE or the wider graphics field that doesn't fit into the other forums.
daveraja
Gnoblar
Posts: 2
Joined: Wed Sep 28, 2016 8:45 am

Setting unique colours for entities with setCustomParameter

Post by daveraja »

I want to assign individual solid colours to each entity. To do this I am setting a custom parameter in my GLSL shader to assign each (sub-)entity a colour value.

As a first step in my testing I created a wrapper for the createEntity() call to modify the entity's material and set the custom parameter to blue. Unfortunately, all I am getting are black entities as if the shader is failing.

But when I manually use setNamedConstant() as a parameter in the pass for the vertex shader it seems to work, which suggests that the shader is working (at some level). I've been searching through the forums for the past couple of weeks and found many related comments (mostly old posts) but nothing quite like what I've experienced.

Here is my wrapper code to set the material and custom colour for each entity:

Code: Select all


constexpr unsigned int MODELCOLOR_INDEX=0;

inline Ogre::MaterialPtr get_object_material()
{
    static Ogre::MaterialPtr g_mat;
    if (g_mat.isNull())
    {
        g_mat = Ogre::MaterialManager::getSingleton().getByName("Gazebo/ObjectMap");
        g_mat->load();
    }
    return g_mat;
}


template<typename... Args>
Ogre::Entity* create_entity(Ogre::SceneManager* sm, Args&&... args)
{
    Ogre::Vector4 somecolor{0.0, 0.0, 1.0, 1.0};
    Ogre::Entity* pEntity = sm->createEntity(args...);
    pEntity->setMaterial(get_object_material());
    for (unsigned int i = 0; i < pEntity->getNumSubEntities(); ++i)
    {
        pEntity->getSubEntity(i)->setCustomParameter(MODELCOLOR_INDEX, somecolor);
        pEntity->getSubEntity(i)->setMaterial(get_object_material());
    }
    return pEntity;
}
The following is the relevant excerpt from the material file (note: I am doing this as part of modifying the Gazebo robot simulator code, hence the Gazebo naming):

Code: Select all

vertex_program Gazebo/ObjectMapVS glsl
{
  source object_map.vert

  param_named_auto modelColor custom 0

  default_params
  {
    param_named_auto texelOffsets texel_offsets
  }
}

fragment_program Gazebo/ObjectMapFS glsl
{
  source object_map.frag
}


material Gazebo/ObjectMap
{
  technique
  {
    pass
    {
      vertex_program_ref Gazebo/ObjectMapVS { }
      fragment_program_ref Gazebo/ObjectMapFS { }
    }
  }
}
And here is the GLSL vertex and fragment shaders. In case you are wondering, I originally had the colour being set in the fragment shader but since that wasn't working I changed it to the vertex shader and then simply passed it as a "varying" to the fragment shader.

The vertex shader object_map.vert:

Code: Select all

uniform vec4 texelOffsets;
uniform vec4 modelColor;
varying vec4 mcolor;
void main()
{
  gl_Position = ftransform();
  gl_Position.xy += texelOffsets.zw * gl_Position.w;
  mcolor = modelColor;
}
and the fragment shader object_map.frag:

Code: Select all

varying vec4 mcolor;
void main()
{
  gl_FragColor = mcolor;
}
With the above all I get is that every object is shaded black!

However, as part of rendering to a texture (which is ultimately what I want to do) I explicitly set the "modelColor" named constant as a parameter for the vertex shader pass:

Code: Select all

   auto vparams = pass->getVertexProgramParameters();
   Ogre::Vector4 vec4{0.0, 1.0, 0.0, 1.0};
    vparams->setNamedConstant("modelColor", vec4);
    pass->setVertexProgramParameters(vparams);
This does work and here sets the colour of each entity to green. So the shaders are working, just not doing what I want.

So I am confused why it is not treating the "modelColor" as a custom parameter (which should be set here with index 0) and instead treating it as a named constant. Is there something wrong in how I've set up the shaders or is it something deeper in my (lack of) understanding?

Dave
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5561
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1403

Re: Setting unique colours for entities with setCustomParame

Post by dark_sylinc »

Here's your bug:

Code: Select all

vertex_program Gazebo/ObjectMapVS glsl
{
  source object_map.vert

  param_named_auto modelColor custom 0

  default_params
  {
    param_named_auto texelOffsets texel_offsets
  }
}
It should be:

Code: Select all

vertex_program Gazebo/ObjectMapVS glsl
{
  source object_map.vert

  default_params
  {
    param_named_auto modelColor custom 0
    param_named_auto texelOffsets texel_offsets
  }
}
You were declaring the auto param in the wrong place :)
daveraja
Gnoblar
Posts: 2
Joined: Wed Sep 28, 2016 8:45 am

Re: Setting unique colours for entities with setCustomParame

Post by daveraja »

dark_sylinc wrote: You were declaring the auto param in the wrong place :)
Agh. I don't know whether to be happy or angry with myself! I was sure I tried that at some point :oops:

Anyway, this gets me one step closer to my goal :D

I'm still confused about the rendering to the texture part where I manually set the material and pass. In this case all the entities are being given the same colour rather than their own unique colours. It is one of the colours assigned with setCustomParameter() but I don't think it was necessarily the last one assigned. So, maybe this level of control sits underneath the custom parameters and I need to set up some sort of rendering queue.

Thanks a lot for your help. I'll keep digging and experimenting... if you haven't already guessed I'm totally new to OGRE/rendering.

Dave