How to use instancing / glsl

Problems building or running the engine, queries about how to use features etc.
Post Reply
kuma
Kobold
Posts: 25
Joined: Sat May 17, 2014 6:35 am

How to use instancing / glsl

Post by kuma »

I'm lost in how to get instancing working, I want to pass the position of an instance to GLSL.
Infact do I even need to do that, will set position on the instanced entity work? If so how can I get glsl to display the instanced entity... it's showing nothing.

The demo sample uses worldMatrix3x4Array , but I just want to pass position, it seems if I don't have worldMatrix3x4Array, it will just fail at glsl compile with ...
what(): OGRE EXCEPTION(2:InvalidParametersException): Material 'material' is malformed for this instancing technique in InstanceBatchShader::calculateMaxNumInstances at /var/tmp/portage/dev-games/ogre-1.9.0-r1/work/ogre-1.9.0/OgreMain/src/OgreInstanceBatchShader.cpp (line 119)
so my code looks something like this..

Code: Select all

    Ogre::InstanceManager *grid_segment = OgreFramework::getSingletonPtr()->m_pSceneMgr->createInstanceManager( "meh", name, Ogre::ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME, Ogre::InstanceManager::ShaderBased, 80, Ogre::IM_USEALL );

    grid_segment->setNumCustomParams( 1024 );

    std::vector<Ogre::SceneNode> m_instancedNodes; //Use an array of SceneNodes not created by Ogre
    std::vector<Ogre::MovableObject*> mEntities;

    mEntities.reserve( pow((map_size/segment_size), 2) );
    m_instancedNodes.reserve( pow((map_size/segment_size), 2) );

    m_instancedNodes.resize( pow((map_size/segment_size), 2), Ogre::SceneNode( 0 ) ); //Create them

    for ( int x = 0 ; x < map_size/segment_size; x++) {
        int x_position = 0;
        for ( int y = 0 ; y < map_size/segment_size; y++) {

            int entity_id = x*(map_size/segment_size)+y;

            Ogre::Vector3 strip_position = Ogre::Vector3((float)x_position, 0.0, (float)y_position);
            Ogre::InstancedEntity *thisInstance = OgreFramework::getSingletonPtr()->m_pSceneMgr->createInstancedEntity( "material", "meh" );
            thisInstance->setCastShadows(false);
            thisInstance->setCustomParam( entity_id, Ogre::Vector4((float)x_position, 0.0, (float)y_position, 0) );
            thisInstance->setScale(Ogre::Vector3(1000,1000,1000));

            mEntities.push_back(thisInstance);

            m_instancedNodes[entity_id].attachObject( mEntities[entity_id] );
            m_instancedNodes[entity_id]._update( true, true ); //Needed after attach.
            m_instancedNodes[entity_id].setPosition(strip_position);

            x_position = x_position + strip_offset;

        }
        y_position = y_position + strip_offset;
    }

The problem I have is I have no idea how I can use this with the shader.. I'm pretty lost and I don't really see any examples or anything in the documentation about it. It's really lacking.
BAntDit
Kobold
Posts: 32
Joined: Mon Oct 27, 2014 5:43 pm
x 2

Re: How to use instancing / glsl

Post by BAntDit »

Code: Select all

 I want to pass the position of an instance to GLSL
Hi,

Ogre3D pass instanced attributes as vec4 uv attributes (from first free uv attribute).

For example, if you have one tex coord set in uv0 then instanced attributes starts form uv1 and Ogre3D pass whole entity transform as row-major matrix in vectors uv1-uv3

For example,

Code: Select all

#version 440

// geometry attributes
in vec4 position;
in vec3 normal;
in vec2 uv0;

// instancing attributes (transform)
in vec4 uv1;
in vec4 uv2;
in vec4 uv3;

// custom instance attribute
// in vec4 uv4; // there could be custom attributes

void main()
{
mat4 worldMatrix;
	worldMatrix[0] = uv1;
	worldMatrix[1] = uv2;
	worldMatrix[2] = uv3;
	worldMatrix[3] = vec4(0.0, 0.0, 0.0, 1.0);

// mul(position, wolrdMatrix) - becouse worldMatrix is row-major
vec4 worldPosition = position * worldMatrix;  [b]// thats world position[/b]

gl_Position = viewProjMatrix * worldPosition;
}
----
if you need only entity position and does not interest in scale and rotation, you can get position from uv attributes as well:

Code: Select all

vec3 entityPosition = vec3(uv1.w, uv2.w, uv3.w);
BAntDit
Kobold
Posts: 32
Joined: Mon Oct 27, 2014 5:43 pm
x 2

Re: How to use instancing / glsl

Post by BAntDit »

Ohh.... sorry,
I've missed techinique that you use.
I've thought you use Hardware Instancing Basic technique, but looks like you use ShaderBased technique...

My bad :oops:

Moderator, pls, remove my message above.
kuma
Kobold
Posts: 25
Joined: Sat May 17, 2014 6:35 am

Re: How to use instancing / glsl

Post by kuma »

Thanks for your reply. I actually don't mind using HWInstancingBasic , I'm just looking for performance increase.
This is for terrain. A couple of things.. Do I need to add set any params? would set position not set the position by itself?
right now I just get one entity drawn.. it seems not to be drawing the others.. maybe it's drawing them all at the same location cause it seems kinda slow...
kuma
Kobold
Posts: 25
Joined: Sat May 17, 2014 6:35 am

Re: How to use instancing / glsl

Post by kuma »

hmm, seems still not working. Is there anything else I need to add into the material file? It still just shows on entity..
I'm using HWInstancingBasic now with the same code above. I've removed the setCustomParam however.. since I saw that was not used in the sample.

Edit: Wait my scale was messed up which meant your uv suggestion is actually working. I'm going to do some more testing and get back :)
kuma
Kobold
Posts: 25
Joined: Sat May 17, 2014 6:35 am

Re: How to use instancing / glsl

Post by kuma »

Ok, great thanks :) That's working more or less how I want.

One other question. This method uses meshes. My previous implementation I was creating my own hardwarebuffers, which had good performance.
Is it possible to use instancedenties with meshes? I can't see a direct way of doing it??

Thanks again for your help!!
Post Reply