实验六凹凸纹理映射技术.docx
- 文档编号:12224087
- 上传时间:2023-04-17
- 格式:DOCX
- 页数:17
- 大小:58.99KB
实验六凹凸纹理映射技术.docx
《实验六凹凸纹理映射技术.docx》由会员分享,可在线阅读,更多相关《实验六凹凸纹理映射技术.docx(17页珍藏版)》请在冰豆网上搜索。
实验六凹凸纹理映射技术
实验六:
凹凸纹理映射技术
一、实验目的
掌握凹凸纹理映射的原理,熟悉Ogre中纹理映射的使用方法。
二、实验仪器
pc、vs2005
三、实验原理及过程
1、网上检索凹凸纹理映射相关技术
凹凸纹理映射是一种纹理混合方法,它可以创建三维物体复杂的纹理外观表面。
普通的纹理映射只能模拟比较平滑的三维物体表面,难以显示表面高低起伏、凹凸不平的效果。
凹凸纹理映射能够通过一张表示物体表面凹凸程度的高度图(称为凹凸纹理),对另一张表示物体表面环境映射的纹理图的纹理坐标进行相应的干扰,经过干扰的纹理坐标将应用于环境映射,从而产生凹凸不平的显示效果。
凹凸纹理映射通常由三张纹理映射图组成,第一张纹理图表示物体表面原始纹理颜色,第二张凹凸纹理图表示物体表面凹凸的高度起伏值,用来对下一张环境纹理图坐标进行干扰,第三张纹理图表示周围镜面反射或漫反射光照的环境光照映射图。
让我们来看看一个粗糙的表面。
从远处看,你判断这个物体是粗糙的的唯一证据是在它表面上下的亮度有改变。
你的大脑能够获得这些亮暗不一的图案信息,然后判断出它们是表面中有凹凸的部位。
左边的一幅图就说明了这一点。
你可以发现它是一个浮雕式的表面。
一些矩型和字母被印入表面,但是它们摸上去就像是一个隐藏的监控器的玻璃。
如果这个图像是在适当的位置上,那么它除了改变亮度,不需要再做任何其他的工作。
那么你也许会问:
我是怎么知道哪些点要亮,哪些点要暗呢?
这不难。
绝大多数人生活在这样一种环境下——这个环境的大多数光源来自上方(译者注:
比如白天主要的光来自太阳,夜晚主要的光来自天花板上的日光灯)。
所以向上倾的地方就会更亮,而向下倾的地方就会更暗。
所以这种现象使你的眼睛看到一个物体上亮暗区域时,可以判断出它的凹凸情况。
相对亮的块被判断是面向上的,相对暗的块被判断是面向下的。
所以我只需要给物体上的线条简单得上色。
如果你想要更多的证据,这里还有一幅几乎相同的图,不同于前的是它旋转了180度。
所以它是前一幅图倒转的图像。
那些先前看起来是凹进去的区域,现在看起来是凸出来的了。
凹凸映射(凹凸纹理)BumpMapping
这个时候你的大脑并没有被完全欺骗,你脑中存留的视觉印象使你仍然有能力判断出这是前一幅图,只是它的光源变了,是从小往上照的你的大脑可能强迫性地判断出它是第一幅图。
事实上,你只要始终盯着它,并且努力地想像着光是从右下方向照射的,你就会理解它是凹的(译者注:
因为日常生活的习惯,你会很容易把这些图形判断成凸出的图形,但是因为有了上一幅对照图的印象,你可能才会特别注意到这些图块其实还是凹入的,只是判断方法不符合我们日常生活习惯,因为这时大多数光不是从上方照射,而是从下往上照射)。
凹凸纹理映射技术可以用来模拟粗糙物体表面凹凸不平的细节,如:
橘子、草莓、树皮等。
凹凸纹理映射最早只能用于离线绘制系统,随着图形硬件的发展,他已经成为游戏引擎中不可缺少的部分。
最早的凹凸纹理映射使用一个高度图和曲面参数(通常是纹理坐标)的偏导数计算扰动后的法向。
这个偏导数表明了物体表面改变的尺度。
理论上,凹凸映射中涉及的法向操作实在像素层次上的。
凹凸纹理映射的步骤如下:
(1)计算每个顶点处的T、B、N,并计算切平面坐标的矩阵。
(2)根据该矩阵将光源变换到切平面空间,变换后光源的x、y即顶点的相邻点。
(3)从凹凸纹理中取出顶点和相邻点处的高度,根据两者的法向量计算出顶点的新法向,再根据新法向量进行光照明计算。
2、利用Ogre实现凹凸纹理映射描述程序实现时的思路包括对每个调用的API进行详细说明
1)顶点渲染主函数:
VS_OUTPUTVS(float4Pos:
POSITION,float2Tex:
TEXCOORD,float3Normal:
NORMAL,float3Tangent:
TANGENT){……}
2)像素渲染器主函数:
PS_OUTPUTPS(float2Tex:
TEXCOORD0,float3Light:
TEXCOORD1,float3View:
TEXCOORD2,float3Att:
TEXCOORD3){……}
四、实验结果
五、实验心得
本次实验主要掌握凹凸纹理映射的原理,熟悉Ogre中纹理映射的使用方法;凹凸纹理映射是一种纹理混合方法,它可以实现三维物体复杂的纹理表面,普通的纹理映射只能模拟比较平滑的三维物体表面,而凹凸纹理映射经相应的技术可以产生凹凸不平的显示效果,凹凸纹理映射技术可以用来模拟粗糙物体表面凹凸不平的细节;凹凸映射和纹理映射非常相似。
然而,纹理映射是把颜色加到多边形上,而凹凸映射是把
粗糙信息加到多边形上。
这在多边形的视觉上会产生很吸引人的效果。
我们只需要添加一点信息到本来需要使用大量多边形的物体上。
需要注意的是这个物体是平的,但是它看起来却是粗糙不平的。
让我们来看看左边的那个立方体。
如果你很近地观察它时,你会发现它上面的很多细节。
它看起来好像是由成千上万个多边形构成的,其实它只是由6个矩形构成。
通过本次实验了解凹凸纹理映射的原理,学会在ogre中对三维物体使用纹理映射的方法,对ogre的了解更进一步,收获颇多。
6、主要代码
Dot3Bump.h
#ifndef__Dot3Bump_H__
#define__Dot3Bump_H__
#include"SdkSample.h"
usingnamespaceOgre;
usingnamespaceOgreBites;
class_OgreSampleClassExportSample_Dot3Bump:
publicSdkSample
{
public:
Sample_Dot3Bump()
:
mMoveLights(true)
{
mInfo["Title"]="BumpMapping";
mInfo["Description"]="Showshowtousethedotproductblendingoperationandnormalizationcubemap"
"toachieveabumpmappingeffect.Tangentspacecomputationsmadethroughtheguideofthetutorial"
"onbumpmappingfromhttp:
//users.ox.ac.uk/~univ1234bypaul.baker@univ.ox.ac.uk.";
mInfo["Thumbnail"]="thumb_bump.png";
mInfo["Category"]="Lighting";
mInfo["Help"]="Leftclickanddraganywhereinthescenetolookaround.Letgoagaintoshow"
"cursorandaccesswidgets.UseWASDkeystomove.";
}
StringVectorgetRequiredPlugins()
{
StringVectornames;
names.push_back("CgProgramManager");
returnnames;
}
voidtestCapabilities(constRenderSystemCapabilities*caps)
{
if(!
caps->hasCapability(RSC_VERTEX_PROGRAM)||!
(caps->hasCapability(RSC_FRAGMENT_PROGRAM)))
{
OGRE_EXCEPT(Exception:
:
ERR_NOT_IMPLEMENTED,"Yourgraphicscarddoesnotsupportvertexandfragmentprograms,"
"soyoucannotrunthissample.Sorry!
","Dot3BumpSample:
:
testCapabilities");
}
if(!
GpuProgramManager:
:
getSingleton().isSyntaxSupported("arbfp1")&&
!
GpuProgramManager:
:
getSingleton().isSyntaxSupported("ps_2_0"))
{
OGRE_EXCEPT(Exception:
:
ERR_NOT_IMPLEMENTED,"Yourcarddoesnotsupportshadermodel2,"
"soyoucannotrunthissample.Sorry!
","Dot3BumpSample:
:
testCapabilities");
}
}
boolframeRenderingQueued(constFrameEvent&evt)
{
if(mMoveLights)
{
//rotatethelightpivots
mLightPivot1->roll(Degree(evt.timeSinceLastFrame*30));
mLightPivot2->roll(Degree(evt.timeSinceLastFrame*10));
}
returnSdkSample:
:
frameRenderingQueued(evt);//don'tforgettheparentclassupdates!
}
voiditemSelected(SelectMenu*menu)
{
if(menu==mMeshMenu)
{
//changetotheselectedentity
mObjectNode->detachAllObjects();
mObjectNode->attachObject(mSceneMgr->getEntity(mMeshMenu->getSelectedItem()));
//rememberwhichmaterialiscurrentlyselected
intindex=std:
:
max
//updatethematerialmenu'soptions
mMaterialMenu->setItems(mPossibilities[mMeshMenu->getSelectedItem()]);
mMaterialMenu->selectItem(index);//selectthematerialwiththesavedindex
}
else
{
//settheselectedmaterialfortheactivemesh
((Entity*)mObjectNode->getAttachedObject(0))->setMaterialName(menu->getSelectedItem());
}
}
voidcheckBoxToggled(CheckBox*box)
{
if(StringUtil:
:
startsWith(box->getName(),"Light",false))
{
//getthelightpivotthatcorrespondstothischeckbox
SceneNode*pivot=box->getName()=="Light1"?
mLightPivot1:
mLightPivot2;
SceneNode:
:
ObjectIteratorit=pivot->getAttachedObjectIterator();
while(it.hasMoreElements())//togglevisibilityoflightandbillboardset
{
MovableObject*o=it.getNext();
o->setVisible(box->isChecked());
}
}
elseif(box->getName()=="MoveLights")
{
mMoveLights=!
mMoveLights;
}
}
protected:
voidsetupContent()
{
//createourmainnodetoattachourentitiesto
mObjectNode=mSceneMgr->getRootSceneNode()->createChildSceneNode();
setupModels();
setupLights();
setupControls();
mCamera->setPosition(0,0,500);
setDragLook(true);
}
voidloadResources()
{
#ifdefUSE_RTSHADER_SYSTEM
ResourceGroupManager&rgm=ResourceGroupManager:
:
getSingleton();
Ogre:
:
StringVectorgroupVector=Ogre:
:
ResourceGroupManager:
:
getSingleton().getResourceGroups();
Ogre:
:
StringVector:
:
iteratoritGroup=groupVector.begin();
Ogre:
:
StringVector:
:
iteratoritGroupEnd=groupVector.end();
Ogre:
:
StringshaderCoreLibsPath;
for(;itGroup!
=itGroupEnd;++itGroup)
{
Ogre:
:
ResourceGroupManager:
:
LocationListresLocationsList=Ogre:
:
ResourceGroupManager:
:
getSingleton().getResourceLocationList(*itGroup);
Ogre:
:
ResourceGroupManager:
:
LocationList:
:
iteratorit=resLocationsList.begin();
Ogre:
:
ResourceGroupManager:
:
LocationList:
:
iteratoritEnd=resLocationsList.end();
boolcoreLibsFound=false;
//Findthelocationofthecoreshaderlibs
for(;it!
=itEnd;++it)
{
if((*it)->archive->getName().find("RTShaderLib")!
=Ogre:
:
String:
:
npos)
{
shaderCoreLibsPath=(*it)->archive->getName()+"/";
coreLibsFound=true;
break;
}
}
//Corelibspathfoundinthecurrentgroup.
if(coreLibsFound)
break;
}
//CreatetheresourcegroupoftheRTShaderSystem.
rgm.createResourceGroup("RTShaderSystemMaterialsGroup");
rgm.addResourceLocation(shaderCoreLibsPath+"materials","FileSystem","RTShaderSystemMaterialsGroup");
rgm.initialiseResourceGroup("RTShaderSystemMaterialsGroup");
rgm.loadResourceGroup("RTShaderSystemMaterialsGroup",true);
#endif
}
voidunloadResources()
{
#ifdefUSE_RTSHADER_SYSTEM
ResourceGroupManager&rgm=ResourceGroupManager:
:
getSingleton();
//DestroytheresourcegroupoftheRTShaderSystem
rgm.destroyResourceGroup("RTShaderSystemMaterialsGroup");
#endif
}
voidsetupModels()
{
StringVectormatNames;
matNames.push_back("Examples/BumpMapping/MultiLight");
matNames.push_back("Examples/BumpMapping/MultiLightSpecular");
matNames.push_back("Examples/OffsetMapping/Specular");
matNames.push_back("Examples/ShowUV");
matNames.push_back("Examples/ShowNormals");
matNames.push_back("Examples/ShowTangents");
#ifdefUSE_RTSHADER_SYSTEM
matNames.push_back("RTSS/NormalMapping_SinglePass");
matNames.push_back("RTSS/NormalMapping_MultiPass");
#endif
mPossibilities["ogrehead.mesh"]=matNames;
mPossibilities["knot.mesh"]=matNames;
matNames.clear();
matNames.push_back("Examples/Athene/NormalMapped");
matNames.push_back("Examples/Athene/NormalMappedSpecular");
matNames.push_back("Examples/Athene/NormalMappedSpecular");
matNames.push_back("Examples/ShowUV");
matNames.push_back("Examples/ShowNormals");
matNames.push_back("Examples/ShowTangents");
#ifdefUSE_RTSHADER_SYSTEM
matNames.push_back("RTSS/Athene/NormalMapping_SinglePass");
matNames.push_back("RTSS/Athene/NormalMapping_MultiPass");
#endif
mPossibilities["athene.mesh"]=matNames;
for(std:
:
map
:
iteratorit=mPossibilities.begin();it!
=mPossibilities.end();it++)
{
//loadeachmeshwithnon-defaulthardwarebufferusageoptions
MeshPtrmesh=MeshManager:
:
getSingleton().load(it->first,ResourceGroupManager:
:
DEFAULT_RESOURCE_GROUP_NAME,
HardwareBuffer:
:
HBU_DYNAMIC_WRITE_ONLY);
//buildtangentvectorsforourmesh
unsignedshortsrc,dest;
if(!
mesh->suggestTangentVectorBuildParams(VES_TANGENT,src,dest))
{
mesh->buildTangentVectors(VES_TANGENT,src,dest);
//thisversioncleansmirroredandrotatedUVsbutrequiresqualitymodels
//mesh->buildTangentVectors(VES_TANGENT,src,dest,true,true);
}
//createanentityfromthemeshandsetthefirstavailablematerial
Entity*ent=mSceneMgr->createEntity(mesh->getName(),mesh->getName());
ent->setMaterialName(it->second.front());
}
}
voidsetupLights()
{
mSceneMgr->setAmbientLight(ColourValue:
:
Black);//disableambientlighting
//createpivotnodes
mLightPivot1=mSceneMgr->getRootSceneNode()->createChildSceneNode();
mLightPivot2=mSceneMgr->getRootSceneNode()->createChildSceneNode();
Light*l;
BillboardSet*bbs;
//createwhitelight
l=mSceneMgr->cr
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 实验 凹凸 纹理 映射 技术