Page 1 of 1
[2.1] Mirroring a texture
Posted: Sun Nov 13, 2016 5:46 pm
by AshMcConnell
Hi Folks,
I am trying to mirror a texture (to use as car mirrors). I have rendered the scene with a rearward facing camera to a texture and would like to flip that texture to make it more mirror-like
Previously I used TextureUnitState::setTextureUScale(-1.0f), is there an equivalent in 2.1?
Thanks for your help
Ash
Re: [2.1] Mirroring a texture
Posted: Sun Nov 13, 2016 6:13 pm
by xrgo
You could modify the hlms implementation to accept a flip parameter, should be easy but what I do is just simply flip the UV of the mesh in blender (or whatever). Another possible way could be using a custom projection matrix for the the camera for flip it (never tried that)
Re: [2.1] Mirroring a texture
Posted: Sun Nov 13, 2016 8:37 pm
by dark_sylinc
Detail diffuse & detail normal maps support UV offset & scale. Set your texture on the detail map instead of the diffuse, and set the scale to x = -1.
Re: [2.1] Mirroring a texture
Posted: Sun Nov 13, 2016 9:13 pm
by AshMcConnell
Thanks for your reply guys, I tried to set the texture type as PBSM_DETAIL0 like so: -
Code: Select all
Ogre::HlmsDatablock *datablock = hlms->createDatablock("MirrorMat", "MirrorMat", Ogre::HlmsMacroblock(), Ogre::HlmsBlendblock(), Ogre::HlmsParamVec());
Ogre::HlmsUnlitDatablock *unlitDb = static_cast<Ogre::HlmsUnlitDatablock*>(datablock); // Texture is set in the resize method
unlitDb->setTexture(Ogre::PbsTextureTypes::PBSM_DETAIL0, 0, _texture);
I got a shader compilation error: -
Code: Select all
20:04:17: GLSL compile log: 1610678272PixelShader_ps
Fragment shader failed to compile with the following errors:
ERROR: 0:91: error(#143) Undeclared identifier: topImage1
ERROR: 0:91: error(#216) Vector field selection out of range "xyz"
ERROR: 0:91: error(#216) Vector field selection out of range "a"
ERROR: 0:91: error(#202) No matching overloaded function found: mix
ERROR: 0:91: error(#160) Cannot convert from: "const float" to: "highp 3-component vector of vec3"
ERROR: 0:92: error(#216) Vector field selection out of range "w"
ERROR: error(#273) 6 compilation errors. No code generated
20:04:17: OGRE EXCEPTION(3:RenderingAPIException): Fragment Program 1610678272PixelShader_ps failed to compile. See compile log above for details. in GLSLShader::compile at C:\Dev\3rdParty\cmake\Ogre\RenderSystems\GL3Plus\src\GLSL\OgreGLSLShader.cpp (line 297)
I haven't done much more than set the diffuse texture up to this point, how should I set the detail map?
I assume the scale should be set using: -
Code: Select all
setDetailMapOffsetScale(0, Vector4(0,0,-1,1))
Is this correct?
Thanks and sorry for the basic questions.
Re: [2.1] Mirroring a texture
Posted: Sun Nov 13, 2016 9:21 pm
by dark_sylinc
You're mixing things.
PbsTextureTypes::PBSM_DETAIL0 is from the PBS implementation, not Unlit.
setDetailMapOffsetScale is also from the PBS implementation, not Unlit.
You seem to be using Unlit.
In Unlit we were supposed to allow this via unlitDatablock->setAnimationMatrix(); but support for matrices never ended up working yet, and still in TODO list. I thought you were talking about the PBS.
Re: [2.1] Mirroring a texture
Posted: Sun Nov 13, 2016 9:59 pm
by AshMcConnell
Thanks, I tried changing it to use PBS instead, but I don't seem to be getting anything rendered, just a black texture.
Here is the full setup code : -
Code: Select all
Ogre::HlmsManager *hlmsManager = Ogre::Root::getSingleton().getHlmsManager();
Ogre::Hlms *hlms = hlmsManager->getHlms(Ogre::HLMS_PBS);
_texture = TextureManager::getSingleton().createManual( "MirrorTex",
ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D,
1024, 512, 0, PF_R8G8B8, TU_RENDERTARGET );
Ogre::HlmsDatablock *datablock = hlms->createDatablock("MirrorMat", "MirrorMat", Ogre::HlmsMacroblock(), Ogre::HlmsBlendblock(), Ogre::HlmsParamVec());
Ogre::HlmsPbsDatablock *pbsDataBlock = static_cast<Ogre::HlmsPbsDatablock*>(datablock);
pbsDataBlock->setTexture(Ogre::PbsTextureTypes::PBSM_DETAIL0, 0, _texture);
pbsDataBlock->setDetailMapOffsetScale(0, Ogre::Vector4(0, 0, -1, 1));
Ogre::CompositorChannel channel;
channel.target = _texture->getBuffer(0)->getRenderTarget();
channel.textures.push_back(_texture);
Ogre::CompositorManager2* pCompositorManager = Ogre::Root::getSingleton().getCompositorManager2();
auto oge = OgreGfxEngine::getInstance();
_mirrorWorkspace = pCompositorManager->addWorkspace(oge->getSceneManager(), channel, _camera.get(),
"MirrorsWorkspace", true);
Can detail / diffuse be simply swapped out like this or do I need to change other aspects of the material / texture? Thanks!
Re: [2.1] Mirroring a texture
Posted: Mon Nov 14, 2016 12:56 am
by dark_sylinc
After like a year and a half of waiting,
I got this crossed off my TODO list:
setAnimationMatrix now works!
To flip in -X direction, just perform:
Code: Select all
Ogre::Matrix4 mat( Ogre::Matrix4::IDENTITY );
mat.setScale( Ogre::Vector3( -1, 1, 1 ) );
datablock->setEnableAnimationMatrix( 0, true );
datablock->setAnimationMatrix( 0, mat );
Where 0 is for texture unit 0.
Re: [2.1] Mirroring a texture
Posted: Mon Nov 14, 2016 10:06 am
by AshMcConnell
Wow, thanks very much - hopefully I'll get a chance to try it out tonight!
Re: [2.1] Mirroring a texture
Posted: Mon Nov 14, 2016 10:54 pm
by AshMcConnell
I'm having trouble getting this one to work. In GL3 it crashes on compliation: -
Code: Select all
21:47:02: OGRE EXCEPTION(2:InvalidParametersException): Parameter called animationMatrixBuf does not exist. in GpuProgramParameters::_findNamedConstantDefinition at C:\Dev\3rdParty\cmake\Ogre\OgreMain\src\OgreGpuProgramParams.cpp (line 2214)
Here is the stack trace: -
When using DX11 the matrix seems to be corrupted. Without the matrix set it looks ok (but not reflected of course)
When setting the matrix (with the example code above) it looks like this: -
When I spin around a bit I see the red writing above the pit stalls stretched out very very thin. Any ideas what I could try?
Thanks for your help!
Re: [2.1] Mirroring a texture
Posted: Sun Nov 20, 2016 7:35 pm
by AshMcConnell
I had just a few mins to do a bit more investigation today.
- It crashes in OpenGL even with an identity matrix passed.
- It doesn't crash in Dx with an identity matrix passed (it looks the same as without setEnableAnimationMatrix (as you might expect)).
- I uncommented the #if OGRE_DEBUG_MODE to some the current knownNames. The ogre exception looks like this now: -
Code: Select all
18:32:26: OGRE EXCEPTION(2:InvalidParametersException): Parameter called animationMatrixBuf does not exist. Known names are: worldMatBuf worldMatBuf[0] in GpuProgramParameters::_findNamedConstantDefinition at C:\Dev\3rdParty\cmake\Ogre\OgreMain\src\OgreGpuProgramParams.cpp (line 2214)
I'm thinking it might be an ordering thing, but I don't really know the order that things are done in to make a decent guess at how to fix it. Is there anything else I can do to provide a bit more info?
Thanks!
Ash
Re: [2.1] Mirroring a texture
Posted: Tue Nov 22, 2016 10:42 pm
by devxkh
AshMcConnell wrote:
Code: Select all
18:32:26: OGRE EXCEPTION(2:InvalidParametersException): Parameter called animationMatrixBuf does not exist. Known names are: worldMatBuf worldMatBuf[0] in GpuProgramParameters::_findNamedConstantDefinition at C:\Dev\3rdParty\cmake\Ogre\OgreMain\src\OgreGpuProgramParams.cpp (line 2214)
Could you solve the problem?

I'm getting the same error.
Re: [2.1] Mirroring a texture
Posted: Tue Nov 22, 2016 10:56 pm
by AshMcConnell
devxkh wrote:
Could you solve the problem?

I'm getting the same error.
Unfortunately not yet, it has been a busy few weeks for me with "real" work
Re: [2.1] Mirroring a texture
Posted: Tue Nov 22, 2016 11:30 pm
by dark_sylinc
Remember to update your Hlms template files, not just the DLLs.
Re: [2.1] Mirroring a texture
Posted: Wed Nov 23, 2016 9:50 pm
by AshMcConnell
dark_sylinc wrote:Remember to update your Hlms template files, not just the DLLs.
I made that mistake initially, but I copied them across. I double checked again tonight and checked against
this commit. I can't think what would be peculiar with my setup that might affect this.
@devxkh : any luck with your setup?
Re: [2.1] Mirroring a texture
Posted: Thu Nov 24, 2016 6:58 pm
by devxkh
AshMcConnell wrote:@devxkh : any luck with your setup?
nope. fresh pull from 2.1 main and updated hlms files. deleted build folder and recompiled. still the same error.
simple call:
Ogre::Matrix4 mat(Ogre::Matrix4::IDENTITY);
unlitDb->setEnableAnimationMatrix(0, true);
unlitDb->setAnimationMatrix(0, mat);
Re: [2.1] Mirroring a texture
Posted: Fri Nov 25, 2016 9:01 pm
by dark_sylinc
There were two bugs regarding Unlit texture matrix in OpenGL:
- It would fail to compile in anything other than AMD proprietary drivers (that's why it worked for me) due to type cast error (GLSL is very picky about this)
- It wouldn't look as intended in the 2.1-pso branch. Also fixed
Please try again and let me know how it goes.
For reference this is what I'm trying:
Code: Select all
Ogre::HlmsManager *hlmsManager = mGraphicsSystem->getRoot()->getHlmsManager();
Ogre::HlmsTextureManager *hlmsTextureManager = hlmsManager->getTextureManager();
assert( dynamic_cast<Ogre::HlmsUnlit*>( hlmsManager->getHlms( Ogre::HLMS_UNLIT ) ) );
Ogre::HlmsUnlit *hlmsUnlit = static_cast<Ogre::HlmsUnlit*>( hlmsManager->getHlms(Ogre::HLMS_UNLIT) );
Ogre::HlmsUnlitDatablock *datablock = (Ogre::HlmsUnlitDatablock*)hlmsUnlit->createDatablock(
"TestMat", "TestMat", Ogre::HlmsMacroblock(), Ogre::HlmsBlendblock(), Ogre::HlmsParamVec() );
datablock->setTexture( 0, 0,
Ogre::TextureManager::getSingleton().load( "1d_debug.png",
Ogre::ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME ), 0 );
Ogre::Matrix4 mat( Ogre::Matrix4::IDENTITY );
mat.setScale( Ogre::Vector3( 1, 1, 1 ) );
mat.setTrans( Ogre::Vector3( 0.75, 0.25, 0 ) );
datablock->setEnableAnimationMatrix( 0, true );
datablock->setAnimationMatrix( 0, mat );
item->setDatablock( datablock );
Re: [2.1] Mirroring a texture
Posted: Fri Nov 25, 2016 10:07 pm
by devxkh
hmm. my vertexshader_vs_glsl contains the last change in the template file with the u at the end:
Code: Select all
textureMatrix = UNPACK_MAT4( animationMatrixBuf, (instance.materialIdx[drawId].x << 4u) + @value( out_uv@n_tex_unit )u );
So my code should be up to date. I've deleted my build folder to be sure there are no old shaders.
But still the same error. I'm having a nvidia GTX 970 card if that's important (Win 10).
Re: [2.1] Mirroring a texture
Posted: Fri Nov 25, 2016 10:32 pm
by dark_sylinc
Could you...?:
- Provide some repro or show your steps
- Upload the generated vertex shader that is failing
Literally I have to say "works for me" here, so unless I get a way to repro, I won't be able to fix whatever problem is causing this

Re: [2.1] Mirroring a texture
Posted: Sat Nov 26, 2016 1:09 am
by devxkh
The problem seems to be somewhere in my code
Within a normal ogre sample it works.
Re: [2.1] Mirroring a texture
Posted: Sun Dec 04, 2016 8:28 pm
by AshMcConnell
devxkh wrote:The problem seems to be somewhere in my code
Within a normal ogre sample it works.
Hi Devxkh,
I was wondering if you had any luck in fixing the mirroring problem? I tried a couple more things without success : -
- using a static texture instead of the rendered mirrors
- removing the MyGUI custom pass
How do you refer to the created Datablock? I just set it on the Item in question. I thought I had it when I realised I was setting the material name rather than a datablock, but still have the same issue
Edit: -
Also, do you get validation warnings: -
Code: Select all
Validation failed! - Different sampler types for same sample texture unit in fragment shader.
18:27:46: Vertex Shader: 536903681VertexShader_vs
GLSL validation result :
Validation warning! - Sampler value worldMatBuf has not been set.
Re: [2.1] Mirroring a texture
Posted: Mon Dec 05, 2016 10:11 pm
by devxkh
Hey Ash,
AshMcConnell wrote:
I was wondering if you had any luck in fixing the mirroring problem?
I tried to update all files again -> no luck
Made a clean project with just this unlit material -> no luck
As already said in an ogre sample it works without expection.
The strange thing is, if i ignore the exception in my own project, the matrix animation works ....
AshMcConnell wrote:
How do you refer to the created Datablock?
I'm just using the code from darc sylinc.
AshMcConnell wrote:
Also, do you get validation warnings: -
Code: Select all
Validation failed! - Different sampler types for same sample texture unit in fragment shader.
18:27:46: Vertex Shader: 536903681VertexShader_vs
GLSL validation result :
Validation warning! - Sampler value worldMatBuf has not been set.
Nope, no warning.
Re: [2.1] Mirroring a texture
Posted: Tue Dec 06, 2016 9:53 pm
by AshMcConnell
Thanks devx.
I've tried to go back to using the PBS implementation, I just can't get unlit to work.
I managed to get the texture to flip by setting the scale as dark had shown above, but
only if I load the texture using the HlmsTextureManager to load a *static* texture
here is the code: -
Code: Select all
Ogre::HlmsTextureManager::TextureLocation texLocation =
hlmsTextureManager->createOrRetrieveTexture("mirrortest.dds", "mirrortest.dds", Ogre::HlmsTextureManager::TEXTURE_TYPE_DIFFUSE);
Ogre::HlmsDatablock *datablock = hlms->createDatablock("MirrorMat", "MirrorMat", Ogre::HlmsMacroblock(), Ogre::HlmsBlendblock(), Ogre::HlmsParamVec());
Ogre::HlmsPbsDatablock *dataBlock = static_cast<Ogre::HlmsPbsDatablock*>(datablock);
dataBlock->setTexture(Ogre::PbsTextureTypes::PBSM_DETAIL0, texLocation.xIdx, texLocation.texture);
dataBlock->setDetailMapOffsetScale(0, Ogre::Vector4(0,0,-1,1));
If I attempt to set the texture using: -
Code: Select all
dataBlock->setTexture(Ogre::PbsTextureTypes::PBSM_DETAIL0, 0, _texture);
I just get a black texture.
Is there anything I'm missing when trying to set the texture from the "normal" texture manager?
Thanks guys!
Re: [2.1] Mirroring a texture
Posted: Wed Dec 07, 2016 5:08 am
by dark_sylinc
_texture must be a 2D array texture (i.e. TEX_TYPE_2D_ARRAY), even if the number of slices is 1 to mimic a regular 2D texture.
HlmsTextureManager just uses TextureManager under the hood and does this (it creates a TEX_TYPE_2D_ARRAY with multiple slices, then starts putting textures into each slice until all slices are full).
Re: [2.1] Mirroring a texture
Posted: Wed Dec 07, 2016 9:39 am
by AshMcConnell
Sorry, I should have mentioned - I found
another thread that mentioned using the TEX_TYPE_2D_ARRAY type, but I must have missed something.
Here is the full code: -
Code: Select all
Ogre::HlmsManager *hlmsManager = Ogre::Root::getSingleton().getHlmsManager();
Ogre::HlmsTextureManager *hlmsTextureManager = hlmsManager->getTextureManager();
Ogre::Hlms *hlms = hlmsManager->getHlms(Ogre::HLMS_PBS);
_texture = TextureManager::getSingleton().createManual( "MirrorTex",
ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D_ARRAY,
1024, 512, 0, PF_R8G8B8, TU_RENDERTARGET );
Ogre::CompositorChannel channel;
channel.target = _texture->getBuffer(0)->getRenderTarget(); //Any of the render targets will do
channel.textures.push_back(_texture);
Ogre::CompositorManager2* pCompositorManager = Ogre::Root::getSingleton().getCompositorManager2();
auto oge = OgreGfxEngine::getInstance();
_mirrorWorkspace = pCompositorManager->addWorkspace(oge->getSceneManager(), channel, _camera.get(),
"MirrorsWorkspace", false);
Ogre::HlmsDatablock *datablock = hlms->createDatablock("MirrorMat", "MirrorMat", Ogre::HlmsMacroblock(), Ogre::HlmsBlendblock(), Ogre::HlmsParamVec());
Ogre::HlmsPbsDatablock *dataBlock = static_cast<Ogre::HlmsPbsDatablock*>(datablock);
dataBlock->setTexture(Ogre::PbsTextureTypes::PBSM_DETAIL0, 0, _texture);
dataBlock->setDetailMapOffsetScale(0, Ogre::Vector4(0,0,-1,1));
Re: [2.1] Mirroring a texture
Posted: Wed Dec 07, 2016 10:16 pm
by AshMcConnell
Aha, a change in another part of the code meant that my mirrors weren't updating. The PBS method now work for me (same code as above). I'll have a bit of a play to try and get it to look ok for mirrors of the car under all lighting conditions.
