WebGLRenderer.js 158 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718
  1. /**
  2. * @author supereggbert / http://www.paulbrunt.co.uk/
  3. * @author mrdoob / http://mrdoob.com/
  4. * @author alteredq / http://alteredqualia.com/
  5. * @author szimek / https://github.com/szimek/
  6. */
  7. THREE.WebGLRenderer = function ( parameters ) {
  8. console.log( 'THREE.WebGLRenderer', THREE.REVISION );
  9. parameters = parameters || {};
  10. var _canvas = parameters.canvas !== undefined ? parameters.canvas : document.createElement( 'canvas' ),
  11. _context = parameters.context !== undefined ? parameters.context : null,
  12. _precision = parameters.precision !== undefined ? parameters.precision : 'highp',
  13. _buffers = {},
  14. _alpha = parameters.alpha !== undefined ? parameters.alpha : false,
  15. _premultipliedAlpha = parameters.premultipliedAlpha !== undefined ? parameters.premultipliedAlpha : true,
  16. _antialias = parameters.antialias !== undefined ? parameters.antialias : false,
  17. _stencil = parameters.stencil !== undefined ? parameters.stencil : true,
  18. _preserveDrawingBuffer = parameters.preserveDrawingBuffer !== undefined ? parameters.preserveDrawingBuffer : false,
  19. _clearColor = new THREE.Color( 0x000000 ),
  20. _clearAlpha = 0;
  21. // public properties
  22. this.domElement = _canvas;
  23. this.context = null;
  24. this.devicePixelRatio = parameters.devicePixelRatio !== undefined
  25. ? parameters.devicePixelRatio
  26. : self.devicePixelRatio !== undefined
  27. ? self.devicePixelRatio
  28. : 1;
  29. // clearing
  30. this.autoClear = true;
  31. this.autoClearColor = true;
  32. this.autoClearDepth = true;
  33. this.autoClearStencil = true;
  34. // scene graph
  35. this.sortObjects = true;
  36. this.autoUpdateObjects = true;
  37. // physically based shading
  38. this.gammaInput = false;
  39. this.gammaOutput = false;
  40. // shadow map
  41. this.shadowMapEnabled = false;
  42. this.shadowMapAutoUpdate = true;
  43. this.shadowMapType = THREE.PCFShadowMap;
  44. this.shadowMapCullFace = THREE.CullFaceFront;
  45. this.shadowMapDebug = false;
  46. this.shadowMapCascade = false;
  47. // morphs
  48. this.maxMorphTargets = 8;
  49. this.maxMorphNormals = 4;
  50. // flags
  51. this.autoScaleCubemaps = true;
  52. // custom render plugins
  53. this.renderPluginsPre = [];
  54. this.renderPluginsPost = [];
  55. // info
  56. this.info = {
  57. memory: {
  58. programs: 0,
  59. geometries: 0,
  60. textures: 0
  61. },
  62. render: {
  63. calls: 0,
  64. vertices: 0,
  65. faces: 0,
  66. points: 0
  67. }
  68. };
  69. // internal properties
  70. var _this = this,
  71. _programs = [],
  72. _programs_counter = 0,
  73. // internal state cache
  74. _currentProgram = null,
  75. _currentFramebuffer = null,
  76. _currentMaterialId = -1,
  77. _currentGeometryGroupHash = null,
  78. _currentCamera = null,
  79. _geometryGroupCounter = 0,
  80. _usedTextureUnits = 0,
  81. // GL state cache
  82. _oldDoubleSided = -1,
  83. _oldFlipSided = -1,
  84. _oldBlending = -1,
  85. _oldBlendEquation = -1,
  86. _oldBlendSrc = -1,
  87. _oldBlendDst = -1,
  88. _oldDepthTest = -1,
  89. _oldDepthWrite = -1,
  90. _oldPolygonOffset = null,
  91. _oldPolygonOffsetFactor = null,
  92. _oldPolygonOffsetUnits = null,
  93. _oldLineWidth = null,
  94. _viewportX = 0,
  95. _viewportY = 0,
  96. _viewportWidth = _canvas.width,
  97. _viewportHeight = _canvas.height,
  98. _currentWidth = 0,
  99. _currentHeight = 0,
  100. _enabledAttributes = new Uint8Array( 16 ),
  101. // frustum
  102. _frustum = new THREE.Frustum(),
  103. // camera matrices cache
  104. _projScreenMatrix = new THREE.Matrix4(),
  105. _projScreenMatrixPS = new THREE.Matrix4(),
  106. _vector3 = new THREE.Vector3(),
  107. // light arrays cache
  108. _direction = new THREE.Vector3(),
  109. _lightsNeedUpdate = true,
  110. _lights = {
  111. ambient: [ 0, 0, 0 ],
  112. directional: { length: 0, colors: new Array(), positions: new Array() },
  113. point: { length: 0, colors: new Array(), positions: new Array(), distances: new Array() },
  114. spot: { length: 0, colors: new Array(), positions: new Array(), distances: new Array(), directions: new Array(), anglesCos: new Array(), exponents: new Array() },
  115. hemi: { length: 0, skyColors: new Array(), groundColors: new Array(), positions: new Array() }
  116. };
  117. // initialize
  118. var _gl;
  119. var _glExtensionTextureFloat;
  120. var _glExtensionTextureFloatLinear;
  121. var _glExtensionStandardDerivatives;
  122. var _glExtensionTextureFilterAnisotropic;
  123. var _glExtensionCompressedTextureS3TC;
  124. initGL();
  125. setDefaultGLState();
  126. this.context = _gl;
  127. // GPU capabilities
  128. var _maxTextures = _gl.getParameter( _gl.MAX_TEXTURE_IMAGE_UNITS );
  129. var _maxVertexTextures = _gl.getParameter( _gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS );
  130. var _maxTextureSize = _gl.getParameter( _gl.MAX_TEXTURE_SIZE );
  131. var _maxCubemapSize = _gl.getParameter( _gl.MAX_CUBE_MAP_TEXTURE_SIZE );
  132. var _maxAnisotropy = _glExtensionTextureFilterAnisotropic ? _gl.getParameter( _glExtensionTextureFilterAnisotropic.MAX_TEXTURE_MAX_ANISOTROPY_EXT ) : 0;
  133. var _supportsVertexTextures = ( _maxVertexTextures > 0 );
  134. var _supportsBoneTextures = _supportsVertexTextures && _glExtensionTextureFloat;
  135. var _compressedTextureFormats = _glExtensionCompressedTextureS3TC ? _gl.getParameter( _gl.COMPRESSED_TEXTURE_FORMATS ) : [];
  136. //
  137. var _vertexShaderPrecisionHighpFloat = _gl.getShaderPrecisionFormat( _gl.VERTEX_SHADER, _gl.HIGH_FLOAT );
  138. var _vertexShaderPrecisionMediumpFloat = _gl.getShaderPrecisionFormat( _gl.VERTEX_SHADER, _gl.MEDIUM_FLOAT );
  139. var _vertexShaderPrecisionLowpFloat = _gl.getShaderPrecisionFormat( _gl.VERTEX_SHADER, _gl.LOW_FLOAT );
  140. var _fragmentShaderPrecisionHighpFloat = _gl.getShaderPrecisionFormat( _gl.FRAGMENT_SHADER, _gl.HIGH_FLOAT );
  141. var _fragmentShaderPrecisionMediumpFloat = _gl.getShaderPrecisionFormat( _gl.FRAGMENT_SHADER, _gl.MEDIUM_FLOAT );
  142. var _fragmentShaderPrecisionLowpFloat = _gl.getShaderPrecisionFormat( _gl.FRAGMENT_SHADER, _gl.LOW_FLOAT );
  143. var _vertexShaderPrecisionHighpInt = _gl.getShaderPrecisionFormat( _gl.VERTEX_SHADER, _gl.HIGH_INT );
  144. var _vertexShaderPrecisionMediumpInt = _gl.getShaderPrecisionFormat( _gl.VERTEX_SHADER, _gl.MEDIUM_INT );
  145. var _vertexShaderPrecisionLowpInt = _gl.getShaderPrecisionFormat( _gl.VERTEX_SHADER, _gl.LOW_INT );
  146. var _fragmentShaderPrecisionHighpInt = _gl.getShaderPrecisionFormat( _gl.FRAGMENT_SHADER, _gl.HIGH_INT );
  147. var _fragmentShaderPrecisionMediumpInt = _gl.getShaderPrecisionFormat( _gl.FRAGMENT_SHADER, _gl.MEDIUM_INT );
  148. var _fragmentShaderPrecisionLowpInt = _gl.getShaderPrecisionFormat( _gl.FRAGMENT_SHADER, _gl.LOW_INT );
  149. // clamp precision to maximum available
  150. var highpAvailable = _vertexShaderPrecisionHighpFloat.precision > 0 && _fragmentShaderPrecisionHighpFloat.precision > 0;
  151. var mediumpAvailable = _vertexShaderPrecisionMediumpFloat.precision > 0 && _fragmentShaderPrecisionMediumpFloat.precision > 0;
  152. if ( _precision === "highp" && ! highpAvailable ) {
  153. if ( mediumpAvailable ) {
  154. _precision = "mediump";
  155. console.warn( "WebGLRenderer: highp not supported, using mediump" );
  156. } else {
  157. _precision = "lowp";
  158. console.warn( "WebGLRenderer: highp and mediump not supported, using lowp" );
  159. }
  160. }
  161. if ( _precision === "mediump" && ! mediumpAvailable ) {
  162. _precision = "lowp";
  163. console.warn( "WebGLRenderer: mediump not supported, using lowp" );
  164. }
  165. // API
  166. this.getContext = function () {
  167. return _gl;
  168. };
  169. this.supportsVertexTextures = function () {
  170. return _supportsVertexTextures;
  171. };
  172. this.supportsFloatTextures = function () {
  173. return _glExtensionTextureFloat;
  174. };
  175. this.supportsStandardDerivatives = function () {
  176. return _glExtensionStandardDerivatives;
  177. };
  178. this.supportsCompressedTextureS3TC = function () {
  179. return _glExtensionCompressedTextureS3TC;
  180. };
  181. this.getMaxAnisotropy = function () {
  182. return _maxAnisotropy;
  183. };
  184. this.getPrecision = function () {
  185. return _precision;
  186. };
  187. this.setSize = function ( width, height, updateStyle ) {
  188. _canvas.width = width * this.devicePixelRatio;
  189. _canvas.height = height * this.devicePixelRatio;
  190. if ( this.devicePixelRatio !== 1 && updateStyle !== false ) {
  191. _canvas.style.width = width + 'px';
  192. _canvas.style.height = height + 'px';
  193. }
  194. this.setViewport( 0, 0, width, height );
  195. };
  196. this.setViewport = function ( x, y, width, height ) {
  197. _viewportX = x * this.devicePixelRatio;
  198. _viewportY = y * this.devicePixelRatio;
  199. _viewportWidth = width * this.devicePixelRatio;
  200. _viewportHeight = height * this.devicePixelRatio;
  201. _gl.viewport( _viewportX, _viewportY, _viewportWidth, _viewportHeight );
  202. };
  203. this.setScissor = function ( x, y, width, height ) {
  204. _gl.scissor(
  205. x * this.devicePixelRatio,
  206. y * this.devicePixelRatio,
  207. width * this.devicePixelRatio,
  208. height * this.devicePixelRatio
  209. );
  210. };
  211. this.enableScissorTest = function ( enable ) {
  212. enable ? _gl.enable( _gl.SCISSOR_TEST ) : _gl.disable( _gl.SCISSOR_TEST );
  213. };
  214. // Clearing
  215. this.setClearColor = function ( color, alpha ) {
  216. _clearColor.set( color );
  217. _clearAlpha = alpha !== undefined ? alpha : 1;
  218. _gl.clearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha );
  219. };
  220. this.setClearColorHex = function ( hex, alpha ) {
  221. console.warn( 'DEPRECATED: .setClearColorHex() is being removed. Use .setClearColor() instead.' );
  222. this.setClearColor( hex, alpha );
  223. };
  224. this.getClearColor = function () {
  225. return _clearColor;
  226. };
  227. this.getClearAlpha = function () {
  228. return _clearAlpha;
  229. };
  230. this.clear = function ( color, depth, stencil ) {
  231. var bits = 0;
  232. if ( color === undefined || color ) bits |= _gl.COLOR_BUFFER_BIT;
  233. if ( depth === undefined || depth ) bits |= _gl.DEPTH_BUFFER_BIT;
  234. if ( stencil === undefined || stencil ) bits |= _gl.STENCIL_BUFFER_BIT;
  235. _gl.clear( bits );
  236. };
  237. this.clearColor = function () {
  238. _gl.clear( _gl.COLOR_BUFFER_BIT );
  239. };
  240. this.clearDepth = function () {
  241. _gl.clear( _gl.DEPTH_BUFFER_BIT );
  242. };
  243. this.clearStencil = function () {
  244. _gl.clear( _gl.STENCIL_BUFFER_BIT );
  245. };
  246. this.clearTarget = function ( renderTarget, color, depth, stencil ) {
  247. this.setRenderTarget( renderTarget );
  248. this.clear( color, depth, stencil );
  249. };
  250. // Plugins
  251. this.addPostPlugin = function ( plugin ) {
  252. plugin.init( this );
  253. this.renderPluginsPost.push( plugin );
  254. };
  255. this.addPrePlugin = function ( plugin ) {
  256. plugin.init( this );
  257. this.renderPluginsPre.push( plugin );
  258. };
  259. // Rendering
  260. this.updateShadowMap = function ( scene, camera ) {
  261. _currentProgram = null;
  262. _oldBlending = -1;
  263. _oldDepthTest = -1;
  264. _oldDepthWrite = -1;
  265. _currentGeometryGroupHash = -1;
  266. _currentMaterialId = -1;
  267. _lightsNeedUpdate = true;
  268. _oldDoubleSided = -1;
  269. _oldFlipSided = -1;
  270. this.shadowMapPlugin.update( scene, camera );
  271. };
  272. // Internal functions
  273. // Buffer allocation
  274. function createParticleBuffers ( geometry ) {
  275. geometry.__webglVertexBuffer = _gl.createBuffer();
  276. geometry.__webglColorBuffer = _gl.createBuffer();
  277. _this.info.memory.geometries ++;
  278. };
  279. function createLineBuffers ( geometry ) {
  280. geometry.__webglVertexBuffer = _gl.createBuffer();
  281. geometry.__webglColorBuffer = _gl.createBuffer();
  282. geometry.__webglLineDistanceBuffer = _gl.createBuffer();
  283. _this.info.memory.geometries ++;
  284. };
  285. function createMeshBuffers ( geometryGroup ) {
  286. geometryGroup.__webglVertexBuffer = _gl.createBuffer();
  287. geometryGroup.__webglNormalBuffer = _gl.createBuffer();
  288. geometryGroup.__webglTangentBuffer = _gl.createBuffer();
  289. geometryGroup.__webglColorBuffer = _gl.createBuffer();
  290. geometryGroup.__webglUVBuffer = _gl.createBuffer();
  291. geometryGroup.__webglUV2Buffer = _gl.createBuffer();
  292. geometryGroup.__webglSkinIndicesBuffer = _gl.createBuffer();
  293. geometryGroup.__webglSkinWeightsBuffer = _gl.createBuffer();
  294. geometryGroup.__webglFaceBuffer = _gl.createBuffer();
  295. geometryGroup.__webglLineBuffer = _gl.createBuffer();
  296. var m, ml;
  297. if ( geometryGroup.numMorphTargets ) {
  298. geometryGroup.__webglMorphTargetsBuffers = [];
  299. for ( m = 0, ml = geometryGroup.numMorphTargets; m < ml; m ++ ) {
  300. geometryGroup.__webglMorphTargetsBuffers.push( _gl.createBuffer() );
  301. }
  302. }
  303. if ( geometryGroup.numMorphNormals ) {
  304. geometryGroup.__webglMorphNormalsBuffers = [];
  305. for ( m = 0, ml = geometryGroup.numMorphNormals; m < ml; m ++ ) {
  306. geometryGroup.__webglMorphNormalsBuffers.push( _gl.createBuffer() );
  307. }
  308. }
  309. _this.info.memory.geometries ++;
  310. };
  311. // Events
  312. var onGeometryDispose = function ( event ) {
  313. var geometry = event.target;
  314. geometry.removeEventListener( 'dispose', onGeometryDispose );
  315. deallocateGeometry( geometry );
  316. };
  317. var onTextureDispose = function ( event ) {
  318. var texture = event.target;
  319. texture.removeEventListener( 'dispose', onTextureDispose );
  320. deallocateTexture( texture );
  321. _this.info.memory.textures --;
  322. };
  323. var onRenderTargetDispose = function ( event ) {
  324. var renderTarget = event.target;
  325. renderTarget.removeEventListener( 'dispose', onRenderTargetDispose );
  326. deallocateRenderTarget( renderTarget );
  327. _this.info.memory.textures --;
  328. };
  329. var onMaterialDispose = function ( event ) {
  330. var material = event.target;
  331. material.removeEventListener( 'dispose', onMaterialDispose );
  332. deallocateMaterial( material );
  333. };
  334. // Buffer deallocation
  335. var deleteBuffers = function ( geometry ) {
  336. if ( geometry.__webglVertexBuffer !== undefined ) _gl.deleteBuffer( geometry.__webglVertexBuffer );
  337. if ( geometry.__webglNormalBuffer !== undefined ) _gl.deleteBuffer( geometry.__webglNormalBuffer );
  338. if ( geometry.__webglTangentBuffer !== undefined ) _gl.deleteBuffer( geometry.__webglTangentBuffer );
  339. if ( geometry.__webglColorBuffer !== undefined ) _gl.deleteBuffer( geometry.__webglColorBuffer );
  340. if ( geometry.__webglUVBuffer !== undefined ) _gl.deleteBuffer( geometry.__webglUVBuffer );
  341. if ( geometry.__webglUV2Buffer !== undefined ) _gl.deleteBuffer( geometry.__webglUV2Buffer );
  342. if ( geometry.__webglSkinIndicesBuffer !== undefined ) _gl.deleteBuffer( geometry.__webglSkinIndicesBuffer );
  343. if ( geometry.__webglSkinWeightsBuffer !== undefined ) _gl.deleteBuffer( geometry.__webglSkinWeightsBuffer );
  344. if ( geometry.__webglFaceBuffer !== undefined ) _gl.deleteBuffer( geometry.__webglFaceBuffer );
  345. if ( geometry.__webglLineBuffer !== undefined ) _gl.deleteBuffer( geometry.__webglLineBuffer );
  346. if ( geometry.__webglLineDistanceBuffer !== undefined ) _gl.deleteBuffer( geometry.__webglLineDistanceBuffer );
  347. // custom attributes
  348. if ( geometry.__webglCustomAttributesList !== undefined ) {
  349. for ( var id in geometry.__webglCustomAttributesList ) {
  350. _gl.deleteBuffer( geometry.__webglCustomAttributesList[ id ].buffer );
  351. }
  352. }
  353. _this.info.memory.geometries --;
  354. };
  355. var deallocateGeometry = function ( geometry ) {
  356. geometry.__webglInit = undefined;
  357. if ( geometry instanceof THREE.BufferGeometry ) {
  358. var attributes = geometry.attributes;
  359. for ( var key in attributes ) {
  360. if ( attributes[ key ].buffer !== undefined ) {
  361. _gl.deleteBuffer( attributes[ key ].buffer );
  362. }
  363. }
  364. _this.info.memory.geometries --;
  365. } else {
  366. if ( geometry.geometryGroups !== undefined ) {
  367. for ( var g in geometry.geometryGroups ) {
  368. var geometryGroup = geometry.geometryGroups[ g ];
  369. if ( geometryGroup.numMorphTargets !== undefined ) {
  370. for ( var m = 0, ml = geometryGroup.numMorphTargets; m < ml; m ++ ) {
  371. _gl.deleteBuffer( geometryGroup.__webglMorphTargetsBuffers[ m ] );
  372. }
  373. }
  374. if ( geometryGroup.numMorphNormals !== undefined ) {
  375. for ( var m = 0, ml = geometryGroup.numMorphNormals; m < ml; m ++ ) {
  376. _gl.deleteBuffer( geometryGroup.__webglMorphNormalsBuffers[ m ] );
  377. }
  378. }
  379. deleteBuffers( geometryGroup );
  380. }
  381. } else {
  382. deleteBuffers( geometry );
  383. }
  384. }
  385. };
  386. var deallocateTexture = function ( texture ) {
  387. if ( texture.image && texture.image.__webglTextureCube ) {
  388. // cube texture
  389. _gl.deleteTexture( texture.image.__webglTextureCube );
  390. } else {
  391. // 2D texture
  392. if ( ! texture.__webglInit ) return;
  393. texture.__webglInit = false;
  394. _gl.deleteTexture( texture.__webglTexture );
  395. }
  396. };
  397. var deallocateRenderTarget = function ( renderTarget ) {
  398. if ( !renderTarget || ! renderTarget.__webglTexture ) return;
  399. _gl.deleteTexture( renderTarget.__webglTexture );
  400. if ( renderTarget instanceof THREE.WebGLRenderTargetCube ) {
  401. for ( var i = 0; i < 6; i ++ ) {
  402. _gl.deleteFramebuffer( renderTarget.__webglFramebuffer[ i ] );
  403. _gl.deleteRenderbuffer( renderTarget.__webglRenderbuffer[ i ] );
  404. }
  405. } else {
  406. _gl.deleteFramebuffer( renderTarget.__webglFramebuffer );
  407. _gl.deleteRenderbuffer( renderTarget.__webglRenderbuffer );
  408. }
  409. };
  410. var deallocateMaterial = function ( material ) {
  411. var program = material.program;
  412. if ( program === undefined ) return;
  413. material.program = undefined;
  414. // only deallocate GL program if this was the last use of shared program
  415. // assumed there is only single copy of any program in the _programs list
  416. // (that's how it's constructed)
  417. var i, il, programInfo;
  418. var deleteProgram = false;
  419. for ( i = 0, il = _programs.length; i < il; i ++ ) {
  420. programInfo = _programs[ i ];
  421. if ( programInfo.program === program ) {
  422. programInfo.usedTimes --;
  423. if ( programInfo.usedTimes === 0 ) {
  424. deleteProgram = true;
  425. }
  426. break;
  427. }
  428. }
  429. if ( deleteProgram === true ) {
  430. // avoid using array.splice, this is costlier than creating new array from scratch
  431. var newPrograms = [];
  432. for ( i = 0, il = _programs.length; i < il; i ++ ) {
  433. programInfo = _programs[ i ];
  434. if ( programInfo.program !== program ) {
  435. newPrograms.push( programInfo );
  436. }
  437. }
  438. _programs = newPrograms;
  439. _gl.deleteProgram( program );
  440. _this.info.memory.programs --;
  441. }
  442. };
  443. // Buffer initialization
  444. function initCustomAttributes ( geometry, object ) {
  445. var nvertices = geometry.vertices.length;
  446. var material = object.material;
  447. if ( material.attributes ) {
  448. if ( geometry.__webglCustomAttributesList === undefined ) {
  449. geometry.__webglCustomAttributesList = [];
  450. }
  451. for ( var a in material.attributes ) {
  452. var attribute = material.attributes[ a ];
  453. if ( !attribute.__webglInitialized || attribute.createUniqueBuffers ) {
  454. attribute.__webglInitialized = true;
  455. var size = 1; // "f" and "i"
  456. if ( attribute.type === "v2" ) size = 2;
  457. else if ( attribute.type === "v3" ) size = 3;
  458. else if ( attribute.type === "v4" ) size = 4;
  459. else if ( attribute.type === "c" ) size = 3;
  460. attribute.size = size;
  461. attribute.array = new Float32Array( nvertices * size );
  462. attribute.buffer = _gl.createBuffer();
  463. attribute.buffer.belongsToAttribute = a;
  464. attribute.needsUpdate = true;
  465. }
  466. geometry.__webglCustomAttributesList.push( attribute );
  467. }
  468. }
  469. };
  470. function initParticleBuffers ( geometry, object ) {
  471. var nvertices = geometry.vertices.length;
  472. geometry.__vertexArray = new Float32Array( nvertices * 3 );
  473. geometry.__colorArray = new Float32Array( nvertices * 3 );
  474. geometry.__sortArray = [];
  475. geometry.__webglParticleCount = nvertices;
  476. initCustomAttributes ( geometry, object );
  477. };
  478. function initLineBuffers ( geometry, object ) {
  479. var nvertices = geometry.vertices.length;
  480. geometry.__vertexArray = new Float32Array( nvertices * 3 );
  481. geometry.__colorArray = new Float32Array( nvertices * 3 );
  482. geometry.__lineDistanceArray = new Float32Array( nvertices * 1 );
  483. geometry.__webglLineCount = nvertices;
  484. initCustomAttributes ( geometry, object );
  485. };
  486. function initMeshBuffers ( geometryGroup, object ) {
  487. var geometry = object.geometry,
  488. faces3 = geometryGroup.faces3,
  489. nvertices = faces3.length * 3,
  490. ntris = faces3.length * 1,
  491. nlines = faces3.length * 3,
  492. material = getBufferMaterial( object, geometryGroup ),
  493. uvType = bufferGuessUVType( material ),
  494. normalType = bufferGuessNormalType( material ),
  495. vertexColorType = bufferGuessVertexColorType( material );
  496. // console.log( "uvType", uvType, "normalType", normalType, "vertexColorType", vertexColorType, object, geometryGroup, material );
  497. geometryGroup.__vertexArray = new Float32Array( nvertices * 3 );
  498. if ( normalType ) {
  499. geometryGroup.__normalArray = new Float32Array( nvertices * 3 );
  500. }
  501. if ( geometry.hasTangents ) {
  502. geometryGroup.__tangentArray = new Float32Array( nvertices * 4 );
  503. }
  504. if ( vertexColorType ) {
  505. geometryGroup.__colorArray = new Float32Array( nvertices * 3 );
  506. }
  507. if ( uvType ) {
  508. if ( geometry.faceVertexUvs.length > 0 ) {
  509. geometryGroup.__uvArray = new Float32Array( nvertices * 2 );
  510. }
  511. if ( geometry.faceVertexUvs.length > 1 ) {
  512. geometryGroup.__uv2Array = new Float32Array( nvertices * 2 );
  513. }
  514. }
  515. if ( object.geometry.skinWeights.length && object.geometry.skinIndices.length ) {
  516. geometryGroup.__skinIndexArray = new Float32Array( nvertices * 4 );
  517. geometryGroup.__skinWeightArray = new Float32Array( nvertices * 4 );
  518. }
  519. geometryGroup.__faceArray = new Uint16Array( ntris * 3 );
  520. geometryGroup.__lineArray = new Uint16Array( nlines * 2 );
  521. var m, ml;
  522. if ( geometryGroup.numMorphTargets ) {
  523. geometryGroup.__morphTargetsArrays = [];
  524. for ( m = 0, ml = geometryGroup.numMorphTargets; m < ml; m ++ ) {
  525. geometryGroup.__morphTargetsArrays.push( new Float32Array( nvertices * 3 ) );
  526. }
  527. }
  528. if ( geometryGroup.numMorphNormals ) {
  529. geometryGroup.__morphNormalsArrays = [];
  530. for ( m = 0, ml = geometryGroup.numMorphNormals; m < ml; m ++ ) {
  531. geometryGroup.__morphNormalsArrays.push( new Float32Array( nvertices * 3 ) );
  532. }
  533. }
  534. geometryGroup.__webglFaceCount = ntris * 3;
  535. geometryGroup.__webglLineCount = nlines * 2;
  536. // custom attributes
  537. if ( material.attributes ) {
  538. if ( geometryGroup.__webglCustomAttributesList === undefined ) {
  539. geometryGroup.__webglCustomAttributesList = [];
  540. }
  541. for ( var a in material.attributes ) {
  542. // Do a shallow copy of the attribute object so different geometryGroup chunks use different
  543. // attribute buffers which are correctly indexed in the setMeshBuffers function
  544. var originalAttribute = material.attributes[ a ];
  545. var attribute = {};
  546. for ( var property in originalAttribute ) {
  547. attribute[ property ] = originalAttribute[ property ];
  548. }
  549. if ( !attribute.__webglInitialized || attribute.createUniqueBuffers ) {
  550. attribute.__webglInitialized = true;
  551. var size = 1; // "f" and "i"
  552. if( attribute.type === "v2" ) size = 2;
  553. else if( attribute.type === "v3" ) size = 3;
  554. else if( attribute.type === "v4" ) size = 4;
  555. else if( attribute.type === "c" ) size = 3;
  556. attribute.size = size;
  557. attribute.array = new Float32Array( nvertices * size );
  558. attribute.buffer = _gl.createBuffer();
  559. attribute.buffer.belongsToAttribute = a;
  560. originalAttribute.needsUpdate = true;
  561. attribute.__original = originalAttribute;
  562. }
  563. geometryGroup.__webglCustomAttributesList.push( attribute );
  564. }
  565. }
  566. geometryGroup.__inittedArrays = true;
  567. };
  568. function getBufferMaterial( object, geometryGroup ) {
  569. return object.material instanceof THREE.MeshFaceMaterial
  570. ? object.material.materials[ geometryGroup.materialIndex ]
  571. : object.material;
  572. };
  573. function materialNeedsSmoothNormals ( material ) {
  574. return material && material.shading !== undefined && material.shading === THREE.SmoothShading;
  575. };
  576. function bufferGuessNormalType ( material ) {
  577. // only MeshBasicMaterial and MeshDepthMaterial don't need normals
  578. if ( ( material instanceof THREE.MeshBasicMaterial && !material.envMap ) || material instanceof THREE.MeshDepthMaterial ) {
  579. return false;
  580. }
  581. if ( materialNeedsSmoothNormals( material ) ) {
  582. return THREE.SmoothShading;
  583. } else {
  584. return THREE.FlatShading;
  585. }
  586. };
  587. function bufferGuessVertexColorType( material ) {
  588. if ( material.vertexColors ) {
  589. return material.vertexColors;
  590. }
  591. return false;
  592. };
  593. function bufferGuessUVType( material ) {
  594. // material must use some texture to require uvs
  595. if ( material.map ||
  596. material.lightMap ||
  597. material.bumpMap ||
  598. material.normalMap ||
  599. material.specularMap ||
  600. material instanceof THREE.ShaderMaterial ) {
  601. return true;
  602. }
  603. return false;
  604. };
  605. //
  606. function initDirectBuffers( geometry ) {
  607. var a, attribute, type;
  608. for ( a in geometry.attributes ) {
  609. if ( a === "index" ) {
  610. type = _gl.ELEMENT_ARRAY_BUFFER;
  611. } else {
  612. type = _gl.ARRAY_BUFFER;
  613. }
  614. attribute = geometry.attributes[ a ];
  615. attribute.buffer = _gl.createBuffer();
  616. _gl.bindBuffer( type, attribute.buffer );
  617. _gl.bufferData( type, attribute.array, _gl.STATIC_DRAW );
  618. }
  619. };
  620. function initGeometry2Buffers( geometry ) {
  621. var buffers = {};
  622. var attributes = [ 'vertices', 'normals', 'uvs' ];
  623. for ( var key in attributes ) {
  624. var array = geometry[ attributes[ key ] ];
  625. var buffer = _gl.createBuffer();
  626. _gl.bindBuffer( _gl.ARRAY_BUFFER, buffer );
  627. _gl.bufferData( _gl.ARRAY_BUFFER, array, _gl.STATIC_DRAW );
  628. buffers[ attributes[ key ] ] = buffer;
  629. }
  630. _buffers[ geometry.id ] = buffers;
  631. };
  632. // Buffer setting
  633. function setParticleBuffers ( geometry, hint, object ) {
  634. var v, c, vertex, offset, index, color,
  635. vertices = geometry.vertices,
  636. vl = vertices.length,
  637. colors = geometry.colors,
  638. cl = colors.length,
  639. vertexArray = geometry.__vertexArray,
  640. colorArray = geometry.__colorArray,
  641. sortArray = geometry.__sortArray,
  642. dirtyVertices = geometry.verticesNeedUpdate,
  643. dirtyElements = geometry.elementsNeedUpdate,
  644. dirtyColors = geometry.colorsNeedUpdate,
  645. customAttributes = geometry.__webglCustomAttributesList,
  646. i, il,
  647. a, ca, cal, value,
  648. customAttribute;
  649. if ( object.sortParticles ) {
  650. _projScreenMatrixPS.copy( _projScreenMatrix );
  651. _projScreenMatrixPS.multiply( object.matrixWorld );
  652. for ( v = 0; v < vl; v ++ ) {
  653. vertex = vertices[ v ];
  654. _vector3.copy( vertex );
  655. _vector3.applyProjection( _projScreenMatrixPS );
  656. sortArray[ v ] = [ _vector3.z, v ];
  657. }
  658. sortArray.sort( numericalSort );
  659. for ( v = 0; v < vl; v ++ ) {
  660. vertex = vertices[ sortArray[v][1] ];
  661. offset = v * 3;
  662. vertexArray[ offset ] = vertex.x;
  663. vertexArray[ offset + 1 ] = vertex.y;
  664. vertexArray[ offset + 2 ] = vertex.z;
  665. }
  666. for ( c = 0; c < cl; c ++ ) {
  667. offset = c * 3;
  668. color = colors[ sortArray[c][1] ];
  669. colorArray[ offset ] = color.r;
  670. colorArray[ offset + 1 ] = color.g;
  671. colorArray[ offset + 2 ] = color.b;
  672. }
  673. if ( customAttributes ) {
  674. for ( i = 0, il = customAttributes.length; i < il; i ++ ) {
  675. customAttribute = customAttributes[ i ];
  676. if ( ! ( customAttribute.boundTo === undefined || customAttribute.boundTo === "vertices" ) ) continue;
  677. offset = 0;
  678. cal = customAttribute.value.length;
  679. if ( customAttribute.size === 1 ) {
  680. for ( ca = 0; ca < cal; ca ++ ) {
  681. index = sortArray[ ca ][ 1 ];
  682. customAttribute.array[ ca ] = customAttribute.value[ index ];
  683. }
  684. } else if ( customAttribute.size === 2 ) {
  685. for ( ca = 0; ca < cal; ca ++ ) {
  686. index = sortArray[ ca ][ 1 ];
  687. value = customAttribute.value[ index ];
  688. customAttribute.array[ offset ] = value.x;
  689. customAttribute.array[ offset + 1 ] = value.y;
  690. offset += 2;
  691. }
  692. } else if ( customAttribute.size === 3 ) {
  693. if ( customAttribute.type === "c" ) {
  694. for ( ca = 0; ca < cal; ca ++ ) {
  695. index = sortArray[ ca ][ 1 ];
  696. value = customAttribute.value[ index ];
  697. customAttribute.array[ offset ] = value.r;
  698. customAttribute.array[ offset + 1 ] = value.g;
  699. customAttribute.array[ offset + 2 ] = value.b;
  700. offset += 3;
  701. }
  702. } else {
  703. for ( ca = 0; ca < cal; ca ++ ) {
  704. index = sortArray[ ca ][ 1 ];
  705. value = customAttribute.value[ index ];
  706. customAttribute.array[ offset ] = value.x;
  707. customAttribute.array[ offset + 1 ] = value.y;
  708. customAttribute.array[ offset + 2 ] = value.z;
  709. offset += 3;
  710. }
  711. }
  712. } else if ( customAttribute.size === 4 ) {
  713. for ( ca = 0; ca < cal; ca ++ ) {
  714. index = sortArray[ ca ][ 1 ];
  715. value = customAttribute.value[ index ];
  716. customAttribute.array[ offset ] = value.x;
  717. customAttribute.array[ offset + 1 ] = value.y;
  718. customAttribute.array[ offset + 2 ] = value.z;
  719. customAttribute.array[ offset + 3 ] = value.w;
  720. offset += 4;
  721. }
  722. }
  723. }
  724. }
  725. } else {
  726. if ( dirtyVertices ) {
  727. for ( v = 0; v < vl; v ++ ) {
  728. vertex = vertices[ v ];
  729. offset = v * 3;
  730. vertexArray[ offset ] = vertex.x;
  731. vertexArray[ offset + 1 ] = vertex.y;
  732. vertexArray[ offset + 2 ] = vertex.z;
  733. }
  734. }
  735. if ( dirtyColors ) {
  736. for ( c = 0; c < cl; c ++ ) {
  737. color = colors[ c ];
  738. offset = c * 3;
  739. colorArray[ offset ] = color.r;
  740. colorArray[ offset + 1 ] = color.g;
  741. colorArray[ offset + 2 ] = color.b;
  742. }
  743. }
  744. if ( customAttributes ) {
  745. for ( i = 0, il = customAttributes.length; i < il; i ++ ) {
  746. customAttribute = customAttributes[ i ];
  747. if ( customAttribute.needsUpdate &&
  748. ( customAttribute.boundTo === undefined ||
  749. customAttribute.boundTo === "vertices") ) {
  750. cal = customAttribute.value.length;
  751. offset = 0;
  752. if ( customAttribute.size === 1 ) {
  753. for ( ca = 0; ca < cal; ca ++ ) {
  754. customAttribute.array[ ca ] = customAttribute.value[ ca ];
  755. }
  756. } else if ( customAttribute.size === 2 ) {
  757. for ( ca = 0; ca < cal; ca ++ ) {
  758. value = customAttribute.value[ ca ];
  759. customAttribute.array[ offset ] = value.x;
  760. customAttribute.array[ offset + 1 ] = value.y;
  761. offset += 2;
  762. }
  763. } else if ( customAttribute.size === 3 ) {
  764. if ( customAttribute.type === "c" ) {
  765. for ( ca = 0; ca < cal; ca ++ ) {
  766. value = customAttribute.value[ ca ];
  767. customAttribute.array[ offset ] = value.r;
  768. customAttribute.array[ offset + 1 ] = value.g;
  769. customAttribute.array[ offset + 2 ] = value.b;
  770. offset += 3;
  771. }
  772. } else {
  773. for ( ca = 0; ca < cal; ca ++ ) {
  774. value = customAttribute.value[ ca ];
  775. customAttribute.array[ offset ] = value.x;
  776. customAttribute.array[ offset + 1 ] = value.y;
  777. customAttribute.array[ offset + 2 ] = value.z;
  778. offset += 3;
  779. }
  780. }
  781. } else if ( customAttribute.size === 4 ) {
  782. for ( ca = 0; ca < cal; ca ++ ) {
  783. value = customAttribute.value[ ca ];
  784. customAttribute.array[ offset ] = value.x;
  785. customAttribute.array[ offset + 1 ] = value.y;
  786. customAttribute.array[ offset + 2 ] = value.z;
  787. customAttribute.array[ offset + 3 ] = value.w;
  788. offset += 4;
  789. }
  790. }
  791. }
  792. }
  793. }
  794. }
  795. if ( dirtyVertices || object.sortParticles ) {
  796. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglVertexBuffer );
  797. _gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );
  798. }
  799. if ( dirtyColors || object.sortParticles ) {
  800. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglColorBuffer );
  801. _gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );
  802. }
  803. if ( customAttributes ) {
  804. for ( i = 0, il = customAttributes.length; i < il; i ++ ) {
  805. customAttribute = customAttributes[ i ];
  806. if ( customAttribute.needsUpdate || object.sortParticles ) {
  807. _gl.bindBuffer( _gl.ARRAY_BUFFER, customAttribute.buffer );
  808. _gl.bufferData( _gl.ARRAY_BUFFER, customAttribute.array, hint );
  809. }
  810. }
  811. }
  812. };
  813. function setLineBuffers ( geometry, hint ) {
  814. var v, c, d, vertex, offset, color,
  815. vertices = geometry.vertices,
  816. colors = geometry.colors,
  817. lineDistances = geometry.lineDistances,
  818. vl = vertices.length,
  819. cl = colors.length,
  820. dl = lineDistances.length,
  821. vertexArray = geometry.__vertexArray,
  822. colorArray = geometry.__colorArray,
  823. lineDistanceArray = geometry.__lineDistanceArray,
  824. dirtyVertices = geometry.verticesNeedUpdate,
  825. dirtyColors = geometry.colorsNeedUpdate,
  826. dirtyLineDistances = geometry.lineDistancesNeedUpdate,
  827. customAttributes = geometry.__webglCustomAttributesList,
  828. i, il,
  829. a, ca, cal, value,
  830. customAttribute;
  831. if ( dirtyVertices ) {
  832. for ( v = 0; v < vl; v ++ ) {
  833. vertex = vertices[ v ];
  834. offset = v * 3;
  835. vertexArray[ offset ] = vertex.x;
  836. vertexArray[ offset + 1 ] = vertex.y;
  837. vertexArray[ offset + 2 ] = vertex.z;
  838. }
  839. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglVertexBuffer );
  840. _gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );
  841. }
  842. if ( dirtyColors ) {
  843. for ( c = 0; c < cl; c ++ ) {
  844. color = colors[ c ];
  845. offset = c * 3;
  846. colorArray[ offset ] = color.r;
  847. colorArray[ offset + 1 ] = color.g;
  848. colorArray[ offset + 2 ] = color.b;
  849. }
  850. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglColorBuffer );
  851. _gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );
  852. }
  853. if ( dirtyLineDistances ) {
  854. for ( d = 0; d < dl; d ++ ) {
  855. lineDistanceArray[ d ] = lineDistances[ d ];
  856. }
  857. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglLineDistanceBuffer );
  858. _gl.bufferData( _gl.ARRAY_BUFFER, lineDistanceArray, hint );
  859. }
  860. if ( customAttributes ) {
  861. for ( i = 0, il = customAttributes.length; i < il; i ++ ) {
  862. customAttribute = customAttributes[ i ];
  863. if ( customAttribute.needsUpdate &&
  864. ( customAttribute.boundTo === undefined ||
  865. customAttribute.boundTo === "vertices" ) ) {
  866. offset = 0;
  867. cal = customAttribute.value.length;
  868. if ( customAttribute.size === 1 ) {
  869. for ( ca = 0; ca < cal; ca ++ ) {
  870. customAttribute.array[ ca ] = customAttribute.value[ ca ];
  871. }
  872. } else if ( customAttribute.size === 2 ) {
  873. for ( ca = 0; ca < cal; ca ++ ) {
  874. value = customAttribute.value[ ca ];
  875. customAttribute.array[ offset ] = value.x;
  876. customAttribute.array[ offset + 1 ] = value.y;
  877. offset += 2;
  878. }
  879. } else if ( customAttribute.size === 3 ) {
  880. if ( customAttribute.type === "c" ) {
  881. for ( ca = 0; ca < cal; ca ++ ) {
  882. value = customAttribute.value[ ca ];
  883. customAttribute.array[ offset ] = value.r;
  884. customAttribute.array[ offset + 1 ] = value.g;
  885. customAttribute.array[ offset + 2 ] = value.b;
  886. offset += 3;
  887. }
  888. } else {
  889. for ( ca = 0; ca < cal; ca ++ ) {
  890. value = customAttribute.value[ ca ];
  891. customAttribute.array[ offset ] = value.x;
  892. customAttribute.array[ offset + 1 ] = value.y;
  893. customAttribute.array[ offset + 2 ] = value.z;
  894. offset += 3;
  895. }
  896. }
  897. } else if ( customAttribute.size === 4 ) {
  898. for ( ca = 0; ca < cal; ca ++ ) {
  899. value = customAttribute.value[ ca ];
  900. customAttribute.array[ offset ] = value.x;
  901. customAttribute.array[ offset + 1 ] = value.y;
  902. customAttribute.array[ offset + 2 ] = value.z;
  903. customAttribute.array[ offset + 3 ] = value.w;
  904. offset += 4;
  905. }
  906. }
  907. _gl.bindBuffer( _gl.ARRAY_BUFFER, customAttribute.buffer );
  908. _gl.bufferData( _gl.ARRAY_BUFFER, customAttribute.array, hint );
  909. }
  910. }
  911. }
  912. };
  913. function setMeshBuffers( geometryGroup, object, hint, dispose, material ) {
  914. if ( ! geometryGroup.__inittedArrays ) {
  915. return;
  916. }
  917. var normalType = bufferGuessNormalType( material ),
  918. vertexColorType = bufferGuessVertexColorType( material ),
  919. uvType = bufferGuessUVType( material ),
  920. needsSmoothNormals = ( normalType === THREE.SmoothShading );
  921. var f, fl, fi, face,
  922. vertexNormals, faceNormal, normal,
  923. vertexColors, faceColor,
  924. vertexTangents,
  925. uv, uv2, v1, v2, v3, v4, t1, t2, t3, t4, n1, n2, n3, n4,
  926. c1, c2, c3, c4,
  927. sw1, sw2, sw3, sw4,
  928. si1, si2, si3, si4,
  929. sa1, sa2, sa3, sa4,
  930. sb1, sb2, sb3, sb4,
  931. m, ml, i, il,
  932. vn, uvi, uv2i,
  933. vk, vkl, vka,
  934. nka, chf, faceVertexNormals,
  935. a,
  936. vertexIndex = 0,
  937. offset = 0,
  938. offset_uv = 0,
  939. offset_uv2 = 0,
  940. offset_face = 0,
  941. offset_normal = 0,
  942. offset_tangent = 0,
  943. offset_line = 0,
  944. offset_color = 0,
  945. offset_skin = 0,
  946. offset_morphTarget = 0,
  947. offset_custom = 0,
  948. offset_customSrc = 0,
  949. value,
  950. vertexArray = geometryGroup.__vertexArray,
  951. uvArray = geometryGroup.__uvArray,
  952. uv2Array = geometryGroup.__uv2Array,
  953. normalArray = geometryGroup.__normalArray,
  954. tangentArray = geometryGroup.__tangentArray,
  955. colorArray = geometryGroup.__colorArray,
  956. skinIndexArray = geometryGroup.__skinIndexArray,
  957. skinWeightArray = geometryGroup.__skinWeightArray,
  958. morphTargetsArrays = geometryGroup.__morphTargetsArrays,
  959. morphNormalsArrays = geometryGroup.__morphNormalsArrays,
  960. customAttributes = geometryGroup.__webglCustomAttributesList,
  961. customAttribute,
  962. faceArray = geometryGroup.__faceArray,
  963. lineArray = geometryGroup.__lineArray,
  964. geometry = object.geometry, // this is shared for all chunks
  965. dirtyVertices = geometry.verticesNeedUpdate,
  966. dirtyElements = geometry.elementsNeedUpdate,
  967. dirtyUvs = geometry.uvsNeedUpdate,
  968. dirtyNormals = geometry.normalsNeedUpdate,
  969. dirtyTangents = geometry.tangentsNeedUpdate,
  970. dirtyColors = geometry.colorsNeedUpdate,
  971. dirtyMorphTargets = geometry.morphTargetsNeedUpdate,
  972. vertices = geometry.vertices,
  973. chunk_faces3 = geometryGroup.faces3,
  974. obj_faces = geometry.faces,
  975. obj_uvs = geometry.faceVertexUvs[ 0 ],
  976. obj_uvs2 = geometry.faceVertexUvs[ 1 ],
  977. obj_colors = geometry.colors,
  978. obj_skinIndices = geometry.skinIndices,
  979. obj_skinWeights = geometry.skinWeights,
  980. morphTargets = geometry.morphTargets,
  981. morphNormals = geometry.morphNormals;
  982. if ( dirtyVertices ) {
  983. for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
  984. face = obj_faces[ chunk_faces3[ f ] ];
  985. v1 = vertices[ face.a ];
  986. v2 = vertices[ face.b ];
  987. v3 = vertices[ face.c ];
  988. vertexArray[ offset ] = v1.x;
  989. vertexArray[ offset + 1 ] = v1.y;
  990. vertexArray[ offset + 2 ] = v1.z;
  991. vertexArray[ offset + 3 ] = v2.x;
  992. vertexArray[ offset + 4 ] = v2.y;
  993. vertexArray[ offset + 5 ] = v2.z;
  994. vertexArray[ offset + 6 ] = v3.x;
  995. vertexArray[ offset + 7 ] = v3.y;
  996. vertexArray[ offset + 8 ] = v3.z;
  997. offset += 9;
  998. }
  999. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer );
  1000. _gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );
  1001. }
  1002. if ( dirtyMorphTargets ) {
  1003. for ( vk = 0, vkl = morphTargets.length; vk < vkl; vk ++ ) {
  1004. offset_morphTarget = 0;
  1005. for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
  1006. chf = chunk_faces3[ f ];
  1007. face = obj_faces[ chf ];
  1008. // morph positions
  1009. v1 = morphTargets[ vk ].vertices[ face.a ];
  1010. v2 = morphTargets[ vk ].vertices[ face.b ];
  1011. v3 = morphTargets[ vk ].vertices[ face.c ];
  1012. vka = morphTargetsArrays[ vk ];
  1013. vka[ offset_morphTarget ] = v1.x;
  1014. vka[ offset_morphTarget + 1 ] = v1.y;
  1015. vka[ offset_morphTarget + 2 ] = v1.z;
  1016. vka[ offset_morphTarget + 3 ] = v2.x;
  1017. vka[ offset_morphTarget + 4 ] = v2.y;
  1018. vka[ offset_morphTarget + 5 ] = v2.z;
  1019. vka[ offset_morphTarget + 6 ] = v3.x;
  1020. vka[ offset_morphTarget + 7 ] = v3.y;
  1021. vka[ offset_morphTarget + 8 ] = v3.z;
  1022. // morph normals
  1023. if ( material.morphNormals ) {
  1024. if ( needsSmoothNormals ) {
  1025. faceVertexNormals = morphNormals[ vk ].vertexNormals[ chf ];
  1026. n1 = faceVertexNormals.a;
  1027. n2 = faceVertexNormals.b;
  1028. n3 = faceVertexNormals.c;
  1029. } else {
  1030. n1 = morphNormals[ vk ].faceNormals[ chf ];
  1031. n2 = n1;
  1032. n3 = n1;
  1033. }
  1034. nka = morphNormalsArrays[ vk ];
  1035. nka[ offset_morphTarget ] = n1.x;
  1036. nka[ offset_morphTarget + 1 ] = n1.y;
  1037. nka[ offset_morphTarget + 2 ] = n1.z;
  1038. nka[ offset_morphTarget + 3 ] = n2.x;
  1039. nka[ offset_morphTarget + 4 ] = n2.y;
  1040. nka[ offset_morphTarget + 5 ] = n2.z;
  1041. nka[ offset_morphTarget + 6 ] = n3.x;
  1042. nka[ offset_morphTarget + 7 ] = n3.y;
  1043. nka[ offset_morphTarget + 8 ] = n3.z;
  1044. }
  1045. //
  1046. offset_morphTarget += 9;
  1047. }
  1048. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ vk ] );
  1049. _gl.bufferData( _gl.ARRAY_BUFFER, morphTargetsArrays[ vk ], hint );
  1050. if ( material.morphNormals ) {
  1051. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphNormalsBuffers[ vk ] );
  1052. _gl.bufferData( _gl.ARRAY_BUFFER, morphNormalsArrays[ vk ], hint );
  1053. }
  1054. }
  1055. }
  1056. if ( obj_skinWeights.length ) {
  1057. for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
  1058. face = obj_faces[ chunk_faces3[ f ] ];
  1059. // weights
  1060. sw1 = obj_skinWeights[ face.a ];
  1061. sw2 = obj_skinWeights[ face.b ];
  1062. sw3 = obj_skinWeights[ face.c ];
  1063. skinWeightArray[ offset_skin ] = sw1.x;
  1064. skinWeightArray[ offset_skin + 1 ] = sw1.y;
  1065. skinWeightArray[ offset_skin + 2 ] = sw1.z;
  1066. skinWeightArray[ offset_skin + 3 ] = sw1.w;
  1067. skinWeightArray[ offset_skin + 4 ] = sw2.x;
  1068. skinWeightArray[ offset_skin + 5 ] = sw2.y;
  1069. skinWeightArray[ offset_skin + 6 ] = sw2.z;
  1070. skinWeightArray[ offset_skin + 7 ] = sw2.w;
  1071. skinWeightArray[ offset_skin + 8 ] = sw3.x;
  1072. skinWeightArray[ offset_skin + 9 ] = sw3.y;
  1073. skinWeightArray[ offset_skin + 10 ] = sw3.z;
  1074. skinWeightArray[ offset_skin + 11 ] = sw3.w;
  1075. // indices
  1076. si1 = obj_skinIndices[ face.a ];
  1077. si2 = obj_skinIndices[ face.b ];
  1078. si3 = obj_skinIndices[ face.c ];
  1079. skinIndexArray[ offset_skin ] = si1.x;
  1080. skinIndexArray[ offset_skin + 1 ] = si1.y;
  1081. skinIndexArray[ offset_skin + 2 ] = si1.z;
  1082. skinIndexArray[ offset_skin + 3 ] = si1.w;
  1083. skinIndexArray[ offset_skin + 4 ] = si2.x;
  1084. skinIndexArray[ offset_skin + 5 ] = si2.y;
  1085. skinIndexArray[ offset_skin + 6 ] = si2.z;
  1086. skinIndexArray[ offset_skin + 7 ] = si2.w;
  1087. skinIndexArray[ offset_skin + 8 ] = si3.x;
  1088. skinIndexArray[ offset_skin + 9 ] = si3.y;
  1089. skinIndexArray[ offset_skin + 10 ] = si3.z;
  1090. skinIndexArray[ offset_skin + 11 ] = si3.w;
  1091. offset_skin += 12;
  1092. }
  1093. if ( offset_skin > 0 ) {
  1094. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinIndicesBuffer );
  1095. _gl.bufferData( _gl.ARRAY_BUFFER, skinIndexArray, hint );
  1096. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinWeightsBuffer );
  1097. _gl.bufferData( _gl.ARRAY_BUFFER, skinWeightArray, hint );
  1098. }
  1099. }
  1100. if ( dirtyColors && vertexColorType ) {
  1101. for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
  1102. face = obj_faces[ chunk_faces3[ f ] ];
  1103. vertexColors = face.vertexColors;
  1104. faceColor = face.color;
  1105. if ( vertexColors.length === 3 && vertexColorType === THREE.VertexColors ) {
  1106. c1 = vertexColors[ 0 ];
  1107. c2 = vertexColors[ 1 ];
  1108. c3 = vertexColors[ 2 ];
  1109. } else {
  1110. c1 = faceColor;
  1111. c2 = faceColor;
  1112. c3 = faceColor;
  1113. }
  1114. colorArray[ offset_color ] = c1.r;
  1115. colorArray[ offset_color + 1 ] = c1.g;
  1116. colorArray[ offset_color + 2 ] = c1.b;
  1117. colorArray[ offset_color + 3 ] = c2.r;
  1118. colorArray[ offset_color + 4 ] = c2.g;
  1119. colorArray[ offset_color + 5 ] = c2.b;
  1120. colorArray[ offset_color + 6 ] = c3.r;
  1121. colorArray[ offset_color + 7 ] = c3.g;
  1122. colorArray[ offset_color + 8 ] = c3.b;
  1123. offset_color += 9;
  1124. }
  1125. if ( offset_color > 0 ) {
  1126. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglColorBuffer );
  1127. _gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );
  1128. }
  1129. }
  1130. if ( dirtyTangents && geometry.hasTangents ) {
  1131. for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
  1132. face = obj_faces[ chunk_faces3[ f ] ];
  1133. vertexTangents = face.vertexTangents;
  1134. t1 = vertexTangents[ 0 ];
  1135. t2 = vertexTangents[ 1 ];
  1136. t3 = vertexTangents[ 2 ];
  1137. tangentArray[ offset_tangent ] = t1.x;
  1138. tangentArray[ offset_tangent + 1 ] = t1.y;
  1139. tangentArray[ offset_tangent + 2 ] = t1.z;
  1140. tangentArray[ offset_tangent + 3 ] = t1.w;
  1141. tangentArray[ offset_tangent + 4 ] = t2.x;
  1142. tangentArray[ offset_tangent + 5 ] = t2.y;
  1143. tangentArray[ offset_tangent + 6 ] = t2.z;
  1144. tangentArray[ offset_tangent + 7 ] = t2.w;
  1145. tangentArray[ offset_tangent + 8 ] = t3.x;
  1146. tangentArray[ offset_tangent + 9 ] = t3.y;
  1147. tangentArray[ offset_tangent + 10 ] = t3.z;
  1148. tangentArray[ offset_tangent + 11 ] = t3.w;
  1149. offset_tangent += 12;
  1150. }
  1151. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglTangentBuffer );
  1152. _gl.bufferData( _gl.ARRAY_BUFFER, tangentArray, hint );
  1153. }
  1154. if ( dirtyNormals && normalType ) {
  1155. for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
  1156. face = obj_faces[ chunk_faces3[ f ] ];
  1157. vertexNormals = face.vertexNormals;
  1158. faceNormal = face.normal;
  1159. if ( vertexNormals.length === 3 && needsSmoothNormals ) {
  1160. for ( i = 0; i < 3; i ++ ) {
  1161. vn = vertexNormals[ i ];
  1162. normalArray[ offset_normal ] = vn.x;
  1163. normalArray[ offset_normal + 1 ] = vn.y;
  1164. normalArray[ offset_normal + 2 ] = vn.z;
  1165. offset_normal += 3;
  1166. }
  1167. } else {
  1168. for ( i = 0; i < 3; i ++ ) {
  1169. normalArray[ offset_normal ] = faceNormal.x;
  1170. normalArray[ offset_normal + 1 ] = faceNormal.y;
  1171. normalArray[ offset_normal + 2 ] = faceNormal.z;
  1172. offset_normal += 3;
  1173. }
  1174. }
  1175. }
  1176. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglNormalBuffer );
  1177. _gl.bufferData( _gl.ARRAY_BUFFER, normalArray, hint );
  1178. }
  1179. if ( dirtyUvs && obj_uvs && uvType ) {
  1180. for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
  1181. fi = chunk_faces3[ f ];
  1182. uv = obj_uvs[ fi ];
  1183. if ( uv === undefined ) continue;
  1184. for ( i = 0; i < 3; i ++ ) {
  1185. uvi = uv[ i ];
  1186. uvArray[ offset_uv ] = uvi.x;
  1187. uvArray[ offset_uv + 1 ] = uvi.y;
  1188. offset_uv += 2;
  1189. }
  1190. }
  1191. if ( offset_uv > 0 ) {
  1192. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUVBuffer );
  1193. _gl.bufferData( _gl.ARRAY_BUFFER, uvArray, hint );
  1194. }
  1195. }
  1196. if ( dirtyUvs && obj_uvs2 && uvType ) {
  1197. for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
  1198. fi = chunk_faces3[ f ];
  1199. uv2 = obj_uvs2[ fi ];
  1200. if ( uv2 === undefined ) continue;
  1201. for ( i = 0; i < 3; i ++ ) {
  1202. uv2i = uv2[ i ];
  1203. uv2Array[ offset_uv2 ] = uv2i.x;
  1204. uv2Array[ offset_uv2 + 1 ] = uv2i.y;
  1205. offset_uv2 += 2;
  1206. }
  1207. }
  1208. if ( offset_uv2 > 0 ) {
  1209. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUV2Buffer );
  1210. _gl.bufferData( _gl.ARRAY_BUFFER, uv2Array, hint );
  1211. }
  1212. }
  1213. if ( dirtyElements ) {
  1214. for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
  1215. faceArray[ offset_face ] = vertexIndex;
  1216. faceArray[ offset_face + 1 ] = vertexIndex + 1;
  1217. faceArray[ offset_face + 2 ] = vertexIndex + 2;
  1218. offset_face += 3;
  1219. lineArray[ offset_line ] = vertexIndex;
  1220. lineArray[ offset_line + 1 ] = vertexIndex + 1;
  1221. lineArray[ offset_line + 2 ] = vertexIndex;
  1222. lineArray[ offset_line + 3 ] = vertexIndex + 2;
  1223. lineArray[ offset_line + 4 ] = vertexIndex + 1;
  1224. lineArray[ offset_line + 5 ] = vertexIndex + 2;
  1225. offset_line += 6;
  1226. vertexIndex += 3;
  1227. }
  1228. _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglFaceBuffer );
  1229. _gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, faceArray, hint );
  1230. _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglLineBuffer );
  1231. _gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, lineArray, hint );
  1232. }
  1233. if ( customAttributes ) {
  1234. for ( i = 0, il = customAttributes.length; i < il; i ++ ) {
  1235. customAttribute = customAttributes[ i ];
  1236. if ( ! customAttribute.__original.needsUpdate ) continue;
  1237. offset_custom = 0;
  1238. offset_customSrc = 0;
  1239. if ( customAttribute.size === 1 ) {
  1240. if ( customAttribute.boundTo === undefined || customAttribute.boundTo === "vertices" ) {
  1241. for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
  1242. face = obj_faces[ chunk_faces3[ f ] ];
  1243. customAttribute.array[ offset_custom ] = customAttribute.value[ face.a ];
  1244. customAttribute.array[ offset_custom + 1 ] = customAttribute.value[ face.b ];
  1245. customAttribute.array[ offset_custom + 2 ] = customAttribute.value[ face.c ];
  1246. offset_custom += 3;
  1247. }
  1248. } else if ( customAttribute.boundTo === "faces" ) {
  1249. for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
  1250. value = customAttribute.value[ chunk_faces3[ f ] ];
  1251. customAttribute.array[ offset_custom ] = value;
  1252. customAttribute.array[ offset_custom + 1 ] = value;
  1253. customAttribute.array[ offset_custom + 2 ] = value;
  1254. offset_custom += 3;
  1255. }
  1256. }
  1257. } else if ( customAttribute.size === 2 ) {
  1258. if ( customAttribute.boundTo === undefined || customAttribute.boundTo === "vertices" ) {
  1259. for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
  1260. face = obj_faces[ chunk_faces3[ f ] ];
  1261. v1 = customAttribute.value[ face.a ];
  1262. v2 = customAttribute.value[ face.b ];
  1263. v3 = customAttribute.value[ face.c ];
  1264. customAttribute.array[ offset_custom ] = v1.x;
  1265. customAttribute.array[ offset_custom + 1 ] = v1.y;
  1266. customAttribute.array[ offset_custom + 2 ] = v2.x;
  1267. customAttribute.array[ offset_custom + 3 ] = v2.y;
  1268. customAttribute.array[ offset_custom + 4 ] = v3.x;
  1269. customAttribute.array[ offset_custom + 5 ] = v3.y;
  1270. offset_custom += 6;
  1271. }
  1272. } else if ( customAttribute.boundTo === "faces" ) {
  1273. for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
  1274. value = customAttribute.value[ chunk_faces3[ f ] ];
  1275. v1 = value;
  1276. v2 = value;
  1277. v3 = value;
  1278. customAttribute.array[ offset_custom ] = v1.x;
  1279. customAttribute.array[ offset_custom + 1 ] = v1.y;
  1280. customAttribute.array[ offset_custom + 2 ] = v2.x;
  1281. customAttribute.array[ offset_custom + 3 ] = v2.y;
  1282. customAttribute.array[ offset_custom + 4 ] = v3.x;
  1283. customAttribute.array[ offset_custom + 5 ] = v3.y;
  1284. offset_custom += 6;
  1285. }
  1286. }
  1287. } else if ( customAttribute.size === 3 ) {
  1288. var pp;
  1289. if ( customAttribute.type === "c" ) {
  1290. pp = [ "r", "g", "b" ];
  1291. } else {
  1292. pp = [ "x", "y", "z" ];
  1293. }
  1294. if ( customAttribute.boundTo === undefined || customAttribute.boundTo === "vertices" ) {
  1295. for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
  1296. face = obj_faces[ chunk_faces3[ f ] ];
  1297. v1 = customAttribute.value[ face.a ];
  1298. v2 = customAttribute.value[ face.b ];
  1299. v3 = customAttribute.value[ face.c ];
  1300. customAttribute.array[ offset_custom ] = v1[ pp[ 0 ] ];
  1301. customAttribute.array[ offset_custom + 1 ] = v1[ pp[ 1 ] ];
  1302. customAttribute.array[ offset_custom + 2 ] = v1[ pp[ 2 ] ];
  1303. customAttribute.array[ offset_custom + 3 ] = v2[ pp[ 0 ] ];
  1304. customAttribute.array[ offset_custom + 4 ] = v2[ pp[ 1 ] ];
  1305. customAttribute.array[ offset_custom + 5 ] = v2[ pp[ 2 ] ];
  1306. customAttribute.array[ offset_custom + 6 ] = v3[ pp[ 0 ] ];
  1307. customAttribute.array[ offset_custom + 7 ] = v3[ pp[ 1 ] ];
  1308. customAttribute.array[ offset_custom + 8 ] = v3[ pp[ 2 ] ];
  1309. offset_custom += 9;
  1310. }
  1311. } else if ( customAttribute.boundTo === "faces" ) {
  1312. for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
  1313. value = customAttribute.value[ chunk_faces3[ f ] ];
  1314. v1 = value;
  1315. v2 = value;
  1316. v3 = value;
  1317. customAttribute.array[ offset_custom ] = v1[ pp[ 0 ] ];
  1318. customAttribute.array[ offset_custom + 1 ] = v1[ pp[ 1 ] ];
  1319. customAttribute.array[ offset_custom + 2 ] = v1[ pp[ 2 ] ];
  1320. customAttribute.array[ offset_custom + 3 ] = v2[ pp[ 0 ] ];
  1321. customAttribute.array[ offset_custom + 4 ] = v2[ pp[ 1 ] ];
  1322. customAttribute.array[ offset_custom + 5 ] = v2[ pp[ 2 ] ];
  1323. customAttribute.array[ offset_custom + 6 ] = v3[ pp[ 0 ] ];
  1324. customAttribute.array[ offset_custom + 7 ] = v3[ pp[ 1 ] ];
  1325. customAttribute.array[ offset_custom + 8 ] = v3[ pp[ 2 ] ];
  1326. offset_custom += 9;
  1327. }
  1328. } else if ( customAttribute.boundTo === "faceVertices" ) {
  1329. for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
  1330. value = customAttribute.value[ chunk_faces3[ f ] ];
  1331. v1 = value[ 0 ];
  1332. v2 = value[ 1 ];
  1333. v3 = value[ 2 ];
  1334. customAttribute.array[ offset_custom ] = v1[ pp[ 0 ] ];
  1335. customAttribute.array[ offset_custom + 1 ] = v1[ pp[ 1 ] ];
  1336. customAttribute.array[ offset_custom + 2 ] = v1[ pp[ 2 ] ];
  1337. customAttribute.array[ offset_custom + 3 ] = v2[ pp[ 0 ] ];
  1338. customAttribute.array[ offset_custom + 4 ] = v2[ pp[ 1 ] ];
  1339. customAttribute.array[ offset_custom + 5 ] = v2[ pp[ 2 ] ];
  1340. customAttribute.array[ offset_custom + 6 ] = v3[ pp[ 0 ] ];
  1341. customAttribute.array[ offset_custom + 7 ] = v3[ pp[ 1 ] ];
  1342. customAttribute.array[ offset_custom + 8 ] = v3[ pp[ 2 ] ];
  1343. offset_custom += 9;
  1344. }
  1345. }
  1346. } else if ( customAttribute.size === 4 ) {
  1347. if ( customAttribute.boundTo === undefined || customAttribute.boundTo === "vertices" ) {
  1348. for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
  1349. face = obj_faces[ chunk_faces3[ f ] ];
  1350. v1 = customAttribute.value[ face.a ];
  1351. v2 = customAttribute.value[ face.b ];
  1352. v3 = customAttribute.value[ face.c ];
  1353. customAttribute.array[ offset_custom ] = v1.x;
  1354. customAttribute.array[ offset_custom + 1 ] = v1.y;
  1355. customAttribute.array[ offset_custom + 2 ] = v1.z;
  1356. customAttribute.array[ offset_custom + 3 ] = v1.w;
  1357. customAttribute.array[ offset_custom + 4 ] = v2.x;
  1358. customAttribute.array[ offset_custom + 5 ] = v2.y;
  1359. customAttribute.array[ offset_custom + 6 ] = v2.z;
  1360. customAttribute.array[ offset_custom + 7 ] = v2.w;
  1361. customAttribute.array[ offset_custom + 8 ] = v3.x;
  1362. customAttribute.array[ offset_custom + 9 ] = v3.y;
  1363. customAttribute.array[ offset_custom + 10 ] = v3.z;
  1364. customAttribute.array[ offset_custom + 11 ] = v3.w;
  1365. offset_custom += 12;
  1366. }
  1367. } else if ( customAttribute.boundTo === "faces" ) {
  1368. for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
  1369. value = customAttribute.value[ chunk_faces3[ f ] ];
  1370. v1 = value;
  1371. v2 = value;
  1372. v3 = value;
  1373. customAttribute.array[ offset_custom ] = v1.x;
  1374. customAttribute.array[ offset_custom + 1 ] = v1.y;
  1375. customAttribute.array[ offset_custom + 2 ] = v1.z;
  1376. customAttribute.array[ offset_custom + 3 ] = v1.w;
  1377. customAttribute.array[ offset_custom + 4 ] = v2.x;
  1378. customAttribute.array[ offset_custom + 5 ] = v2.y;
  1379. customAttribute.array[ offset_custom + 6 ] = v2.z;
  1380. customAttribute.array[ offset_custom + 7 ] = v2.w;
  1381. customAttribute.array[ offset_custom + 8 ] = v3.x;
  1382. customAttribute.array[ offset_custom + 9 ] = v3.y;
  1383. customAttribute.array[ offset_custom + 10 ] = v3.z;
  1384. customAttribute.array[ offset_custom + 11 ] = v3.w;
  1385. offset_custom += 12;
  1386. }
  1387. } else if ( customAttribute.boundTo === "faceVertices" ) {
  1388. for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
  1389. value = customAttribute.value[ chunk_faces3[ f ] ];
  1390. v1 = value[ 0 ];
  1391. v2 = value[ 1 ];
  1392. v3 = value[ 2 ];
  1393. customAttribute.array[ offset_custom ] = v1.x;
  1394. customAttribute.array[ offset_custom + 1 ] = v1.y;
  1395. customAttribute.array[ offset_custom + 2 ] = v1.z;
  1396. customAttribute.array[ offset_custom + 3 ] = v1.w;
  1397. customAttribute.array[ offset_custom + 4 ] = v2.x;
  1398. customAttribute.array[ offset_custom + 5 ] = v2.y;
  1399. customAttribute.array[ offset_custom + 6 ] = v2.z;
  1400. customAttribute.array[ offset_custom + 7 ] = v2.w;
  1401. customAttribute.array[ offset_custom + 8 ] = v3.x;
  1402. customAttribute.array[ offset_custom + 9 ] = v3.y;
  1403. customAttribute.array[ offset_custom + 10 ] = v3.z;
  1404. customAttribute.array[ offset_custom + 11 ] = v3.w;
  1405. offset_custom += 12;
  1406. }
  1407. }
  1408. }
  1409. _gl.bindBuffer( _gl.ARRAY_BUFFER, customAttribute.buffer );
  1410. _gl.bufferData( _gl.ARRAY_BUFFER, customAttribute.array, hint );
  1411. }
  1412. }
  1413. if ( dispose ) {
  1414. delete geometryGroup.__inittedArrays;
  1415. delete geometryGroup.__colorArray;
  1416. delete geometryGroup.__normalArray;
  1417. delete geometryGroup.__tangentArray;
  1418. delete geometryGroup.__uvArray;
  1419. delete geometryGroup.__uv2Array;
  1420. delete geometryGroup.__faceArray;
  1421. delete geometryGroup.__vertexArray;
  1422. delete geometryGroup.__lineArray;
  1423. delete geometryGroup.__skinIndexArray;
  1424. delete geometryGroup.__skinWeightArray;
  1425. }
  1426. };
  1427. // used by renderBufferDirect for THREE.Line
  1428. function setupLinesVertexAttributes( material, programAttributes, geometryAttributes, startIndex ) {
  1429. var attributeItem, attributeName, attributePointer, attributeSize;
  1430. for ( attributeName in programAttributes ) {
  1431. attributePointer = programAttributes[ attributeName ];
  1432. attributeItem = geometryAttributes[ attributeName ];
  1433. if ( attributePointer >= 0 ) {
  1434. if ( attributeItem ) {
  1435. attributeSize = attributeItem.itemSize;
  1436. _gl.bindBuffer( _gl.ARRAY_BUFFER, attributeItem.buffer );
  1437. enableAttribute( attributePointer );
  1438. _gl.vertexAttribPointer( attributePointer, attributeSize, _gl.FLOAT, false, 0, startIndex * attributeSize * 4 ); // 4 bytes per Float32
  1439. } else if ( material.defaultAttributeValues ) {
  1440. if ( material.defaultAttributeValues[ attributeName ].length === 2 ) {
  1441. _gl.vertexAttrib2fv( attributePointer, material.defaultAttributeValues[ attributeName ] );
  1442. } else if ( material.defaultAttributeValues[ attributeName ].length === 3 ) {
  1443. _gl.vertexAttrib3fv( attributePointer, material.defaultAttributeValues[ attributeName ] );
  1444. }
  1445. }
  1446. }
  1447. }
  1448. }
  1449. function setDirectBuffers( geometry, hint ) {
  1450. var attributes = geometry.attributes;
  1451. var attributeName, attributeItem;
  1452. for ( attributeName in attributes ) {
  1453. attributeItem = attributes[ attributeName ];
  1454. if ( attributeItem.needsUpdate ) {
  1455. if ( attributeName === 'index' ) {
  1456. _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, attributeItem.buffer );
  1457. _gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, attributeItem.array, hint );
  1458. } else {
  1459. _gl.bindBuffer( _gl.ARRAY_BUFFER, attributeItem.buffer );
  1460. _gl.bufferData( _gl.ARRAY_BUFFER, attributeItem.array, hint );
  1461. }
  1462. attributeItem.needsUpdate = false;
  1463. }
  1464. }
  1465. }
  1466. function setGeometry2Buffers( geometry, hint ) {
  1467. if ( geometry.needsUpdate === false ) return;
  1468. var attributes = [ 'vertices', 'normals', 'uvs' ];
  1469. var buffers = _buffers[ geometry.id ];
  1470. for ( var key in attributes ) {
  1471. var array = geometry[ attributes[ key ] ];
  1472. var buffer = buffers[ attributes[ key ] ];
  1473. _gl.bindBuffer( _gl.ARRAY_BUFFER, buffer );
  1474. _gl.bufferData( _gl.ARRAY_BUFFER, array, hint );
  1475. }
  1476. geometry.needsUpdate = false;
  1477. };
  1478. // Buffer rendering
  1479. this.renderBufferImmediate = function ( object, program, material ) {
  1480. if ( object.hasPositions && ! object.__webglVertexBuffer ) object.__webglVertexBuffer = _gl.createBuffer();
  1481. if ( object.hasNormals && ! object.__webglNormalBuffer ) object.__webglNormalBuffer = _gl.createBuffer();
  1482. if ( object.hasUvs && ! object.__webglUvBuffer ) object.__webglUvBuffer = _gl.createBuffer();
  1483. if ( object.hasColors && ! object.__webglColorBuffer ) object.__webglColorBuffer = _gl.createBuffer();
  1484. if ( object.hasPositions ) {
  1485. _gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webglVertexBuffer );
  1486. _gl.bufferData( _gl.ARRAY_BUFFER, object.positionArray, _gl.DYNAMIC_DRAW );
  1487. _gl.enableVertexAttribArray( program.attributes.position );
  1488. _gl.vertexAttribPointer( program.attributes.position, 3, _gl.FLOAT, false, 0, 0 );
  1489. }
  1490. if ( object.hasNormals ) {
  1491. _gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webglNormalBuffer );
  1492. if ( material.shading === THREE.FlatShading ) {
  1493. var nx, ny, nz,
  1494. nax, nbx, ncx, nay, nby, ncy, naz, nbz, ncz,
  1495. normalArray,
  1496. i, il = object.count * 3;
  1497. for( i = 0; i < il; i += 9 ) {
  1498. normalArray = object.normalArray;
  1499. nax = normalArray[ i ];
  1500. nay = normalArray[ i + 1 ];
  1501. naz = normalArray[ i + 2 ];
  1502. nbx = normalArray[ i + 3 ];
  1503. nby = normalArray[ i + 4 ];
  1504. nbz = normalArray[ i + 5 ];
  1505. ncx = normalArray[ i + 6 ];
  1506. ncy = normalArray[ i + 7 ];
  1507. ncz = normalArray[ i + 8 ];
  1508. nx = ( nax + nbx + ncx ) / 3;
  1509. ny = ( nay + nby + ncy ) / 3;
  1510. nz = ( naz + nbz + ncz ) / 3;
  1511. normalArray[ i ] = nx;
  1512. normalArray[ i + 1 ] = ny;
  1513. normalArray[ i + 2 ] = nz;
  1514. normalArray[ i + 3 ] = nx;
  1515. normalArray[ i + 4 ] = ny;
  1516. normalArray[ i + 5 ] = nz;
  1517. normalArray[ i + 6 ] = nx;
  1518. normalArray[ i + 7 ] = ny;
  1519. normalArray[ i + 8 ] = nz;
  1520. }
  1521. }
  1522. _gl.bufferData( _gl.ARRAY_BUFFER, object.normalArray, _gl.DYNAMIC_DRAW );
  1523. _gl.enableVertexAttribArray( program.attributes.normal );
  1524. _gl.vertexAttribPointer( program.attributes.normal, 3, _gl.FLOAT, false, 0, 0 );
  1525. }
  1526. if ( object.hasUvs && material.map ) {
  1527. _gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webglUvBuffer );
  1528. _gl.bufferData( _gl.ARRAY_BUFFER, object.uvArray, _gl.DYNAMIC_DRAW );
  1529. _gl.enableVertexAttribArray( program.attributes.uv );
  1530. _gl.vertexAttribPointer( program.attributes.uv, 2, _gl.FLOAT, false, 0, 0 );
  1531. }
  1532. if ( object.hasColors && material.vertexColors !== THREE.NoColors ) {
  1533. _gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webglColorBuffer );
  1534. _gl.bufferData( _gl.ARRAY_BUFFER, object.colorArray, _gl.DYNAMIC_DRAW );
  1535. _gl.enableVertexAttribArray( program.attributes.color );
  1536. _gl.vertexAttribPointer( program.attributes.color, 3, _gl.FLOAT, false, 0, 0 );
  1537. }
  1538. _gl.drawArrays( _gl.TRIANGLES, 0, object.count );
  1539. object.count = 0;
  1540. };
  1541. this.renderBufferGeometry2 = function ( camera, lights, fog, material, geometry, object ) {
  1542. var program = setProgram( camera, lights, fog, material, object );
  1543. var programAttributes = program.attributes;
  1544. var attributes = { 'position': 'vertices', 'normal': 'normals', 'uv': 'uvs' };
  1545. var itemSizes = { 'position': 3, 'normal': 3, 'uv': 2 };
  1546. var buffers = _buffers[ geometry.id ];
  1547. disableAttributes();
  1548. for ( var name in programAttributes ) {
  1549. var attributePointer = programAttributes[ name ];
  1550. if ( attributePointer >= 0 ) {
  1551. var array = geometry[ attributes[ name ] ];
  1552. if ( array !== undefined && array.length > 0 ) {
  1553. _gl.bindBuffer( _gl.ARRAY_BUFFER, buffers[ attributes[ name ] ] );
  1554. enableAttribute( attributePointer );
  1555. _gl.vertexAttribPointer( attributePointer, itemSizes[ name ], _gl.FLOAT, false, 0, 0 );
  1556. } else {
  1557. if ( itemSizes[ name ] === 3 ) {
  1558. _gl.vertexAttrib3fv( attributePointer, [ 0, 0, 0 ] );
  1559. } else if ( itemSizes[ name ] === 2 ) {
  1560. _gl.vertexAttrib2fv( attributePointer, [ 0, 0 ] );
  1561. }
  1562. }
  1563. }
  1564. }
  1565. _gl.drawArrays( _gl.TRIANGLES, 0, geometry.vertices.length / 3 );
  1566. };
  1567. this.renderBufferDirect = function ( camera, lights, fog, material, geometry, object ) {
  1568. if ( material.visible === false ) return;
  1569. var linewidth, a, attribute;
  1570. var attributeItem, attributeName, attributePointer, attributeSize;
  1571. var program = setProgram( camera, lights, fog, material, object );
  1572. var programAttributes = program.attributes;
  1573. var geometryAttributes = geometry.attributes;
  1574. var updateBuffers = false,
  1575. wireframeBit = material.wireframe ? 1 : 0,
  1576. geometryHash = ( geometry.id * 0xffffff ) + ( program.id * 2 ) + wireframeBit;
  1577. if ( geometryHash !== _currentGeometryGroupHash ) {
  1578. _currentGeometryGroupHash = geometryHash;
  1579. updateBuffers = true;
  1580. }
  1581. if ( updateBuffers ) {
  1582. disableAttributes();
  1583. }
  1584. // render mesh
  1585. if ( object instanceof THREE.Mesh ) {
  1586. var index = geometryAttributes[ "index" ];
  1587. // indexed triangles
  1588. if ( index ) {
  1589. var offsets = geometry.offsets;
  1590. // if there is more than 1 chunk
  1591. // must set attribute pointers to use new offsets for each chunk
  1592. // even if geometry and materials didn't change
  1593. if ( offsets.length > 1 ) updateBuffers = true;
  1594. for ( var i = 0, il = offsets.length; i < il; i ++ ) {
  1595. var startIndex = offsets[ i ].index;
  1596. if ( updateBuffers ) {
  1597. for ( attributeName in programAttributes ) {
  1598. attributePointer = programAttributes[ attributeName ];
  1599. attributeItem = geometryAttributes[ attributeName ];
  1600. if ( attributePointer >= 0 ) {
  1601. if ( attributeItem ) {
  1602. attributeSize = attributeItem.itemSize;
  1603. _gl.bindBuffer( _gl.ARRAY_BUFFER, attributeItem.buffer );
  1604. enableAttribute( attributePointer );
  1605. _gl.vertexAttribPointer( attributePointer, attributeSize, _gl.FLOAT, false, 0, startIndex * attributeSize * 4 ); // 4 bytes per Float32
  1606. } else if ( material.defaultAttributeValues ) {
  1607. if ( material.defaultAttributeValues[ attributeName ].length === 2 ) {
  1608. _gl.vertexAttrib2fv( attributePointer, material.defaultAttributeValues[ attributeName ] );
  1609. } else if ( material.defaultAttributeValues[ attributeName ].length === 3 ) {
  1610. _gl.vertexAttrib3fv( attributePointer, material.defaultAttributeValues[ attributeName ] );
  1611. }
  1612. }
  1613. }
  1614. }
  1615. // indices
  1616. _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, index.buffer );
  1617. }
  1618. // render indexed triangles
  1619. _gl.drawElements( _gl.TRIANGLES, offsets[ i ].count, _gl.UNSIGNED_SHORT, offsets[ i ].start * 2 ); // 2 bytes per Uint16
  1620. _this.info.render.calls ++;
  1621. _this.info.render.vertices += offsets[ i ].count; // not really true, here vertices can be shared
  1622. _this.info.render.faces += offsets[ i ].count / 3;
  1623. }
  1624. // non-indexed triangles
  1625. } else {
  1626. if ( updateBuffers ) {
  1627. for ( attributeName in programAttributes ) {
  1628. if ( attributeName === 'index') continue;
  1629. attributePointer = programAttributes[ attributeName ];
  1630. attributeItem = geometryAttributes[ attributeName ];
  1631. if ( attributePointer >= 0 ) {
  1632. if ( attributeItem ) {
  1633. attributeSize = attributeItem.itemSize;
  1634. _gl.bindBuffer( _gl.ARRAY_BUFFER, attributeItem.buffer );
  1635. enableAttribute( attributePointer );
  1636. _gl.vertexAttribPointer( attributePointer, attributeSize, _gl.FLOAT, false, 0, 0 );
  1637. } else if ( material.defaultAttributeValues && material.defaultAttributeValues[ attributeName ] ) {
  1638. if ( material.defaultAttributeValues[ attributeName ].length === 2 ) {
  1639. _gl.vertexAttrib2fv( attributePointer, material.defaultAttributeValues[ attributeName ] );
  1640. } else if ( material.defaultAttributeValues[ attributeName ].length === 3 ) {
  1641. _gl.vertexAttrib3fv( attributePointer, material.defaultAttributeValues[ attributeName ] );
  1642. }
  1643. }
  1644. }
  1645. }
  1646. }
  1647. var position = geometry.attributes[ "position" ];
  1648. // render non-indexed triangles
  1649. _gl.drawArrays( _gl.TRIANGLES, 0, position.array.length / 3 );
  1650. _this.info.render.calls ++;
  1651. _this.info.render.vertices += position.array.length / 3;
  1652. _this.info.render.faces += position.array.length / 3 / 3;
  1653. }
  1654. // render particles
  1655. } else if ( object instanceof THREE.ParticleSystem ) {
  1656. if ( updateBuffers ) {
  1657. for ( attributeName in programAttributes ) {
  1658. attributePointer = programAttributes[ attributeName ];
  1659. attributeItem = geometryAttributes[ attributeName ];
  1660. if ( attributePointer >= 0 ) {
  1661. if ( attributeItem ) {
  1662. attributeSize = attributeItem.itemSize;
  1663. _gl.bindBuffer( _gl.ARRAY_BUFFER, attributeItem.buffer );
  1664. enableAttribute( attributePointer );
  1665. _gl.vertexAttribPointer( attributePointer, attributeSize, _gl.FLOAT, false, 0, 0 );
  1666. } else if ( material.defaultAttributeValues && material.defaultAttributeValues[ attributeName ] ) {
  1667. if ( material.defaultAttributeValues[ attributeName ].length === 2 ) {
  1668. _gl.vertexAttrib2fv( attributePointer, material.defaultAttributeValues[ attributeName ] );
  1669. } else if ( material.defaultAttributeValues[ attributeName ].length === 3 ) {
  1670. _gl.vertexAttrib3fv( attributePointer, material.defaultAttributeValues[ attributeName ] );
  1671. }
  1672. }
  1673. }
  1674. }
  1675. }
  1676. var position = geometryAttributes[ "position" ];
  1677. // render particles
  1678. _gl.drawArrays( _gl.POINTS, 0, position.array.length / 3 );
  1679. _this.info.render.calls ++;
  1680. _this.info.render.points += position.array.length / 3;
  1681. } else if ( object instanceof THREE.Line ) {
  1682. var primitives = ( object.type === THREE.LineStrip ) ? _gl.LINE_STRIP : _gl.LINES;
  1683. setLineWidth( material.linewidth );
  1684. var index = geometryAttributes[ "index" ];
  1685. // indexed lines
  1686. if ( index ) {
  1687. var offsets = geometry.offsets;
  1688. // if there is more than 1 chunk
  1689. // must set attribute pointers to use new offsets for each chunk
  1690. // even if geometry and materials didn't change
  1691. if ( offsets.length > 1 ) updateBuffers = true;
  1692. for ( var i = 0, il = offsets.length; i < il; i ++ ) {
  1693. var startIndex = offsets[ i ].index;
  1694. if ( updateBuffers ) {
  1695. setupLinesVertexAttributes(material, programAttributes, geometryAttributes, startIndex);
  1696. // indices
  1697. _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, index.buffer );
  1698. }
  1699. // render indexed lines
  1700. _gl.drawElements( _gl.LINES, offsets[ i ].count, _gl.UNSIGNED_SHORT, offsets[ i ].start * 2 ); // 2 bytes per Uint16Array
  1701. _this.info.render.calls ++;
  1702. _this.info.render.vertices += offsets[ i ].count; // not really true, here vertices can be shared
  1703. }
  1704. }
  1705. // non-indexed lines
  1706. else {
  1707. if ( updateBuffers ) {
  1708. setupLinesVertexAttributes(material, programAttributes, geometryAttributes, 0);
  1709. }
  1710. var position = geometryAttributes[ "position" ];
  1711. _gl.drawArrays( primitives, 0, position.array.length / 3 );
  1712. _this.info.render.calls ++;
  1713. _this.info.render.points += position.array.length;
  1714. }
  1715. }
  1716. };
  1717. this.renderBuffer = function ( camera, lights, fog, material, geometryGroup, object ) {
  1718. if ( material.visible === false ) return;
  1719. var linewidth, a, attribute, i, il;
  1720. var program = setProgram( camera, lights, fog, material, object );
  1721. var attributes = program.attributes;
  1722. var updateBuffers = false,
  1723. wireframeBit = material.wireframe ? 1 : 0,
  1724. geometryGroupHash = ( geometryGroup.id * 0xffffff ) + ( program.id * 2 ) + wireframeBit;
  1725. if ( geometryGroupHash !== _currentGeometryGroupHash ) {
  1726. _currentGeometryGroupHash = geometryGroupHash;
  1727. updateBuffers = true;
  1728. }
  1729. if ( updateBuffers ) {
  1730. disableAttributes();
  1731. }
  1732. // vertices
  1733. if ( !material.morphTargets && attributes.position >= 0 ) {
  1734. if ( updateBuffers ) {
  1735. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer );
  1736. enableAttribute( attributes.position );
  1737. _gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
  1738. }
  1739. } else {
  1740. if ( object.morphTargetBase ) {
  1741. setupMorphTargets( material, geometryGroup, object );
  1742. }
  1743. }
  1744. if ( updateBuffers ) {
  1745. // custom attributes
  1746. // Use the per-geometryGroup custom attribute arrays which are setup in initMeshBuffers
  1747. if ( geometryGroup.__webglCustomAttributesList ) {
  1748. for ( i = 0, il = geometryGroup.__webglCustomAttributesList.length; i < il; i ++ ) {
  1749. attribute = geometryGroup.__webglCustomAttributesList[ i ];
  1750. if ( attributes[ attribute.buffer.belongsToAttribute ] >= 0 ) {
  1751. _gl.bindBuffer( _gl.ARRAY_BUFFER, attribute.buffer );
  1752. enableAttribute( attributes[ attribute.buffer.belongsToAttribute ] );
  1753. _gl.vertexAttribPointer( attributes[ attribute.buffer.belongsToAttribute ], attribute.size, _gl.FLOAT, false, 0, 0 );
  1754. }
  1755. }
  1756. }
  1757. // colors
  1758. if ( attributes.color >= 0 ) {
  1759. if ( object.geometry.colors.length > 0 || object.geometry.faces.length > 0 ) {
  1760. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglColorBuffer );
  1761. enableAttribute( attributes.color );
  1762. _gl.vertexAttribPointer( attributes.color, 3, _gl.FLOAT, false, 0, 0 );
  1763. } else if ( material.defaultAttributeValues ) {
  1764. _gl.vertexAttrib3fv( attributes.color, material.defaultAttributeValues.color );
  1765. }
  1766. }
  1767. // normals
  1768. if ( attributes.normal >= 0 ) {
  1769. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglNormalBuffer );
  1770. enableAttribute( attributes.normal );
  1771. _gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );
  1772. }
  1773. // tangents
  1774. if ( attributes.tangent >= 0 ) {
  1775. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglTangentBuffer );
  1776. enableAttribute( attributes.tangent );
  1777. _gl.vertexAttribPointer( attributes.tangent, 4, _gl.FLOAT, false, 0, 0 );
  1778. }
  1779. // uvs
  1780. if ( attributes.uv >= 0 ) {
  1781. if ( object.geometry.faceVertexUvs[0] ) {
  1782. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUVBuffer );
  1783. enableAttribute( attributes.uv );
  1784. _gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );
  1785. } else if ( material.defaultAttributeValues ) {
  1786. _gl.vertexAttrib2fv( attributes.uv, material.defaultAttributeValues.uv );
  1787. }
  1788. }
  1789. if ( attributes.uv2 >= 0 ) {
  1790. if ( object.geometry.faceVertexUvs[1] ) {
  1791. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUV2Buffer );
  1792. enableAttribute( attributes.uv2 );
  1793. _gl.vertexAttribPointer( attributes.uv2, 2, _gl.FLOAT, false, 0, 0 );
  1794. } else if ( material.defaultAttributeValues ) {
  1795. _gl.vertexAttrib2fv( attributes.uv2, material.defaultAttributeValues.uv2 );
  1796. }
  1797. }
  1798. if ( material.skinning &&
  1799. attributes.skinIndex >= 0 && attributes.skinWeight >= 0 ) {
  1800. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinIndicesBuffer );
  1801. enableAttribute( attributes.skinIndex );
  1802. _gl.vertexAttribPointer( attributes.skinIndex, 4, _gl.FLOAT, false, 0, 0 );
  1803. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinWeightsBuffer );
  1804. enableAttribute( attributes.skinWeight );
  1805. _gl.vertexAttribPointer( attributes.skinWeight, 4, _gl.FLOAT, false, 0, 0 );
  1806. }
  1807. // line distances
  1808. if ( attributes.lineDistance >= 0 ) {
  1809. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglLineDistanceBuffer );
  1810. enableAttribute( attributes.lineDistance );
  1811. _gl.vertexAttribPointer( attributes.lineDistance, 1, _gl.FLOAT, false, 0, 0 );
  1812. }
  1813. }
  1814. // render mesh
  1815. if ( object instanceof THREE.Mesh ) {
  1816. // wireframe
  1817. if ( material.wireframe ) {
  1818. setLineWidth( material.wireframeLinewidth );
  1819. if ( updateBuffers ) _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglLineBuffer );
  1820. _gl.drawElements( _gl.LINES, geometryGroup.__webglLineCount, _gl.UNSIGNED_SHORT, 0 );
  1821. // triangles
  1822. } else {
  1823. if ( updateBuffers ) _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglFaceBuffer );
  1824. _gl.drawElements( _gl.TRIANGLES, geometryGroup.__webglFaceCount, _gl.UNSIGNED_SHORT, 0 );
  1825. }
  1826. _this.info.render.calls ++;
  1827. _this.info.render.vertices += geometryGroup.__webglFaceCount;
  1828. _this.info.render.faces += geometryGroup.__webglFaceCount / 3;
  1829. // render lines
  1830. } else if ( object instanceof THREE.Line ) {
  1831. var primitives = ( object.type === THREE.LineStrip ) ? _gl.LINE_STRIP : _gl.LINES;
  1832. setLineWidth( material.linewidth );
  1833. _gl.drawArrays( primitives, 0, geometryGroup.__webglLineCount );
  1834. _this.info.render.calls ++;
  1835. // render particles
  1836. } else if ( object instanceof THREE.ParticleSystem ) {
  1837. _gl.drawArrays( _gl.POINTS, 0, geometryGroup.__webglParticleCount );
  1838. _this.info.render.calls ++;
  1839. _this.info.render.points += geometryGroup.__webglParticleCount;
  1840. }
  1841. };
  1842. function enableAttribute( attribute ) {
  1843. if ( _enabledAttributes[ attribute ] === 0 ) {
  1844. _gl.enableVertexAttribArray( attribute );
  1845. _enabledAttributes[ attribute ] = 1;
  1846. }
  1847. };
  1848. function disableAttributes() {
  1849. for ( var attribute in _enabledAttributes ) {
  1850. if ( _enabledAttributes[ attribute ] === 1 ) {
  1851. _gl.disableVertexAttribArray( attribute );
  1852. _enabledAttributes[ attribute ] = 0;
  1853. }
  1854. }
  1855. };
  1856. function setupMorphTargets ( material, geometryGroup, object ) {
  1857. // set base
  1858. var attributes = material.program.attributes;
  1859. if ( object.morphTargetBase !== -1 && attributes.position >= 0 ) {
  1860. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ object.morphTargetBase ] );
  1861. enableAttribute( attributes.position );
  1862. _gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
  1863. } else if ( attributes.position >= 0 ) {
  1864. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer );
  1865. enableAttribute( attributes.position );
  1866. _gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
  1867. }
  1868. if ( object.morphTargetForcedOrder.length ) {
  1869. // set forced order
  1870. var m = 0;
  1871. var order = object.morphTargetForcedOrder;
  1872. var influences = object.morphTargetInfluences;
  1873. while ( m < material.numSupportedMorphTargets && m < order.length ) {
  1874. if ( attributes[ "morphTarget" + m ] >= 0 ) {
  1875. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ order[ m ] ] );
  1876. enableAttribute( attributes[ "morphTarget" + m ] );
  1877. _gl.vertexAttribPointer( attributes[ "morphTarget" + m ], 3, _gl.FLOAT, false, 0, 0 );
  1878. }
  1879. if ( attributes[ "morphNormal" + m ] >= 0 && material.morphNormals ) {
  1880. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphNormalsBuffers[ order[ m ] ] );
  1881. enableAttribute( attributes[ "morphNormal" + m ] );
  1882. _gl.vertexAttribPointer( attributes[ "morphNormal" + m ], 3, _gl.FLOAT, false, 0, 0 );
  1883. }
  1884. object.__webglMorphTargetInfluences[ m ] = influences[ order[ m ] ];
  1885. m ++;
  1886. }
  1887. } else {
  1888. // find the most influencing
  1889. var influence, activeInfluenceIndices = [];
  1890. var influences = object.morphTargetInfluences;
  1891. var i, il = influences.length;
  1892. for ( i = 0; i < il; i ++ ) {
  1893. influence = influences[ i ];
  1894. if ( influence > 0 ) {
  1895. activeInfluenceIndices.push( [ influence, i ] );
  1896. }
  1897. }
  1898. if ( activeInfluenceIndices.length > material.numSupportedMorphTargets ) {
  1899. activeInfluenceIndices.sort( numericalSort );
  1900. activeInfluenceIndices.length = material.numSupportedMorphTargets;
  1901. } else if ( activeInfluenceIndices.length > material.numSupportedMorphNormals ) {
  1902. activeInfluenceIndices.sort( numericalSort );
  1903. } else if ( activeInfluenceIndices.length === 0 ) {
  1904. activeInfluenceIndices.push( [ 0, 0 ] );
  1905. };
  1906. var influenceIndex, m = 0;
  1907. while ( m < material.numSupportedMorphTargets ) {
  1908. if ( activeInfluenceIndices[ m ] ) {
  1909. influenceIndex = activeInfluenceIndices[ m ][ 1 ];
  1910. if ( attributes[ "morphTarget" + m ] >= 0 ) {
  1911. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ influenceIndex ] );
  1912. enableAttribute( attributes[ "morphTarget" + m ] );
  1913. _gl.vertexAttribPointer( attributes[ "morphTarget" + m ], 3, _gl.FLOAT, false, 0, 0 );
  1914. }
  1915. if ( attributes[ "morphNormal" + m ] >= 0 && material.morphNormals ) {
  1916. _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphNormalsBuffers[ influenceIndex ] );
  1917. enableAttribute( attributes[ "morphNormal" + m ] );
  1918. _gl.vertexAttribPointer( attributes[ "morphNormal" + m ], 3, _gl.FLOAT, false, 0, 0 );
  1919. }
  1920. object.__webglMorphTargetInfluences[ m ] = influences[ influenceIndex ];
  1921. } else {
  1922. /*
  1923. _gl.vertexAttribPointer( attributes[ "morphTarget" + m ], 3, _gl.FLOAT, false, 0, 0 );
  1924. if ( material.morphNormals ) {
  1925. _gl.vertexAttribPointer( attributes[ "morphNormal" + m ], 3, _gl.FLOAT, false, 0, 0 );
  1926. }
  1927. */
  1928. object.__webglMorphTargetInfluences[ m ] = 0;
  1929. }
  1930. m ++;
  1931. }
  1932. }
  1933. // load updated influences uniform
  1934. if ( material.program.uniforms.morphTargetInfluences !== null ) {
  1935. _gl.uniform1fv( material.program.uniforms.morphTargetInfluences, object.__webglMorphTargetInfluences );
  1936. }
  1937. };
  1938. // Sorting
  1939. function painterSortStable ( a, b ) {
  1940. if ( a.z !== b.z ) {
  1941. return b.z - a.z;
  1942. } else {
  1943. return a.id - b.id;
  1944. }
  1945. };
  1946. function numericalSort ( a, b ) {
  1947. return b[ 0 ] - a[ 0 ];
  1948. };
  1949. // Rendering
  1950. this.render = function ( scene, camera, renderTarget, forceClear ) {
  1951. if ( camera instanceof THREE.Camera === false ) {
  1952. console.error( 'THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.' );
  1953. return;
  1954. }
  1955. var i, il,
  1956. webglObject, object,
  1957. renderList,
  1958. lights = scene.__lights,
  1959. fog = scene.fog;
  1960. // reset caching for this frame
  1961. _currentMaterialId = -1;
  1962. _lightsNeedUpdate = true;
  1963. // update scene graph
  1964. if ( scene.autoUpdate === true ) scene.updateMatrixWorld();
  1965. // update camera matrices and frustum
  1966. if ( camera.parent === undefined ) camera.updateMatrixWorld();
  1967. camera.matrixWorldInverse.getInverse( camera.matrixWorld );
  1968. _projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );
  1969. _frustum.setFromMatrix( _projScreenMatrix );
  1970. // update WebGL objects
  1971. if ( this.autoUpdateObjects ) this.initWebGLObjects( scene );
  1972. // custom render plugins (pre pass)
  1973. renderPlugins( this.renderPluginsPre, scene, camera );
  1974. //
  1975. _this.info.render.calls = 0;
  1976. _this.info.render.vertices = 0;
  1977. _this.info.render.faces = 0;
  1978. _this.info.render.points = 0;
  1979. this.setRenderTarget( renderTarget );
  1980. if ( this.autoClear || forceClear ) {
  1981. this.clear( this.autoClearColor, this.autoClearDepth, this.autoClearStencil );
  1982. }
  1983. // set matrices for regular objects (frustum culled)
  1984. renderList = scene.__webglObjects;
  1985. for ( i = 0, il = renderList.length; i < il; i ++ ) {
  1986. webglObject = renderList[ i ];
  1987. object = webglObject.object;
  1988. webglObject.id = i;
  1989. webglObject.render = false;
  1990. if ( object.visible ) {
  1991. if ( ! ( object instanceof THREE.Mesh || object instanceof THREE.ParticleSystem ) || ! ( object.frustumCulled ) || _frustum.intersectsObject( object ) ) {
  1992. setupMatrices( object, camera );
  1993. unrollBufferMaterial( webglObject );
  1994. webglObject.render = true;
  1995. if ( this.sortObjects === true ) {
  1996. if ( object.renderDepth !== null ) {
  1997. webglObject.z = object.renderDepth;
  1998. } else {
  1999. _vector3.setFromMatrixPosition( object.matrixWorld );
  2000. _vector3.applyProjection( _projScreenMatrix );
  2001. webglObject.z = _vector3.z;
  2002. }
  2003. }
  2004. }
  2005. }
  2006. }
  2007. if ( this.sortObjects ) {
  2008. renderList.sort( painterSortStable );
  2009. }
  2010. // set matrices for immediate objects
  2011. renderList = scene.__webglObjectsImmediate;
  2012. for ( i = 0, il = renderList.length; i < il; i ++ ) {
  2013. webglObject = renderList[ i ];
  2014. object = webglObject.object;
  2015. if ( object.visible ) {
  2016. setupMatrices( object, camera );
  2017. unrollImmediateBufferMaterial( webglObject );
  2018. }
  2019. }
  2020. if ( scene.overrideMaterial ) {
  2021. var material = scene.overrideMaterial;
  2022. this.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst );
  2023. this.setDepthTest( material.depthTest );
  2024. this.setDepthWrite( material.depthWrite );
  2025. setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );
  2026. renderObjects( scene.__webglObjects, false, "", camera, lights, fog, true, material );
  2027. renderObjectsImmediate( scene.__webglObjectsImmediate, "", camera, lights, fog, false, material );
  2028. } else {
  2029. var material = null;
  2030. // opaque pass (front-to-back order)
  2031. this.setBlending( THREE.NoBlending );
  2032. renderObjects( scene.__webglObjects, true, "opaque", camera, lights, fog, false, material );
  2033. renderObjectsImmediate( scene.__webglObjectsImmediate, "opaque", camera, lights, fog, false, material );
  2034. // transparent pass (back-to-front order)
  2035. renderObjects( scene.__webglObjects, false, "transparent", camera, lights, fog, true, material );
  2036. renderObjectsImmediate( scene.__webglObjectsImmediate, "transparent", camera, lights, fog, true, material );
  2037. }
  2038. // custom render plugins (post pass)
  2039. renderPlugins( this.renderPluginsPost, scene, camera );
  2040. // Generate mipmap if we're using any kind of mipmap filtering
  2041. if ( renderTarget && renderTarget.generateMipmaps && renderTarget.minFilter !== THREE.NearestFilter && renderTarget.minFilter !== THREE.LinearFilter ) {
  2042. updateRenderTargetMipmap( renderTarget );
  2043. }
  2044. // Ensure depth buffer writing is enabled so it can be cleared on next render
  2045. this.setDepthTest( true );
  2046. this.setDepthWrite( true );
  2047. // _gl.finish();
  2048. };
  2049. function renderPlugins( plugins, scene, camera ) {
  2050. if ( ! plugins.length ) return;
  2051. for ( var i = 0, il = plugins.length; i < il; i ++ ) {
  2052. // reset state for plugin (to start from clean slate)
  2053. _currentProgram = null;
  2054. _currentCamera = null;
  2055. _oldBlending = -1;
  2056. _oldDepthTest = -1;
  2057. _oldDepthWrite = -1;
  2058. _oldDoubleSided = -1;
  2059. _oldFlipSided = -1;
  2060. _currentGeometryGroupHash = -1;
  2061. _currentMaterialId = -1;
  2062. _lightsNeedUpdate = true;
  2063. plugins[ i ].render( scene, camera, _currentWidth, _currentHeight );
  2064. // reset state after plugin (anything could have changed)
  2065. _currentProgram = null;
  2066. _currentCamera = null;
  2067. _oldBlending = -1;
  2068. _oldDepthTest = -1;
  2069. _oldDepthWrite = -1;
  2070. _oldDoubleSided = -1;
  2071. _oldFlipSided = -1;
  2072. _currentGeometryGroupHash = -1;
  2073. _currentMaterialId = -1;
  2074. _lightsNeedUpdate = true;
  2075. }
  2076. };
  2077. function renderObjects( renderList, reverse, materialType, camera, lights, fog, useBlending, overrideMaterial ) {
  2078. var webglObject, object, buffer, material, start, end, delta;
  2079. if ( reverse ) {
  2080. start = renderList.length - 1;
  2081. end = -1;
  2082. delta = -1;
  2083. } else {
  2084. start = 0;
  2085. end = renderList.length;
  2086. delta = 1;
  2087. }
  2088. for ( var i = start; i !== end; i += delta ) {
  2089. webglObject = renderList[ i ];
  2090. if ( webglObject.render ) {
  2091. object = webglObject.object;
  2092. buffer = webglObject.buffer;
  2093. if ( overrideMaterial ) {
  2094. material = overrideMaterial;
  2095. } else {
  2096. material = webglObject[ materialType ];
  2097. if ( ! material ) continue;
  2098. if ( useBlending ) _this.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst );
  2099. _this.setDepthTest( material.depthTest );
  2100. _this.setDepthWrite( material.depthWrite );
  2101. setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );
  2102. }
  2103. _this.setMaterialFaces( material );
  2104. if ( buffer instanceof THREE.BufferGeometry ) {
  2105. _this.renderBufferDirect( camera, lights, fog, material, buffer, object );
  2106. } else if ( buffer instanceof THREE.Geometry2 ) {
  2107. _this.renderBufferGeometry2( camera, lights, fog, material, buffer, object );
  2108. } else {
  2109. _this.renderBuffer( camera, lights, fog, material, buffer, object );
  2110. }
  2111. }
  2112. }
  2113. };
  2114. function renderObjectsImmediate ( renderList, materialType, camera, lights, fog, useBlending, overrideMaterial ) {
  2115. var webglObject, object, material, program;
  2116. for ( var i = 0, il = renderList.length; i < il; i ++ ) {
  2117. webglObject = renderList[ i ];
  2118. object = webglObject.object;
  2119. if ( object.visible ) {
  2120. if ( overrideMaterial ) {
  2121. material = overrideMaterial;
  2122. } else {
  2123. material = webglObject[ materialType ];
  2124. if ( ! material ) continue;
  2125. if ( useBlending ) _this.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst );
  2126. _this.setDepthTest( material.depthTest );
  2127. _this.setDepthWrite( material.depthWrite );
  2128. setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );
  2129. }
  2130. _this.renderImmediateObject( camera, lights, fog, material, object );
  2131. }
  2132. }
  2133. };
  2134. this.renderImmediateObject = function ( camera, lights, fog, material, object ) {
  2135. var program = setProgram( camera, lights, fog, material, object );
  2136. _currentGeometryGroupHash = -1;
  2137. _this.setMaterialFaces( material );
  2138. if ( object.immediateRenderCallback ) {
  2139. object.immediateRenderCallback( program, _gl, _frustum );
  2140. } else {
  2141. object.render( function( object ) { _this.renderBufferImmediate( object, program, material ); } );
  2142. }
  2143. };
  2144. function unrollImmediateBufferMaterial ( globject ) {
  2145. var object = globject.object,
  2146. material = object.material;
  2147. if ( material.transparent ) {
  2148. globject.transparent = material;
  2149. globject.opaque = null;
  2150. } else {
  2151. globject.opaque = material;
  2152. globject.transparent = null;
  2153. }
  2154. };
  2155. function unrollBufferMaterial ( globject ) {
  2156. var object = globject.object;
  2157. var buffer = globject.buffer;
  2158. var geometry = object.geometry;
  2159. var material = object.material;
  2160. if ( material instanceof THREE.MeshFaceMaterial ) {
  2161. var materialIndex = geometry instanceof THREE.BufferGeometry ? 0 : buffer.materialIndex;
  2162. material = material.materials[ materialIndex ];
  2163. if ( material.transparent ) {
  2164. globject.transparent = material;
  2165. globject.opaque = null;
  2166. } else {
  2167. globject.opaque = material;
  2168. globject.transparent = null;
  2169. }
  2170. } else {
  2171. if ( material ) {
  2172. if ( material.transparent ) {
  2173. globject.transparent = material;
  2174. globject.opaque = null;
  2175. } else {
  2176. globject.opaque = material;
  2177. globject.transparent = null;
  2178. }
  2179. }
  2180. }
  2181. };
  2182. // Geometry splitting
  2183. function sortFacesByMaterial ( geometry, material ) {
  2184. var f, fl, face, materialIndex, vertices,
  2185. groupHash, hash_map = {};
  2186. var numMorphTargets = geometry.morphTargets.length;
  2187. var numMorphNormals = geometry.morphNormals.length;
  2188. var usesFaceMaterial = material instanceof THREE.MeshFaceMaterial;
  2189. geometry.geometryGroups = {};
  2190. for ( f = 0, fl = geometry.faces.length; f < fl; f ++ ) {
  2191. face = geometry.faces[ f ];
  2192. materialIndex = usesFaceMaterial ? face.materialIndex : 0;
  2193. if ( hash_map[ materialIndex ] === undefined ) {
  2194. hash_map[ materialIndex ] = { 'hash': materialIndex, 'counter': 0 };
  2195. }
  2196. groupHash = hash_map[ materialIndex ].hash + '_' + hash_map[ materialIndex ].counter;
  2197. if ( geometry.geometryGroups[ groupHash ] === undefined ) {
  2198. geometry.geometryGroups[ groupHash ] = { 'faces3': [], 'materialIndex': materialIndex, 'vertices': 0, 'numMorphTargets': numMorphTargets, 'numMorphNormals': numMorphNormals };
  2199. }
  2200. vertices = 3;
  2201. if ( geometry.geometryGroups[ groupHash ].vertices + vertices > 65535 ) {
  2202. hash_map[ materialIndex ].counter += 1;
  2203. groupHash = hash_map[ materialIndex ].hash + '_' + hash_map[ materialIndex ].counter;
  2204. if ( geometry.geometryGroups[ groupHash ] === undefined ) {
  2205. geometry.geometryGroups[ groupHash ] = { 'faces3': [], 'materialIndex': materialIndex, 'vertices': 0, 'numMorphTargets': numMorphTargets, 'numMorphNormals': numMorphNormals };
  2206. }
  2207. }
  2208. geometry.geometryGroups[ groupHash ].faces3.push( f );
  2209. geometry.geometryGroups[ groupHash ].vertices += vertices;
  2210. }
  2211. geometry.geometryGroupsList = [];
  2212. for ( var g in geometry.geometryGroups ) {
  2213. geometry.geometryGroups[ g ].id = _geometryGroupCounter ++;
  2214. geometry.geometryGroupsList.push( geometry.geometryGroups[ g ] );
  2215. }
  2216. };
  2217. // Objects refresh
  2218. this.initWebGLObjects = function ( scene ) {
  2219. if ( !scene.__webglObjects ) {
  2220. scene.__webglObjects = [];
  2221. scene.__webglObjectsImmediate = [];
  2222. scene.__webglSprites = [];
  2223. scene.__webglFlares = [];
  2224. }
  2225. while ( scene.__objectsAdded.length ) {
  2226. addObject( scene.__objectsAdded[ 0 ], scene );
  2227. scene.__objectsAdded.splice( 0, 1 );
  2228. }
  2229. while ( scene.__objectsRemoved.length ) {
  2230. removeObject( scene.__objectsRemoved[ 0 ], scene );
  2231. scene.__objectsRemoved.splice( 0, 1 );
  2232. }
  2233. // update must be called after objects adding / removal
  2234. for ( var o = 0, ol = scene.__webglObjects.length; o < ol; o ++ ) {
  2235. var object = scene.__webglObjects[ o ].object;
  2236. // TODO: Remove this hack (WebGLRenderer refactoring)
  2237. if ( object.__webglInit === undefined ) {
  2238. if ( object.__webglActive !== undefined ) {
  2239. removeObject( object, scene );
  2240. }
  2241. addObject( object, scene );
  2242. }
  2243. updateObject( object );
  2244. }
  2245. };
  2246. // Objects adding
  2247. function addObject( object, scene ) {
  2248. var g, geometry, material, geometryGroup;
  2249. if ( object.__webglInit === undefined ) {
  2250. object.__webglInit = true;
  2251. object._modelViewMatrix = new THREE.Matrix4();
  2252. object._normalMatrix = new THREE.Matrix3();
  2253. if ( object.geometry !== undefined && object.geometry.__webglInit === undefined ) {
  2254. object.geometry.__webglInit = true;
  2255. object.geometry.addEventListener( 'dispose', onGeometryDispose );
  2256. }
  2257. geometry = object.geometry;
  2258. if ( geometry === undefined ) {
  2259. // fail silently for now
  2260. } else if ( geometry instanceof THREE.BufferGeometry ) {
  2261. initDirectBuffers( geometry );
  2262. } else if ( geometry instanceof THREE.Geometry2 ) {
  2263. initGeometry2Buffers( geometry );
  2264. } else if ( object instanceof THREE.Mesh ) {
  2265. material = object.material;
  2266. if ( geometry.geometryGroups === undefined ) {
  2267. sortFacesByMaterial( geometry, material );
  2268. }
  2269. // create separate VBOs per geometry chunk
  2270. for ( g in geometry.geometryGroups ) {
  2271. geometryGroup = geometry.geometryGroups[ g ];
  2272. // initialise VBO on the first access
  2273. if ( ! geometryGroup.__webglVertexBuffer ) {
  2274. createMeshBuffers( geometryGroup );
  2275. initMeshBuffers( geometryGroup, object );
  2276. geometry.verticesNeedUpdate = true;
  2277. geometry.morphTargetsNeedUpdate = true;
  2278. geometry.elementsNeedUpdate = true;
  2279. geometry.uvsNeedUpdate = true;
  2280. geometry.normalsNeedUpdate = true;
  2281. geometry.tangentsNeedUpdate = true;
  2282. geometry.colorsNeedUpdate = true;
  2283. }
  2284. }
  2285. } else if ( object instanceof THREE.Line ) {
  2286. if ( ! geometry.__webglVertexBuffer ) {
  2287. createLineBuffers( geometry );
  2288. initLineBuffers( geometry, object );
  2289. geometry.verticesNeedUpdate = true;
  2290. geometry.colorsNeedUpdate = true;
  2291. geometry.lineDistancesNeedUpdate = true;
  2292. }
  2293. } else if ( object instanceof THREE.ParticleSystem ) {
  2294. if ( ! geometry.__webglVertexBuffer ) {
  2295. createParticleBuffers( geometry );
  2296. initParticleBuffers( geometry, object );
  2297. geometry.verticesNeedUpdate = true;
  2298. geometry.colorsNeedUpdate = true;
  2299. }
  2300. }
  2301. }
  2302. if ( object.__webglActive === undefined ) {
  2303. if ( object instanceof THREE.Mesh ) {
  2304. geometry = object.geometry;
  2305. if ( geometry instanceof THREE.BufferGeometry ) {
  2306. addBuffer( scene.__webglObjects, geometry, object );
  2307. } else if ( geometry instanceof THREE.Geometry2 ) {
  2308. addBuffer( scene.__webglObjects, geometry, object );
  2309. } else if ( geometry instanceof THREE.Geometry ) {
  2310. for ( g in geometry.geometryGroups ) {
  2311. geometryGroup = geometry.geometryGroups[ g ];
  2312. addBuffer( scene.__webglObjects, geometryGroup, object );
  2313. }
  2314. }
  2315. } else if ( object instanceof THREE.Line ||
  2316. object instanceof THREE.ParticleSystem ) {
  2317. geometry = object.geometry;
  2318. addBuffer( scene.__webglObjects, geometry, object );
  2319. } else if ( object instanceof THREE.ImmediateRenderObject || object.immediateRenderCallback ) {
  2320. addBufferImmediate( scene.__webglObjectsImmediate, object );
  2321. } else if ( object instanceof THREE.Sprite ) {
  2322. scene.__webglSprites.push( object );
  2323. } else if ( object instanceof THREE.LensFlare ) {
  2324. scene.__webglFlares.push( object );
  2325. }
  2326. object.__webglActive = true;
  2327. }
  2328. };
  2329. function addBuffer( objlist, buffer, object ) {
  2330. objlist.push(
  2331. {
  2332. id: null,
  2333. buffer: buffer,
  2334. object: object,
  2335. opaque: null,
  2336. transparent: null,
  2337. z: 0
  2338. }
  2339. );
  2340. };
  2341. function addBufferImmediate( objlist, object ) {
  2342. objlist.push(
  2343. {
  2344. id: null,
  2345. object: object,
  2346. opaque: null,
  2347. transparent: null,
  2348. z: 0
  2349. }
  2350. );
  2351. };
  2352. // Objects updates
  2353. function updateObject( object ) {
  2354. var geometry = object.geometry,
  2355. geometryGroup, customAttributesDirty, material;
  2356. if ( geometry instanceof THREE.BufferGeometry ) {
  2357. setDirectBuffers( geometry, _gl.DYNAMIC_DRAW );
  2358. } else if ( geometry instanceof THREE.Geometry2 ) {
  2359. setGeometry2Buffers( geometry, _gl.DYNAMIC_DRAW );
  2360. } else if ( object instanceof THREE.Mesh ) {
  2361. // check all geometry groups
  2362. for( var i = 0, il = geometry.geometryGroupsList.length; i < il; i ++ ) {
  2363. geometryGroup = geometry.geometryGroupsList[ i ];
  2364. material = getBufferMaterial( object, geometryGroup );
  2365. if ( geometry.buffersNeedUpdate ) {
  2366. initMeshBuffers( geometryGroup, object );
  2367. }
  2368. customAttributesDirty = material.attributes && areCustomAttributesDirty( material );
  2369. if ( geometry.verticesNeedUpdate || geometry.morphTargetsNeedUpdate || geometry.elementsNeedUpdate ||
  2370. geometry.uvsNeedUpdate || geometry.normalsNeedUpdate ||
  2371. geometry.colorsNeedUpdate || geometry.tangentsNeedUpdate || customAttributesDirty ) {
  2372. setMeshBuffers( geometryGroup, object, _gl.DYNAMIC_DRAW, !geometry.dynamic, material );
  2373. }
  2374. }
  2375. geometry.verticesNeedUpdate = false;
  2376. geometry.morphTargetsNeedUpdate = false;
  2377. geometry.elementsNeedUpdate = false;
  2378. geometry.uvsNeedUpdate = false;
  2379. geometry.normalsNeedUpdate = false;
  2380. geometry.colorsNeedUpdate = false;
  2381. geometry.tangentsNeedUpdate = false;
  2382. geometry.buffersNeedUpdate = false;
  2383. material.attributes && clearCustomAttributes( material );
  2384. } else if ( object instanceof THREE.Line ) {
  2385. material = getBufferMaterial( object, geometry );
  2386. customAttributesDirty = material.attributes && areCustomAttributesDirty( material );
  2387. if ( geometry.verticesNeedUpdate || geometry.colorsNeedUpdate || geometry.lineDistancesNeedUpdate || customAttributesDirty ) {
  2388. setLineBuffers( geometry, _gl.DYNAMIC_DRAW );
  2389. }
  2390. geometry.verticesNeedUpdate = false;
  2391. geometry.colorsNeedUpdate = false;
  2392. geometry.lineDistancesNeedUpdate = false;
  2393. material.attributes && clearCustomAttributes( material );
  2394. } else if ( object instanceof THREE.ParticleSystem ) {
  2395. material = getBufferMaterial( object, geometry );
  2396. customAttributesDirty = material.attributes && areCustomAttributesDirty( material );
  2397. if ( geometry.verticesNeedUpdate || geometry.colorsNeedUpdate || object.sortParticles || customAttributesDirty ) {
  2398. setParticleBuffers( geometry, _gl.DYNAMIC_DRAW, object );
  2399. }
  2400. geometry.verticesNeedUpdate = false;
  2401. geometry.colorsNeedUpdate = false;
  2402. material.attributes && clearCustomAttributes( material );
  2403. }
  2404. };
  2405. // Objects updates - custom attributes check
  2406. function areCustomAttributesDirty( material ) {
  2407. for ( var a in material.attributes ) {
  2408. if ( material.attributes[ a ].needsUpdate ) return true;
  2409. }
  2410. return false;
  2411. };
  2412. function clearCustomAttributes( material ) {
  2413. for ( var a in material.attributes ) {
  2414. material.attributes[ a ].needsUpdate = false;
  2415. }
  2416. };
  2417. // Objects removal
  2418. function removeObject( object, scene ) {
  2419. if ( object instanceof THREE.Mesh ||
  2420. object instanceof THREE.ParticleSystem ||
  2421. object instanceof THREE.Line ) {
  2422. removeInstances( scene.__webglObjects, object );
  2423. } else if ( object instanceof THREE.Sprite ) {
  2424. removeInstancesDirect( scene.__webglSprites, object );
  2425. } else if ( object instanceof THREE.LensFlare ) {
  2426. removeInstancesDirect( scene.__webglFlares, object );
  2427. } else if ( object instanceof THREE.ImmediateRenderObject || object.immediateRenderCallback ) {
  2428. removeInstances( scene.__webglObjectsImmediate, object );
  2429. }
  2430. delete object.__webglActive;
  2431. };
  2432. function removeInstances( objlist, object ) {
  2433. for ( var o = objlist.length - 1; o >= 0; o -- ) {
  2434. if ( objlist[ o ].object === object ) {
  2435. objlist.splice( o, 1 );
  2436. }
  2437. }
  2438. };
  2439. function removeInstancesDirect( objlist, object ) {
  2440. for ( var o = objlist.length - 1; o >= 0; o -- ) {
  2441. if ( objlist[ o ] === object ) {
  2442. objlist.splice( o, 1 );
  2443. }
  2444. }
  2445. };
  2446. // Materials
  2447. this.initMaterial = function ( material, lights, fog, object ) {
  2448. material.addEventListener( 'dispose', onMaterialDispose );
  2449. var u, a, identifiers, i, parameters, maxLightCount, maxBones, maxShadows, shaderID;
  2450. if ( material instanceof THREE.MeshDepthMaterial ) {
  2451. shaderID = 'depth';
  2452. } else if ( material instanceof THREE.MeshNormalMaterial ) {
  2453. shaderID = 'normal';
  2454. } else if ( material instanceof THREE.MeshBasicMaterial ) {
  2455. shaderID = 'basic';
  2456. } else if ( material instanceof THREE.MeshLambertMaterial ) {
  2457. shaderID = 'lambert';
  2458. } else if ( material instanceof THREE.MeshPhongMaterial ) {
  2459. shaderID = 'phong';
  2460. } else if ( material instanceof THREE.LineBasicMaterial ) {
  2461. shaderID = 'basic';
  2462. } else if ( material instanceof THREE.LineDashedMaterial ) {
  2463. shaderID = 'dashed';
  2464. } else if ( material instanceof THREE.ParticleSystemMaterial ) {
  2465. shaderID = 'particle_basic';
  2466. }
  2467. if ( shaderID ) {
  2468. setMaterialShaders( material, THREE.ShaderLib[ shaderID ] );
  2469. }
  2470. // heuristics to create shader parameters according to lights in the scene
  2471. // (not to blow over maxLights budget)
  2472. maxLightCount = allocateLights( lights );
  2473. maxShadows = allocateShadows( lights );
  2474. maxBones = allocateBones( object );
  2475. parameters = {
  2476. map: !!material.map,
  2477. envMap: !!material.envMap,
  2478. lightMap: !!material.lightMap,
  2479. bumpMap: !!material.bumpMap,
  2480. normalMap: !!material.normalMap,
  2481. specularMap: !!material.specularMap,
  2482. vertexColors: material.vertexColors,
  2483. fog: fog,
  2484. useFog: material.fog,
  2485. fogExp: fog instanceof THREE.FogExp2,
  2486. sizeAttenuation: material.sizeAttenuation,
  2487. skinning: material.skinning,
  2488. maxBones: maxBones,
  2489. useVertexTexture: _supportsBoneTextures && object && object.useVertexTexture,
  2490. morphTargets: material.morphTargets,
  2491. morphNormals: material.morphNormals,
  2492. maxMorphTargets: this.maxMorphTargets,
  2493. maxMorphNormals: this.maxMorphNormals,
  2494. maxDirLights: maxLightCount.directional,
  2495. maxPointLights: maxLightCount.point,
  2496. maxSpotLights: maxLightCount.spot,
  2497. maxHemiLights: maxLightCount.hemi,
  2498. maxShadows: maxShadows,
  2499. shadowMapEnabled: this.shadowMapEnabled && object.receiveShadow,
  2500. shadowMapType: this.shadowMapType,
  2501. shadowMapDebug: this.shadowMapDebug,
  2502. shadowMapCascade: this.shadowMapCascade,
  2503. alphaTest: material.alphaTest,
  2504. metal: material.metal,
  2505. wrapAround: material.wrapAround,
  2506. doubleSided: material.side === THREE.DoubleSide,
  2507. flipSided: material.side === THREE.BackSide
  2508. };
  2509. material.program = buildProgram( shaderID, material.fragmentShader, material.vertexShader, material.uniforms, material.attributes, material.defines, parameters, material.index0AttributeName );
  2510. var attributes = material.program.attributes;
  2511. if ( material.morphTargets ) {
  2512. material.numSupportedMorphTargets = 0;
  2513. var id, base = "morphTarget";
  2514. for ( i = 0; i < this.maxMorphTargets; i ++ ) {
  2515. id = base + i;
  2516. if ( attributes[ id ] >= 0 ) {
  2517. material.numSupportedMorphTargets ++;
  2518. }
  2519. }
  2520. }
  2521. if ( material.morphNormals ) {
  2522. material.numSupportedMorphNormals = 0;
  2523. var id, base = "morphNormal";
  2524. for ( i = 0; i < this.maxMorphNormals; i ++ ) {
  2525. id = base + i;
  2526. if ( attributes[ id ] >= 0 ) {
  2527. material.numSupportedMorphNormals ++;
  2528. }
  2529. }
  2530. }
  2531. material.uniformsList = [];
  2532. for ( u in material.uniforms ) {
  2533. material.uniformsList.push( [ material.uniforms[ u ], u ] );
  2534. }
  2535. };
  2536. function setMaterialShaders( material, shaders ) {
  2537. material.uniforms = THREE.UniformsUtils.clone( shaders.uniforms );
  2538. material.vertexShader = shaders.vertexShader;
  2539. material.fragmentShader = shaders.fragmentShader;
  2540. };
  2541. function setProgram( camera, lights, fog, material, object ) {
  2542. _usedTextureUnits = 0;
  2543. if ( material.needsUpdate ) {
  2544. if ( material.program ) deallocateMaterial( material );
  2545. _this.initMaterial( material, lights, fog, object );
  2546. material.needsUpdate = false;
  2547. }
  2548. if ( material.morphTargets ) {
  2549. if ( ! object.__webglMorphTargetInfluences ) {
  2550. object.__webglMorphTargetInfluences = new Float32Array( _this.maxMorphTargets );
  2551. }
  2552. }
  2553. var refreshMaterial = false;
  2554. var program = material.program,
  2555. p_uniforms = program.uniforms,
  2556. m_uniforms = material.uniforms;
  2557. if ( program !== _currentProgram ) {
  2558. _gl.useProgram( program );
  2559. _currentProgram = program;
  2560. refreshMaterial = true;
  2561. }
  2562. if ( material.id !== _currentMaterialId ) {
  2563. _currentMaterialId = material.id;
  2564. refreshMaterial = true;
  2565. }
  2566. if ( refreshMaterial || camera !== _currentCamera ) {
  2567. _gl.uniformMatrix4fv( p_uniforms.projectionMatrix, false, camera.projectionMatrix.elements );
  2568. if ( camera !== _currentCamera ) _currentCamera = camera;
  2569. }
  2570. // skinning uniforms must be set even if material didn't change
  2571. // auto-setting of texture unit for bone texture must go before other textures
  2572. // not sure why, but otherwise weird things happen
  2573. if ( material.skinning ) {
  2574. if ( _supportsBoneTextures && object.useVertexTexture ) {
  2575. if ( p_uniforms.boneTexture !== null ) {
  2576. var textureUnit = getTextureUnit();
  2577. _gl.uniform1i( p_uniforms.boneTexture, textureUnit );
  2578. _this.setTexture( object.boneTexture, textureUnit );
  2579. }
  2580. if ( p_uniforms.boneTextureWidth !== null ) {
  2581. _gl.uniform1i( p_uniforms.boneTextureWidth, object.boneTextureWidth );
  2582. }
  2583. if ( p_uniforms.boneTextureHeight !== null ) {
  2584. _gl.uniform1i( p_uniforms.boneTextureHeight, object.boneTextureHeight );
  2585. }
  2586. } else {
  2587. if ( p_uniforms.boneGlobalMatrices !== null ) {
  2588. _gl.uniformMatrix4fv( p_uniforms.boneGlobalMatrices, false, object.boneMatrices );
  2589. }
  2590. }
  2591. }
  2592. if ( refreshMaterial ) {
  2593. // refresh uniforms common to several materials
  2594. if ( fog && material.fog ) {
  2595. refreshUniformsFog( m_uniforms, fog );
  2596. }
  2597. if ( material instanceof THREE.MeshPhongMaterial ||
  2598. material instanceof THREE.MeshLambertMaterial ||
  2599. material.lights ) {
  2600. if ( _lightsNeedUpdate ) {
  2601. setupLights( program, lights );
  2602. _lightsNeedUpdate = false;
  2603. }
  2604. refreshUniformsLights( m_uniforms, _lights );
  2605. }
  2606. if ( material instanceof THREE.MeshBasicMaterial ||
  2607. material instanceof THREE.MeshLambertMaterial ||
  2608. material instanceof THREE.MeshPhongMaterial ) {
  2609. refreshUniformsCommon( m_uniforms, material );
  2610. }
  2611. // refresh single material specific uniforms
  2612. if ( material instanceof THREE.LineBasicMaterial ) {
  2613. refreshUniformsLine( m_uniforms, material );
  2614. } else if ( material instanceof THREE.LineDashedMaterial ) {
  2615. refreshUniformsLine( m_uniforms, material );
  2616. refreshUniformsDash( m_uniforms, material );
  2617. } else if ( material instanceof THREE.ParticleSystemMaterial ) {
  2618. refreshUniformsParticle( m_uniforms, material );
  2619. } else if ( material instanceof THREE.MeshPhongMaterial ) {
  2620. refreshUniformsPhong( m_uniforms, material );
  2621. } else if ( material instanceof THREE.MeshLambertMaterial ) {
  2622. refreshUniformsLambert( m_uniforms, material );
  2623. } else if ( material instanceof THREE.MeshDepthMaterial ) {
  2624. m_uniforms.mNear.value = camera.near;
  2625. m_uniforms.mFar.value = camera.far;
  2626. m_uniforms.opacity.value = material.opacity;
  2627. } else if ( material instanceof THREE.MeshNormalMaterial ) {
  2628. m_uniforms.opacity.value = material.opacity;
  2629. }
  2630. if ( object.receiveShadow && ! material._shadowPass ) {
  2631. refreshUniformsShadow( m_uniforms, lights );
  2632. }
  2633. // load common uniforms
  2634. loadUniformsGeneric( program, material.uniformsList );
  2635. // load material specific uniforms
  2636. // (shader material also gets them for the sake of genericity)
  2637. if ( material instanceof THREE.ShaderMaterial ||
  2638. material instanceof THREE.MeshPhongMaterial ||
  2639. material.envMap ) {
  2640. if ( p_uniforms.cameraPosition !== null ) {
  2641. _vector3.setFromMatrixPosition( camera.matrixWorld );
  2642. _gl.uniform3f( p_uniforms.cameraPosition, _vector3.x, _vector3.y, _vector3.z );
  2643. }
  2644. }
  2645. if ( material instanceof THREE.MeshPhongMaterial ||
  2646. material instanceof THREE.MeshLambertMaterial ||
  2647. material instanceof THREE.ShaderMaterial ||
  2648. material.skinning ) {
  2649. if ( p_uniforms.viewMatrix !== null ) {
  2650. _gl.uniformMatrix4fv( p_uniforms.viewMatrix, false, camera.matrixWorldInverse.elements );
  2651. }
  2652. }
  2653. }
  2654. loadUniformsMatrices( p_uniforms, object );
  2655. if ( p_uniforms.modelMatrix !== null ) {
  2656. _gl.uniformMatrix4fv( p_uniforms.modelMatrix, false, object.matrixWorld.elements );
  2657. }
  2658. return program;
  2659. };
  2660. // Uniforms (refresh uniforms objects)
  2661. function refreshUniformsCommon ( uniforms, material ) {
  2662. uniforms.opacity.value = material.opacity;
  2663. if ( _this.gammaInput ) {
  2664. uniforms.diffuse.value.copyGammaToLinear( material.color );
  2665. } else {
  2666. uniforms.diffuse.value = material.color;
  2667. }
  2668. uniforms.map.value = material.map;
  2669. uniforms.lightMap.value = material.lightMap;
  2670. uniforms.specularMap.value = material.specularMap;
  2671. if ( material.bumpMap ) {
  2672. uniforms.bumpMap.value = material.bumpMap;
  2673. uniforms.bumpScale.value = material.bumpScale;
  2674. }
  2675. if ( material.normalMap ) {
  2676. uniforms.normalMap.value = material.normalMap;
  2677. uniforms.normalScale.value.copy( material.normalScale );
  2678. }
  2679. // uv repeat and offset setting priorities
  2680. // 1. color map
  2681. // 2. specular map
  2682. // 3. normal map
  2683. // 4. bump map
  2684. var uvScaleMap;
  2685. if ( material.map ) {
  2686. uvScaleMap = material.map;
  2687. } else if ( material.specularMap ) {
  2688. uvScaleMap = material.specularMap;
  2689. } else if ( material.normalMap ) {
  2690. uvScaleMap = material.normalMap;
  2691. } else if ( material.bumpMap ) {
  2692. uvScaleMap = material.bumpMap;
  2693. }
  2694. if ( uvScaleMap !== undefined ) {
  2695. var offset = uvScaleMap.offset;
  2696. var repeat = uvScaleMap.repeat;
  2697. uniforms.offsetRepeat.value.set( offset.x, offset.y, repeat.x, repeat.y );
  2698. }
  2699. uniforms.envMap.value = material.envMap;
  2700. uniforms.flipEnvMap.value = ( material.envMap instanceof THREE.WebGLRenderTargetCube ) ? 1 : -1;
  2701. if ( _this.gammaInput ) {
  2702. //uniforms.reflectivity.value = material.reflectivity * material.reflectivity;
  2703. uniforms.reflectivity.value = material.reflectivity;
  2704. } else {
  2705. uniforms.reflectivity.value = material.reflectivity;
  2706. }
  2707. uniforms.refractionRatio.value = material.refractionRatio;
  2708. uniforms.combine.value = material.combine;
  2709. uniforms.useRefract.value = material.envMap && material.envMap.mapping instanceof THREE.CubeRefractionMapping;
  2710. };
  2711. function refreshUniformsLine ( uniforms, material ) {
  2712. uniforms.diffuse.value = material.color;
  2713. uniforms.opacity.value = material.opacity;
  2714. };
  2715. function refreshUniformsDash ( uniforms, material ) {
  2716. uniforms.dashSize.value = material.dashSize;
  2717. uniforms.totalSize.value = material.dashSize + material.gapSize;
  2718. uniforms.scale.value = material.scale;
  2719. };
  2720. function refreshUniformsParticle ( uniforms, material ) {
  2721. uniforms.psColor.value = material.color;
  2722. uniforms.opacity.value = material.opacity;
  2723. uniforms.size.value = material.size;
  2724. uniforms.scale.value = _canvas.height / 2.0; // TODO: Cache this.
  2725. uniforms.map.value = material.map;
  2726. };
  2727. function refreshUniformsFog ( uniforms, fog ) {
  2728. uniforms.fogColor.value = fog.color;
  2729. if ( fog instanceof THREE.Fog ) {
  2730. uniforms.fogNear.value = fog.near;
  2731. uniforms.fogFar.value = fog.far;
  2732. } else if ( fog instanceof THREE.FogExp2 ) {
  2733. uniforms.fogDensity.value = fog.density;
  2734. }
  2735. };
  2736. function refreshUniformsPhong ( uniforms, material ) {
  2737. uniforms.shininess.value = material.shininess;
  2738. if ( _this.gammaInput ) {
  2739. uniforms.ambient.value.copyGammaToLinear( material.ambient );
  2740. uniforms.emissive.value.copyGammaToLinear( material.emissive );
  2741. uniforms.specular.value.copyGammaToLinear( material.specular );
  2742. } else {
  2743. uniforms.ambient.value = material.ambient;
  2744. uniforms.emissive.value = material.emissive;
  2745. uniforms.specular.value = material.specular;
  2746. }
  2747. if ( material.wrapAround ) {
  2748. uniforms.wrapRGB.value.copy( material.wrapRGB );
  2749. }
  2750. };
  2751. function refreshUniformsLambert ( uniforms, material ) {
  2752. if ( _this.gammaInput ) {
  2753. uniforms.ambient.value.copyGammaToLinear( material.ambient );
  2754. uniforms.emissive.value.copyGammaToLinear( material.emissive );
  2755. } else {
  2756. uniforms.ambient.value = material.ambient;
  2757. uniforms.emissive.value = material.emissive;
  2758. }
  2759. if ( material.wrapAround ) {
  2760. uniforms.wrapRGB.value.copy( material.wrapRGB );
  2761. }
  2762. };
  2763. function refreshUniformsLights ( uniforms, lights ) {
  2764. uniforms.ambientLightColor.value = lights.ambient;
  2765. uniforms.directionalLightColor.value = lights.directional.colors;
  2766. uniforms.directionalLightDirection.value = lights.directional.positions;
  2767. uniforms.pointLightColor.value = lights.point.colors;
  2768. uniforms.pointLightPosition.value = lights.point.positions;
  2769. uniforms.pointLightDistance.value = lights.point.distances;
  2770. uniforms.spotLightColor.value = lights.spot.colors;
  2771. uniforms.spotLightPosition.value = lights.spot.positions;
  2772. uniforms.spotLightDistance.value = lights.spot.distances;
  2773. uniforms.spotLightDirection.value = lights.spot.directions;
  2774. uniforms.spotLightAngleCos.value = lights.spot.anglesCos;
  2775. uniforms.spotLightExponent.value = lights.spot.exponents;
  2776. uniforms.hemisphereLightSkyColor.value = lights.hemi.skyColors;
  2777. uniforms.hemisphereLightGroundColor.value = lights.hemi.groundColors;
  2778. uniforms.hemisphereLightDirection.value = lights.hemi.positions;
  2779. };
  2780. function refreshUniformsShadow ( uniforms, lights ) {
  2781. if ( uniforms.shadowMatrix ) {
  2782. var j = 0;
  2783. for ( var i = 0, il = lights.length; i < il; i ++ ) {
  2784. var light = lights[ i ];
  2785. if ( ! light.castShadow ) continue;
  2786. if ( light instanceof THREE.SpotLight || ( light instanceof THREE.DirectionalLight && ! light.shadowCascade ) ) {
  2787. uniforms.shadowMap.value[ j ] = light.shadowMap;
  2788. uniforms.shadowMapSize.value[ j ] = light.shadowMapSize;
  2789. uniforms.shadowMatrix.value[ j ] = light.shadowMatrix;
  2790. uniforms.shadowDarkness.value[ j ] = light.shadowDarkness;
  2791. uniforms.shadowBias.value[ j ] = light.shadowBias;
  2792. j ++;
  2793. }
  2794. }
  2795. }
  2796. };
  2797. // Uniforms (load to GPU)
  2798. function loadUniformsMatrices ( uniforms, object ) {
  2799. _gl.uniformMatrix4fv( uniforms.modelViewMatrix, false, object._modelViewMatrix.elements );
  2800. if ( uniforms.normalMatrix ) {
  2801. _gl.uniformMatrix3fv( uniforms.normalMatrix, false, object._normalMatrix.elements );
  2802. }
  2803. };
  2804. function getTextureUnit() {
  2805. var textureUnit = _usedTextureUnits;
  2806. if ( textureUnit >= _maxTextures ) {
  2807. console.warn( "WebGLRenderer: trying to use " + textureUnit + " texture units while this GPU supports only " + _maxTextures );
  2808. }
  2809. _usedTextureUnits += 1;
  2810. return textureUnit;
  2811. };
  2812. function loadUniformsGeneric ( program, uniforms ) {
  2813. var uniform, value, type, location, texture, textureUnit, i, il, j, jl, offset;
  2814. for ( j = 0, jl = uniforms.length; j < jl; j ++ ) {
  2815. location = program.uniforms[ uniforms[ j ][ 1 ] ];
  2816. if ( !location ) continue;
  2817. uniform = uniforms[ j ][ 0 ];
  2818. type = uniform.type;
  2819. value = uniform.value;
  2820. if ( type === "i" ) { // single integer
  2821. _gl.uniform1i( location, value );
  2822. } else if ( type === "f" ) { // single float
  2823. _gl.uniform1f( location, value );
  2824. } else if ( type === "v2" ) { // single THREE.Vector2
  2825. _gl.uniform2f( location, value.x, value.y );
  2826. } else if ( type === "v3" ) { // single THREE.Vector3
  2827. _gl.uniform3f( location, value.x, value.y, value.z );
  2828. } else if ( type === "v4" ) { // single THREE.Vector4
  2829. _gl.uniform4f( location, value.x, value.y, value.z, value.w );
  2830. } else if ( type === "c" ) { // single THREE.Color
  2831. _gl.uniform3f( location, value.r, value.g, value.b );
  2832. } else if ( type === "iv1" ) { // flat array of integers (JS or typed array)
  2833. _gl.uniform1iv( location, value );
  2834. } else if ( type === "iv" ) { // flat array of integers with 3 x N size (JS or typed array)
  2835. _gl.uniform3iv( location, value );
  2836. } else if ( type === "fv1" ) { // flat array of floats (JS or typed array)
  2837. _gl.uniform1fv( location, value );
  2838. } else if ( type === "fv" ) { // flat array of floats with 3 x N size (JS or typed array)
  2839. _gl.uniform3fv( location, value );
  2840. } else if ( type === "v2v" ) { // array of THREE.Vector2
  2841. if ( uniform._array === undefined ) {
  2842. uniform._array = new Float32Array( 2 * value.length );
  2843. }
  2844. for ( i = 0, il = value.length; i < il; i ++ ) {
  2845. offset = i * 2;
  2846. uniform._array[ offset ] = value[ i ].x;
  2847. uniform._array[ offset + 1 ] = value[ i ].y;
  2848. }
  2849. _gl.uniform2fv( location, uniform._array );
  2850. } else if ( type === "v3v" ) { // array of THREE.Vector3
  2851. if ( uniform._array === undefined ) {
  2852. uniform._array = new Float32Array( 3 * value.length );
  2853. }
  2854. for ( i = 0, il = value.length; i < il; i ++ ) {
  2855. offset = i * 3;
  2856. uniform._array[ offset ] = value[ i ].x;
  2857. uniform._array[ offset + 1 ] = value[ i ].y;
  2858. uniform._array[ offset + 2 ] = value[ i ].z;
  2859. }
  2860. _gl.uniform3fv( location, uniform._array );
  2861. } else if ( type === "v4v" ) { // array of THREE.Vector4
  2862. if ( uniform._array === undefined ) {
  2863. uniform._array = new Float32Array( 4 * value.length );
  2864. }
  2865. for ( i = 0, il = value.length; i < il; i ++ ) {
  2866. offset = i * 4;
  2867. uniform._array[ offset ] = value[ i ].x;
  2868. uniform._array[ offset + 1 ] = value[ i ].y;
  2869. uniform._array[ offset + 2 ] = value[ i ].z;
  2870. uniform._array[ offset + 3 ] = value[ i ].w;
  2871. }
  2872. _gl.uniform4fv( location, uniform._array );
  2873. } else if ( type === "m4") { // single THREE.Matrix4
  2874. if ( uniform._array === undefined ) {
  2875. uniform._array = new Float32Array( 16 );
  2876. }
  2877. value.flattenToArray( uniform._array );
  2878. _gl.uniformMatrix4fv( location, false, uniform._array );
  2879. } else if ( type === "m4v" ) { // array of THREE.Matrix4
  2880. if ( uniform._array === undefined ) {
  2881. uniform._array = new Float32Array( 16 * value.length );
  2882. }
  2883. for ( i = 0, il = value.length; i < il; i ++ ) {
  2884. value[ i ].flattenToArrayOffset( uniform._array, i * 16 );
  2885. }
  2886. _gl.uniformMatrix4fv( location, false, uniform._array );
  2887. } else if ( type === "t" ) { // single THREE.Texture (2d or cube)
  2888. texture = value;
  2889. textureUnit = getTextureUnit();
  2890. _gl.uniform1i( location, textureUnit );
  2891. if ( !texture ) continue;
  2892. if ( texture.image instanceof Array && texture.image.length === 6 ) {
  2893. setCubeTexture( texture, textureUnit );
  2894. } else if ( texture instanceof THREE.WebGLRenderTargetCube ) {
  2895. setCubeTextureDynamic( texture, textureUnit );
  2896. } else {
  2897. _this.setTexture( texture, textureUnit );
  2898. }
  2899. } else if ( type === "tv" ) { // array of THREE.Texture (2d)
  2900. if ( uniform._array === undefined ) {
  2901. uniform._array = [];
  2902. }
  2903. for( i = 0, il = uniform.value.length; i < il; i ++ ) {
  2904. uniform._array[ i ] = getTextureUnit();
  2905. }
  2906. _gl.uniform1iv( location, uniform._array );
  2907. for( i = 0, il = uniform.value.length; i < il; i ++ ) {
  2908. texture = uniform.value[ i ];
  2909. textureUnit = uniform._array[ i ];
  2910. if ( !texture ) continue;
  2911. _this.setTexture( texture, textureUnit );
  2912. }
  2913. } else {
  2914. console.warn( 'THREE.WebGLRenderer: Unknown uniform type: ' + type );
  2915. }
  2916. }
  2917. };
  2918. function setupMatrices ( object, camera ) {
  2919. object._modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld );
  2920. object._normalMatrix.getNormalMatrix( object._modelViewMatrix );
  2921. };
  2922. //
  2923. function setColorGamma( array, offset, color, intensitySq ) {
  2924. array[ offset ] = color.r * color.r * intensitySq;
  2925. array[ offset + 1 ] = color.g * color.g * intensitySq;
  2926. array[ offset + 2 ] = color.b * color.b * intensitySq;
  2927. };
  2928. function setColorLinear( array, offset, color, intensity ) {
  2929. array[ offset ] = color.r * intensity;
  2930. array[ offset + 1 ] = color.g * intensity;
  2931. array[ offset + 2 ] = color.b * intensity;
  2932. };
  2933. function setupLights ( program, lights ) {
  2934. var l, ll, light, n,
  2935. r = 0, g = 0, b = 0,
  2936. color, skyColor, groundColor,
  2937. intensity, intensitySq,
  2938. position,
  2939. distance,
  2940. zlights = _lights,
  2941. dirColors = zlights.directional.colors,
  2942. dirPositions = zlights.directional.positions,
  2943. pointColors = zlights.point.colors,
  2944. pointPositions = zlights.point.positions,
  2945. pointDistances = zlights.point.distances,
  2946. spotColors = zlights.spot.colors,
  2947. spotPositions = zlights.spot.positions,
  2948. spotDistances = zlights.spot.distances,
  2949. spotDirections = zlights.spot.directions,
  2950. spotAnglesCos = zlights.spot.anglesCos,
  2951. spotExponents = zlights.spot.exponents,
  2952. hemiSkyColors = zlights.hemi.skyColors,
  2953. hemiGroundColors = zlights.hemi.groundColors,
  2954. hemiPositions = zlights.hemi.positions,
  2955. dirLength = 0,
  2956. pointLength = 0,
  2957. spotLength = 0,
  2958. hemiLength = 0,
  2959. dirCount = 0,
  2960. pointCount = 0,
  2961. spotCount = 0,
  2962. hemiCount = 0,
  2963. dirOffset = 0,
  2964. pointOffset = 0,
  2965. spotOffset = 0,
  2966. hemiOffset = 0;
  2967. for ( l = 0, ll = lights.length; l < ll; l ++ ) {
  2968. light = lights[ l ];
  2969. if ( light.onlyShadow ) continue;
  2970. color = light.color;
  2971. intensity = light.intensity;
  2972. distance = light.distance;
  2973. if ( light instanceof THREE.AmbientLight ) {
  2974. if ( ! light.visible ) continue;
  2975. if ( _this.gammaInput ) {
  2976. r += color.r * color.r;
  2977. g += color.g * color.g;
  2978. b += color.b * color.b;
  2979. } else {
  2980. r += color.r;
  2981. g += color.g;
  2982. b += color.b;
  2983. }
  2984. } else if ( light instanceof THREE.DirectionalLight ) {
  2985. dirCount += 1;
  2986. if ( ! light.visible ) continue;
  2987. _direction.setFromMatrixPosition( light.matrixWorld );
  2988. _vector3.setFromMatrixPosition( light.target.matrixWorld );
  2989. _direction.sub( _vector3 );
  2990. _direction.normalize();
  2991. // skip lights with undefined direction
  2992. // these create troubles in OpenGL (making pixel black)
  2993. if ( _direction.x === 0 && _direction.y === 0 && _direction.z === 0 ) continue;
  2994. dirOffset = dirLength * 3;
  2995. dirPositions[ dirOffset ] = _direction.x;
  2996. dirPositions[ dirOffset + 1 ] = _direction.y;
  2997. dirPositions[ dirOffset + 2 ] = _direction.z;
  2998. if ( _this.gammaInput ) {
  2999. setColorGamma( dirColors, dirOffset, color, intensity * intensity );
  3000. } else {
  3001. setColorLinear( dirColors, dirOffset, color, intensity );
  3002. }
  3003. dirLength += 1;
  3004. } else if ( light instanceof THREE.PointLight ) {
  3005. pointCount += 1;
  3006. if ( ! light.visible ) continue;
  3007. pointOffset = pointLength * 3;
  3008. if ( _this.gammaInput ) {
  3009. setColorGamma( pointColors, pointOffset, color, intensity * intensity );
  3010. } else {
  3011. setColorLinear( pointColors, pointOffset, color, intensity );
  3012. }
  3013. _vector3.setFromMatrixPosition( light.matrixWorld );
  3014. pointPositions[ pointOffset ] = _vector3.x;
  3015. pointPositions[ pointOffset + 1 ] = _vector3.y;
  3016. pointPositions[ pointOffset + 2 ] = _vector3.z;
  3017. pointDistances[ pointLength ] = distance;
  3018. pointLength += 1;
  3019. } else if ( light instanceof THREE.SpotLight ) {
  3020. spotCount += 1;
  3021. if ( ! light.visible ) continue;
  3022. spotOffset = spotLength * 3;
  3023. if ( _this.gammaInput ) {
  3024. setColorGamma( spotColors, spotOffset, color, intensity * intensity );
  3025. } else {
  3026. setColorLinear( spotColors, spotOffset, color, intensity );
  3027. }
  3028. _vector3.setFromMatrixPosition( light.matrixWorld );
  3029. spotPositions[ spotOffset ] = _vector3.x;
  3030. spotPositions[ spotOffset + 1 ] = _vector3.y;
  3031. spotPositions[ spotOffset + 2 ] = _vector3.z;
  3032. spotDistances[ spotLength ] = distance;
  3033. _direction.copy( _vector3 );
  3034. _vector3.setFromMatrixPosition( light.target.matrixWorld );
  3035. _direction.sub( _vector3 );
  3036. _direction.normalize();
  3037. spotDirections[ spotOffset ] = _direction.x;
  3038. spotDirections[ spotOffset + 1 ] = _direction.y;
  3039. spotDirections[ spotOffset + 2 ] = _direction.z;
  3040. spotAnglesCos[ spotLength ] = Math.cos( light.angle );
  3041. spotExponents[ spotLength ] = light.exponent;
  3042. spotLength += 1;
  3043. } else if ( light instanceof THREE.HemisphereLight ) {
  3044. hemiCount += 1;
  3045. if ( ! light.visible ) continue;
  3046. _direction.setFromMatrixPosition( light.matrixWorld );
  3047. _direction.normalize();
  3048. // skip lights with undefined direction
  3049. // these create troubles in OpenGL (making pixel black)
  3050. if ( _direction.x === 0 && _direction.y === 0 && _direction.z === 0 ) continue;
  3051. hemiOffset = hemiLength * 3;
  3052. hemiPositions[ hemiOffset ] = _direction.x;
  3053. hemiPositions[ hemiOffset + 1 ] = _direction.y;
  3054. hemiPositions[ hemiOffset + 2 ] = _direction.z;
  3055. skyColor = light.color;
  3056. groundColor = light.groundColor;
  3057. if ( _this.gammaInput ) {
  3058. intensitySq = intensity * intensity;
  3059. setColorGamma( hemiSkyColors, hemiOffset, skyColor, intensitySq );
  3060. setColorGamma( hemiGroundColors, hemiOffset, groundColor, intensitySq );
  3061. } else {
  3062. setColorLinear( hemiSkyColors, hemiOffset, skyColor, intensity );
  3063. setColorLinear( hemiGroundColors, hemiOffset, groundColor, intensity );
  3064. }
  3065. hemiLength += 1;
  3066. }
  3067. }
  3068. // null eventual remains from removed lights
  3069. // (this is to avoid if in shader)
  3070. for ( l = dirLength * 3, ll = Math.max( dirColors.length, dirCount * 3 ); l < ll; l ++ ) dirColors[ l ] = 0.0;
  3071. for ( l = pointLength * 3, ll = Math.max( pointColors.length, pointCount * 3 ); l < ll; l ++ ) pointColors[ l ] = 0.0;
  3072. for ( l = spotLength * 3, ll = Math.max( spotColors.length, spotCount * 3 ); l < ll; l ++ ) spotColors[ l ] = 0.0;
  3073. for ( l = hemiLength * 3, ll = Math.max( hemiSkyColors.length, hemiCount * 3 ); l < ll; l ++ ) hemiSkyColors[ l ] = 0.0;
  3074. for ( l = hemiLength * 3, ll = Math.max( hemiGroundColors.length, hemiCount * 3 ); l < ll; l ++ ) hemiGroundColors[ l ] = 0.0;
  3075. zlights.directional.length = dirLength;
  3076. zlights.point.length = pointLength;
  3077. zlights.spot.length = spotLength;
  3078. zlights.hemi.length = hemiLength;
  3079. zlights.ambient[ 0 ] = r;
  3080. zlights.ambient[ 1 ] = g;
  3081. zlights.ambient[ 2 ] = b;
  3082. };
  3083. // GL state setting
  3084. this.setFaceCulling = function ( cullFace, frontFaceDirection ) {
  3085. if ( cullFace === THREE.CullFaceNone ) {
  3086. _gl.disable( _gl.CULL_FACE );
  3087. } else {
  3088. if ( frontFaceDirection === THREE.FrontFaceDirectionCW ) {
  3089. _gl.frontFace( _gl.CW );
  3090. } else {
  3091. _gl.frontFace( _gl.CCW );
  3092. }
  3093. if ( cullFace === THREE.CullFaceBack ) {
  3094. _gl.cullFace( _gl.BACK );
  3095. } else if ( cullFace === THREE.CullFaceFront ) {
  3096. _gl.cullFace( _gl.FRONT );
  3097. } else {
  3098. _gl.cullFace( _gl.FRONT_AND_BACK );
  3099. }
  3100. _gl.enable( _gl.CULL_FACE );
  3101. }
  3102. };
  3103. this.setMaterialFaces = function ( material ) {
  3104. var doubleSided = material.side === THREE.DoubleSide;
  3105. var flipSided = material.side === THREE.BackSide;
  3106. if ( _oldDoubleSided !== doubleSided ) {
  3107. if ( doubleSided ) {
  3108. _gl.disable( _gl.CULL_FACE );
  3109. } else {
  3110. _gl.enable( _gl.CULL_FACE );
  3111. }
  3112. _oldDoubleSided = doubleSided;
  3113. }
  3114. if ( _oldFlipSided !== flipSided ) {
  3115. if ( flipSided ) {
  3116. _gl.frontFace( _gl.CW );
  3117. } else {
  3118. _gl.frontFace( _gl.CCW );
  3119. }
  3120. _oldFlipSided = flipSided;
  3121. }
  3122. };
  3123. this.setDepthTest = function ( depthTest ) {
  3124. if ( _oldDepthTest !== depthTest ) {
  3125. if ( depthTest ) {
  3126. _gl.enable( _gl.DEPTH_TEST );
  3127. } else {
  3128. _gl.disable( _gl.DEPTH_TEST );
  3129. }
  3130. _oldDepthTest = depthTest;
  3131. }
  3132. };
  3133. this.setDepthWrite = function ( depthWrite ) {
  3134. if ( _oldDepthWrite !== depthWrite ) {
  3135. _gl.depthMask( depthWrite );
  3136. _oldDepthWrite = depthWrite;
  3137. }
  3138. };
  3139. function setLineWidth ( width ) {
  3140. if ( width !== _oldLineWidth ) {
  3141. _gl.lineWidth( width );
  3142. _oldLineWidth = width;
  3143. }
  3144. };
  3145. function setPolygonOffset ( polygonoffset, factor, units ) {
  3146. if ( _oldPolygonOffset !== polygonoffset ) {
  3147. if ( polygonoffset ) {
  3148. _gl.enable( _gl.POLYGON_OFFSET_FILL );
  3149. } else {
  3150. _gl.disable( _gl.POLYGON_OFFSET_FILL );
  3151. }
  3152. _oldPolygonOffset = polygonoffset;
  3153. }
  3154. if ( polygonoffset && ( _oldPolygonOffsetFactor !== factor || _oldPolygonOffsetUnits !== units ) ) {
  3155. _gl.polygonOffset( factor, units );
  3156. _oldPolygonOffsetFactor = factor;
  3157. _oldPolygonOffsetUnits = units;
  3158. }
  3159. };
  3160. this.setBlending = function ( blending, blendEquation, blendSrc, blendDst ) {
  3161. if ( blending !== _oldBlending ) {
  3162. if ( blending === THREE.NoBlending ) {
  3163. _gl.disable( _gl.BLEND );
  3164. } else if ( blending === THREE.AdditiveBlending ) {
  3165. _gl.enable( _gl.BLEND );
  3166. _gl.blendEquation( _gl.FUNC_ADD );
  3167. _gl.blendFunc( _gl.SRC_ALPHA, _gl.ONE );
  3168. } else if ( blending === THREE.SubtractiveBlending ) {
  3169. // TODO: Find blendFuncSeparate() combination
  3170. _gl.enable( _gl.BLEND );
  3171. _gl.blendEquation( _gl.FUNC_ADD );
  3172. _gl.blendFunc( _gl.ZERO, _gl.ONE_MINUS_SRC_COLOR );
  3173. } else if ( blending === THREE.MultiplyBlending ) {
  3174. // TODO: Find blendFuncSeparate() combination
  3175. _gl.enable( _gl.BLEND );
  3176. _gl.blendEquation( _gl.FUNC_ADD );
  3177. _gl.blendFunc( _gl.ZERO, _gl.SRC_COLOR );
  3178. } else if ( blending === THREE.CustomBlending ) {
  3179. _gl.enable( _gl.BLEND );
  3180. } else {
  3181. _gl.enable( _gl.BLEND );
  3182. _gl.blendEquationSeparate( _gl.FUNC_ADD, _gl.FUNC_ADD );
  3183. _gl.blendFuncSeparate( _gl.SRC_ALPHA, _gl.ONE_MINUS_SRC_ALPHA, _gl.ONE, _gl.ONE_MINUS_SRC_ALPHA );
  3184. }
  3185. _oldBlending = blending;
  3186. }
  3187. if ( blending === THREE.CustomBlending ) {
  3188. if ( blendEquation !== _oldBlendEquation ) {
  3189. _gl.blendEquation( paramThreeToGL( blendEquation ) );
  3190. _oldBlendEquation = blendEquation;
  3191. }
  3192. if ( blendSrc !== _oldBlendSrc || blendDst !== _oldBlendDst ) {
  3193. _gl.blendFunc( paramThreeToGL( blendSrc ), paramThreeToGL( blendDst ) );
  3194. _oldBlendSrc = blendSrc;
  3195. _oldBlendDst = blendDst;
  3196. }
  3197. } else {
  3198. _oldBlendEquation = null;
  3199. _oldBlendSrc = null;
  3200. _oldBlendDst = null;
  3201. }
  3202. };
  3203. // Defines
  3204. function generateDefines ( defines ) {
  3205. var value, chunk, chunks = [];
  3206. for ( var d in defines ) {
  3207. value = defines[ d ];
  3208. if ( value === false ) continue;
  3209. chunk = "#define " + d + " " + value;
  3210. chunks.push( chunk );
  3211. }
  3212. return chunks.join( "\n" );
  3213. };
  3214. // Shaders
  3215. function buildProgram ( shaderID, fragmentShader, vertexShader, uniforms, attributes, defines, parameters, index0AttributeName ) {
  3216. var p, pl, d, program, code;
  3217. var chunks = [];
  3218. // Generate code
  3219. if ( shaderID ) {
  3220. chunks.push( shaderID );
  3221. } else {
  3222. chunks.push( fragmentShader );
  3223. chunks.push( vertexShader );
  3224. }
  3225. for ( d in defines ) {
  3226. chunks.push( d );
  3227. chunks.push( defines[ d ] );
  3228. }
  3229. for ( p in parameters ) {
  3230. chunks.push( p );
  3231. chunks.push( parameters[ p ] );
  3232. }
  3233. code = chunks.join();
  3234. // Check if code has been already compiled
  3235. for ( p = 0, pl = _programs.length; p < pl; p ++ ) {
  3236. var programInfo = _programs[ p ];
  3237. if ( programInfo.code === code ) {
  3238. // console.log( "Code already compiled." /*: \n\n" + code*/ );
  3239. programInfo.usedTimes ++;
  3240. return programInfo.program;
  3241. }
  3242. }
  3243. var shadowMapTypeDefine = "SHADOWMAP_TYPE_BASIC";
  3244. if ( parameters.shadowMapType === THREE.PCFShadowMap ) {
  3245. shadowMapTypeDefine = "SHADOWMAP_TYPE_PCF";
  3246. } else if ( parameters.shadowMapType === THREE.PCFSoftShadowMap ) {
  3247. shadowMapTypeDefine = "SHADOWMAP_TYPE_PCF_SOFT";
  3248. }
  3249. // console.log( "building new program " );
  3250. //
  3251. var customDefines = generateDefines( defines );
  3252. //
  3253. program = _gl.createProgram();
  3254. var prefix_vertex = [
  3255. "precision " + _precision + " float;",
  3256. "precision " + _precision + " int;",
  3257. customDefines,
  3258. _supportsVertexTextures ? "#define VERTEX_TEXTURES" : "",
  3259. _this.gammaInput ? "#define GAMMA_INPUT" : "",
  3260. _this.gammaOutput ? "#define GAMMA_OUTPUT" : "",
  3261. "#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
  3262. "#define MAX_POINT_LIGHTS " + parameters.maxPointLights,
  3263. "#define MAX_SPOT_LIGHTS " + parameters.maxSpotLights,
  3264. "#define MAX_HEMI_LIGHTS " + parameters.maxHemiLights,
  3265. "#define MAX_SHADOWS " + parameters.maxShadows,
  3266. "#define MAX_BONES " + parameters.maxBones,
  3267. parameters.map ? "#define USE_MAP" : "",
  3268. parameters.envMap ? "#define USE_ENVMAP" : "",
  3269. parameters.lightMap ? "#define USE_LIGHTMAP" : "",
  3270. parameters.bumpMap ? "#define USE_BUMPMAP" : "",
  3271. parameters.normalMap ? "#define USE_NORMALMAP" : "",
  3272. parameters.specularMap ? "#define USE_SPECULARMAP" : "",
  3273. parameters.vertexColors ? "#define USE_COLOR" : "",
  3274. parameters.skinning ? "#define USE_SKINNING" : "",
  3275. parameters.useVertexTexture ? "#define BONE_TEXTURE" : "",
  3276. parameters.morphTargets ? "#define USE_MORPHTARGETS" : "",
  3277. parameters.morphNormals ? "#define USE_MORPHNORMALS" : "",
  3278. parameters.wrapAround ? "#define WRAP_AROUND" : "",
  3279. parameters.doubleSided ? "#define DOUBLE_SIDED" : "",
  3280. parameters.flipSided ? "#define FLIP_SIDED" : "",
  3281. parameters.shadowMapEnabled ? "#define USE_SHADOWMAP" : "",
  3282. parameters.shadowMapEnabled ? "#define " + shadowMapTypeDefine : "",
  3283. parameters.shadowMapDebug ? "#define SHADOWMAP_DEBUG" : "",
  3284. parameters.shadowMapCascade ? "#define SHADOWMAP_CASCADE" : "",
  3285. parameters.sizeAttenuation ? "#define USE_SIZEATTENUATION" : "",
  3286. "uniform mat4 modelMatrix;",
  3287. "uniform mat4 modelViewMatrix;",
  3288. "uniform mat4 projectionMatrix;",
  3289. "uniform mat4 viewMatrix;",
  3290. "uniform mat3 normalMatrix;",
  3291. "uniform vec3 cameraPosition;",
  3292. "attribute vec3 position;",
  3293. "attribute vec3 normal;",
  3294. "attribute vec2 uv;",
  3295. "attribute vec2 uv2;",
  3296. "#ifdef USE_COLOR",
  3297. "attribute vec3 color;",
  3298. "#endif",
  3299. "#ifdef USE_MORPHTARGETS",
  3300. "attribute vec3 morphTarget0;",
  3301. "attribute vec3 morphTarget1;",
  3302. "attribute vec3 morphTarget2;",
  3303. "attribute vec3 morphTarget3;",
  3304. "#ifdef USE_MORPHNORMALS",
  3305. "attribute vec3 morphNormal0;",
  3306. "attribute vec3 morphNormal1;",
  3307. "attribute vec3 morphNormal2;",
  3308. "attribute vec3 morphNormal3;",
  3309. "#else",
  3310. "attribute vec3 morphTarget4;",
  3311. "attribute vec3 morphTarget5;",
  3312. "attribute vec3 morphTarget6;",
  3313. "attribute vec3 morphTarget7;",
  3314. "#endif",
  3315. "#endif",
  3316. "#ifdef USE_SKINNING",
  3317. "attribute vec4 skinIndex;",
  3318. "attribute vec4 skinWeight;",
  3319. "#endif",
  3320. ""
  3321. ].join("\n");
  3322. var prefix_fragment = [
  3323. "precision " + _precision + " float;",
  3324. "precision " + _precision + " int;",
  3325. ( parameters.bumpMap || parameters.normalMap ) ? "#extension GL_OES_standard_derivatives : enable" : "",
  3326. customDefines,
  3327. "#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
  3328. "#define MAX_POINT_LIGHTS " + parameters.maxPointLights,
  3329. "#define MAX_SPOT_LIGHTS " + parameters.maxSpotLights,
  3330. "#define MAX_HEMI_LIGHTS " + parameters.maxHemiLights,
  3331. "#define MAX_SHADOWS " + parameters.maxShadows,
  3332. parameters.alphaTest ? "#define ALPHATEST " + parameters.alphaTest: "",
  3333. _this.gammaInput ? "#define GAMMA_INPUT" : "",
  3334. _this.gammaOutput ? "#define GAMMA_OUTPUT" : "",
  3335. ( parameters.useFog && parameters.fog ) ? "#define USE_FOG" : "",
  3336. ( parameters.useFog && parameters.fogExp ) ? "#define FOG_EXP2" : "",
  3337. parameters.map ? "#define USE_MAP" : "",
  3338. parameters.envMap ? "#define USE_ENVMAP" : "",
  3339. parameters.lightMap ? "#define USE_LIGHTMAP" : "",
  3340. parameters.bumpMap ? "#define USE_BUMPMAP" : "",
  3341. parameters.normalMap ? "#define USE_NORMALMAP" : "",
  3342. parameters.specularMap ? "#define USE_SPECULARMAP" : "",
  3343. parameters.vertexColors ? "#define USE_COLOR" : "",
  3344. parameters.metal ? "#define METAL" : "",
  3345. parameters.wrapAround ? "#define WRAP_AROUND" : "",
  3346. parameters.doubleSided ? "#define DOUBLE_SIDED" : "",
  3347. parameters.flipSided ? "#define FLIP_SIDED" : "",
  3348. parameters.shadowMapEnabled ? "#define USE_SHADOWMAP" : "",
  3349. parameters.shadowMapEnabled ? "#define " + shadowMapTypeDefine : "",
  3350. parameters.shadowMapDebug ? "#define SHADOWMAP_DEBUG" : "",
  3351. parameters.shadowMapCascade ? "#define SHADOWMAP_CASCADE" : "",
  3352. "uniform mat4 viewMatrix;",
  3353. "uniform vec3 cameraPosition;",
  3354. ""
  3355. ].join("\n");
  3356. var glVertexShader = getShader( "vertex", prefix_vertex + vertexShader );
  3357. var glFragmentShader = getShader( "fragment", prefix_fragment + fragmentShader );
  3358. _gl.attachShader( program, glVertexShader );
  3359. _gl.attachShader( program, glFragmentShader );
  3360. // Force a particular attribute to index 0.
  3361. // because potentially expensive emulation is done by browser if attribute 0 is disabled.
  3362. // And, color, for example is often automatically bound to index 0 so disabling it
  3363. if ( index0AttributeName !== undefined ) {
  3364. _gl.bindAttribLocation( program, 0, index0AttributeName );
  3365. } else {
  3366. _gl.bindAttribLocation( program, 0, 'position' );
  3367. }
  3368. _gl.linkProgram( program );
  3369. if ( !_gl.getProgramParameter( program, _gl.LINK_STATUS ) ) {
  3370. console.error( "Could not initialise shader\n" + "VALIDATE_STATUS: " + _gl.getProgramParameter( program, _gl.VALIDATE_STATUS ) + ", gl error [" + _gl.getError() + "]" );
  3371. console.error( "Program Info Log: " + _gl.getProgramInfoLog( program ) );
  3372. }
  3373. // clean up
  3374. _gl.deleteShader( glFragmentShader );
  3375. _gl.deleteShader( glVertexShader );
  3376. // console.log( prefix_fragment + fragmentShader );
  3377. // console.log( prefix_vertex + vertexShader );
  3378. program.uniforms = {};
  3379. program.attributes = {};
  3380. var identifiers, u, a, i;
  3381. // cache uniform locations
  3382. identifiers = [
  3383. 'viewMatrix', 'modelViewMatrix', 'projectionMatrix', 'normalMatrix', 'modelMatrix', 'cameraPosition',
  3384. 'morphTargetInfluences'
  3385. ];
  3386. if ( parameters.useVertexTexture ) {
  3387. identifiers.push( 'boneTexture' );
  3388. identifiers.push( 'boneTextureWidth' );
  3389. identifiers.push( 'boneTextureHeight' );
  3390. } else {
  3391. identifiers.push( 'boneGlobalMatrices' );
  3392. }
  3393. for ( u in uniforms ) {
  3394. identifiers.push( u );
  3395. }
  3396. cacheUniformLocations( program, identifiers );
  3397. // cache attributes locations
  3398. identifiers = [
  3399. "position", "normal", "uv", "uv2", "tangent", "color",
  3400. "skinIndex", "skinWeight", "lineDistance"
  3401. ];
  3402. for ( i = 0; i < parameters.maxMorphTargets; i ++ ) {
  3403. identifiers.push( "morphTarget" + i );
  3404. }
  3405. for ( i = 0; i < parameters.maxMorphNormals; i ++ ) {
  3406. identifiers.push( "morphNormal" + i );
  3407. }
  3408. for ( a in attributes ) {
  3409. identifiers.push( a );
  3410. }
  3411. cacheAttributeLocations( program, identifiers );
  3412. program.id = _programs_counter ++;
  3413. _programs.push( { program: program, code: code, usedTimes: 1 } );
  3414. _this.info.memory.programs = _programs.length;
  3415. return program;
  3416. };
  3417. // Shader parameters cache
  3418. function cacheUniformLocations ( program, identifiers ) {
  3419. var i, l, id;
  3420. for( i = 0, l = identifiers.length; i < l; i ++ ) {
  3421. id = identifiers[ i ];
  3422. program.uniforms[ id ] = _gl.getUniformLocation( program, id );
  3423. }
  3424. };
  3425. function cacheAttributeLocations ( program, identifiers ) {
  3426. var i, l, id;
  3427. for( i = 0, l = identifiers.length; i < l; i ++ ) {
  3428. id = identifiers[ i ];
  3429. program.attributes[ id ] = _gl.getAttribLocation( program, id );
  3430. }
  3431. };
  3432. function addLineNumbers ( string ) {
  3433. var chunks = string.split( "\n" );
  3434. for ( var i = 0, il = chunks.length; i < il; i ++ ) {
  3435. // Chrome reports shader errors on lines
  3436. // starting counting from 1
  3437. chunks[ i ] = ( i + 1 ) + ": " + chunks[ i ];
  3438. }
  3439. return chunks.join( "\n" );
  3440. };
  3441. function getShader ( type, string ) {
  3442. var shader;
  3443. if ( type === "fragment" ) {
  3444. shader = _gl.createShader( _gl.FRAGMENT_SHADER );
  3445. } else if ( type === "vertex" ) {
  3446. shader = _gl.createShader( _gl.VERTEX_SHADER );
  3447. }
  3448. _gl.shaderSource( shader, string );
  3449. _gl.compileShader( shader );
  3450. if ( !_gl.getShaderParameter( shader, _gl.COMPILE_STATUS ) ) {
  3451. console.error( _gl.getShaderInfoLog( shader ) );
  3452. console.error( addLineNumbers( string ) );
  3453. return null;
  3454. }
  3455. return shader;
  3456. };
  3457. // Textures
  3458. function setTextureParameters ( textureType, texture, isImagePowerOfTwo ) {
  3459. if ( isImagePowerOfTwo ) {
  3460. _gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, paramThreeToGL( texture.wrapS ) );
  3461. _gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, paramThreeToGL( texture.wrapT ) );
  3462. _gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, paramThreeToGL( texture.magFilter ) );
  3463. _gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, paramThreeToGL( texture.minFilter ) );
  3464. } else {
  3465. _gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );
  3466. _gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );
  3467. _gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, filterFallback( texture.magFilter ) );
  3468. _gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, filterFallback( texture.minFilter ) );
  3469. }
  3470. if ( _glExtensionTextureFilterAnisotropic && texture.type !== THREE.FloatType ) {
  3471. if ( texture.anisotropy > 1 || texture.__oldAnisotropy ) {
  3472. _gl.texParameterf( textureType, _glExtensionTextureFilterAnisotropic.TEXTURE_MAX_ANISOTROPY_EXT, Math.min( texture.anisotropy, _maxAnisotropy ) );
  3473. texture.__oldAnisotropy = texture.anisotropy;
  3474. }
  3475. }
  3476. };
  3477. this.setTexture = function ( texture, slot ) {
  3478. if ( texture.needsUpdate ) {
  3479. if ( ! texture.__webglInit ) {
  3480. texture.__webglInit = true;
  3481. texture.addEventListener( 'dispose', onTextureDispose );
  3482. texture.__webglTexture = _gl.createTexture();
  3483. _this.info.memory.textures ++;
  3484. }
  3485. _gl.activeTexture( _gl.TEXTURE0 + slot );
  3486. _gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );
  3487. _gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );
  3488. _gl.pixelStorei( _gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha );
  3489. _gl.pixelStorei( _gl.UNPACK_ALIGNMENT, texture.unpackAlignment );
  3490. var image = texture.image,
  3491. isImagePowerOfTwo = THREE.Math.isPowerOfTwo( image.width ) && THREE.Math.isPowerOfTwo( image.height ),
  3492. glFormat = paramThreeToGL( texture.format ),
  3493. glType = paramThreeToGL( texture.type );
  3494. setTextureParameters( _gl.TEXTURE_2D, texture, isImagePowerOfTwo );
  3495. var mipmap, mipmaps = texture.mipmaps;
  3496. if ( texture instanceof THREE.DataTexture ) {
  3497. // use manually created mipmaps if available
  3498. // if there are no manual mipmaps
  3499. // set 0 level mipmap and then use GL to generate other mipmap levels
  3500. if ( mipmaps.length > 0 && isImagePowerOfTwo ) {
  3501. for ( var i = 0, il = mipmaps.length; i < il; i ++ ) {
  3502. mipmap = mipmaps[ i ];
  3503. _gl.texImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );
  3504. }
  3505. texture.generateMipmaps = false;
  3506. } else {
  3507. _gl.texImage2D( _gl.TEXTURE_2D, 0, glFormat, image.width, image.height, 0, glFormat, glType, image.data );
  3508. }
  3509. } else if ( texture instanceof THREE.CompressedTexture ) {
  3510. for( var i = 0, il = mipmaps.length; i < il; i ++ ) {
  3511. mipmap = mipmaps[ i ];
  3512. if ( texture.format!==THREE.RGBAFormat ) {
  3513. _gl.compressedTexImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, mipmap.data );
  3514. } else {
  3515. _gl.texImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );
  3516. }
  3517. }
  3518. } else { // regular Texture (image, video, canvas)
  3519. // use manually created mipmaps if available
  3520. // if there are no manual mipmaps
  3521. // set 0 level mipmap and then use GL to generate other mipmap levels
  3522. if ( mipmaps.length > 0 && isImagePowerOfTwo ) {
  3523. for ( var i = 0, il = mipmaps.length; i < il; i ++ ) {
  3524. mipmap = mipmaps[ i ];
  3525. _gl.texImage2D( _gl.TEXTURE_2D, i, glFormat, glFormat, glType, mipmap );
  3526. }
  3527. texture.generateMipmaps = false;
  3528. } else {
  3529. _gl.texImage2D( _gl.TEXTURE_2D, 0, glFormat, glFormat, glType, texture.image );
  3530. }
  3531. }
  3532. if ( texture.generateMipmaps && isImagePowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_2D );
  3533. texture.needsUpdate = false;
  3534. if ( texture.onUpdate ) texture.onUpdate();
  3535. } else {
  3536. _gl.activeTexture( _gl.TEXTURE0 + slot );
  3537. _gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );
  3538. }
  3539. };
  3540. function clampToMaxSize ( image, maxSize ) {
  3541. if ( image.width <= maxSize && image.height <= maxSize ) {
  3542. return image;
  3543. }
  3544. // Warning: Scaling through the canvas will only work with images that use
  3545. // premultiplied alpha.
  3546. var maxDimension = Math.max( image.width, image.height );
  3547. var newWidth = Math.floor( image.width * maxSize / maxDimension );
  3548. var newHeight = Math.floor( image.height * maxSize / maxDimension );
  3549. var canvas = document.createElement( 'canvas' );
  3550. canvas.width = newWidth;
  3551. canvas.height = newHeight;
  3552. var ctx = canvas.getContext( "2d" );
  3553. ctx.drawImage( image, 0, 0, image.width, image.height, 0, 0, newWidth, newHeight );
  3554. return canvas;
  3555. }
  3556. function setCubeTexture ( texture, slot ) {
  3557. if ( texture.image.length === 6 ) {
  3558. if ( texture.needsUpdate ) {
  3559. if ( ! texture.image.__webglTextureCube ) {
  3560. texture.addEventListener( 'dispose', onTextureDispose );
  3561. texture.image.__webglTextureCube = _gl.createTexture();
  3562. _this.info.memory.textures ++;
  3563. }
  3564. _gl.activeTexture( _gl.TEXTURE0 + slot );
  3565. _gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webglTextureCube );
  3566. _gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );
  3567. var isCompressed = texture instanceof THREE.CompressedTexture;
  3568. var cubeImage = [];
  3569. for ( var i = 0; i < 6; i ++ ) {
  3570. if ( _this.autoScaleCubemaps && ! isCompressed ) {
  3571. cubeImage[ i ] = clampToMaxSize( texture.image[ i ], _maxCubemapSize );
  3572. } else {
  3573. cubeImage[ i ] = texture.image[ i ];
  3574. }
  3575. }
  3576. var image = cubeImage[ 0 ],
  3577. isImagePowerOfTwo = THREE.Math.isPowerOfTwo( image.width ) && THREE.Math.isPowerOfTwo( image.height ),
  3578. glFormat = paramThreeToGL( texture.format ),
  3579. glType = paramThreeToGL( texture.type );
  3580. setTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, isImagePowerOfTwo );
  3581. for ( var i = 0; i < 6; i ++ ) {
  3582. if( !isCompressed ) {
  3583. _gl.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, glFormat, glType, cubeImage[ i ] );
  3584. } else {
  3585. var mipmap, mipmaps = cubeImage[ i ].mipmaps;
  3586. for( var j = 0, jl = mipmaps.length; j < jl; j ++ ) {
  3587. mipmap = mipmaps[ j ];
  3588. if ( texture.format!==THREE.RGBAFormat ) {
  3589. _gl.compressedTexImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glFormat, mipmap.width, mipmap.height, 0, mipmap.data );
  3590. } else {
  3591. _gl.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );
  3592. }
  3593. }
  3594. }
  3595. }
  3596. if ( texture.generateMipmaps && isImagePowerOfTwo ) {
  3597. _gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );
  3598. }
  3599. texture.needsUpdate = false;
  3600. if ( texture.onUpdate ) texture.onUpdate();
  3601. } else {
  3602. _gl.activeTexture( _gl.TEXTURE0 + slot );
  3603. _gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webglTextureCube );
  3604. }
  3605. }
  3606. };
  3607. function setCubeTextureDynamic ( texture, slot ) {
  3608. _gl.activeTexture( _gl.TEXTURE0 + slot );
  3609. _gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.__webglTexture );
  3610. };
  3611. // Render targets
  3612. function setupFrameBuffer ( framebuffer, renderTarget, textureTarget ) {
  3613. _gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
  3614. _gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, textureTarget, renderTarget.__webglTexture, 0 );
  3615. };
  3616. function setupRenderBuffer ( renderbuffer, renderTarget ) {
  3617. _gl.bindRenderbuffer( _gl.RENDERBUFFER, renderbuffer );
  3618. if ( renderTarget.depthBuffer && ! renderTarget.stencilBuffer ) {
  3619. _gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_COMPONENT16, renderTarget.width, renderTarget.height );
  3620. _gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );
  3621. /* For some reason this is not working. Defaulting to RGBA4.
  3622. } else if( ! renderTarget.depthBuffer && renderTarget.stencilBuffer ) {
  3623. _gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.STENCIL_INDEX8, renderTarget.width, renderTarget.height );
  3624. _gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );
  3625. */
  3626. } else if ( renderTarget.depthBuffer && renderTarget.stencilBuffer ) {
  3627. _gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_STENCIL, renderTarget.width, renderTarget.height );
  3628. _gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );
  3629. } else {
  3630. _gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.RGBA4, renderTarget.width, renderTarget.height );
  3631. }
  3632. };
  3633. this.setRenderTarget = function ( renderTarget ) {
  3634. var isCube = ( renderTarget instanceof THREE.WebGLRenderTargetCube );
  3635. if ( renderTarget && ! renderTarget.__webglFramebuffer ) {
  3636. if ( renderTarget.depthBuffer === undefined ) renderTarget.depthBuffer = true;
  3637. if ( renderTarget.stencilBuffer === undefined ) renderTarget.stencilBuffer = true;
  3638. renderTarget.addEventListener( 'dispose', onRenderTargetDispose );
  3639. renderTarget.__webglTexture = _gl.createTexture();
  3640. _this.info.memory.textures ++;
  3641. // Setup texture, create render and frame buffers
  3642. var isTargetPowerOfTwo = THREE.Math.isPowerOfTwo( renderTarget.width ) && THREE.Math.isPowerOfTwo( renderTarget.height ),
  3643. glFormat = paramThreeToGL( renderTarget.format ),
  3644. glType = paramThreeToGL( renderTarget.type );
  3645. if ( isCube ) {
  3646. renderTarget.__webglFramebuffer = [];
  3647. renderTarget.__webglRenderbuffer = [];
  3648. _gl.bindTexture( _gl.TEXTURE_CUBE_MAP, renderTarget.__webglTexture );
  3649. setTextureParameters( _gl.TEXTURE_CUBE_MAP, renderTarget, isTargetPowerOfTwo );
  3650. for ( var i = 0; i < 6; i ++ ) {
  3651. renderTarget.__webglFramebuffer[ i ] = _gl.createFramebuffer();
  3652. renderTarget.__webglRenderbuffer[ i ] = _gl.createRenderbuffer();
  3653. _gl.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );
  3654. setupFrameBuffer( renderTarget.__webglFramebuffer[ i ], renderTarget, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i );
  3655. setupRenderBuffer( renderTarget.__webglRenderbuffer[ i ], renderTarget );
  3656. }
  3657. if ( isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );
  3658. } else {
  3659. renderTarget.__webglFramebuffer = _gl.createFramebuffer();
  3660. if ( renderTarget.shareDepthFrom ) {
  3661. renderTarget.__webglRenderbuffer = renderTarget.shareDepthFrom.__webglRenderbuffer;
  3662. } else {
  3663. renderTarget.__webglRenderbuffer = _gl.createRenderbuffer();
  3664. }
  3665. _gl.bindTexture( _gl.TEXTURE_2D, renderTarget.__webglTexture );
  3666. setTextureParameters( _gl.TEXTURE_2D, renderTarget, isTargetPowerOfTwo );
  3667. _gl.texImage2D( _gl.TEXTURE_2D, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );
  3668. setupFrameBuffer( renderTarget.__webglFramebuffer, renderTarget, _gl.TEXTURE_2D );
  3669. if ( renderTarget.shareDepthFrom ) {
  3670. if ( renderTarget.depthBuffer && ! renderTarget.stencilBuffer ) {
  3671. _gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderTarget.__webglRenderbuffer );
  3672. } else if ( renderTarget.depthBuffer && renderTarget.stencilBuffer ) {
  3673. _gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderTarget.__webglRenderbuffer );
  3674. }
  3675. } else {
  3676. setupRenderBuffer( renderTarget.__webglRenderbuffer, renderTarget );
  3677. }
  3678. if ( isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_2D );
  3679. }
  3680. // Release everything
  3681. if ( isCube ) {
  3682. _gl.bindTexture( _gl.TEXTURE_CUBE_MAP, null );
  3683. } else {
  3684. _gl.bindTexture( _gl.TEXTURE_2D, null );
  3685. }
  3686. _gl.bindRenderbuffer( _gl.RENDERBUFFER, null );
  3687. _gl.bindFramebuffer( _gl.FRAMEBUFFER, null );
  3688. }
  3689. var framebuffer, width, height, vx, vy;
  3690. if ( renderTarget ) {
  3691. if ( isCube ) {
  3692. framebuffer = renderTarget.__webglFramebuffer[ renderTarget.activeCubeFace ];
  3693. } else {
  3694. framebuffer = renderTarget.__webglFramebuffer;
  3695. }
  3696. width = renderTarget.width;
  3697. height = renderTarget.height;
  3698. vx = 0;
  3699. vy = 0;
  3700. } else {
  3701. framebuffer = null;
  3702. width = _viewportWidth;
  3703. height = _viewportHeight;
  3704. vx = _viewportX;
  3705. vy = _viewportY;
  3706. }
  3707. if ( framebuffer !== _currentFramebuffer ) {
  3708. _gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
  3709. _gl.viewport( vx, vy, width, height );
  3710. _currentFramebuffer = framebuffer;
  3711. }
  3712. _currentWidth = width;
  3713. _currentHeight = height;
  3714. };
  3715. function updateRenderTargetMipmap ( renderTarget ) {
  3716. if ( renderTarget instanceof THREE.WebGLRenderTargetCube ) {
  3717. _gl.bindTexture( _gl.TEXTURE_CUBE_MAP, renderTarget.__webglTexture );
  3718. _gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );
  3719. _gl.bindTexture( _gl.TEXTURE_CUBE_MAP, null );
  3720. } else {
  3721. _gl.bindTexture( _gl.TEXTURE_2D, renderTarget.__webglTexture );
  3722. _gl.generateMipmap( _gl.TEXTURE_2D );
  3723. _gl.bindTexture( _gl.TEXTURE_2D, null );
  3724. }
  3725. };
  3726. // Fallback filters for non-power-of-2 textures
  3727. function filterFallback ( f ) {
  3728. if ( f === THREE.NearestFilter || f === THREE.NearestMipMapNearestFilter || f === THREE.NearestMipMapLinearFilter ) {
  3729. return _gl.NEAREST;
  3730. }
  3731. return _gl.LINEAR;
  3732. };
  3733. // Map three.js constants to WebGL constants
  3734. function paramThreeToGL ( p ) {
  3735. if ( p === THREE.RepeatWrapping ) return _gl.REPEAT;
  3736. if ( p === THREE.ClampToEdgeWrapping ) return _gl.CLAMP_TO_EDGE;
  3737. if ( p === THREE.MirroredRepeatWrapping ) return _gl.MIRRORED_REPEAT;
  3738. if ( p === THREE.NearestFilter ) return _gl.NEAREST;
  3739. if ( p === THREE.NearestMipMapNearestFilter ) return _gl.NEAREST_MIPMAP_NEAREST;
  3740. if ( p === THREE.NearestMipMapLinearFilter ) return _gl.NEAREST_MIPMAP_LINEAR;
  3741. if ( p === THREE.LinearFilter ) return _gl.LINEAR;
  3742. if ( p === THREE.LinearMipMapNearestFilter ) return _gl.LINEAR_MIPMAP_NEAREST;
  3743. if ( p === THREE.LinearMipMapLinearFilter ) return _gl.LINEAR_MIPMAP_LINEAR;
  3744. if ( p === THREE.UnsignedByteType ) return _gl.UNSIGNED_BYTE;
  3745. if ( p === THREE.UnsignedShort4444Type ) return _gl.UNSIGNED_SHORT_4_4_4_4;
  3746. if ( p === THREE.UnsignedShort5551Type ) return _gl.UNSIGNED_SHORT_5_5_5_1;
  3747. if ( p === THREE.UnsignedShort565Type ) return _gl.UNSIGNED_SHORT_5_6_5;
  3748. if ( p === THREE.ByteType ) return _gl.BYTE;
  3749. if ( p === THREE.ShortType ) return _gl.SHORT;
  3750. if ( p === THREE.UnsignedShortType ) return _gl.UNSIGNED_SHORT;
  3751. if ( p === THREE.IntType ) return _gl.INT;
  3752. if ( p === THREE.UnsignedIntType ) return _gl.UNSIGNED_INT;
  3753. if ( p === THREE.FloatType ) return _gl.FLOAT;
  3754. if ( p === THREE.AlphaFormat ) return _gl.ALPHA;
  3755. if ( p === THREE.RGBFormat ) return _gl.RGB;
  3756. if ( p === THREE.RGBAFormat ) return _gl.RGBA;
  3757. if ( p === THREE.LuminanceFormat ) return _gl.LUMINANCE;
  3758. if ( p === THREE.LuminanceAlphaFormat ) return _gl.LUMINANCE_ALPHA;
  3759. if ( p === THREE.AddEquation ) return _gl.FUNC_ADD;
  3760. if ( p === THREE.SubtractEquation ) return _gl.FUNC_SUBTRACT;
  3761. if ( p === THREE.ReverseSubtractEquation ) return _gl.FUNC_REVERSE_SUBTRACT;
  3762. if ( p === THREE.ZeroFactor ) return _gl.ZERO;
  3763. if ( p === THREE.OneFactor ) return _gl.ONE;
  3764. if ( p === THREE.SrcColorFactor ) return _gl.SRC_COLOR;
  3765. if ( p === THREE.OneMinusSrcColorFactor ) return _gl.ONE_MINUS_SRC_COLOR;
  3766. if ( p === THREE.SrcAlphaFactor ) return _gl.SRC_ALPHA;
  3767. if ( p === THREE.OneMinusSrcAlphaFactor ) return _gl.ONE_MINUS_SRC_ALPHA;
  3768. if ( p === THREE.DstAlphaFactor ) return _gl.DST_ALPHA;
  3769. if ( p === THREE.OneMinusDstAlphaFactor ) return _gl.ONE_MINUS_DST_ALPHA;
  3770. if ( p === THREE.DstColorFactor ) return _gl.DST_COLOR;
  3771. if ( p === THREE.OneMinusDstColorFactor ) return _gl.ONE_MINUS_DST_COLOR;
  3772. if ( p === THREE.SrcAlphaSaturateFactor ) return _gl.SRC_ALPHA_SATURATE;
  3773. if ( _glExtensionCompressedTextureS3TC !== undefined ) {
  3774. if ( p === THREE.RGB_S3TC_DXT1_Format ) return _glExtensionCompressedTextureS3TC.COMPRESSED_RGB_S3TC_DXT1_EXT;
  3775. if ( p === THREE.RGBA_S3TC_DXT1_Format ) return _glExtensionCompressedTextureS3TC.COMPRESSED_RGBA_S3TC_DXT1_EXT;
  3776. if ( p === THREE.RGBA_S3TC_DXT3_Format ) return _glExtensionCompressedTextureS3TC.COMPRESSED_RGBA_S3TC_DXT3_EXT;
  3777. if ( p === THREE.RGBA_S3TC_DXT5_Format ) return _glExtensionCompressedTextureS3TC.COMPRESSED_RGBA_S3TC_DXT5_EXT;
  3778. }
  3779. return 0;
  3780. };
  3781. // Allocations
  3782. function allocateBones ( object ) {
  3783. if ( _supportsBoneTextures && object && object.useVertexTexture ) {
  3784. return 1024;
  3785. } else {
  3786. // default for when object is not specified
  3787. // ( for example when prebuilding shader
  3788. // to be used with multiple objects )
  3789. //
  3790. // - leave some extra space for other uniforms
  3791. // - limit here is ANGLE's 254 max uniform vectors
  3792. // (up to 54 should be safe)
  3793. var nVertexUniforms = _gl.getParameter( _gl.MAX_VERTEX_UNIFORM_VECTORS );
  3794. var nVertexMatrices = Math.floor( ( nVertexUniforms - 20 ) / 4 );
  3795. var maxBones = nVertexMatrices;
  3796. if ( object !== undefined && object instanceof THREE.SkinnedMesh ) {
  3797. maxBones = Math.min( object.bones.length, maxBones );
  3798. if ( maxBones < object.bones.length ) {
  3799. console.warn( "WebGLRenderer: too many bones - " + object.bones.length + ", this GPU supports just " + maxBones + " (try OpenGL instead of ANGLE)" );
  3800. }
  3801. }
  3802. return maxBones;
  3803. }
  3804. };
  3805. function allocateLights( lights ) {
  3806. var dirLights = 0;
  3807. var pointLights = 0;
  3808. var spotLights = 0;
  3809. var hemiLights = 0;
  3810. for ( var l = 0, ll = lights.length; l < ll; l ++ ) {
  3811. var light = lights[ l ];
  3812. if ( light.onlyShadow ) continue;
  3813. if ( light instanceof THREE.DirectionalLight ) dirLights ++;
  3814. if ( light instanceof THREE.PointLight ) pointLights ++;
  3815. if ( light instanceof THREE.SpotLight ) spotLights ++;
  3816. if ( light instanceof THREE.HemisphereLight ) hemiLights ++;
  3817. }
  3818. return { 'directional' : dirLights, 'point' : pointLights, 'spot': spotLights, 'hemi': hemiLights };
  3819. };
  3820. function allocateShadows( lights ) {
  3821. var maxShadows = 0;
  3822. for ( var l = 0, ll = lights.length; l < ll; l++ ) {
  3823. var light = lights[ l ];
  3824. if ( ! light.castShadow ) continue;
  3825. if ( light instanceof THREE.SpotLight ) maxShadows ++;
  3826. if ( light instanceof THREE.DirectionalLight && ! light.shadowCascade ) maxShadows ++;
  3827. }
  3828. return maxShadows;
  3829. };
  3830. // Initialization
  3831. function initGL() {
  3832. try {
  3833. var attributes = {
  3834. alpha: _alpha,
  3835. premultipliedAlpha: _premultipliedAlpha,
  3836. antialias: _antialias,
  3837. stencil: _stencil,
  3838. preserveDrawingBuffer: _preserveDrawingBuffer
  3839. };
  3840. _gl = _context || _canvas.getContext( 'webgl', attributes ) || _canvas.getContext( 'experimental-webgl', attributes );
  3841. if ( _gl === null ) {
  3842. throw 'Error creating WebGL context.';
  3843. }
  3844. } catch ( error ) {
  3845. console.error( error );
  3846. }
  3847. _glExtensionTextureFloat = _gl.getExtension( 'OES_texture_float' );
  3848. _glExtensionTextureFloatLinear = _gl.getExtension( 'OES_texture_float_linear' );
  3849. _glExtensionStandardDerivatives = _gl.getExtension( 'OES_standard_derivatives' );
  3850. _glExtensionTextureFilterAnisotropic = _gl.getExtension( 'EXT_texture_filter_anisotropic' ) || _gl.getExtension( 'MOZ_EXT_texture_filter_anisotropic' ) || _gl.getExtension( 'WEBKIT_EXT_texture_filter_anisotropic' );
  3851. _glExtensionCompressedTextureS3TC = _gl.getExtension( 'WEBGL_compressed_texture_s3tc' ) || _gl.getExtension( 'MOZ_WEBGL_compressed_texture_s3tc' ) || _gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_s3tc' );
  3852. if ( ! _glExtensionTextureFloat ) {
  3853. console.log( 'THREE.WebGLRenderer: Float textures not supported.' );
  3854. }
  3855. if ( ! _glExtensionStandardDerivatives ) {
  3856. console.log( 'THREE.WebGLRenderer: Standard derivatives not supported.' );
  3857. }
  3858. if ( ! _glExtensionTextureFilterAnisotropic ) {
  3859. console.log( 'THREE.WebGLRenderer: Anisotropic texture filtering not supported.' );
  3860. }
  3861. if ( ! _glExtensionCompressedTextureS3TC ) {
  3862. console.log( 'THREE.WebGLRenderer: S3TC compressed textures not supported.' );
  3863. }
  3864. if ( _gl.getShaderPrecisionFormat === undefined ) {
  3865. _gl.getShaderPrecisionFormat = function() {
  3866. return {
  3867. "rangeMin" : 1,
  3868. "rangeMax" : 1,
  3869. "precision" : 1
  3870. };
  3871. }
  3872. }
  3873. };
  3874. function setDefaultGLState () {
  3875. _gl.clearColor( 0, 0, 0, 1 );
  3876. _gl.clearDepth( 1 );
  3877. _gl.clearStencil( 0 );
  3878. _gl.enable( _gl.DEPTH_TEST );
  3879. _gl.depthFunc( _gl.LEQUAL );
  3880. _gl.frontFace( _gl.CCW );
  3881. _gl.cullFace( _gl.BACK );
  3882. _gl.enable( _gl.CULL_FACE );
  3883. _gl.enable( _gl.BLEND );
  3884. _gl.blendEquation( _gl.FUNC_ADD );
  3885. _gl.blendFunc( _gl.SRC_ALPHA, _gl.ONE_MINUS_SRC_ALPHA );
  3886. _gl.viewport( _viewportX, _viewportY, _viewportWidth, _viewportHeight );
  3887. _gl.clearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha );
  3888. };
  3889. // default plugins (order is important)
  3890. this.shadowMapPlugin = new THREE.ShadowMapPlugin();
  3891. this.addPrePlugin( this.shadowMapPlugin );
  3892. this.addPostPlugin( new THREE.SpritePlugin() );
  3893. this.addPostPlugin( new THREE.LensFlarePlugin() );
  3894. };