[2.1] Mirroring a texture

A place for users of OGRE to discuss ideas and experiences of utilitising OGRE in their games / demos / applications.
Post Reply
User avatar
AshMcConnell
Silver Sponsor
Silver Sponsor
Posts: 605
Joined: Fri Dec 14, 2007 11:44 am
Location: Northern Ireland
x 16
Contact:

[2.1] Mirroring a texture

Post 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
xrgo
OGRE Expert User
OGRE Expert User
Posts: 1148
Joined: Sat Jul 06, 2013 10:59 pm
Location: Chile
x 168

Re: [2.1] Mirroring a texture

Post 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)
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5296
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1278
Contact:

Re: [2.1] Mirroring a texture

Post 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.
User avatar
AshMcConnell
Silver Sponsor
Silver Sponsor
Posts: 605
Joined: Fri Dec 14, 2007 11:44 am
Location: Northern Ireland
x 16
Contact:

Re: [2.1] Mirroring a texture

Post 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.
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5296
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1278
Contact:

Re: [2.1] Mirroring a texture

Post 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.
User avatar
AshMcConnell
Silver Sponsor
Silver Sponsor
Posts: 605
Joined: Fri Dec 14, 2007 11:44 am
Location: Northern Ireland
x 16
Contact:

Re: [2.1] Mirroring a texture

Post 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!
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5296
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1278
Contact:

Re: [2.1] Mirroring a texture

Post 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.
User avatar
AshMcConnell
Silver Sponsor
Silver Sponsor
Posts: 605
Joined: Fri Dec 14, 2007 11:44 am
Location: Northern Ireland
x 16
Contact:

Re: [2.1] Mirroring a texture

Post by AshMcConnell »

Wow, thanks very much - hopefully I'll get a chance to try it out tonight!
User avatar
AshMcConnell
Silver Sponsor
Silver Sponsor
Posts: 605
Joined: Fri Dec 14, 2007 11:44 am
Location: Northern Ireland
x 16
Contact:

Re: [2.1] Mirroring a texture

Post 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!
User avatar
AshMcConnell
Silver Sponsor
Silver Sponsor
Posts: 605
Joined: Fri Dec 14, 2007 11:44 am
Location: Northern Ireland
x 16
Contact:

Re: [2.1] Mirroring a texture

Post 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
User avatar
devxkh
Halfling
Posts: 84
Joined: Tue Aug 02, 2016 6:07 pm
Location: Germany
x 12

Re: [2.1] Mirroring a texture

Post 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.
My little OGRE engine -> FrankE WIP
User avatar
AshMcConnell
Silver Sponsor
Silver Sponsor
Posts: 605
Joined: Fri Dec 14, 2007 11:44 am
Location: Northern Ireland
x 16
Contact:

Re: [2.1] Mirroring a texture

Post 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
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5296
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1278
Contact:

Re: [2.1] Mirroring a texture

Post by dark_sylinc »

Remember to update your Hlms template files, not just the DLLs.
User avatar
AshMcConnell
Silver Sponsor
Silver Sponsor
Posts: 605
Joined: Fri Dec 14, 2007 11:44 am
Location: Northern Ireland
x 16
Contact:

Re: [2.1] Mirroring a texture

Post 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?
User avatar
devxkh
Halfling
Posts: 84
Joined: Tue Aug 02, 2016 6:07 pm
Location: Germany
x 12

Re: [2.1] Mirroring a texture

Post 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);
My little OGRE engine -> FrankE WIP
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5296
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1278
Contact:

Re: [2.1] Mirroring a texture

Post 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 );
User avatar
devxkh
Halfling
Posts: 84
Joined: Tue Aug 02, 2016 6:07 pm
Location: Germany
x 12

Re: [2.1] Mirroring a texture

Post 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).
My little OGRE engine -> FrankE WIP
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5296
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1278
Contact:

Re: [2.1] Mirroring a texture

Post 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 :wink:
User avatar
devxkh
Halfling
Posts: 84
Joined: Tue Aug 02, 2016 6:07 pm
Location: Germany
x 12

Re: [2.1] Mirroring a texture

Post by devxkh »

The problem seems to be somewhere in my code :oops:
Within a normal ogre sample it works.
My little OGRE engine -> FrankE WIP
User avatar
AshMcConnell
Silver Sponsor
Silver Sponsor
Posts: 605
Joined: Fri Dec 14, 2007 11:44 am
Location: Northern Ireland
x 16
Contact:

Re: [2.1] Mirroring a texture

Post by AshMcConnell »

devxkh wrote:The problem seems to be somewhere in my code :oops:
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.
User avatar
devxkh
Halfling
Posts: 84
Joined: Tue Aug 02, 2016 6:07 pm
Location: Germany
x 12

Re: [2.1] Mirroring a texture

Post 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.
My little OGRE engine -> FrankE WIP
User avatar
AshMcConnell
Silver Sponsor
Silver Sponsor
Posts: 605
Joined: Fri Dec 14, 2007 11:44 am
Location: Northern Ireland
x 16
Contact:

Re: [2.1] Mirroring a texture

Post 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!
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5296
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1278
Contact:

Re: [2.1] Mirroring a texture

Post 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).
User avatar
AshMcConnell
Silver Sponsor
Silver Sponsor
Posts: 605
Joined: Fri Dec 14, 2007 11:44 am
Location: Northern Ireland
x 16
Contact:

Re: [2.1] Mirroring a texture

Post 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));
User avatar
AshMcConnell
Silver Sponsor
Silver Sponsor
Posts: 605
Joined: Fri Dec 14, 2007 11:44 am
Location: Northern Ireland
x 16
Contact:

Re: [2.1] Mirroring a texture

Post 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.

Image
Image
Post Reply