This is the result:
Basically I've created a terrain mesh with a sand-like texture, added a blueish ambient light, a blueish fog and a copy of the same terrain mesh placed a little bit above the first one with additional material flags as follows:
EMF_LIGHTING, false
EMF_FOG_ENABLE, true
EMT_TRANSPARENT_ADD_COLOR
The second mesh (transparent) has a TextureAnimator that loop 32 caustic images like this one:
I'm very sastified with the resulting effect, but the problem is that I can't perfectly match both terrain meshes at the edges and a lighter border is clearly visible between them.
Here is my code:
Code: Select all
IAnimatedMesh* terrain = 0;
terrain = smgr->getMesh("./media/meshes/seabed.x");
ISceneNode* terrainnode = 0;
terrainnode = smgr->addOctTreeSceneNode(terrain);
ITriangleSelector* selectorterrain = 0;
if (terrainnode)
{
terrainnode->setScale(vector3df(60,60,60));
terrainnode->setPosition(core::vector3df(0,0,0));
terrainnode->setRotation(core::vector3df(270,0,0));
terrainnode->setMaterialTexture(0, driver->getTexture("./media/meshes/00003.jpg"));
terrainnode->setMaterialFlag(video::EMF_NORMALIZE_NORMALS, true);
terrainnode->setMaterialFlag(video::EMF_LIGHTING, true);
terrainnode->setMaterialFlag(EMF_FOG_ENABLE, true);
selectorterrain = smgr->createOctTreeTriangleSelector(terrain->getMesh(0), terrainnode, 128);
terrainnode->setTriangleSelector(selectorterrain);
selectorterrain->drop();
}
ISceneNodeAnimator* animaterrain = smgr->createCollisionResponseAnimator(
selectorterrain, camera, core::vector3df(10,30,10),
core::vector3df(0,-30.0f,0),
core::vector3df(0,30,0));
camera->addAnimator(animaterrain);
animaterrain->drop();
IAnimatedMesh* caustic = 0;
caustic = smgr->getMesh("./media/meshes/seabed.x");
ISceneNode* causticnode = 0;
causticnode = smgr->addOctTreeSceneNode(caustic);
causticnode->setScale(vector3df(59.98,59.98,59.98));
causticnode->setPosition(core::vector3df(0,1,0));
causticnode->setRotation(core::vector3df(270,0,0));
causticnode->setMaterialFlag(video::EMF_NORMALIZE_NORMALS, true);
causticnode->setMaterialFlag(video::EMF_LIGHTING, false);
causticnode->setMaterialFlag(EMF_FOG_ENABLE, true);
causticnode->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR);
causticnode->setMaterialTexture(0, driver->getTexture("./media/meshes/caustic_001.bmp"));
core::array<ITexture*> tt(32);
tt.insert(driver->getTexture("./media/meshes/caustic_001.bmp"));
tt.insert(driver->getTexture("./media/meshes/caustic_002.bmp"));
tt.insert(driver->getTexture("./media/meshes/caustic_003.bmp"));
tt.insert(driver->getTexture("./media/meshes/caustic_004.bmp"));
tt.insert(driver->getTexture("./media/meshes/caustic_005.bmp"));
tt.insert(driver->getTexture("./media/meshes/caustic_006.bmp"));
tt.insert(driver->getTexture("./media/meshes/caustic_007.bmp"));
tt.insert(driver->getTexture("./media/meshes/caustic_008.bmp"));
tt.insert(driver->getTexture("./media/meshes/caustic_009.bmp"));
tt.insert(driver->getTexture("./media/meshes/caustic_010.bmp"));
tt.insert(driver->getTexture("./media/meshes/caustic_011.bmp"));
tt.insert(driver->getTexture("./media/meshes/caustic_012.bmp"));
tt.insert(driver->getTexture("./media/meshes/caustic_013.bmp"));
tt.insert(driver->getTexture("./media/meshes/caustic_014.bmp"));
tt.insert(driver->getTexture("./media/meshes/caustic_015.bmp"));
tt.insert(driver->getTexture("./media/meshes/caustic_016.bmp"));
tt.insert(driver->getTexture("./media/meshes/caustic_017.bmp"));
tt.insert(driver->getTexture("./media/meshes/caustic_018.bmp"));
tt.insert(driver->getTexture("./media/meshes/caustic_019.bmp"));
tt.insert(driver->getTexture("./media/meshes/caustic_020.bmp"));
tt.insert(driver->getTexture("./media/meshes/caustic_021.bmp"));
tt.insert(driver->getTexture("./media/meshes/caustic_022.bmp"));
tt.insert(driver->getTexture("./media/meshes/caustic_023.bmp"));
tt.insert(driver->getTexture("./media/meshes/caustic_024.bmp"));
tt.insert(driver->getTexture("./media/meshes/caustic_025.bmp"));
tt.insert(driver->getTexture("./media/meshes/caustic_026.bmp"));
tt.insert(driver->getTexture("./media/meshes/caustic_027.bmp"));
tt.insert(driver->getTexture("./media/meshes/caustic_028.bmp"));
tt.insert(driver->getTexture("./media/meshes/caustic_029.bmp"));
tt.insert(driver->getTexture("./media/meshes/caustic_030.bmp"));
tt.insert(driver->getTexture("./media/meshes/caustic_031.bmp"));
tt.insert(driver->getTexture("./media/meshes/caustic_032.bmp"));
ISceneNodeAnimator* animatecaustic = smgr->createTextureAnimator(tt,200,true);
causticnode->addAnimator(animatecaustic);
animatecaustic->drop();
----------------------------------
After a few tests, I've found the solution. There was a blending problem when the transparent node get folded. It wasn't completely transparent (probably due to the fog). So I've overlayed the caustic images with the sand-like texture and applied the resulting textures to a single mesh node and animated it with TextureAnimator.
Here is the result:
...and the code:
Code: Select all
IAnimatedMesh* terrain = 0;
terrain = smgr->getMesh("./media/meshes/seabed.x");
ISceneNode* terrainnode = 0;
terrainnode = smgr->addOctTreeSceneNode(terrain);
ITriangleSelector* selectorterrain = 0;
if (terrainnode)
{
terrainnode->setScale(vector3df(60,60,60));
terrainnode->setPosition(core::vector3df(0,0,0));
terrainnode->setRotation(core::vector3df(270,0,0));
terrainnode->setMaterialTexture(0, driver->getTexture("./media/meshes/caustic_001.bmp"));
core::array<ITexture*> tt(32);
tt.insert(driver->getTexture("./media/meshes/caustic_001.bmp"));
tt.insert(driver->getTexture("./media/meshes/caustic_002.bmp"));
tt.insert(driver->getTexture("./media/meshes/caustic_003.bmp"));
tt.insert(driver->getTexture("./media/meshes/caustic_004.bmp"));
tt.insert(driver->getTexture("./media/meshes/caustic_005.bmp"));
tt.insert(driver->getTexture("./media/meshes/caustic_006.bmp"));
tt.insert(driver->getTexture("./media/meshes/caustic_007.bmp"));
tt.insert(driver->getTexture("./media/meshes/caustic_008.bmp"));
tt.insert(driver->getTexture("./media/meshes/caustic_009.bmp"));
tt.insert(driver->getTexture("./media/meshes/caustic_010.bmp"));
tt.insert(driver->getTexture("./media/meshes/caustic_011.bmp"));
tt.insert(driver->getTexture("./media/meshes/caustic_012.bmp"));
tt.insert(driver->getTexture("./media/meshes/caustic_013.bmp"));
tt.insert(driver->getTexture("./media/meshes/caustic_014.bmp"));
tt.insert(driver->getTexture("./media/meshes/caustic_015.bmp"));
tt.insert(driver->getTexture("./media/meshes/caustic_016.bmp"));
tt.insert(driver->getTexture("./media/meshes/caustic_017.bmp"));
tt.insert(driver->getTexture("./media/meshes/caustic_018.bmp"));
tt.insert(driver->getTexture("./media/meshes/caustic_019.bmp"));
tt.insert(driver->getTexture("./media/meshes/caustic_020.bmp"));
tt.insert(driver->getTexture("./media/meshes/caustic_021.bmp"));
tt.insert(driver->getTexture("./media/meshes/caustic_022.bmp"));
tt.insert(driver->getTexture("./media/meshes/caustic_023.bmp"));
tt.insert(driver->getTexture("./media/meshes/caustic_024.bmp"));
tt.insert(driver->getTexture("./media/meshes/caustic_025.bmp"));
tt.insert(driver->getTexture("./media/meshes/caustic_026.bmp"));
tt.insert(driver->getTexture("./media/meshes/caustic_027.bmp"));
tt.insert(driver->getTexture("./media/meshes/caustic_028.bmp"));
tt.insert(driver->getTexture("./media/meshes/caustic_029.bmp"));
tt.insert(driver->getTexture("./media/meshes/caustic_030.bmp"));
tt.insert(driver->getTexture("./media/meshes/caustic_031.bmp"));
tt.insert(driver->getTexture("./media/meshes/caustic_032.bmp"));
ISceneNodeAnimator* animatecaustic = smgr->createTextureAnimator(tt,200,true);
terrainnode->addAnimator(animatecaustic);
animatecaustic->drop();
terrainnode->setMaterialFlag(video::EMF_NORMALIZE_NORMALS, true);
terrainnode->setMaterialFlag(video::EMF_LIGHTING, false);
terrainnode->setMaterialFlag(EMF_FOG_ENABLE, true);
selectorterrain = smgr->createOctTreeTriangleSelector(terrain->getMesh(0), terrainnode, 128);
terrainnode->setTriangleSelector(selectorterrain);
selectorterrain->drop();
}
ISceneNodeAnimator* animaterrain = smgr->createCollisionResponseAnimator(
selectorterrain, camera, core::vector3df(10,30,10),
core::vector3df(0,-30.0f,0),
core::vector3df(0,30,0));
camera->addAnimator(animaterrain);
animaterrain->drop();