英语翻译书籍系列,张道真英语语法珍藏系列

更新时间:2024-02-16 作者:用户投稿原创标记本站原创 点赞:31827 浏览:144909

[声明:本人仅仅英语四级水平,因为喜欢翻译和喜欢Ogre,翻译以下文字,如果哪里有错误或不足还望大虾们见谅,如果您发现有什么错误,请把问题发送到whistleofmysong@gmail.,我将尽快的改正.想到可能对新手有些许帮助,所以对别人是个帮助,对自己也是个鼓励~^_^]

3Camera,Light,andShadow

【第三章摄像机,光源和阴影】

Wealreadylearnedhowtocreateaplexscene,butwithoutlightand

shadow,ascenewon'tbeplete.

【我们已经学习过如果创建一个复杂的场景.但是如果没有光源和阴影,一个场景是不完整的.】

Inthischapter,wewilllearnabout:

【在这章,我们将会学习到:】

*ThetypesofdifferentlightsourcesOgre3Dsupportsandhowtheywork

*Addingshadowstoasceneandthedifferentshadowtechniquesailable

*Whatacameraandviewportareandwhyweneedtohethem

*Ogre3D支持的不同类型的光源和它们是如何使用的.

*对一个场景添加阴影和添加可用的不同的阴影技术.

*什么是摄像机和视口和我们为什么需要使用它们.

Creatingaplane

【创建一个平面】

Beforewecanaddlightstoourscene,wefirstneedtoaddaplane,ontowhichshadowsand

lightareprojected,andthereforevisibletous.Anormalapplicationwouldn'tneedaplane

becausetherewouldbeaterrainorafloortoprojectlightonto.Lightcalculationwouldwork

withouttheplane,butwewouldn'tbeabletoseetheeffectofthelight.

【在我们添加光源到我们的场景之前,我们首先需要添加一个可以投射阴影和光源的平面,这样我们就可以看到阴影了.通常一个应用程序不需要一个平面,因为项目的本身有可以打上光的地形和地板.光的计算可以在一个没有平面的程序中,但是那样我们就看不到光源的效果了.】

Timeforaction–creatingaplane

【实践时刻——创建一个平面】

Untilnow,wehealwaysloadeda3Dmodelfromafile.Nowwewillcreateonedirectly:

【目前为止,我们总是从一个文件中加载3D模型.现在我们就直接创建一个平面:】

1.DeleteallthecodeinsidethecreateScene()function.

【1.删除createScene()函数中的所有代码:】

2.AddthefollowinglinetodefineaplaneinthecreateScene()function:

【2.在createScene()函数中添加下面一行代码来定义一个平面.】

Ogre::Planeplane(Vector3::UNIT_Y,-10),

Nowcreatetheplaneintoyourmemory:

【现在创建一个平面写入到你的内存中.】

Ogre::MeshManager::getSingleton().createPlane("plane",

ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,plane,

1500,1500,20,20,true,1,5,5,Vector3::UNIT_Z),

Createaninstanceoftheplane:

【创建一个平面的实例.】

Ogre::Entity*ent等于mSceneMgr->,createEntity("LightPlaneEntity","plane"),

Attachtheplanetothescene:

【关联平面到场景.】

mSceneMgr->,getRootSceneNode()->,createChildSceneNode()->,attachObject(ent),

6.Togetanythingotherthanawhiteplane,setthematerialoftheplanetoan

existingmaterial:

【为了得到一个不同于白色的平面,设置平面的纹理为一个已经存在的材质.】

ent->,setMaterialName("Examples/BeachStones"),

Compiletheapplicationandrunit.Youshouldseesomedarkstones.

【编译程序并运行,你将会看到一些暗石头.】

Weheinvertedthecolororeaseofreading!

【我们转变了文字的颜色以便于阅读!】(译者注:估计是指的书的文字颜色.)

Whatjusthappened

【刚刚发生了什么】

Wejustcreatedaplaneandaddedittothescene.Step2createdaninstanceof

Ogre::Plane.Thisclassdescribesaplaneusingthenormalvectoroftheplaneand

anoffsetfromthenullpointusingthenormalvector.

Anormalvector(orinshort,justnormal)isanoften-usedconstructin3Dgraphics.

Thenormalofasurfaceisectorthatstandsperpendicularonthissurface.The

lengthofthenormalisoften1andisusedextensivelyinputergraphicorlight

andocclusioncalculation.

我们刚刚创建了一个平面并且把它添加到了场景中.在第二部中我们创建了一个Ogre::Plane的实例.这个类描述了一个使用法向量和原点偏移量的平面.

一个法向量(或平面法向量)是在3D图形学中一个常用的概念.一个平面法向量指的是一个垂直于平面的向量.法向量的长度通常是1并且它被广泛的应用的计算机图形学的光计算和遮挡计算.

InStep3,weusedtheplanedefinitiontocreateameshoutofit.Todothis,weusedtheOgreMeshManager.Thianagermanageeshes,whichshouldn'tbeasurprise.Besideanagingmeshesthatweloadedfromafile,itcanalsocreateplaneromourplanedefinition,aswellasalotofotherthings.

【在第三步中,我们使用了一个定义一个外面有网格的平面.为了实现这个,我们使用了OgreMeshManager(Ogre网格管理器).这个管理器管理着场景中的网格.除了管理从文件加载的网格,这个管理器也创建一个由我们自己定义的平面,当然也创建别的一些东西.】

Ogre::MeshManager::getSingleton().createPlane("plane",

ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,plane,

1500,1500,20,20,true,1,5,5,Vector3::UNIT_Z),

