Tutorial 13 : Normal Mapping

文章推薦指數: 80 %
投票人數:10人

The basic idea of normal mapping is to give normals similar variations. Normal textures. A “normal texture” looks like this : In each RGB texel is encoded a XYZ ... Normaltextures TangentandBitangent PreparingourVBO Computingthetangentsandbitangents Indexing Theshader Additionalbuffers&uniforms Vertexshader Fragmentshader Results Goingfurther Orthogonalization Handedness Speculartexture Debuggingwiththeimmediatemode Debuggingwithcolors Debuggingwithvariablenames Howtocreateanormalmap Exercises Tools&Links References Welcomeforour13thtutorial!Todaywewilltalkaboutnormalmapping. SinceTutorial8:Basicshading,youknowhowtogetdecentshadingusingtrianglenormals.Onecaveatisthatuntilnow,weonlyhadonenormalpervertex:insideeachtriangle,theyvarysmoothly,ontheoppositetothecolour,whichsamplesatexture.Thebasicideaofnormalmappingistogivenormalssimilarvariations. Normaltextures A“normaltexture”lookslikethis: IneachRGBtexelisencodedaXYZvector:eachcolourcomponentisbetween0and1,andeachvectorcomponentisbetween-1and1,sothissimplemappinggoesfromthetexeltothenormal: normal=(2*color)-1//oneachcomponent Thetexturehasageneralbluetonebecauseoverall,thenormalistowardsthe“outsideofthesurface”.Asusual,Xisrightintheplaneofthetexture,Yisup(againintheplaneofthetexture),thusgiventherighthandruleZpointtothe“outside”oftheplaneofthetexture. Thistextureismappedjustlikethediffuseone;thebigproblemishowtoconvertournormal,whichisexpressedinthespaceeachindividualtriangle(tangentspace,alsocalledimagespace),inmodelspace(sincethisiswhatisusedinourshadingequation). TangentandBitangent Youarenowsofamiliarwithmatricesthatyouknowthatinordertodefineaspace(inourcase,thetangentspace),weneed3vectors.WealreadyhaveourUPvector:it’sthenormal,givenbyBlenderorcomputedfromthetrianglebyasimplecrossproduct.It’srepresentedinblue,justliketheoverallcolorofthenormalmap: Nextweneedatangent,T:avectorparalleltothesurface.Buttherearemanysuchvectors: Whichoneshouldwechoose?Intheory,any,butwehavetobeconsistentwiththeneighborstoavoidintroducinguglyedges.Thestandardmethodistoorientthetangentinthesamedirectionthatourtexturecoordinates: Sinceweneed3vectorstodefineabasis,wemustalsocomputethebitangentB(whichisanyothertangentvector,butifeverythingisperpendicular,mathissimpler): Hereisthealgorithm:ifwenotedeltaPos1anddeltaPos2twoedgesofourtriangle,anddeltaUV1anddeltaUV2thecorrespondingdifferencesinUVs,wecanexpressourproblemwiththefollowingequation: deltaPos1=deltaUV1.x*T+deltaUV1.y*B deltaPos2=deltaUV2.x*T+deltaUV2.y*B JustsolvethissystemforTandB,andyouhaveyourvectors!(Seecodebelow) OncewehaveourT,B,Nvectors,wealsohavethisnicematrixwhichenablesustogofromTangentSpacetoModelSpace: WiththisTBNmatrix,wecantransformnormals(extractedfromthetexture)intomodelspace.However,it’susuallydonetheotherwayaround:transformeverythingfromModelSpacetoTangentSpace,andkeeptheextractednormalas-is.AllcomputationsaredoneinTangentSpace,whichdoesn’tchangesanything. Dohavethisinversetransformation,wesimplyhavetotakethematrixinverse,whichinthiscase(anorthogonalmatrix,i.eeachvectorisperpendiculartotheothers.See“goingfurther”below)isalsoitstranspose,muchcheapertocompute: invTBN=transpose(TBN) ,i.e.: PreparingourVBO Computingthetangentsandbitangents Sinceweneedourtangentsandbitangentsontopofournormals,wehavetocomputethemforthewholemesh.We’lldothisinaseparatefunction: voidcomputeTangentBasis( //inputs std::vector<:vec3>&vertices, std::vector<:vec2>&uvs, std::vector<:vec3>&normals, //outputs std::vector<:vec3>&tangents, std::vector<:vec3>&bitangents ){ Foreachtriangle,wecomputetheedge(deltaPos)andthedeltaUV for(inti=0;i0,soweneedtocheckifdot(cross(n,t),b)>0. Ifit’sfalse,justinvertt: if(glm::dot(glm::cross(n,t),b)<0.0f){ t=t*-1.0f; } ThisisalsodoneforeachvertexattheendofcomputeTangentBasis(). Speculartexture Justforfun,Iaddedaspeculartexturetothecode.Itlookslikethis: andisusedinsteadofthesimple“vec3(0.3,0.3,0.3)”greythatweusedasspecularcolor. Noticethatnow,cementisalwaysblack:thetexturesaysthatithasnospecularcomponent. Debuggingwiththeimmediatemode TherealaimofthiswebsiteisthatyouDON’Tuseimmediatemode,whichisdeprecated,slow,andproblematicinmanyaspects. However,italsohappenstobereallyhandyfordebugging: Herewevisualizeourtangentspacewithlinesdrawninimmediatemode. Forthis,youneedtoabandonthe3.3coreprofile: glfwOpenWindowHint(GLFW_OPENGL_PROFILE,GLFW_OPENGL_COMPAT_PROFILE); thengiveourmatricestoOpenGL’sold-schoolpipeline(youcanwriteanothershadertoo,butit’ssimplerthisway,andyou’rehackinganyway): glMatrixMode(GL_PROJECTION); glLoadMatrixf((constGLfloat*)&ProjectionMatrix[0]); glMatrixMode(GL_MODELVIEW); glm::mat4MV=ViewMatrix*ModelMatrix; glLoadMatrixf((constGLfloat*)&MV[0]); Disableshaders: glUseProgram(0); Anddrawyourlines(inthiscase,normals,normalizedandmultipliedby0.1,andappliedatthecorrectvertex): glColor3f(0,0,1); glBegin(GL_LINES); for(inti=0;i



請為這篇文章評分?