driver->setFog(video::SColor(0,138,125,81), // color
video::EFT_FOG_LINEAR, // fog type
0, // start
500, // end
0.005f, // density
true, // pixel fog
false // range fog
);
The object must has the fog flag enabled in its material.
注意,按下面的方式创建水的特效,必须要设置光照,同时创建 device 时,device 的 type 最好不要用 EDT_SOFTWARE,用这种 type,会影响水效。
mesh = smgr->addHillPlaneMesh("myHill", // name
core::dimension2d<f32>(20,20), // tile Size
core::dimension2d<u32>(40,40), // tile Count
0, // material
0, // hill Height
core::dimension2d<f32>(0,0), // There will be countHills.X hills along the X axis and countHills.Y
// along the Y axis. So in total there will be countHills.X * countHills.Y hills.
core::dimension2d<f32>(10,10) // texture Repeat Count
);
利用上面的 mesh,创建一个水面的 node,并为 node 设置两层纹理,一层做为水表,一层做为水底物体透明纹理。
node = smgr->addWaterSurfaceSceneNode(mesh->getMesh(0), // mesh
3.0f, // waveHeight
300.0f, // waveSpeed
30.0f // waveLength
);
node->setPosition(core::vector3df(0,7,0));
node->setMaterialTexture(0, driver->getTexture("../../media/stones.jpg"));
node->setMaterialTexture(1, driver->getTexture("../../media/water.jpg"));
node->setMaterialType(video::EMT_REFLECTION_2_LAYER);
用公告板与一个动态光结合实现一个动态灯光。
公告板是什么? A billboard is like a 3d sprite: A 2d element, which always looks to the camera.
scene::ISceneNode* node = smgr->addLightSceneNode(0, // parent
core::vector3df(0,0,0), // position
video::SColorf(1.0f, 0.6f, 0.7f, 1.0f), // color
800.0f); // radius
scene::ISceneNodeAnimator* anim = 0;
anim = smgr->createFlyCircleAnimator(core::vector3df(0,150,0), 250.0f);
node->addAnimator(anim);
anim->drop();
制作公告板,并将公告板的 parent 设为动态灯,这样公告板便可以有灯光一起动。
node = smgr->addBillboardSceneNode(node, // parent
core::dimension2d<f32>(50, 50) // size
); // position relative to its parent is (0, 0, 0)
node->setMaterialFlag(video::EMF_LIGHTING, false);
node->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR);
node->setMaterialTexture(0, driver->getTexture("../../media/particlewhite.bmp"));
scene::IParticleSystemSceneNode * ps =smgr->addParticleSystemSceneNode (false, node);
scene::IParticleEmitter * em = ps->createBoxEmitter(
core::aabbox3d<f32>(-3,0,-3,3,1,3), // emitter size the box
core::vector3df(0.0f,0.06f,0.0f), // initial direction and speed
80, // Minimal amount of particles emitted per second
100, // Maximal amount of particles emitted per second
video::SColor(0,255,255,255), // Minimal initial start color of a particle
video::SColor(0,255,255,255), // Maximal initial start color of a particle
800, 2000, // min and max age,
0, //angle
core::dimension2df(10.f,10.f), // min size
core::dimension2df(20.f,20.f) // max size
);
ps->setEmitter(em); // this grabs the emitter
em->drop(); // so we can drop it here without deleting it
scene::IParticleAffector* paf = ps->createFadeOutParticleAffector();
ps->addAffector(paf); // same goes for the affector
paf->drop();
ps->setPosition(core::vector3df(-70,60,40));
ps->setScale(core::vector3df(2,2,2));
ps->setMaterialFlag(video::EMF_LIGHTING, false);
ps->setMaterialFlag(video::EMF_ZWRITE_ENABLE, false);
ps->setMaterialTexture(0, driver->getTexture("../../media/fire.bmp"));
ps->setMaterialType(video::EMT_TRANSPARENT_VERTEX_ALPHA);
Render to Texture 渲染到纹理:普通的图形渲染流程中,最终结果是渲染到帧缓存中, 最后显示到屏幕上,现在可以利用 FBO 等技术,把图像渲染到纹理中,然后可以把纹理 继续应用到场景绘制中,比如渲染一个场景 A 到纹理中,在另一个场景 B 的一个电视屏 幕上把刚才的纹理贴上去,就像是在播放 A 一样,再比如各种镜子中的景象也是一样道 理,阴影图( shadow mapping )也算是运用了 RTT。随着 GPU 的发展,RTT 还可以有更 多的应用,让用户更深入的参与到渲染流程中。(摘自石头的笔记)
rt = driver->addRenderTargetTexture(core::dimension2d<u32>(256,256), "RTT1");
test->setMaterialTexture(0, rt);
driver->setRenderTarget(rt, true, true, video::SColor(0,0,0,255));
rtsmgr->drawAll();
一般情况下,需要设置两个照相机,一个是用于用户空间,一个用于纹理映射。同时在
render 时,进行两次 render,第一次将用于纹理映射的相机设为活动摄像机,把场景 render
到 texture 上,第二次将用户空间摄像机设为活动摄像机,将整个场景 render 到帧缓冲区,
并显示到屏幕上。IrrlichtDevice *device =
createDevice( video::EDT_OPENGL, dimension2d<u32>(640, 480), 16, false, TRUE, false, 0);
mesh = smgr->getMesh("../../media/dwarf.x");
scene::IAnimatedMeshSceneNode* anode = 0;
anode = smgr->addAnimatedMeshSceneNode(mesh);
anode->setPosition(core::vector3df(-50,20,-60));
anode->setAnimationSpeed(15);
// add shadow
anode->addShadowVolumeSceneNode();
smgr->setShadowColor(video::SColor(150,0,0,0));
anode->setScale(core::vector3df(2,2,2));
anode->setMaterialFlag(video::EMF_NORMALIZE_NORMALS, true);
创建地形:
scene::ITerrainSceneNode* terrain = smgr->addTerrainSceneNode(
"../../media/terrain-heightmap.bmp", // 高度图的文件名称
0, // parent node
-1, // node id
core::vector3df(0.f, 0.f, 0.f), // position
core::vector3df(0.f, 0.f, 0.f), // rotation
core::vector3df(40.f, 4.4f, 40.f), // scale // 对地形进行放大
video::SColor ( 255, 255, 255, 255 ), // vertexColor
5, // maxLOD LOD (levels of detail)
scene::ETPS_17, // patchSize 地形块大小
4 // smoothFactor
);
terrain->setMaterialFlag(video::EMF_LIGHTING, false);
terrain->setMaterialTexture(0,
driver->getTexture("../../media/terrain-texture.jpg"));
terrain->setMaterialTexture(1,
driver->getTexture("../../media/detailmap3.jpg"));
terrain->setMaterialType(video::EMT_DETAIL_MAP);
terrain->scaleTexture(1.0f, 20.0f); // 第一层纹理保持不变,第二层纹理放大 20 倍
LOD 技术在不影响画面视觉效果的条件下,通过逐次简化景物的表面细节来减少场景的 几何复杂性,从而提高绘制算法的效率。该技术通常对每一原始多面体模型建立几个不同逼 近精度的几何模型。与原模型相比,每个模型均保留了一定层次细节。在绘制时,根据不同 的标准选择适当的层次模型来表示物体。
灰度是指黑白图像中点的颜色深度,范围一般从 0 到 255,白色为 255,黑色为 0,故 黑白图片也称灰度图像,在医学、图像识别领域有很广泛的用途。 "灰度" 代表 DPI 的值,DPI 的意思是每平方英寸有多少象素点,象素点越大,图象的精确度越大,同时文件的尺寸 也越大,当然也不是 DPI 越大就越好,具体情况具体分析。
任何颜色都有红、绿、蓝三原色组成,假如原来某点的颜色为 RGB(R, G, B),那么, 我们可以通过下面几种方法,将其转换为灰度:
Gray=R*0.3+G*0.59+B*0.11
Gray=(R*30+G*59+B*11)/100
Gray=(R*28+G*151+B*77)>>8
Gray=(R+G+B)/3
Gray=G
通过上述任一种方法求得 Gray 后,将原来的 RGB(R,G,B) 中的 R,G,B 统一用 Gray 替换, 形成新的颜色 RGB(Gray,Gray,Gray),用它替换原来的 RGB(R,G,B) 就是灰度图了。
Material type:EMT_NORMAL_MAP_SOLID
法线贴图 根据这个参数作为 光照模型 亮度计算时候的参数。
Material type:EMT_PARALLAX_MAP_SOLID
作为实现 bump map 的技术之一,Parallax Mapping(视差映射)的目的同样也是让平坦表面实现凹凸效果。和 Normal Mapping 相比,Parallax Mapping 能实现更加真实和强烈的凹凸感。
凹凸映射和纹理映射非常相似。然而,纹理映射是把颜色加到多边形上,而凹凸映射 是把粗糙信息加到多边形上。 凹凸映射 Bump Mapping
经典的 Shading 方式有三种,Lambert Shading(D3D 中称为 Flat Shading)、Gouraud Shading 和 Phong Shading。
其实后两种 Shading 方式就是我们常说的逐顶点光照和逐像素光照,只不过那个是从 Shader 流程上区分并命名的而已,原理则是分别来自这两种不同的 Shading 方式的。