Besidestheplanedefinition,weneedtogivetheplaneaname.Whenloadingmesheromthedisk,thefile'snameisusedastheresourcename,resourcename.Italsoneedsanresourcegroupitbelongsto,resourcegroupsarelikenamespacesinC++.Thethirdparameteristheplanedefinitionandthefourthandfifthparametersarethesizeoftheplane.Thesixthandseventhparametersareusedtosayhowmanysegmentstheplaneshouldhe.Tounderstandwhatasegmentis,wewilltakeaalldetouronhow3Dmodelsarerepresentedin3Dspace.

【除了定义平面,我们需要给定义的平面一个名称.当从磁盘加载网格的时候,该文件的名称作为该资源的名称.它也需要一个属于资源组Representingmodelsin3D

【在3D空间中表示模型】

Torendera3Dmodel,itneedstobedescribedinawayaputercanunderstandandrender

itmosteffectively.Themostmonformtorepresent3Dmodelsinreal-timeapplicationis

triangles.Ourplanecanberepresentedusingtwotrianglestoformaquad.Withthesegment

optionforthex-andthey-axis,wecancontrolhowmanytrianglesaregeneratedforthe

plane.Inthefollowingimage,weseethetrianglesthatmakeuptheplanewithone,two,or

threesegmentoreachaxis.Toseethiseffect,westarttheapplicationandthenpresstheR

key.Thiswillswitchtherenderingmodefirsttowireframemode,whereweseethetriangles.

Anotherkeypresswillchangethemodetopointmode,whereweseeonlythepointsofthe

triangles.Anotherpresswillsettherendermodetonormal.

【渲染一个3D的模型需要以某种计算机可以理解并且可以渲染的更有效率的描述方式.在实时程序中描述3D模型的最常见形式就是三角形.我们的平面可以用两个三角形可以组成一个四边形的方式来表示.因为切片的有X和Y轴的大小的平面参数,我们可以控制用多少三角形来生成一个平面.在下面的图片中,我们将会看到用每个轴一个,二个或者三个三角形切片组成平面.为看到这种效果,我们运行程序然后按下R键.这样就可以从第一渲染模式变为线框模式,这样我们就可以看到三角形了.再按一下R键将会改变现有模式为点模式,我们将会三角形的顶点了.再按一下R键将会改变为正常的渲染模式.】


Afterwehedefinedhowmanysegmentswewant,wepassaBooleanparameter

whichtellsOgre3Dthatwewantthenormaloftheplanetobecalculated.Assaidbefore,

anormalisectorwhichstandsverticallyonthesurfaceoftheplane.Thenextthree

parametersareusedfortexturing.Totexturesomethingallpointsneedtexturecoordinates.

Texturecoordinatestelltherenderenginehowtomapthetextureontothetriangle.

Becauseapictureisa2Dsurface,thetexturecoordinatesalsoconsistoftwovalues,

namely,xandy.Theyarepresentedasatuple(x,y).Thevaluerangeoftexturecoordinates

isnormalizedfromzerotoone.(0,0)meanstheupper-leftcornerofthetextureand(1,1)

thebottom-rightcorner.Sometimesthevaluescanbegreaterthan1.Thieansthatthe

texturecouldberepeateddependingonthesetmode.Thistopicwillbeexplainedinalater

chapterextensively.(2,2)couldrepeatthetexturetwiceacrossbothaxis.Thetenthand

eleventhparameterstellOgre3Dhowoftenwewantthetexturetobetiledacrosstheplane.

Theninthparameterdefineshowmanytextures'coordinateswewant.Thiscanbeuseful

whenworkingwithmorethanonetextureforonesurface.Thelastparameterdefinesthe

"up"directionforourtextures.Thisalsoaffectshowthetexturecoordinatesaregenerated.

Wesimplysaythatthez-axisshouldbe"up"forourplane.

【在定义完我们想要的切片的程度,我们传递一个布尔的参数来告诉Ogre3D平面的法向量是否被计算.正如之前所述,法向量是垂直于平面的一个向量.最后的那三个参数是作用用于纹理.渲染的纹理时,所有的点都需要纹理坐标.纹理坐标告诉渲染引擎如何映射材质到三角形.因为一张图片是一个2D的表面,纹理的坐标包含两个值即——x和y.它们被表示为一个数组(x,y).纹理坐标值正常初始化的范围为从0到1.(0,0)表示纹理的左上角,(1,1)表示为右下角.有时候它们的值会大于1,这表示纹理可以根据设置模式来进行重复.这个话题我们将在接下来的章节展开来谈.(2,2)可能表示纹理横跨两轴重复两次.第十和第十一个参数告诉Ogre3D我们想要纹理平铺平面的频率.第九个参数定义了我们需要多少个纹理坐标系.当我们使用超过1个的表面纹理的时候,这个参数就变的很有用了.最后一个参数定于了纹理"up"的方向.这也会影响到纹理坐标的生成.我们简单的说Z轴应"up"我们的平面.】

Instep4,wecreatedaninstanceoftheplanethatwejustcreatedwiththeMeshManager.

Todothis,weneedtousethenamewegetheplaneduringcreation.Step5attachedthe

entitytothescene.

【在第四步,我们创建了一个刚经过MeshManage(网格管理器)创建的平面的实例.要做到这一点,我们需要使用在创建过程中我们给予平面的名称.在第五步中我们关联实体到场景.】

Instep6,wesetanewmaterialtotheinstanceoftheentity.Eachentityhasamaterial

