Robust Polyline Rendering with WebGL - Cesium

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

Rendering with Line Primitives. We ran into a few problems when using line primitives (LINES, LINE_STRIP, or LINE_LOOP) to render lines. SkiptomaincontentRenderingwithLinePrimitivesWeranintoafewproblemswhenusinglineprimitives(LINES, LINE_STRIP,or LINE_LOOP)torenderlines.First,themaximumlinewidthwhenusing ANGLE is 1.0.Second,drawinglineprimitiveswith lineWidth (withoutANGLE)doesnotjoinlinesegmentsatasharedvertex:Theimagebelowshowslineswiththetwojoinsmitered:Finally,ourmethodtodrawoutlinedlineswithoutz-fightingwastousethreepasseswiththestencilbuffer.OurMethodOurnewmethodfordrawingpolylinesistodrawascreen-alignedquadsforeachsegmentoftheline.InWebGL,wedonothavegeometryshaders,soweduplicateeachpositionofthelineandextrudetheminscreenspaceinthevertexshader.Toextrudethepositions,weneedtoknowthepositionsofadjacentvertices.Again,wedonothavegeometryshaderssoweneedtocreateadditionalvertexattributesfortheadjacentpositioninformation.Oncewehavetheadjacentvertexpositionsandtwoverticesatthesameposition,wecanextrudethepositionsinthedirectionsnormaltotheline.Ifthisisdonetoallofthevertexpositions,wewouldendupwithsomethingsimilartodrawinglineprimitiveswith lineWidth withoutANGLEimageabove.Thatisfinefortheendpointsofthepolyline,butwewanttojointhepointswherethesegmentsofthepolylineareconnected.Tofindthedirectiontoextrudetheposition,transformallofthepositionstowindowcoordinatesandfindhalfthesumofthetwovectorspointingfromtheadjacentpositionstothevertexposition.Theamounttomovethevertexpositioninthatdirectionwillinvolvesometrigonometryandwillbediscussedlaterinthepost.Atfirst,wetriedtokeepthenumberofvertexattributesunder8becausethatistheminimumneededtosupportWebGL.Foreachposition,weneedfour vec3s.Twoareusedforthepositionin3Dandtwoareusedforthepositionin2D.TheneedforthepositionintwodifferentmodesisuniquetoCesium.Thereasonweneedtwo vec3sforasingle3Dpositionisemulateddoubleprecisioninthevertexshader.Formoreonthattopicsee, Precisions,Precisions.Toincludeeachvertexpositionplusbothadjacentvertexpositions,wewouldneedatleast12vertexattributes.Onewaytokeepthenumberofvertexattributesto8,wastouseonlythedirectionsfromthecurrentvertextotheadjacentvertices.Wewouldneeddirectionsforboth3Dand2D.Thatstillleavesuswithfour vec3sforthedirectionsandatotalof8vertexattributes.Wewouldliketoincludemoreinformationinothervertexattributessuchastexturecoordinates,width,etc.Wecouldfurtherreducethenumberofattributesbycompressingtheunitvectordirections.Thiswilltakeustotwo vec4sforthedirection.Themethodforcompressingthemwillbedescribedlaterinthepost.Wecameacrossaprecisionproblemwhenusingthecompressednormals.Whenzoomedinclosetoapolylineendpointthathasanotherendpointatmorethanabout90thousandmetersaway,theextrudedpositionswilljitterlikeintheimagebelow:Onesolutionistosubdividetheline;however,fortheaccesslinebetweentheGeoeye1andtheISSshownbelow,thenumberofpositionsgoesfrom2toabout50.Insteadofaddingthatmanyadditionalpointsforasimpleaccessline,wedecidedtousethe12vertexattributesforthecurrentvertexpositionandtheadjacentpositions.Afterweextrudethepositionsinscreenspace,weneedtotransformthepositiontoclipcoordinatesfortheoutputofthevertexshader.Thefinalpositioninscreenspaceisavec4ofthemodifiedxandycoordinates,thenegativezcoordinateandawcoordinateof1.0.Weusethenegativezcoordinatebecausetheviewdirectionisalongthenegativezaxisineveryspaceafterandincludingeyespace.Thewcoordinateisusedfortheperspectivedividewhichmakeobjectsfartherfromtheeyeseemsmaller.Wesetthewcoordinateto1.0becausewewantthewidthtobeconstantregardlessofperspective.Thiscausesanissuewhenthelineintersectsthenearplane.Wethenreversetheoperationsoftheviewporttransformationtohaveourfinalvertexshaderoutputpositioninclipspace.Belowshowsalinebeforeitintersectsthenearplane:andthisnextimageshowsthesamelineafterzoominginthatnowintersectsthenearplane:Formoreinformationaboutwhythishappens,seeClippingusinghomogeneouscoordinates.Tofixthis,weneedtoclipthelinetothenearplanebeforetransformingtoscreenspace.Whatifthereisasituationsuchasintheimagebelow:Ontheleft,twolinesegmentsshouldbeclippedbythenearplaneandtheysharethesamevertexposition.Thelinesegmentsintersectthenearplaneatthepointsinthegreencircles.Thepositionthatneedstobeclippediscircledinblue.Whichgreenpositionshouldweclipthebluepositionto?Eachvertexthatissharedbytwolinesegmentsneedstobeduplicatedagain.Foreachconnectedline,eachpositionisduplicatedtwiceattheendpointsandfourtimesatthesharedpositions.Wealsoneedtoknowwhichlinesegmentthepositionbelongstoandclipitintherightdirection.Thesituationontherightiseasiertohandleoncewehavehandledthesituationontheleft.Ifavertexpositionbelongstoalinethatisculled,simplyoutputclipcoordinatesthatarebehindthenearplaneensuringthatthelineisnotdrawn.VertexShaderDetailsExtrudeVertexinScreenSpaceThediagrambelowshowsalinedrawninblackandthesamelineextrudedtoagreaterwidthinscreenspaceoutlinedinred.Toextrudethelineattheendpoints,simplymovetheverticesthedesirednumberofpixelsinthedirectionofthenormalstothelinesegment.Thediagrambelowshowsacloseupoftheareasurroundedbyadashedorangelineintheimageabove.Letthegreenvectorbe u andtheblackvectorbe v.Wewanttofindthevector u.Weknowthedirectionof v becauseitiseitherthedirectiontothenextpointorthepreviouspointontheline.Wecanfindthedirectionof u becauseithalf-waybetweenthedirectiontothenextandpreviouspointsontheline.Now,wejustneedtofindthemagnitudeof u which,fromthetrigonometryidentity,weknowis ||u||=width/sin(a).Weknowthatforanyvectors p and q that ||pxq||=||p||||q|||sin(a)|.Ifwetreat û and v̂ asthreedimensionalvectorsinthexy-plane,wecansubstitute û and v̂ intotheexpression.Because û and v̂ areunitvectorsandthezcoordinateis 0.0,thelastexpressioncanbesimplifiedto sin(a)=|û.x*v̂.y-û.y*v̂.x|.TheGLSLcodeisgivenbelow: floatsinAngle=abs(u.x*v.y-u.y*v.x); width/=sinAngle; vec2offset=direction*directionSign*width*czm_highResolutionSnapScale; gl_Position=czm_viewportOrthographic*vec4(positionWC.xy+offset,-positionWC.z,1.0); Caremustbegiventomakesurethat sinAngle isnotclosetozeroandthatwemovethevertexintherightdirection(either u or -u inourexample). ClippingtotheNearPlane Asexplainedabove,weneedtocliptheendpointsofthelinesegmentstothenearplane.HereistheGLSLfunctionusedtoclipapointtothenearplaneineyecoordinates: voidclipLineSegmentToNearPlane( vec3p0, vec3p1, outvec4positionWC, outboolculledByNearPlane) { culledByNearPlane=false; vec3p1ToP0=p1-p0; floatmagnitude=length(p1ToP0); vec3direction=normalize(p1ToP0); floatendPoint0Distance=-(czm_currentFrustum.x+p0.z); floatdenominator=-direction.z; if(endPoint0Distance<0.0&&abs(denominator)czm_epsilon7) { //ray-planeintersection: //t=(-planedistance-dot(planenormal,rayorigin)) //t/=dot(planenormal,raydirection); floatt=(czm_currentFrustum.x+p0.z)/denominator; if(t<0.0||t>magnitude) { //thesegmentintersectsthenearplane, //buttheentiresegmentisbehindthe //nearplane culledByNearPlane=true; } else { //segmentintersectsthenearplane, //findintersection p0=p0+t*direction; } } positionWC=czm_eyeToWindowCoordinates(vec4(p0,1.0)); } Thecommentsthroughoutthefunctiondescribetheconditionswhenitisclippedorculled.Thefunctionhasbeensimplifiedbasedontheassumptionthatthenearplanenormalis vec3(0.0,0.0,-1.0) andisadistance czm_currentFrustum.x fromtheorigin.Encoding/DecodingUnitVectorsWhenwewererestrictingourselvesto8vertexattributes,weencodedthethetwounitvectorsthatpointedtopreviousandnextpointsonthelineusingthe SpheremapTransform.Thisallowedustocompresstwo vec3 vertexattributesintoasingle vec4 vertexattribute.BelowistheJavascriptcodeusedtocompressaunitvectorintotwocomponents:functionencode(cartesian){ varp=Math.sqrt(cartesian.z*8.0+8.0); varresult=newCartesian2(); result.x=cartesian.x/p+0.5; result.y=cartesian.y/p+0.5; returnresult; } andhereistheGLSLcodetodecompresstheunitvectorinthevertexshader: vec3decode(vec2enc) { vec2fenc=enc*4.0-2.0; floatf=dot(fenc,fenc); floatg=sqrt(1.0-f/4.0); vec3n; n.xy=fenc*g; n.z=1.0-f/2.0; returnn; } Formoreinformationondifferentwaystocompressunitvectors,see CompactNormalStorageforSmallG-Buffers.References3DEngineDesignforVirtualGlobesOpenGLInsightsTron,VolumetricLinesandMeshlessTubesCompactNormalStorageforSmallG-BuffersEncodingFloatstoRGBA,AgainCreatingVastGameWorlds-ExperiencesfromAvalancheStudiosClippingusinghomogeneouscoordinates



請為這篇文章評分?