Terrain component shaders
-
- Gremlin
- Posts: 153
- Joined: Tue Jun 09, 2009 9:31 am
- Location: Russia
- x 12
- Contact:
Terrain component shaders
Hello!
I need to do two things:
1. change shader of terrain composite map - add specular (or more) settings.
2. change texture blending shader.
the simpliest way I've found is to use Nauk's code from here http://www.ogre3d.org/forums/viewtopic.php?f=5&t=72455, but it downgrades 1.7+ terrain to 1.6 one, so I lose all advanced features like composite map etc.
I think, that depth texture blending is more realistik, so I'd like to change only blending and don't touch other shader and component features. What should I look at?
I need to do two things:
1. change shader of terrain composite map - add specular (or more) settings.
2. change texture blending shader.
the simpliest way I've found is to use Nauk's code from here http://www.ogre3d.org/forums/viewtopic.php?f=5&t=72455, but it downgrades 1.7+ terrain to 1.6 one, so I lose all advanced features like composite map etc.
I think, that depth texture blending is more realistik, so I'd like to change only blending and don't touch other shader and component features. What should I look at?
- c6burns
- Beholder
- Posts: 1512
- Joined: Fri Feb 22, 2013 4:44 am
- Location: Deep behind enemy lines
- x 138
Re: Terrain component shaders
Check out OgreTerrainMaterialGeneratorA.h in the Terrain component. You will see that for each type of shader, a class derived from ShaderHelper is created (eg. ShaderHelperCg, ShaderHelperGLSL, etc). These classes generate the actual shader code based on which type of shader is required. You can see the call order is:
1) generateVpHeader / generateFpHeader
2) generateVpLayer / generateFpLayer
3) generateVpFooter / generateFpFooter
Also each method is called with a TechniqueType param, so you could change just composite map generation, or just per-layer settings for the highlod shaders, or whatever you need.
1) generateVpHeader / generateFpHeader
2) generateVpLayer / generateFpLayer
3) generateVpFooter / generateFpFooter
Also each method is called with a TechniqueType param, so you could change just composite map generation, or just per-layer settings for the highlod shaders, or whatever you need.
-
- Gremlin
- Posts: 153
- Joined: Tue Jun 09, 2009 9:31 am
- Location: Russia
- x 12
- Contact:
Re: Terrain component shaders
Thank you for suggestion!
I copied TerrainMaterialGeneratorA and renamed it to TerrainMaterialGeneratorB, after this I copied shader helper classes. I think it would be enough to take just shader helper classes, but TerrainMaterialGeneratorA declares them with _OgreTerrainExport, so my project tries to be compiled to .lib with lots of linker mistakes, but not to .exe.
I copied TerrainMaterialGeneratorA and renamed it to TerrainMaterialGeneratorB, after this I copied shader helper classes. I think it would be enough to take just shader helper classes, but TerrainMaterialGeneratorA declares them with _OgreTerrainExport, so my project tries to be compiled to .lib with lots of linker mistakes, but not to .exe.
- tod
- Troll
- Posts: 1394
- Joined: Wed Aug 02, 2006 9:41 am
- Location: Bucharest
- x 94
- Contact:
Re: Terrain component shaders
Look here for an example on how to change the material generator.
- c6burns
- Beholder
- Posts: 1512
- Joined: Fri Feb 22, 2013 4:44 am
- Location: Deep behind enemy lines
- x 138
Re: Terrain component shaders
Just get rid of _OgreTerrainExport (search and replace with blank in your own project) because it will be defined as __declspec( dllexport ). Then replace OgreTerrainMaterialGeneratorA with OgreTerrainMaterialGeneratorB (or whatever your new name is) in all files. This is what I did to create my first Material Generator. Then I went into TerrainMaterialGeneratorB::SM2Profile::ShaderHelper::generateVertexProgram and generateFragmentProgram and made sure it was always outputting the final shaders into my ogre log. It's hard at first to get a sense of how the shaders work as a whole because of how broken up they are in the shader generator. From there I was able to make the necessary changes for my own project.
-
- Gremlin
- Posts: 153
- Joined: Tue Jun 09, 2009 9:31 am
- Location: Russia
- x 12
- Contact:
Re: Terrain component shaders
Yes, I did it the way you say. It works correctly.
Now I can't figure out how they send samplers to shader. I tried to add globalNormal sampler to LOW_LOD technique (in order to calculare specular for composite map), but I don't know where in material I should set this texture. And how to work with terrain's material at all.
setting for LOW_LOD in TerrainMaterialGeneratorB:
couses correct shader code:
but of course this sampler is empty.
Now I can't figure out how they send samplers to shader. I tried to add globalNormal sampler to LOW_LOD technique (in order to calculare specular for composite map), but I don't know where in material I should set this texture. And how to work with terrain's material at all.
setting for LOW_LOD in TerrainMaterialGeneratorB:
Code: Select all
params->setNamedConstant("globalNormal", (int)numSamplers++);
Code: Select all
uniform sampler2D globalNormal : register(s0)
, uniform sampler2D compositeMap : register(s1)
-
- Gremlin
- Posts: 153
- Joined: Tue Jun 09, 2009 9:31 am
- Location: Russia
- x 12
- Contact:
Re: Terrain component shaders
The answer is here:
Code: Select all
void TerrainMaterialGeneratorB::SM2Profile::addTechnique(
const MaterialPtr& mat, const Terrain* terrain, TechniqueType tt)
...
// global normal map
TextureUnitState* tu = pass->createTextureUnitState();
tu->setTextureName(terrain->getTerrainNormalMap()->getName());
-
- Gremlin
- Posts: 153
- Joined: Tue Jun 09, 2009 9:31 am
- Location: Russia
- x 12
- Contact:
Re: Terrain component shaders
Good surprise was, that composite map already contains specular (that take into account shadowmap) in it's alpha channel.
- insider
- Orc
- Posts: 462
- Joined: Thu Sep 15, 2011 12:50 pm
- x 31
Re: Terrain component shaders
Could you post the full code, I am breaking my head over this.Kenshido wrote:The answer is here:
Code: Select all
void TerrainMaterialGeneratorB::SM2Profile::addTechnique( const MaterialPtr& mat, const Terrain* terrain, TechniqueType tt) ... // global normal map TextureUnitState* tu = pass->createTextureUnitState(); tu->setTextureName(terrain->getTerrainNormalMap()->getName());
-
- Gremlin
- Posts: 153
- Joined: Tue Jun 09, 2009 9:31 am
- Location: Russia
- x 12
- Contact:
Re: Terrain component shaders
Find this method in TerrainMaterialGeneratorB.cpp:
find code:
as you can see, global normal map texture is set for HIGH_LOD and RENDER_COMPOSITE_MAP techniques.
So change the code to:
Now in the method:
find code:
and change it to:
Now in TerrainMaterialShaderHelperCg.cpp find method:
the code:
change to:
Now you have globalNormal texture in low_lod shader, and can use normals to calculate specular for composite map.
Code: Select all
void TerrainMaterialGeneratorB::SM2Profile::addTechnique(
const MaterialPtr& mat, const Terrain* terrain, TechniqueType tt)
Code: Select all
else
{
// LOW_LOD textures
// composite map
TextureUnitState* tu = pass->createTextureUnitState();
tu->setTextureName(terrain->getCompositeMap()->getName());
tu->setTextureAddressingMode(TextureUnitState::TAM_CLAMP);
// That's it!
}
So change the code to:
Code: Select all
else
{
// LOW_LOD textures
// global normal map
TextureUnitState* tu = pass->createTextureUnitState();
tu->setTextureName(terrain->getTerrainNormalMap()->getName());
// composite map
TextureUnitState* tu = pass->createTextureUnitState();
tu->setTextureName(terrain->getCompositeMap()->getName());
tu->setTextureAddressingMode(TextureUnitState::TAM_CLAMP);
// That's it!
}
Code: Select all
void TerrainMaterialGeneratorB::SM2Profile::ShaderHelper::defaultFpParams(
const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, const HighLevelGpuProgramPtr& prog)
Code: Select all
if (tt == LOW_LOD)
{
params->setNamedConstant("compositeMap", (int)numSamplers++);
}
Code: Select all
if (tt == LOW_LOD)
{
params->setNamedConstant("globalNormal", (int)numSamplers++);
params->setNamedConstant("compositeMap", (int)numSamplers++);
}
Code: Select all
void TerrainMaterialGeneratorB::SM2Profile::ShaderHelperCg::generateFpHeader(
const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream)
Code: Select all
if (tt == LOW_LOD)
{
// single composite map covers all the others below
outStream <<
"uniform sampler2D compositeMap : register(s" << currentSamplerIdx++ << ")\n";
}
Code: Select all
if (tt == LOW_LOD)
{
// single composite map covers all the others below
outStream <<
"uniform sampler2D globalNormal : register(s" << currentSamplerIdx++ << ")\n";
outStream <<
", uniform sampler2D compositeMap : register(s" << currentSamplerIdx++ << ")\n";
}
- insider
- Orc
- Posts: 462
- Joined: Thu Sep 15, 2011 12:50 pm
- x 31
Re: Terrain component shaders
Brilliant it workedKenshido wrote:Find this method in TerrainMaterialGeneratorB.cpp:
-
- Gremlin
- Posts: 153
- Joined: Tue Jun 09, 2009 9:31 am
- Location: Russia
- x 12
- Contact:
Re: Terrain component shaders
well... there's a lot should be done with TerrainMaterialGeneratorB, if you want terrain look good at close and in the far...
Inspired by
http://udn.epicgames.com/Three/TerrainA ... tures.html
and
http://www.gamasutra.com/blogs/AndreyMi ... atting.php
Inspired by
http://udn.epicgames.com/Three/TerrainA ... tures.html
and
http://www.gamasutra.com/blogs/AndreyMi ... atting.php
-
- Gremlin
- Posts: 153
- Joined: Tue Jun 09, 2009 9:31 am
- Location: Russia
- x 12
- Contact:
Re: Terrain component shaders
Hello again!
How can I obtain access to custom members of class TerrainMaterialGeneratorB?
so, if I later want to get material generator object:
I get a pointer to TerrainMaterialGenerator (derived class), of course is does not know anything about interiting class TerrainMaterialGeneratorB.
I need to get something like this:
How can I obtain access to custom members of class TerrainMaterialGeneratorB?
Code: Select all
typedef SharedPtr<TerrainMaterialGenerator> TerrainMaterialGeneratorPtr;
mTerrainGlobals = OGRE_NEW Ogre::TerrainGlobalOptions();
mTerrainGlobals->setDefaultMaterialGenerator(Ogre::TerrainMaterialGeneratorPtr(new Ogre::TerrainMaterialGeneratorB));
Code: Select all
mTerrainGlobals->getDefaultMaterialGenerator();
I need to get something like this:
Code: Select all
Ogre::TerrainMaterialGeneratorB *object = (convert to Ogre::TerrainMaterialGeneratorB)mTerrainGlobals->getDefaultMaterialGenerator();
object ->myCustomMethod();