assignedtoit.Thematerialdescribeswhichtexturetouse,howthelightinginteractswith

thematerial,andmuchmore.Wewilllearnaboutallofthisinthechapteronmaterials.

Theplanewecreateddoesn'theamaterialyetandthereforewouldberenderedwhite.

Becausewewanttoseetheeffectoflightswecreatelater,whiteisn'tthebestcolortouse.

Weusedamaterialthatisalreadydefinedinthemediafolder.Thiaterialsimplyaddsa

stonetexturetoourplane.

【在第六步中,我们设置了实体实例的一个新材质.每个实体会有一个材质分配给它.这个材质描述了我们使用的纹理与其所具有的光效果与材料的相互作用media文件夹下定义的材质.这个材质简单对我们的平面的添加了石头纹理.】

Addingapointlight

【添加一个点光源】

Nowthatwehecreatedaplanetoseetheeffectthatthelighthasonourscene,weneedtoaddalighttoseesomething.

【现在我们已经创建了一个可以扎在我们场景中看见光源效果的平面,我们需要添加一个光源去看下效果.】

Timeforaction–addingapointlight

【实践时刻——添加一个点光源】

Wewillcreateapointlightandaddittoourscenetoseetheeffectithasonourscene:

【我们将会创建一个点光源并且添加到我们的场景中,然后观察光源在我们场景中的效果:】

Addthefollowingcodeaftersettingthematerialfortheplane:

【1.在设置完平面的材质之后添加以下代码:】

Ogre::SceneNode*node等于mSceneMgr->,createSceneNode("Node1"),

mSceneMgr->,getRootSceneNode()->,addChild(node),

CreatealightwiththenameLight1andtellOgre3Dit'sapointlight:

【2.创建一个名为Light1的光源并且告诉Ogre3D这是一个点光源:】

Ogre::Light*light1等于mSceneMgr->,createLight("Light1"),

light1->,setType(Ogre::Light::LT_POINT),

Setthelightcolorandposition:

【3.设置光源的颜色和位置:】

light1->,setPosition(0,20,0),

light1->,setDiffuseColour(1.0f,1.0f,1.0f),

4.Createasphereandsetitatthepositionofthelight,sowecanseewhere

thelightis:

【4.创建一个球并且设置它在点光源的位置,这样我们就可以看到光源的位置了.】

Ogre::Entity*LightEnt等于mSceneMgr->,createEntity("MyEntity","sphere.mesh"),

Ogre::SceneNode*node3等于node->,createChildSceneNode("node3"),

node3->,setScale(0.1f,0.1f,0.1f),

node3->,setPosition(0,20,0),

node3->,attachObject(LightEnt),

5.Compileandruntheapplication,youshouldseethestonetexturelitbyawhite

light,andseeawhitesphereabitabovetheplane.

【编译运行程序,你应会看到石头的纹理将会被一个白色的光源照亮,并且会看到在平面上面有一个白色的圆球.】

Whatjusthappened

【刚刚发生了什么】

Weaddedapointlighttooursceneandusedawhitespheretomarkthepositionof

thelight.Instep1,wecreatedascenenodeandaddedittotherootscenenode.Wecreatedthe

scenenodebecauseweneeditlatertoattachthelightsphereto.Thefirstinterestingthing

happenedinstep2.Therewecreatedanewlightusingthescenemanager.Eachlightwill

needauniquename,ifwedecidetogiveitaname.Ifwedecidenottouseaname,then

Ogre3Dwillgenerateoneforus.

【我们在场景中添加了一个点光源并且使用了一个白色的球体在标明点光源的位置.在第一步中,我们创建了一个场景结点并添加它到我们的场景根结点.我们创建场景结点是因为我们要为稍后关联白色球体做准备.第一个比较有趣的事情是发生在第二步.我们使用场景管理器创建了一个新光源.如果我们给光源一名称,每个光源的名字必须是独一无二的,如果我们不给光源名称,然后Ogre3D会为我们生成一个.】

WeusedLight1asaname.Aftercreation,wetoldOgre3Dthatwewanttocreateapointlight.Therearethreedifferentkindsoflightswecancreate,namely,pointlights,spotlights,anddirectionallights.Herewecreatedapointlight,soonwewillcreatetheothertypesoflights.Apointlightcanbethoughtofasbeinglikealightbulb.It'sapointinspacewhichilluminateseverythingaroundit.Instep3,weusedthecreatedlightandsetthepositionofthelightanditscolor.Everylightcolorisdescribedbyatuple(r,g,b).Allthreeparametershearangefrom0.0to1.0andrepresenttheattributionoftheirassignedcolorparttothecolor.'r'standorred,'g'forgreen,and'b'forblue.(1.0,1.0,1.0)iswhite,(1.0,0.0,0.0)isred,andsoon.ThefunctionwecalledwassetDiffuseColour(r,g,b),whichtakesexactlythesethreeparameterorthecolor.

Step4addedawhitesphereatthepositionofthelight,sowecouldseewherethelightis

positionedinthescene.

