[SOLVED]Ogre 1 12 instantiating

Problems building or running the engine, queries about how to use features etc.
User avatar
paul424
Gnome
Posts: 377
Joined: Thu May 24, 2012 7:16 pm
x 18

[SOLVED]Ogre 1 12 instantiating

Post by paul424 »

Ogre Version: : 1 12 13:
Operating System: :Linux Tumbleweed:
Render System: :OpenGL3+

This code should help with instanciacing a non-animated mesh, however it shows ONLY one mesh in
world coordinates (0,0,0) although the number of Dirt Tiles goes in hundreds .... What I presume the instanceMatrix is wrongly passed to the shader.....
How it should be done in 1 12 13, or should I upgrade it to 1 14 2 ( a tough task as I cannot make CEGUI working with the newest ogre version)....

Code: Select all

#version 330 core

layout(location = 0) in vec3 inPosition;         // Vertex position
layout(location = 1) in vec3 inNormal;           // Vertex normal
layout(location = 2) in vec2 inTexCoord;         // Texture coordinates
layout(location = 3) in vec4 instanceMatrixRow0; // Instance matrix row 0
layout(location = 4) in vec4 instanceMatrixRow1; // Instance matrix row 1
layout(location = 5) in vec4 instanceMatrixRow2; // Instance matrix row 2
layout(location = 6) in vec4 instanceMatrixRow3; // Instance matrix row 3

uniform mat4 viewProj; // Combined view and projection matrix

out vec2 fragTexCoord; // Pass texture coordinates to fragment shader

