Normal Mapping with Programmatic Material Topic is solved

Problems building or running the engine, queries about how to use features etc.
chilly willy
Halfling
Posts: 75
Joined: Tue Jun 02, 2020 4:11 am
x 22

Normal Mapping with Programmatic Material

Post by chilly willy »

Ogre Version: latest
Operating System: macOS
Render System: GL3Plus

I am trying to create a Material through code that uses normal mapping. I am following this guide and the Shader System sample but cannot get my code to work.

First I create the material and give it a TextureUnitState:

Code: Select all

Ogre::MaterialPtr material = Ogre::MaterialManager::getSingleton().create(material_name, Ogre::RGN_DEFAULT);
material->setAmbient(color * 0.75);
material->setDiffuse(color * 0.75);
material->setSpecular(Ogre::ColourValue::White);

Ogre::Technique * ffpTechnique = material->getTechnique(0);

Ogre::TextureUnitState * tus = ffpTechnique->getPass(0)->createTextureUnitState();
tus->setTextureName(texture_name, Ogre::TEX_TYPE_2D);

With just the above it uses the texture as a normal ambient/diffuse texture. I use the following to disable that:

Code: Select all

Ogre::RTShader::ShaderGenerator::_markNonFFP(tus);

With the above code it (as expected) does not have any texturing.

Then I try the following to turn it into a shader-based material with normal map:

Code: Select all

Ogre::RTShader::ShaderGenerator * shaderGenerator = Ogre::RTShader::ShaderGenerator::getSingletonPtr();
assert(shaderGenerator->createShaderBasedTechnique(ffpTechnique, Ogre::MSN_SHADERGEN));

Ogre::RTShader::SubRenderState * srs = shaderGenerator->createSubRenderState(Ogre::RTShader::SRS_NORMALMAP);
srs->setParameter("normalmap_space", "tangent_space");
srs->setParameter("texture_index", "0");

Ogre::RTShader::RenderState * rs = shaderGenerator->getRenderState(Ogre::MSN_SHADERGEN, *material, 0);
rs->addTemplateSubRenderState(srs);

This does seems to have some effect as it makes the object appear flat and dark but the normals from the map do not work.

I have a single directional light. The texture is Ogre::PF_BYTE_RGBA format. The alpha channel is always 255.

The mesh vertices have their own normal's. Could that be a problem?

Can anyone see what I am doing wrong?

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

Re: Normal Mapping with Programmatic Material

Post by paroj »

if you use the tangent space, your mesh needs tangents

chilly willy
Halfling
Posts: 75
Joined: Tue Jun 02, 2020 4:11 am
x 22

Re: Normal Mapping with Programmatic Material

Post by chilly willy »

paroj wrote: Fri Jan 09, 2026 12:55 pm

if you use the tangent space, your mesh needs tangents

That was it! It works now. Thank you.

It almost works. It looks like the normal mapping does not respect the scale values set by TextureUnitState::setTextureScale(). Am I doing something wrong or is this by design? Is there a work-around?

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

Re: Normal Mapping with Programmatic Material

Post by paroj »

this is by design. setTextureScale sends a 4x4 matrix per texture layer. Typically you want to transform the color and normal map with the same values. In this case modifying the uv coordinates of the mesh is the faster and more consistent approach.

chilly willy
Halfling
Posts: 75
Joined: Tue Jun 02, 2020 4:11 am
x 22

Re: Normal Mapping with Programmatic Material

Post by chilly willy »

Ok. Thank you, paroj.