【我们使用Light1作为光源的名称.创建之后,我们告诉Ogre3D我们想要创建一个点光源.我们可以创建三种不同的光源,即为——点光源,聚光源和方向光源.在这我们创建了一个点光源.一会我们将会创建别的类型的光源.一个点光源可以被认为是一个明亮的灯泡.它就好像是空间中可以照亮周围一切的光源.在第三步中,我们使用了刚创建的光源并且设置了光源的位置和颜色.每个光源的颜色是用一个(r,g,b)的数组来描述的.所有三个参数的范围都是从0.0到1.0而且每个参数表述了它们各自对应颜色属性对最终颜色效果的影响.'r'代表红色,'g'代表绿色,'b'代表蓝色.(1.0,1.0,1.0)是白色,(1.0,0.0,0.0)为红色,其他等等如此类推.我们调用的函数setDiffuseColour(r,g,b)中的三个参数恰恰是对应表述颜色的(r,g,b)三个参数.在第四步在光源的位置添加了一个白色球体,这样我们就可以看到光源在场景中的位置了.】

Heagohero–addingasecondpointlight

【让英雄动起来——添加第二个点光源】

Addasecondpointlightat(20,20,20),whichilluminatesthescenewitharedlight.Alsoadd

anotherspheretoshowwherethepointlightis.Here'showitshouldlook:

【在(20,20,20)的位置添加第二个照亮场景的红色点光源.同样的添加另一个球体以显示点光源的位置.以下就是效果图:】

Addingaspotlight

【添加一个聚光源】

Wehecreatedapointlightandnowwewillcreateaspotlight—thesecondlighttypewe

canuse.

【我们已经创建了一个点光源而现在我们将会创建一个聚光源——第二种我们可以使用的光源类型.】

Timeforaction–creatingaspotlight

【实践时刻——创建一个聚光源】

Wewillusethecodewecreatedbeforeandmodifyitabittoseehowaspotlightworks:

【我们将会使用我们之前已经写好的代码并且简单修改一下,然后观察一个聚光源是如何工作的:】

1.Deletethecodewherewecreatedthelightandinsertthefollowingcodetocreate

anewscenenode.Becarefulnottodeletethepartofthecodeweusedtocreate

LigthEntandthenaddthefollowingcode:

【1.删除我们创建光源的代码并插入以下代码以创建一个新的场景结点.注意不要删除我们使用过的LigthEnt的代码段,然后添加以下代码:】

Ogre::SceneNode*node2等于node->,createChildSceneNode("node2"),

node2->,setPosition(0,100,0),

Again,createalight,butnowsetthetypetospotlight:

【2.同样的,创建一个光源,但是现在设置光源的类型为spotlight】

Ogre::Light*light等于mSceneMgr->,createLight("Light1"),

light->,setType(Ogre::Light::LT_SPOTLIGHT),

Nowsetsomeparameters,wewilldiscusstheirmeaningslater:

【3.现在设置一些参数,我们将会稍后讨论他们的意思.】

light->,setDirection(Ogre::Vector3(1,-1,0)),

light->,setSpotlightInnerAngle(Ogre::Degree(5.0f)),

light->,setSpotlightOuterAngle(Ogre::Degree(45.0f)),

light->,setSpotlightFalloff(0.0f),

Setthelightcolorandaddthelighttothenewlycreatedscenenode:

【4.设置光源的颜色然后添加光源到刚创建的场景结点:】

light->,setDiffuseColour(Ogre::ColourValue(0.0f,1.0f,0.0f)),

node2->,attachObject(light),

Compileandruntheapplication,itshouldlooklikethis:

【5.编译运行程序.它将会有以下效果:】

Whatjusthappened

【刚刚发生了什么】

Wecreatedaspotlightinthesamemannerwecreatedapointlight,wejustusedsome

differentparameterorthelight.

Step1createdanotherscenenodetobeusedlater.Step2createdthelightaswedid

before,wejustusedadifferentlighttype—thistimeOgre::Light::LT_SPOTLIGHT—to

getaspotlight.Step3isthereallyinterestingone,therewesetdifferentparameteror

thespotlight.

【我们几乎以创建点光源同样的方式创建了一个聚光源.不同的是我们改变了光源的一些参数.在第一步中,我们创建了在稍后会用到的场景结点.在第二步中,我们如往常一样创建了一个光源,但是我们使用了不同的光源类型——这次我们使用了Ogre::Light::LT_SPOTLIGHT——来获取一个聚光源.在第三步是有趣的的步,我们为聚光源设置了不同的参数.】

Spotlights

【聚光源】

Spotlightsarejustlikeflashlightsintheireffect.Theyheapositionwheretheyareanda

directioninwhichtheyilluminatethescene.Thisdirectionwasthefirstthingwesetafter

creatingthelight.Thedirectionsimplydefinesinwhichdirectionthespotlightispointed.

Thenexttwoparameterswesetweretheinnerandtheouteranglesofthespotlight.The

innerpartofthespotlightilluminatestheareawiththepletepowerofthelightsource's

color.Theouterpartoftheconeuseslesspowertolighttheilluminatedobjects.Thisis

donetoemulatetheeffectsofarealflashlight.Arealflashlightalsohasaninnerpartand

anouterpartthatilluminatethearealesserthenthecenterofthespotlight.Theinnerand

outerangleswesetdefinehowbigtheinnerandtheouterpartshouldbe.Aftersettingthe

angles,wesetafalloffparameter.Thialloffparameterdescribeshowmuchpower

thelightloseswhenilluminatingtheouterpartofthelightcone.Thefartherawayapointto

beilluminatediromtheinnercone,themorethefalloffaffectsthepoint.Ifapointis

outsidetheoutercone,thenitisn'tilluminatedbythespotlight.