void main()
{
    // Construct the instance transformation matrix
    mat4 instanceMatrix = mat4(instanceMatrixRow0, instanceMatrixRow1, instanceMatrixRow2, instanceMatrixRow3);
    
// Apply the instance transformation vec4 worldPosition = instanceMatrix * vec4(inPosition, 1.0); // Compute final position gl_Position = viewProj * worldPosition; // Pass texture coordinates to fragment shader fragTexCoord = inTexCoord; }
Last edited by paul424 on Fri Jul 26, 2024 1:10 pm, edited 1 time in total.
User avatar
paul424
Gnome
Posts: 377
Joined: Thu May 24, 2012 7:16 pm
x 18

Re: Ogre 1 12 instantiating

Post by paul424 »

I didn't provide a broader context , sorry.
I do use Ogre::InstanceManager::HWInstancingBasic, like :

Ogre::InstanceManager* instanceManager = sceneManager->createInstanceManager(
"InstanceMgr",
"Dirt_fl_1011.mesh",
"General",
Ogre::InstanceManager::HWInstancingBasic,
80,
Ogre::IM_USEALL
);

Here's the example program I tinkertoy with and so far with THIS program I cannot get a single mesh on screen:

(If I change createInstancedEntity to createEntity ( plus a few other changes ) I get a mesh on screen ......)

Code: Select all

#include <iostream>
#include <Ogre.h>
#include <OgreApplicationContext.h>
#include <OgreInstancedEntity.h>
#include <OgreInstanceManager.h>
#include <OgreRTShaderSystem.h> // Include the RTShader header

class MyApplication : public OgreBites::ApplicationContext, public OgreBites::InputListener
{
public:
    MyApplication() : OgreBites::ApplicationContext("MyApplication") {}

void setup()
{
    OgreBites::ApplicationContext::setup();
    addInputListener(this);

    Ogre::Root* root = getRoot();
    Ogre::SceneManager* sceneManager = root->createSceneManager();

    // Initialize RTShader system
    if (!Ogre::RTShader::ShaderGenerator::initialize())
    {
        OGRE_EXCEPT(Ogre::Exception::ERR_INTERNAL_ERROR, "Failed to initialize RTShader system", "MyApplication::setup");
    }
    Ogre::RTShader::ShaderGenerator* shadergen = Ogre::RTShader::ShaderGenerator::getSingletonPtr();
    shadergen->addSceneManager(sceneManager);

    // Disable shadows
    sceneManager->setShadowTechnique(Ogre::ShadowTechnique::SHADOWTYPE_NONE);

    // Load resources from resources.cfg
    Ogre::ConfigFile cf;
    cf.load("resources.cfg");

    Ogre::String name, locType;
    Ogre::ConfigFile::SectionIterator secIt = cf.getSectionIterator();

    while (secIt.hasMoreElements())
    {
        Ogre::ConfigFile::SettingsMultiMap* settings = secIt.getNext();
        for (auto& pair : *settings)
        {
            locType = pair.first;
            name = pair.second;
            Ogre::ResourceGroupManager::getSingleton().addResourceLocation(name, locType);
        }
    }

    Ogre::LogManager::getSingleton().logMessage("Initializing resource groups...");
    Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();

    // Create a camera and a scene
    Ogre::LogManager::getSingleton().logMessage("Creating camera...");
    Ogre::Camera* cam = sceneManager->createCamera("myCam");
    cam->setAutoAspectRatio(true);
    cam->setNearClipDistance(5);
    getRenderWindow()->addViewport(cam);

    Ogre::LogManager::getSingleton().logMessage("Creating light...");
    Ogre::Light* light = sceneManager->createLight("MainLight");
    light->setCastShadows(false);
    Ogre::SceneNode* lightNode = sceneManager->getRootSceneNode()->createChildSceneNode();
    lightNode->setPosition(0, 10, 15);
    lightNode->attachObject(light);

    Ogre::SceneNode* camNode = sceneManager->getRootSceneNode()->createChildSceneNode();
    camNode->setPosition(0, 10, 40);
    camNode->lookAt(Ogre::Vector3(0, 0, 0), Ogre::Node::TS_PARENT);
    camNode->attachObject(cam);

    // Setup instancing
    Ogre::LogManager::getSingleton().logMessage("Setting up instancing...");
    Ogre::InstanceManager* instanceManager = sceneManager->createInstanceManager(
        "InstanceMgr",
        "Dirt_fl_1011.mesh",
        "General",
        Ogre::InstanceManager::HWInstancingBasic,
        80,
        Ogre::IM_USEALL
    );

    Ogre::MaterialPtr material = Ogre::MaterialManager::getSingleton().getByName("Dirt");
    if (material.isNull())
    {
        Ogre::LogManager::getSingleton().logMessage("Material 'Dirt.material' not found!", Ogre::LML_CRITICAL);
        OGRE_EXCEPT(Ogre::Exception::ERR_ITEM_NOT_FOUND, "Material 'Dirt.material' not found!", "MyApplication::setup");
    }

   
        Ogre::InstancedEntity* instancedEntity = instanceManager->createInstancedEntity("Dirt");
        instancedEntity->setCastShadows(false);
        Ogre::SceneNode* node = sceneManager->getRootSceneNode()->createChildSceneNode();
        node->attachObject(instancedEntity);
        node->setPosition(0, 0, 0);
    

    Ogre::LogManager::getSingleton().logMessage("Setup complete.");
}
};

int main(int argc, char** argv)
{
    try
    {
        MyApplication app;
        app.initApp();
        app.getRoot()->startRendering();
        app.closeApp();
    }
    catch (const Ogre::Exception& e)
    {
        std::cerr << "An exception has occurred: " << e.getFullDescription().c_str() << std::endl;
        return 1;
    }
    return 0;
}

Do I need Ogre::IM_USEALL in createInstanceManager ?

rpgplayerrobin
Gnoll
Posts: 685
Joined: Wed Mar 18, 2009 3:03 am
x 379

Re: Ogre 1 12 instantiating

Post by rpgplayerrobin »

Is your "Dirt" material a copy of exactly how they are shown in the Sample Browser?

Because these are the ones that I find (which you could possibly get the generated glsl shaders from):

Code: Select all

material Examples/Instancing/RTSS/Robot
{
	technique
	{
		shadow_caster_material Examples/Instancing/ShaderBased/shadow_caster

	pass
	{
		specular	1 1 1 1 12.5

		texture_unit
		{
			texture		r2skin.jpg
		}

		rtshader_system
		{
			hardware_skinning 70 1 linear false false
		}
	}
}
}

Code: Select all

material Examples/Instancing/HWBasic/Robot
{
	technique
	{
		shadow_caster_material Examples/Instancing/HWBasic/shadow_caster

	pass
	{
		specular	1 1 1 1 12.5

		texture_unit Diffuse
		{
			texture		r2skin.jpg
		}

		rtshader_system
        {
			transform_stage instanced
		}
	}
}
}
User avatar
paul424
Gnome
Posts: 377
Joined: Thu May 24, 2012 7:16 pm
x 18

Re: Ogre 1 12 instantiating

Post by paul424 »

Code: Select all


// Dirt


vertex_program myDirtTileVertexShader glsl
{
  source DirtTile.vert
    default_params
    {
        param_named_auto projectionMatrix projection_matrix
        param_named_auto viewMatrix view_matrix
        //param_named_auto worldMatrix world_matrix
        //param_named_auto lightMatrix texture_worldviewproj_matrix          
}
} fragment_program myDirtTileFragmentShader glsl { source DirtTile.frag default_params {
} } material Dirt { technique { pass { vertex_program_ref myDirtTileVertexShader { } fragment_program_ref myDirtTileFragmentShader { } } } }
rpgplayerrobin
Gnoll
Posts: 685
Joined: Wed Mar 18, 2009 3:03 am
x 379

Re: Ogre 1 12 instantiating

Post by rpgplayerrobin »

That did not answer my answer.

Have you gone through the generated glsl code from RTSS to see if it is exactly like your own version?

In HLSL it looks a bit different for sure (minimal code here only for the instancing for HWBasic):

Code: Select all

VS_OUTPUT main_vs( float4 position : POSITION,
				   out float4 oPosition : POSITION,
				   float3 normal : NORMAL,
				   float3 iTangent : TANGENT,
				   float2 iUV : TEXCOORD0,
				   float4 mat14 : TEXCOORD1,
				   float4 mat24 : TEXCOORD2,
				   float4 mat34 : TEXCOORD3 )
{
	VS_OUTPUT Out;

float3x4 calculatedWorldMatrix;
calculatedWorldMatrix[0] = mat14;
calculatedWorldMatrix[1] = mat24;
calculatedWorldMatrix[2] = mat34;

float4 worldPos = float4(mul(calculatedWorldMatrix, position).xyz, 1);
float3 worldNorm = normalize(mul((float3x3)calculatedWorldMatrix, normal));
float3 worldTangent = normalize(mul((float3x3)calculatedWorldMatrix, iTangent));

...
}

The difference here is that in the HLSL version for me it takes in the instancing variables at texcoord 1-3 (which are 3 elements in total), but your take in 4 different elements and I am not sure how GLSL actually knows how to bind it to them.

Go into the code and get the generated RTSS code and shader material declaration to get a version that you know is working already.

User avatar
paul424
Gnome
Posts: 377
Joined: Thu May 24, 2012 7:16 pm
x 18

Re: Ogre 1 12 instantiating

Post by paul424 »

I give up:
From such program :

Code: Select all


#version 460
//-----------------------------------------------------------------------------
//                         PROGRAM DEPENDENCIES
//-----------------------------------------------------------------------------
#define USE_OGRE_FROM_FUTURE
#include <OgreUnifiedShader.h>
#include "FFPLib_Transform.glsl"
#include "SGXLib_PerPixelLighting.glsl"
#include "FFPLib_Texturing.glsl"

//-----------------------------------------------------------------------------
//                         GLOBAL PARAMETERS
//-----------------------------------------------------------------------------

layout(location = 0) uniform	mat4	worldviewproj_matrix;
layout(location = 4) uniform	mat3	normal_matrix;
layout(location = 7) uniform	mat4	worldview_matrix;

//-----------------------------------------------------------------------------
//                         MAIN
//-----------------------------------------------------------------------------
IN(vec4	vertex, POSITION)
IN(mat3x4	uv1, TEXCOORD1)
IN(vec3	normal, NORMAL)
IN(vec4	uv0, TEXCOORD0)
OUT(vec3	iTexcoord_0, 0)
OUT(vec3	iTexcoord_1, 1)
OUT(vec2	iTexcoord_2, 2)
void main(void) {
	vec4	lColor_0;
	vec4	lColor_1;

vec4 local_vertex = vertex;
FFP_Transform(uv1, local_vertex, local_vertex.xyz);
vec3 local_normal = normal;
FFP_Transform(uv1, local_normal, local_normal);
FFP_Transform(worldviewproj_matrix, local_vertex, gl_Position);
lColor_0	=	vec4(1.00000,1.00000,1.00000,1.00000);
lColor_1	=	vec4(0.00000,0.00000,0.00000,0.00000);
FFP_Transform(worldview_matrix, local_vertex, iTexcoord_1);
iTexcoord_2	=	uv0.xy;
}


I deduced such program :

Code: Select all

#version 330 core
#extension GL_ARB_explicit_uniform_location : enable
#extension GL_ARB_shading_language_include : enable

#define USE_OGRE_FROM_FUTURE
#include <OgreUnifiedShader.h>
#include "FFPLib_Transform.glsl"
#include "SGXLib_PerPixelLighting.glsl"
#include "FFPLib_Texturing.glsl"
#include "PerlinNoise.glsl" 


uniform    mat4 projectionMatrix;
uniform    mat4 viewMatrix;
uniform    mat4 worldMatrix;
uniform    mat4 worldviewproj_matrix;
uniform    mat4 lightMatrix;

layout (location = 0) in vec4 position;
layout (location = 2)  in vec3 normal;



layout (location = 8) in vec2 uv_0;
layout (location = 8) in vec2 uv_1;
layout (location = 14) in vec3 tangent;
IN(mat3x4	uv1, TEXCOORD1)
out vec2 out_UV0;
out vec2 out_UV1;

out vec3 FragPos;
out vec4 VertexPos; 
 
out mat3 TBN;
 
float freq = 3.1415; 
 
void main() {
    vec4 local_position = position;
    FFP_Transform(uv1, local_position, local_position.xyz);
    vec3 local_normal = normal;
    FFP_Transform(uv1, local_normal, local_normal.xyz);

vec3 local_tangent =tangent;
 FFP_Transform(uv1, local_tangent, local_tangent.xyz); 
// compute world space local_position, local_tangent, bilocal_tangent
vec3 P = (worldMatrix * local_position).xyz;
vec3 T = normalize(vec3(worldMatrix * vec4(local_tangent, 0.0)));
vec3 B = normalize(vec3(worldMatrix * vec4(cross(local_tangent, local_normal), 0.0))); 
 
vec3 N = cross(B, T);
TBN = mat3(T, B, N);
 
gl_Position = worldviewproj_matrix * local_position;
FragPos = P;
 
out_UV0 = vec2(1.0,1.0);// uv_0;
out_UV1 = vec2(1.0,1.0); //uv_1;
VertexPos = lightMatrix * local_position;    
}  

But I get degenerated mesh; that is instead of this :

I get this :

How does ogre3d handle mat3x4 , are those macrodefintions or extensions ? Afaik the GLSL does not support non-square matrix'es ....
EDIT : the deformed mesh is introduced only when line FFP_Transform(uv1, local_position, local_position.xyz); is present --- that means the uv1 format is wrong ...

User avatar
paul424
Gnome
Posts: 377
Joined: Thu May 24, 2012 7:16 pm
x 18

Re: Ogre 1 12 instantiating

Post by paul424 »

Uhh the mesh I was operating had more then one texture coordinates, that fooled the vertex program and it recieved in IN(mat3x4 uv1, TEXCOORD1) obviously not instance transformation mesh, but that texture coordiantes. I mark the topic as solved then....

paroj
OGRE Team Member
OGRE Team Member
Posts: 2108
Joined: Sun Mar 30, 2014 2:51 pm
x 1134

Re: [SOLVED]Ogre 1 12 instantiating

Post by paroj »

note that I have added instancing to my fork here (requires Ogre 13.5+)
https://github.com/paroj/OpenDungeons/c ... 255ac25d33

User avatar
paul424
Gnome
Posts: 377
Joined: Thu May 24, 2012 7:16 pm
x 18

Re: [SOLVED]Ogre 1 12 instantiating

Post by paul424 »

Hmm that would be inresting , if not most of the Tile based Entitites used custom shaders.
What I try to achieve is this :

I will see tomorrow what can be achieved with those clouds ..... that is how fast the instantiating would boost the drawing of it.
So far on a decent card it slows down from 60 to ~ 30 fps.....