【聚光源恰如手电筒的效果.它们有发光源的位置和在照亮场景的一个方向.设置光线方向是我们创建聚光源完成后要做的第一件事.光线的方向简单的定义了聚光灯的指向.接下来的我们设置的两个参数为聚光源的内角度和外角度.聚光源的内光部分使用完整的光源颜色来照射区域,而外部的锥体只使用较少的光源能量来照亮物体.这样做是为了模拟手电筒的效果.一个真正的手电筒也是有内光部分和外光部分,其中外光部分没有聚光源的光源的亮度强.我们的定义的内角和外角决定了光源照射的内部和外部的范围有多大.在设置完角度之后,我们设置了一个下降(falloff)参数.这个下降参数描述了当照射外层锥体光能损失.被照射的点离内部的距离越大,下降效果就越明显.如果一个点是在圆锥体之后,那它将不会被聚光源所照射到.】

Wesetthefallofftozero.Intheory,weshouldseeaperfectlightcircleontheplane,but

itisratherblurryanddeformed.Thereasonforthisisthatthelightingthatweuseatthe

momentusesthetrianglepointsoftheplanetocalculateandapplytheillumination.When

creatingtheplane,wetoldOgre3Dthattheplaneshouldbecreatedwith20X20segments.

Thisisaratherlowresolutionforsuchabigplaneandmeansthelightcannotbecalculated

accuratelyenough,becausetherearetoofewpointstoapplyinanareatomakeaooth

circle.Sotogetabetterqualityrender,wehetoincreasethesegmentsoftheplane.Let's

sayweincreasethesegmentrom20to200.Theplanecreationcodelookslikethisafter

theincrease:

【我们设置下降为0.理论上Ogre::MeshManager::getSingleton().createPlane("plane",ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,plane,1500,1500,200,200,true,1,5,5,Vector3::UNIT_Z),

Nowwhenrepilingandrestartingtheapplication,wegetaniceroundcircleoflightfrom

ourspotlight.

【现在当我们重新编译运行程序,我们将会从我们聚光源得到一个更圆的光圈.】

Thecirclestillisn'tperfect,ifneeded,wecouldincreasethesegmentsoftheplaneeven

furthertomakeitperfect.Therearedifferentlightingtechniqueswhichgivebetterresults

withalow-resolutionplane,buttheyareratherplexandwouldplicatethingsnow.

Butevenwiththeplexlightingtechniques,thebasicsarethesameandwecanchange

ourlightingschemelaterusingthesamelightswecreatedhere.

【这个圆任然不是完美的.如果需要,我们可以增加平面的切片程度,也可以把光源放远一点使它看起来更加完美.也有不同的光源技术使低分辨率的平面达到更好的效果,但是它们却相当复杂并且使事情之间变得复杂.但是即使是复杂的光源技术,基本的原理是相同的而且可以通过改变我们的光源策略来使用这里创建的光源】

Instep4,wesawanotherwaytodescribeacolorinOgre3D.Previously,weusedthree

values,(r,g,b),tosetthediffusecolorofourlight.HereweusedOgre::ColourValue

(r,g,b),whichisbasicallythesamebutencapsulatedasaclasswithsomeadditional

functionsandthusitmakestheintentionoftheparameterclearer.

【在第四步中,我们看到了在Ogre3D中描述颜色的另一种方式.在此之前,我们使用三个值(r,g,b),来设置我们光源的漫射色.这里我们使用了Ogre::ColourValue(r,g,b),两种表述方式基本一样,但是这种方式加以一些额外的函数作为一个类被封装,从而使得参数的意图更清晰Popquiz–differentlightsources

【简单测试——不同的光源资源】

Describethedifferencebetweenapointlightandaspotlightinafewwords.

【用几句话描述点光源和聚光源之间的不同.】

Heagohero–mixinglightcolors

【让英雄动起来——混合光线颜色】

Createasecondspotlightthatisatadifferentpositionasparedtothefirstspotlight.

Givethisspotlightaredcolorandpositionitinsuchawaythatthecirclesofbothspotlightsoverlapeachotherabit.Youshouldseethatthecoloriixingintheareawherethegreenandredlightoverlap.

【创建与第一个聚光源位置不同的第二个聚光源,给第二个聚光源以红色的光线,以如此方式安置光源,可以使两个聚光源重叠一部分.你就可以看到在绿色和红色的重叠区域会有颜色的混合.】

Directionallights

【方向光源】

Wehecreatedspotlightsandpointlights.Nowwearegoingtocreatethelastlighttype—directionallights.Adirectionallightisalightthatiarawayandonlyhasadirectionandacolor,butnolightconeorradiuslikespotlightsorpointlights.Itcanbethoughtofasthesun.Forus,thesunlighteromonedirection,thedirectionofthesun.

【我们已经创建过了聚光源和点光源.现在我们准备创建最后一种光源类型——方向光源.方向光源是一种离你很远的光源而且这种光只有方向和颜色,但是却没有像聚光源和点光源的锥形光束光照范围Timeforaction–creatingadirectionallight

【实践时刻——创建一个方向光源】

1.DeletealltheoldcodeincreateScene(),exceptfortheplane-relatedcode.

【1.除了与平面相关的代码,删除所有的createScene()函数中的旧代码.】

Createalightandsetthelighttypetodirectionallight:

【2.创建一个光源并且设置光源的类型为方向光源:】

Ogre::Light*light等于mSceneMgr->,createLight("Light1"),

light->,setType(Ogre::Light::LT_DIRECTIONAL),

Setthelighttoawhitecolorandthelightdirectiontoshineinadown-rightdirection:

【设置光源为白色并且设置光源的方向为右下方.】

light->,setDiffuseColour(Ogre::ColourValue(1.0f,1.0f,1.0f)),

light->,setDirection(Ogre::Vector3(1,-1,0)),

Compileandruntheapplication.

【编译运行程序.】

Whatjusthappened

【刚刚发生了什么】

Wecreatedadirectionallightandsetittoshinedownandrightwardswith

setDirection(1,-1,0).Inthepreviousexamples,wealwayshadaratherblackplane

andaallpartoftheplanewasilluminatedbyourpointlightorspotlight.Here,weused

adirectionallightandhencethepleteplaneisilluminated.Assaidbefore,adirectional

lightcanbethoughtofasthesun,andthesundoesn'theafalloffradiusoranythingelse.Sowhenitshines,itilluminateseverythingthereis,thesameistrueforourdirectionallight.

【我们创建了一个方向光源并且使用setDirection(1,-1,0)设置它发光的方向是右下.在之前的例子中,我们创建的平面几乎是黑色并且平面只有一小部分被点光源或聚光源所照亮.这里,我们使用了一个方向光源,这以后整个平面被照亮了.正如前面所述,方向光源可以认为是一个太阳,太阳发出的光是没有衰减半径,也没有别的特殊性质.所以当太阳发光的时候,它会照亮所有的物体.这对我们的方向光源同样适用.】

Popquiz–differentlighttypes

【简单测试——不同的光源类型】

RecallallthreelighttypesthatOgre3Dhasandstatethedifferences.

【回忆Ogre3D中的三种光源类型并且说明之间的不同】

Themissingthing

【遗漏的东西】

Wealreadyheaddedlighttoourscene,butsomethingiissing.What'issingwillbe

showninthenextexample.

【我们已经添加光源到我们的场景中,但是却遗漏了一些东西.在下个例子中我们将会显示出到底是遗漏了什么.】

Timeforaction–findingoutwhat'issing

【实践时刻——找出到底遗漏了什么】

Weareusingthepreviouslysuggestedcodetofindoutwhatiissinginourscene.

【我们使用之前推荐的代码来找出在场景中遗漏了什么东西.】

1.Afterthecreationofthelight,addcodetocreateaninstanceofSinbad.meshand

alsocreateanodeandattachthemodeltoit:

【1.在创建光源完成后,添加代码以创建一个Sinbad.mesh的实例并创建一个节点用以关联模型.】

Ogre::Entity*Sinbad等于mSceneMgr->,createEntity("Sinbad","Sinbad.mesh"),

Ogre::SceneNode*SinbadNode等于node->,createChildSceneNode("SinbadNode"),

2.ThenscaleSinbadtothreetimeshissizeandmovehimabitupwards,otherwise,he

willbestuckintheplane.Alsoaddhimtothescenenode,sohewillberendered:

【2.然后按三倍的大小来设置Sinabad的缩放比例,并把它稍往上移动一点.否则,它将卡在平面上.同样的,添加它到场景,这样它就可以被渲染了.】

SinbadNode->,setScale(3.0f,3.0f,3.0f),

SinbadNode->,setPosition(Ogre::Vector3(0.0f,4.0f,0.0f)),

SinbadNode->,attachObject(Sinbad),

Compileandruntheapplication.

【4.编译运行程序.】

Whatjusthappened

【刚刚发生了什么】

WeaddedaninstanceofSinbadintoourscene.Oursceneisstilllit,butweseethatSinbad

doesn'tthrowashadow,whichisratherunrealistic.Thenextstepistoaddshadowsto

ourscene.

【我们在场景中添加了一个Sinbad的实例.我们的场景仍然是发亮的,但是我们看到Sinbad却不投射出影子,这就相当的不切实际了.下一步就是添加阴影到我们的场景.】

Addingshadows

【添加阴影】

Withoutshadows,a3Dsceneisn'treallyplete,solet'saddthem.

【一个没有阴影的3D场景不是真正完整的3D场景.因此,让我们添加它们】

Timeforaction–addingshadows

【实践时刻】

Usethepreviouslyusedcode.

【使用之前已使用过的代码】

1.AfteraddingalltheothercodeinthecreateScene()function,addthe

followingline:

【1.在createScene()函数中现存的代码之后添加以下一行:】

mSceneMgr->,setShadowTechnique(Ogre::SHADOWTYPE_STENCIL_ADDITIVE),

Compileandruntheapplication.

【2.编译运行程序.】

Whatjusthappened

【刚刚发生了什么】

Withjustoneline,weaddedshadowstoourscene.Ogre3Ddoestherestofthework

forus.Ogre3Dsupportsdifferentshadowtechniques.Weusedadditivestencilshadows.

Stencilmeansaspecialtexturebufferusedwhilerenderingthescene.

【用了刚才的一行代码,我们添加阴影到我们的场景之中.Ogre3D为我们做了在剩下的工作additivestencilshadows.Stencil意思是指,当渲染场景时,使用的一种特殊的纹理缓冲.】

Additiveimpliesthatthesceneisrenderedoncefromthecameraperspectiveandthecontributionofeachlightisaccumulatedintothefinalrender.Thistechniquecreatesgoodresultsbutisalsoreallyexpensivebecauseeachlightaddsanotherrenderingrun.Wewon'tgointodetailsonhowshadowsworkbecausethisisaplexfield.Manybookscouldbewrittenaboutthistopic,andalso,shadowtechniqueschangerapidlyandareheilyresearched.Ifyouareinterestedinthistopic,youcanfindinterestingarticlesintheNVIDIAbookseriesGPUGems,theShaderXbookseries,andintheproceedingsoftheSiggraphconference(siggraph./).

【Additive意味着场景在画面视角你可以NVIDIA的有关GPU的宝石系列丛书ShaderX系列丛书中有意义的文章Siggraph(计算机图形图像特别兴趣小组会议记录siggraph./).】

Creatingacamera

【创建一个摄像机】

Sofar,wehealwaysusedacamerathatwascreatedforusebythe

ExampleApplication.Nowlet'screateoneforourselves.Acamera,asthenamesuggests,

capturesapartofourscenefromacertainposition.Therecanonlybeonecameraactive

ataparticulartimebecauseweonlyheoneoutputmedium,thatis,ourmonitor.Butitis

possibletouseseveralcamerasinonescenewheneachoneisrenderedaftertheother.

【目前为止,我们总是使用ExampleApplication类中创建的摄像机.现在让我们自己创建一个摄像机.摄像机,顾名思义在某一特定时间显示器Timeforaction–creatingacamera

【实践时刻——创建一个摄像机】

Thistimewewon'tmodifythecreateScene()function,sojustleeitasitiswiththe

Sinbadinstanceandshadows:

【这次我们不修改createScene()函数,所以保留Sinbad的实例和阴影.】

CreateanewemptyfunctionnamedcreateCamera()intheExampleApplicationclass:

【在ExampleApplication中创建一个新的名为createCamera()的空函数】

voidcreateCamera(){

}

CreateanewcameranamedMyCamera1andassignittothemembermCamera:

【2.创建一个新的称为MyCamera1的摄像机并把它分配给数据成员mCamera:】

mCamera等于mSceneMgr->,createCamera("MyCamera1"),

Setthepositionofthecameraandletitlookatthenullpoint:

【3.设置摄像机的位置并让其镜头朝向原点:】

mCamera->,setPosition(0,100,200),

mCamera->,lookAt(0,0,0),

mCamera->,setNearClipDistance(5),

Nowchangetherendermodetowireframemodus:

【4.现在改变渲染模式至线框模式】

mCamera->,setPolygonMode(Ogre::PM_WIREFRAME),

Compileandruntheapplication.

【5.编译运行程序.】

Whatjusthappened

【刚刚发生了什么】

WeoverrodethecreateCamera()function,whichinitiallycreatedacameraandsetit

toaposition.Aftercreation,wesetapositionandusedthelookat()functiontosetthe

camerauptolookattheorigin.Thenextstepwedidwassettingthenearclippingdistance.

【我们重写了最初创建摄像机的createCamera()函数并设置它到一个位置.在创建之后,我们设置完它的位置并且使用lookat()函数以设置摄像机的镜头对准原点.我们所做的下一步是设置剪裁的距离.】

Acameracanonlyseepartsofa3Dscene,sorenderingitpletelywouldbeawasteof

preciousCPUandGPUtime.Topreventthis,beforerendering,largepartsofthesceneare

"cutout"fromthescenebytheSceneManager.Onlyobjectsvisibletothecameraare

rendered.Thisstepiscalledculling.Onlythoseobjectsthatarebeforethenearclipping

planeandbehindthefarclippingplanearerenderedandthenonlywhentheyareinsidea

pyramid,thisiscalledtheviewfrustumofthecamera.Theviewfrustumisapyramidwith

thetopcutoff,onlythoseobjectsthatareinsidethecut-offpyramidcanbeseenbythe

camera.Moreinformationcanbefoundatlighthouse3d./opengl/

viewfrustum/.Wesetthenearclippingplaneto5.Whenyouuseahigher-valuepartof

thescenewhichisnearthecamera,itwillbeculledandnotvisible.

【一个摄像机只可以看到部分的3D场景.因为完整渲染需要浪费宝贵的CPU和GPU时间.为避免这种情况SceneManager)将会把大部分的场景从场景中裁剪出去.只有摄像机的课件部分被渲染到.这一步叫做拣选.只有位于远近裁剪面并且在视锥体内部的物体才会被渲染.这被称为摄像机的视锥.视锥没有顶部的锥体.只有在剪裁过的锥体内部的对象才能被摄像机所看到.更多信息可在lighthouse3d./opengl/viewfrustum/中找到】

Thenwechangedtherendermodetowireframe.ThiseffectthatwegetwhenwepresstheRkey,assuggestedbefore,isthesameastheonewegotwhenwewantedtoseetheplanetriangles.WithR,thiseffectcanalsobeundone.Whentheapplicationstarts,wenowseeadifferenceasparedtoearlier,thecameraisnowabovetheinstanceofSinbadandlooksdownonhim.

【然后我们改变渲染模式为线框模式.】

BeforeoverridingthecreateCamera()function,thecamerastartedhoveringslightlyovertheplanelookingattheorigin.WithsetPosition(0,100,200),

wesetthecamerahigherthanbefore,thefollowingscreenshotshowsthechange.Oneinterestingaspectwecanobserveisthatevenafterwehecreatedourowninstanceofacamera,wecanstillnigatethesceneasbefore.ThisispossiblebecauseweusedthemCameramembervariablefromExampleApplication.ThiskeepsExampleApplicationincontrolofourcameraandthusitcanbemodified.Oneimportantfeatureofacameraisthatitcanalsobeattachedtoascenenodeandwillreactthesamewayanentitydoeswhenattachedtoascenenode.

【在重写createCamera()函数之前,摄像机的起始位置是悬停在平面上方一点,镜头朝向原点.使用setPosition(0,100,200),设置我们的摄像机到更高的位置.下面的截图显示了改变的效果.】

Heagohero–doingmorewiththething

【让英雄动起来——做更多的事】

Tryusingdifferentpositionsandlookatpointstoseehowthisaffectsthestartingpositionofthecamera.Alsotryincreasingthenearclippingdistanceandtryoutwhateffectthishas.Thisshouldproducefunnyimageslikethefollowing,wherewecanlookintoSinbad'shead.Thenearclippingdistancewassetto50toproducethisimage.

【尝试设置摄像机到不同位置和使用摄像机不同镜头朝向,查看摄像机在初始位置发生的效果.同样也尝试一下增加近距离剪裁并试验这种效果是什么.下图可能是我们看到的效果,我们可以看到Sinbad的头部的内部(译注:图中红色的Sinbad的大舌头^_^).近距离剪裁设置到50可以产生这种效果.】

Creatingiewport

【创建一个视口Entwinedwiththeconceptofacameraistheconceptofiewport.Sowewillalsocreate

ourownviewport.Aviewportisa2Dsurfacewhichisusedforrendering.Wecanthinkofitasthepaperonwhichaphotoistaken.Thepaperhasabackgroundcolorandifthephotodoesn'tcoverthisregion,thebackgroundcolorwillbeseen.

【我摄像机概念紧密结合的一个概念就是视口.所以我们也将会创建我们自己的视口.视口是一个被用来渲染的2D表面.我们可以把它当做呈现照片的纸.这种纸有一个底色而且如果照片没有覆盖这个区域,那么底色将被我们所看见.】

Timeforaction–doingsomethingthatillustratesthething"inaction"

【实践时刻——用"行动"举例说明】

Wewillusethecodethatweusedbeforeandonceagaincreateanewemptymethod:

【我们将会使用之前的代码并且在此创建一个新的方法:】

1.RemovethesetShadowTechnique()functioncallfromthecreateCamera()

function.Wedon'twantoursceneinwireframemode.

【1.删除在createCamera()函数中调用的setShadowTechnique()函数.】

CreateanemptycreateViewports()method:

【2.创建一个空的createViewports()方法:】

voidcreateViewports(){

}

Createiewport:

【3.创建一个视口:】

Ogre::Viewport*vp等于mWindow->,addViewport(mCamera),

4.Setthebackgroundcolorandtheaspectratio:

【4.设置背景颜色和纵横比vp->,setBackgroundColour(ColourValue(0.0f,0.0f,1.0f)),

mCamera->,setAspectRatio(Real(vp->,getActualWidth())/Real(vp->,getActualHeight())),

5.Compileandruntheapplication.

【编译运行程序.】

Whatjusthappened

【刚刚发生了什么】

Wecreatediewport.Todothis,weneededtopassacameratothefunction.Each

viewportcanonlyrendertheviewofonecamera,soOgre3Denforcesthatonecamerais

givenduringcreation.Ofcourse,thecameracanbechangedlaterusingtheappropriate

getterandsetterfunctions.Themostnoticeablechangeisthatthebackgroundcolor

changedfromblacktoblue.Thereasonshouldbeobvious:thenewviewporthasthe

backgroundcolorblue,wesetitinstep3.Alsoinstep3,wesettheaspectratio—theaspectratiodescribestheratiobetweenthewidthandheightofarenderedimage,inmathterms:aspectratio等于widthofwindowdividedbyheightofwindow.

【我们创建一个视口.创建的时,我们需要传递一个摄像机作为函数的参数.每个视口只可渲染一个摄像机的视野,所以在传参时,Ogre3D强制函数只能接受一个摄像机作为参数.当然,摄像机可适当地使用getter和setter函数以发生改变.最值得注意的改变是背景色从黑色变为蓝色.原因很明显:在第三步中,新的视口设置背景色为蓝色.同样在第三步,我们设置了纵横比——纵横比描述了当渲染图像时宽和高的比例.数学公式为:纵横比等于窗口宽度/窗口高度】

Heagohero–playingwithdifferentaspectratio

【让英雄动起来——使用不同的纵横比】

Tryplayingwithdifferentaspectratiosandseehowthisaffectstheimageproduced.Also

changethebackgroundcolor.Hereisanimagewherethewidthoftheaspectratioisdividedbyfive.

【尝试使用不同的纵横比并查看图形产生的不同效果.同样的,改变背景色并查看效果.下面的图片是纵横比的宽度设置为1/5的效果图.】

Summary

【概要】

Inthischapter,weaddedlightsandshadowstoourscene,creatediewport,andworkedwithiewfrustum.

【在这一章,我们添加光源和阴影到我们的场景,创建了视口并且了解了无锥顶的视锥体.】

Specifically,wecovered:

*Whatlightsareandhowtheycanmodifytheappearanceofourscene

*Addingshadowstoourscene

*Creatingourowncamera,frustum,andviewport

【具体来说,我们讨论:Inthenextchapter,wewilllearnhowtoprocessuserinputfromthekeyboardandmouse.

WewillalsolearnwhataFrameListenerisandhowtouseit.

【在下一章,我们将会学习如何处理用户的键盘和鼠标输入.我们将会学习什么是帧监听和如何使用它.】

[*译者:寻找喜欢翻译,喜欢Ogre或者想要以此方式研究学习的人,可以联系

whistleofmysong@gmail.,可以在singmelody.上留言,也可以联系:280697265或者群:65746525和我一起翻译和学习ogre,先声明本人的水平也相当不高.呵呵~欢迎大家踊跃来电O(∩_∩)O.]

相关论文范文