12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493 |
- import BoundingRectangle from "../Core/BoundingRectangle.js";
- import BoundingSphere from "../Core/BoundingSphere.js";
- import BoxGeometry from "../Core/BoxGeometry.js";
- import Cartesian3 from "../Core/Cartesian3.js";
- import Cartographic from "../Core/Cartographic.js";
- import clone from "../Core/clone.js";
- import Color from "../Core/Color.js";
- import ColorGeometryInstanceAttribute from "../Core/ColorGeometryInstanceAttribute.js";
- import createGuid from "../Core/createGuid.js";
- import CullingVolume from "../Core/CullingVolume.js";
- import defaultValue from "../Core/defaultValue.js";
- import defined from "../Core/defined.js";
- import destroyObject from "../Core/destroyObject.js";
- import DeveloperError from "../Core/DeveloperError.js";
- import EllipsoidGeometry from "../Core/EllipsoidGeometry.js";
- import Event from "../Core/Event.js";
- import GeographicProjection from "../Core/GeographicProjection.js";
- import GeometryInstance from "../Core/GeometryInstance.js";
- import GeometryPipeline from "../Core/GeometryPipeline.js";
- import Intersect from "../Core/Intersect.js";
- import JulianDate from "../Core/JulianDate.js";
- import CesiumMath from "../Core/Math.js";
- import Matrix4 from "../Core/Matrix4.js";
- import mergeSort from "../Core/mergeSort.js";
- import Occluder from "../Core/Occluder.js";
- import OrthographicFrustum from "../Core/OrthographicFrustum.js";
- import OrthographicOffCenterFrustum from "../Core/OrthographicOffCenterFrustum.js";
- import PerspectiveFrustum from "../Core/PerspectiveFrustum.js";
- import PerspectiveOffCenterFrustum from "../Core/PerspectiveOffCenterFrustum.js";
- import RequestScheduler from "../Core/RequestScheduler.js";
- import TaskProcessor from "../Core/TaskProcessor.js";
- import Transforms from "../Core/Transforms.js";
- import ClearCommand from "../Renderer/ClearCommand.js";
- import ComputeEngine from "../Renderer/ComputeEngine.js";
- import Context from "../Renderer/Context.js";
- import ContextLimits from "../Renderer/ContextLimits.js";
- import Pass from "../Renderer/Pass.js";
- import RenderState from "../Renderer/RenderState.js";
- import BrdfLutGenerator from "./BrdfLutGenerator.js";
- import Camera from "./Camera.js";
- import Cesium3DTilePass from "./Cesium3DTilePass.js";
- import Cesium3DTilePassState from "./Cesium3DTilePassState.js";
- import CreditDisplay from "./CreditDisplay.js";
- import DebugCameraPrimitive from "./DebugCameraPrimitive.js";
- import DepthPlane from "./DepthPlane.js";
- import DerivedCommand from "./DerivedCommand.js";
- import DeviceOrientationCameraController from "./DeviceOrientationCameraController.js";
- import Fog from "./Fog.js";
- import FrameState from "./FrameState.js";
- import GlobeDepth from "./GlobeDepth.js";
- import GlobeTranslucencyState from "./GlobeTranslucencyState.js";
- import InvertClassification from "./InvertClassification.js";
- import JobScheduler from "./JobScheduler.js";
- import MapMode2D from "./MapMode2D.js";
- import OctahedralProjectedCubeMap from "./OctahedralProjectedCubeMap.js";
- import PerformanceDisplay from "./PerformanceDisplay.js";
- import PerInstanceColorAppearance from "./PerInstanceColorAppearance.js";
- import Picking from "./Picking.js";
- import PostProcessStageCollection from "./PostProcessStageCollection.js";
- import Primitive from "./Primitive.js";
- import PrimitiveCollection from "./PrimitiveCollection.js";
- import SceneMode from "./SceneMode.js";
- import SceneTransforms from "./SceneTransforms.js";
- import SceneTransitioner from "./SceneTransitioner.js";
- import ScreenSpaceCameraController from "./ScreenSpaceCameraController.js";
- import ShadowMap from "./ShadowMap.js";
- import StencilConstants from "./StencilConstants.js";
- import SunLight from "./SunLight.js";
- import SunPostProcess from "./SunPostProcess.js";
- import TweenCollection from "./TweenCollection.js";
- import View from "./View.js";
- import DebugInspector from "./DebugInspector.js";
- var requestRenderAfterFrame = function (scene) {
- return function () {
- scene.frameState.afterRender.push(function () {
- scene.requestRender();
- });
- };
- };
- /**
- * The container for all 3D graphical objects and state in a Cesium virtual scene. Generally,
- * a scene is not created directly; instead, it is implicitly created by {@link CesiumWidget}.
- * <p>
- * <em><code>contextOptions</code> parameter details:</em>
- * </p>
- * <p>
- * The default values are:
- * <code>
- * {
- * webgl : {
- * alpha : false,
- * depth : true,
- * stencil : false,
- * antialias : true,
- * powerPreference: 'high-performance',
- * premultipliedAlpha : true,
- * preserveDrawingBuffer : false,
- * failIfMajorPerformanceCaveat : false
- * },
- * allowTextureFilterAnisotropic : true
- * }
- * </code>
- * </p>
- * <p>
- * The <code>webgl</code> property corresponds to the {@link http://www.khronos.org/registry/webgl/specs/latest/#5.2|WebGLContextAttributes}
- * object used to create the WebGL context.
- * </p>
- * <p>
- * <code>webgl.alpha</code> defaults to false, which can improve performance compared to the standard WebGL default
- * of true. If an application needs to composite Cesium above other HTML elements using alpha-blending, set
- * <code>webgl.alpha</code> to true.
- * </p>
- * <p>
- * The other <code>webgl</code> properties match the WebGL defaults for {@link http://www.khronos.org/registry/webgl/specs/latest/#5.2|WebGLContextAttributes}.
- * </p>
- * <p>
- * <code>allowTextureFilterAnisotropic</code> defaults to true, which enables anisotropic texture filtering when the
- * WebGL extension is supported. Setting this to false will improve performance, but hurt visual quality, especially for horizon views.
- * </p>
- *
- * @alias Scene
- * @constructor
- *
- * @param {Object} [options] Object with the following properties:
- * @param {HTMLCanvasElement} options.canvas The HTML canvas element to create the scene for.
- * @param {Object} [options.contextOptions] Context and WebGL creation properties. See details above.
- * @param {Element} [options.creditContainer] The HTML element in which the credits will be displayed.
- * @param {Element} [options.creditViewport] The HTML element in which to display the credit popup. If not specified, the viewport will be a added as a sibling of the canvas.
- * @param {MapProjection} [options.mapProjection=new GeographicProjection()] The map projection to use in 2D and Columbus View modes.
- * @param {Boolean} [options.orderIndependentTranslucency=true] If true and the configuration supports it, use order independent translucency.
- * @param {Boolean} [options.scene3DOnly=false] If true, optimizes memory use and performance for 3D mode but disables the ability to use 2D or Columbus View.
- * @param {Number} [options.terrainExaggeration=1.0] A scalar used to exaggerate the terrain. Note that terrain exaggeration will not modify any other primitive as they are positioned relative to the ellipsoid.
- * @param {Boolean} [options.shadows=false] Determines if shadows are cast by light sources.
- * @param {MapMode2D} [options.mapMode2D=MapMode2D.INFINITE_SCROLL] Determines if the 2D map is rotatable or can be scrolled infinitely in the horizontal direction.
- * @param {Boolean} [options.requestRenderMode=false] If true, rendering a frame will only occur when needed as determined by changes within the scene. Enabling improves performance of the application, but requires using {@link Scene#requestRender} to render a new frame explicitly in this mode. This will be necessary in many cases after making changes to the scene in other parts of the API. See {@link https://cesium.com/blog/2018/01/24/cesium-scene-rendering-performance/|Improving Performance with Explicit Rendering}.
- * @param {Number} [options.maximumRenderTimeChange=0.0] If requestRenderMode is true, this value defines the maximum change in simulation time allowed before a render is requested. See {@link https://cesium.com/blog/2018/01/24/cesium-scene-rendering-performance/|Improving Performance with Explicit Rendering}.
- *
- * @see CesiumWidget
- * @see {@link http://www.khronos.org/registry/webgl/specs/latest/#5.2|WebGLContextAttributes}
- *
- * @exception {DeveloperError} options and options.canvas are required.
- *
- * @example
- * // Create scene without anisotropic texture filtering
- * var scene = new Cesium.Scene({
- * canvas : canvas,
- * contextOptions : {
- * allowTextureFilterAnisotropic : false
- * }
- * });
- */
- function Scene(options) {
- options = defaultValue(options, defaultValue.EMPTY_OBJECT);
- var canvas = options.canvas;
- var creditContainer = options.creditContainer;
- var creditViewport = options.creditViewport;
- var contextOptions = clone(options.contextOptions);
- if (!defined(contextOptions)) {
- contextOptions = {};
- }
- if (!defined(contextOptions.webgl)) {
- contextOptions.webgl = {};
- }
- contextOptions.webgl.powerPreference = defaultValue(
- contextOptions.webgl.powerPreference,
- "high-performance"
- );
- //>>includeStart('debug', pragmas.debug);
- if (!defined(canvas)) {
- throw new DeveloperError("options and options.canvas are required.");
- }
- //>>includeEnd('debug');
- var hasCreditContainer = defined(creditContainer);
- var context = new Context(canvas, contextOptions);
- if (!hasCreditContainer) {
- creditContainer = document.createElement("div");
- creditContainer.style.position = "absolute";
- creditContainer.style.bottom = "0";
- creditContainer.style["text-shadow"] = "0 0 2px #000000";
- creditContainer.style.color = "#ffffff";
- creditContainer.style["font-size"] = "10px";
- creditContainer.style["padding-right"] = "5px";
- canvas.parentNode.appendChild(creditContainer);
- }
- if (!defined(creditViewport)) {
- creditViewport = canvas.parentNode;
- }
- this._id = createGuid();
- this._jobScheduler = new JobScheduler();
- this._frameState = new FrameState(
- context,
- new CreditDisplay(creditContainer, " • ", creditViewport),
- this._jobScheduler
- );
- this._frameState.scene3DOnly = defaultValue(options.scene3DOnly, false);
- this._removeCreditContainer = !hasCreditContainer;
- this._creditContainer = creditContainer;
- this._canvas = canvas;
- this._context = context;
- this._computeEngine = new ComputeEngine(context);
- this._globe = undefined;
- this._globeTranslucencyState = new GlobeTranslucencyState();
- this._primitives = new PrimitiveCollection();
- this._groundPrimitives = new PrimitiveCollection();
- this._globeHeight = undefined;
- this._cameraUnderground = false;
- this._logDepthBuffer = context.fragmentDepth;
- this._logDepthBufferDirty = true;
- this._tweens = new TweenCollection();
- this._shaderFrameCount = 0;
- this._sunPostProcess = undefined;
- this._computeCommandList = [];
- this._overlayCommandList = [];
- this._useOIT = defaultValue(options.orderIndependentTranslucency, true);
- this._executeOITFunction = undefined;
- this._depthPlane = new DepthPlane();
- this._clearColorCommand = new ClearCommand({
- color: new Color(),
- stencil: 0,
- owner: this,
- });
- this._depthClearCommand = new ClearCommand({
- depth: 1.0,
- owner: this,
- });
- this._stencilClearCommand = new ClearCommand({
- stencil: 0,
- });
- this._classificationStencilClearCommand = new ClearCommand({
- stencil: 0,
- renderState: RenderState.fromCache({
- stencilMask: StencilConstants.CLASSIFICATION_MASK,
- }),
- });
- this._depthOnlyRenderStateCache = {};
- this._transitioner = new SceneTransitioner(this);
- this._preUpdate = new Event();
- this._postUpdate = new Event();
- this._renderError = new Event();
- this._preRender = new Event();
- this._postRender = new Event();
- this._minimumDisableDepthTestDistance = 0.0;
- this._debugInspector = new DebugInspector();
- /**
- * Exceptions occurring in <code>render</code> are always caught in order to raise the
- * <code>renderError</code> event. If this property is true, the error is rethrown
- * after the event is raised. If this property is false, the <code>render</code> function
- * returns normally after raising the event.
- *
- * @type {Boolean}
- * @default false
- */
- this.rethrowRenderErrors = false;
- /**
- * Determines whether or not to instantly complete the
- * scene transition animation on user input.
- *
- * @type {Boolean}
- * @default true
- */
- this.completeMorphOnUserInput = true;
- /**
- * The event fired at the beginning of a scene transition.
- * @type {Event}
- * @default Event()
- */
- this.morphStart = new Event();
- /**
- * The event fired at the completion of a scene transition.
- * @type {Event}
- * @default Event()
- */
- this.morphComplete = new Event();
- /**
- * The {@link SkyBox} used to draw the stars.
- *
- * @type {SkyBox}
- * @default undefined
- *
- * @see Scene#backgroundColor
- */
- this.skyBox = undefined;
- /**
- * The sky atmosphere drawn around the globe.
- *
- * @type {SkyAtmosphere}
- * @default undefined
- */
- this.skyAtmosphere = undefined;
- /**
- * The {@link Sun}.
- *
- * @type {Sun}
- * @default undefined
- */
- this.sun = undefined;
- /**
- * Uses a bloom filter on the sun when enabled.
- *
- * @type {Boolean}
- * @default true
- */
- this.sunBloom = true;
- this._sunBloom = undefined;
- /**
- * The {@link Moon}
- *
- * @type Moon
- * @default undefined
- */
- this.moon = undefined;
- /**
- * The background color, which is only visible if there is no sky box, i.e., {@link Scene#skyBox} is undefined.
- *
- * @type {Color}
- * @default {@link Color.BLACK}
- *
- * @see Scene#skyBox
- */
- this.backgroundColor = Color.clone(Color.BLACK);
- this._mode = SceneMode.SCENE3D;
- this._mapProjection = defined(options.mapProjection)
- ? options.mapProjection
- : new GeographicProjection();
- /**
- * The current morph transition time between 2D/Columbus View and 3D,
- * with 0.0 being 2D or Columbus View and 1.0 being 3D.
- *
- * @type {Number}
- * @default 1.0
- */
- this.morphTime = 1.0;
- /**
- * The far-to-near ratio of the multi-frustum when using a normal depth buffer.
- * <p>
- * This value is used to create the near and far values for each frustum of the multi-frustum. It is only used
- * when {@link Scene#logarithmicDepthBuffer} is <code>false</code>. When <code>logarithmicDepthBuffer</code> is
- * <code>true</code>, use {@link Scene#logarithmicDepthFarToNearRatio}.
- * </p>
- *
- * @type {Number}
- * @default 1000.0
- */
- this.farToNearRatio = 1000.0;
- /**
- * The far-to-near ratio of the multi-frustum when using a logarithmic depth buffer.
- * <p>
- * This value is used to create the near and far values for each frustum of the multi-frustum. It is only used
- * when {@link Scene#logarithmicDepthBuffer} is <code>true</code>. When <code>logarithmicDepthBuffer</code> is
- * <code>false</code>, use {@link Scene#farToNearRatio}.
- * </p>
- *
- * @type {Number}
- * @default 1e9
- */
- this.logarithmicDepthFarToNearRatio = 1e9;
- /**
- * Determines the uniform depth size in meters of each frustum of the multifrustum in 2D. If a primitive or model close
- * to the surface shows z-fighting, decreasing this will eliminate the artifact, but decrease performance. On the
- * other hand, increasing this will increase performance but may cause z-fighting among primitives close to the surface.
- *
- * @type {Number}
- * @default 1.75e6
- */
- this.nearToFarDistance2D = 1.75e6;
- /**
- * This property is for debugging only; it is not for production use.
- * <p>
- * A function that determines what commands are executed. As shown in the examples below,
- * the function receives the command's <code>owner</code> as an argument, and returns a boolean indicating if the
- * command should be executed.
- * </p>
- * <p>
- * The default is <code>undefined</code>, indicating that all commands are executed.
- * </p>
- *
- * @type Function
- *
- * @default undefined
- *
- * @example
- * // Do not execute any commands.
- * scene.debugCommandFilter = function(command) {
- * return false;
- * };
- *
- * // Execute only the billboard's commands. That is, only draw the billboard.
- * var billboards = new Cesium.BillboardCollection();
- * scene.debugCommandFilter = function(command) {
- * return command.owner === billboards;
- * };
- */
- this.debugCommandFilter = undefined;
- /**
- * This property is for debugging only; it is not for production use.
- * <p>
- * When <code>true</code>, commands are randomly shaded. This is useful
- * for performance analysis to see what parts of a scene or model are
- * command-dense and could benefit from batching.
- * </p>
- *
- * @type Boolean
- *
- * @default false
- */
- this.debugShowCommands = false;
- /**
- * This property is for debugging only; it is not for production use.
- * <p>
- * When <code>true</code>, commands are shaded based on the frustums they
- * overlap. Commands in the closest frustum are tinted red, commands in
- * the next closest are green, and commands in the farthest frustum are
- * blue. If a command overlaps more than one frustum, the color components
- * are combined, e.g., a command overlapping the first two frustums is tinted
- * yellow.
- * </p>
- *
- * @type Boolean
- *
- * @default false
- */
- this.debugShowFrustums = false;
- /**
- * This property is for debugging only; it is not for production use.
- * <p>
- * Displays frames per second and time between frames.
- * </p>
- *
- * @type Boolean
- *
- * @default false
- */
- this.debugShowFramesPerSecond = false;
- /**
- * This property is for debugging only; it is not for production use.
- * <p>
- * Displays depth information for the indicated frustum.
- * </p>
- *
- * @type Boolean
- *
- * @default false
- */
- this.debugShowGlobeDepth = false;
- /**
- * This property is for debugging only; it is not for production use.
- * <p>
- * Indicates which frustum will have depth information displayed.
- * </p>
- *
- * @type Number
- *
- * @default 1
- */
- this.debugShowDepthFrustum = 1;
- /**
- * This property is for debugging only; it is not for production use.
- * <p>
- * When <code>true</code>, draws outlines to show the boundaries of the camera frustums
- * </p>
- *
- * @type Boolean
- *
- * @default false
- */
- this.debugShowFrustumPlanes = false;
- this._debugShowFrustumPlanes = false;
- this._debugFrustumPlanes = undefined;
- /**
- * When <code>true</code>, enables picking using the depth buffer.
- *
- * @type Boolean
- * @default true
- */
- this.useDepthPicking = true;
- /**
- * When <code>true</code>, enables picking translucent geometry using the depth buffer. Note that {@link Scene#useDepthPicking} must also be true for enabling this to work.
- *
- * <p>
- * Render must be called between picks.
- * <br>There is a decrease in performance when enabled. There are extra draw calls to write depth for
- * translucent geometry.
- * </p>
- *
- * @example
- * // picking the position of a translucent primitive
- * viewer.screenSpaceEventHandler.setInputAction(function onLeftClick(movement) {
- * var pickedFeature = viewer.scene.pick(movement.position);
- * if (!Cesium.defined(pickedFeature)) {
- * // nothing picked
- * return;
- * }
- * viewer.scene.render();
- * var worldPosition = viewer.scene.pickPosition(movement.position);
- * }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
- *
- * @type {Boolean}
- * @default false
- */
- this.pickTranslucentDepth = false;
- /**
- * The time in milliseconds to wait before checking if the camera has not moved and fire the cameraMoveEnd event.
- * @type {Number}
- * @default 500.0
- * @private
- */
- this.cameraEventWaitTime = 500.0;
- /**
- * Blends the atmosphere to geometry far from the camera for horizon views. Allows for additional
- * performance improvements by rendering less geometry and dispatching less terrain requests.
- * @type {Fog}
- */
- this.fog = new Fog();
- this._shadowMapCamera = new Camera(this);
- /**
- * The shadow map for the scene's light source. When enabled, models, primitives, and the globe may cast and receive shadows.
- * @type {ShadowMap}
- */
- this.shadowMap = new ShadowMap({
- context: context,
- lightCamera: this._shadowMapCamera,
- enabled: defaultValue(options.shadows, false),
- });
- /**
- * When <code>false</code>, 3D Tiles will render normally. When <code>true</code>, classified 3D Tile geometry will render normally and
- * unclassified 3D Tile geometry will render with the color multiplied by {@link Scene#invertClassificationColor}.
- * @type {Boolean}
- * @default false
- */
- this.invertClassification = false;
- /**
- * The highlight color of unclassified 3D Tile geometry when {@link Scene#invertClassification} is <code>true</code>.
- * <p>When the color's alpha is less than 1.0, the unclassified portions of the 3D Tiles will not blend correctly with the classified positions of the 3D Tiles.</p>
- * <p>Also, when the color's alpha is less than 1.0, the WEBGL_depth_texture and EXT_frag_depth WebGL extensions must be supported.</p>
- * @type {Color}
- * @default Color.WHITE
- */
- this.invertClassificationColor = Color.clone(Color.WHITE);
- this._actualInvertClassificationColor = Color.clone(
- this._invertClassificationColor
- );
- this._invertClassification = new InvertClassification();
- /**
- * The focal length for use when with cardboard or WebVR.
- * @type {Number}
- */
- this.focalLength = undefined;
- /**
- * The eye separation distance in meters for use with cardboard or WebVR.
- * @type {Number}
- */
- this.eyeSeparation = undefined;
- /**
- * Post processing effects applied to the final render.
- * @type {PostProcessStageCollection}
- */
- this.postProcessStages = new PostProcessStageCollection();
- this._brdfLutGenerator = new BrdfLutGenerator();
- this._terrainExaggeration = defaultValue(options.terrainExaggeration, 1.0);
- this._performanceDisplay = undefined;
- this._debugVolume = undefined;
- this._screenSpaceCameraController = new ScreenSpaceCameraController(this);
- this._cameraUnderground = false;
- this._mapMode2D = defaultValue(options.mapMode2D, MapMode2D.INFINITE_SCROLL);
- // Keeps track of the state of a frame. FrameState is the state across
- // the primitives of the scene. This state is for internally keeping track
- // of celestial and environment effects that need to be updated/rendered in
- // a certain order as well as updating/tracking framebuffer usage.
- this._environmentState = {
- skyBoxCommand: undefined,
- skyAtmosphereCommand: undefined,
- sunDrawCommand: undefined,
- sunComputeCommand: undefined,
- moonCommand: undefined,
- isSunVisible: false,
- isMoonVisible: false,
- isReadyForAtmosphere: false,
- isSkyAtmosphereVisible: false,
- clearGlobeDepth: false,
- useDepthPlane: false,
- renderTranslucentDepthForPick: false,
- originalFramebuffer: undefined,
- useGlobeDepthFramebuffer: false,
- separatePrimitiveFramebuffer: false,
- useOIT: false,
- useInvertClassification: false,
- usePostProcess: false,
- usePostProcessSelected: false,
- useWebVR: false,
- };
- this._useWebVR = false;
- this._cameraVR = undefined;
- this._aspectRatioVR = undefined;
- /**
- * When <code>true</code>, rendering a frame will only occur when needed as determined by changes within the scene.
- * Enabling improves performance of the application, but requires using {@link Scene#requestRender}
- * to render a new frame explicitly in this mode. This will be necessary in many cases after making changes
- * to the scene in other parts of the API.
- *
- * @see {@link https://cesium.com/blog/2018/01/24/cesium-scene-rendering-performance/|Improving Performance with Explicit Rendering}
- * @see Scene#maximumRenderTimeChange
- * @see Scene#requestRender
- *
- * @type {Boolean}
- * @default false
- */
- this.requestRenderMode = defaultValue(options.requestRenderMode, false);
- this._renderRequested = true;
- /**
- * If {@link Scene#requestRenderMode} is <code>true</code>, this value defines the maximum change in
- * simulation time allowed before a render is requested. Lower values increase the number of frames rendered
- * and higher values decrease the number of frames rendered. If <code>undefined</code>, changes to
- * the simulation time will never request a render.
- * This value impacts the rate of rendering for changes in the scene like lighting, entity property updates,
- * and animations.
- *
- * @see {@link https://cesium.com/blog/2018/01/24/cesium-scene-rendering-performance/|Improving Performance with Explicit Rendering}
- * @see Scene#requestRenderMode
- *
- * @type {Number}
- * @default 0.0
- */
- this.maximumRenderTimeChange = defaultValue(
- options.maximumRenderTimeChange,
- 0.0
- );
- this._lastRenderTime = undefined;
- this._frameRateMonitor = undefined;
- this._removeRequestListenerCallback = RequestScheduler.requestCompletedEvent.addEventListener(
- requestRenderAfterFrame(this)
- );
- this._removeTaskProcessorListenerCallback = TaskProcessor.taskCompletedEvent.addEventListener(
- requestRenderAfterFrame(this)
- );
- this._removeGlobeCallbacks = [];
- var viewport = new BoundingRectangle(
- 0,
- 0,
- context.drawingBufferWidth,
- context.drawingBufferHeight
- );
- var camera = new Camera(this);
- if (this._logDepthBuffer) {
- camera.frustum.near = 0.1;
- camera.frustum.far = 10000000000.0;
- }
- /**
- * The camera view for the scene camera flight destination. Used for preloading flight destination tiles.
- * @type {Camera}
- * @private
- */
- this.preloadFlightCamera = new Camera(this);
- /**
- * The culling volume for the scene camera flight destination. Used for preloading flight destination tiles.
- * @type {CullingVolume}
- * @private
- */
- this.preloadFlightCullingVolume = undefined;
- this._picking = new Picking(this);
- this._defaultView = new View(this, camera, viewport);
- this._view = this._defaultView;
- this._hdr = undefined;
- this._hdrDirty = undefined;
- this.highDynamicRange = false;
- this.gamma = 2.2;
- /**
- * The spherical harmonic coefficients for image-based lighting of PBR models.
- * @type {Cartesian3[]}
- */
- this.sphericalHarmonicCoefficients = undefined;
- /**
- * The url to the KTX file containing the specular environment map and convoluted mipmaps for image-based lighting of PBR models.
- * @type {String}
- */
- this.specularEnvironmentMaps = undefined;
- this._specularEnvironmentMapAtlas = undefined;
- /**
- * The light source for shading. Defaults to a directional light from the Sun.
- * @type {Light}
- */
- this.light = new SunLight();
- // Give frameState, camera, and screen space camera controller initial state before rendering
- updateFrameNumber(this, 0.0, JulianDate.now());
- this.updateFrameState();
- this.initializeFrame();
- }
- function updateGlobeListeners(scene, globe) {
- for (var i = 0; i < scene._removeGlobeCallbacks.length; ++i) {
- scene._removeGlobeCallbacks[i]();
- }
- scene._removeGlobeCallbacks.length = 0;
- var removeGlobeCallbacks = [];
- if (defined(globe)) {
- removeGlobeCallbacks.push(
- globe.imageryLayersUpdatedEvent.addEventListener(
- requestRenderAfterFrame(scene)
- )
- );
- removeGlobeCallbacks.push(
- globe.terrainProviderChanged.addEventListener(
- requestRenderAfterFrame(scene)
- )
- );
- }
- scene._removeGlobeCallbacks = removeGlobeCallbacks;
- }
- Object.defineProperties(Scene.prototype, {
- /**
- * Gets the canvas element to which this scene is bound.
- * @memberof Scene.prototype
- *
- * @type {HTMLCanvasElement}
- * @readonly
- */
- canvas: {
- get: function () {
- return this._canvas;
- },
- },
- /**
- * The drawingBufferHeight of the underlying GL context.
- * @memberof Scene.prototype
- *
- * @type {Number}
- * @readonly
- *
- * @see {@link https://www.khronos.org/registry/webgl/specs/1.0/#DOM-WebGLRenderingContext-drawingBufferHeight|drawingBufferHeight}
- */
- drawingBufferHeight: {
- get: function () {
- return this._context.drawingBufferHeight;
- },
- },
- /**
- * The drawingBufferHeight of the underlying GL context.
- * @memberof Scene.prototype
- *
- * @type {Number}
- * @readonly
- *
- * @see {@link https://www.khronos.org/registry/webgl/specs/1.0/#DOM-WebGLRenderingContext-drawingBufferHeight|drawingBufferHeight}
- */
- drawingBufferWidth: {
- get: function () {
- return this._context.drawingBufferWidth;
- },
- },
- /**
- * The maximum aliased line width, in pixels, supported by this WebGL implementation. It will be at least one.
- * @memberof Scene.prototype
- *
- * @type {Number}
- * @readonly
- *
- * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glGet.xml|glGet} with <code>ALIASED_LINE_WIDTH_RANGE</code>.
- */
- maximumAliasedLineWidth: {
- get: function () {
- return ContextLimits.maximumAliasedLineWidth;
- },
- },
- /**
- * The maximum length in pixels of one edge of a cube map, supported by this WebGL implementation. It will be at least 16.
- * @memberof Scene.prototype
- *
- * @type {Number}
- * @readonly
- *
- * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glGet.xml|glGet} with <code>GL_MAX_CUBE_MAP_TEXTURE_SIZE</code>.
- */
- maximumCubeMapSize: {
- get: function () {
- return ContextLimits.maximumCubeMapSize;
- },
- },
- /**
- * Returns <code>true</code> if the {@link Scene#pickPosition} function is supported.
- * @memberof Scene.prototype
- *
- * @type {Boolean}
- * @readonly
- *
- * @see Scene#pickPosition
- */
- pickPositionSupported: {
- get: function () {
- return this._context.depthTexture;
- },
- },
- /**
- * Returns <code>true</code> if the {@link Scene#sampleHeight} and {@link Scene#sampleHeightMostDetailed} functions are supported.
- * @memberof Scene.prototype
- *
- * @type {Boolean}
- * @readonly
- *
- * @see Scene#sampleHeight
- * @see Scene#sampleHeightMostDetailed
- */
- sampleHeightSupported: {
- get: function () {
- return this._context.depthTexture;
- },
- },
- /**
- * Returns <code>true</code> if the {@link Scene#clampToHeight} and {@link Scene#clampToHeightMostDetailed} functions are supported.
- * @memberof Scene.prototype
- *
- * @type {Boolean}
- * @readonly
- *
- * @see Scene#clampToHeight
- * @see Scene#clampToHeightMostDetailed
- */
- clampToHeightSupported: {
- get: function () {
- return this._context.depthTexture;
- },
- },
- /**
- * Returns <code>true</code> if the {@link Scene#invertClassification} is supported.
- * @memberof Scene.prototype
- *
- * @type {Boolean}
- * @readonly
- *
- * @see Scene#invertClassification
- */
- invertClassificationSupported: {
- get: function () {
- return this._context.depthTexture;
- },
- },
- /**
- * Returns <code>true</code> if specular environment maps are supported.
- * @memberof Scene.prototype
- *
- * @type {Boolean}
- * @readonly
- *
- * @see Scene#specularEnvironmentMaps
- */
- specularEnvironmentMapsSupported: {
- get: function () {
- return OctahedralProjectedCubeMap.isSupported(this._context);
- },
- },
- /**
- * Gets or sets the depth-test ellipsoid.
- * @memberof Scene.prototype
- *
- * @type {Globe}
- */
- globe: {
- get: function () {
- return this._globe;
- },
- set: function (globe) {
- this._globe = this._globe && this._globe.destroy();
- this._globe = globe;
- updateGlobeListeners(this, globe);
- },
- },
- /**
- * Gets the collection of primitives.
- * @memberof Scene.prototype
- *
- * @type {PrimitiveCollection}
- * @readonly
- */
- primitives: {
- get: function () {
- return this._primitives;
- },
- },
- /**
- * Gets the collection of ground primitives.
- * @memberof Scene.prototype
- *
- * @type {PrimitiveCollection}
- * @readonly
- */
- groundPrimitives: {
- get: function () {
- return this._groundPrimitives;
- },
- },
- /**
- * Gets or sets the camera.
- * @memberof Scene.prototype
- *
- * @type {Camera}
- * @readonly
- */
- camera: {
- get: function () {
- return this._view.camera;
- },
- set: function (camera) {
- // For internal use only. Documentation is still @readonly.
- this._view.camera = camera;
- },
- },
- /**
- * Gets or sets the view.
- * @memberof Scene.prototype
- *
- * @type {View}
- * @readonly
- *
- * @private
- */
- view: {
- get: function () {
- return this._view;
- },
- set: function (view) {
- // For internal use only. Documentation is still @readonly.
- this._view = view;
- },
- },
- /**
- * Gets the default view.
- * @memberof Scene.prototype
- *
- * @type {View}
- * @readonly
- *
- * @private
- */
- defaultView: {
- get: function () {
- return this._defaultView;
- },
- },
- /**
- * Gets picking functions and state
- * @memberof Scene.prototype
- *
- * @type {Picking}
- * @readonly
- *
- * @private
- */
- picking: {
- get: function () {
- return this._picking;
- },
- },
- /**
- * Gets the controller for camera input handling.
- * @memberof Scene.prototype
- *
- * @type {ScreenSpaceCameraController}
- * @readonly
- */
- screenSpaceCameraController: {
- get: function () {
- return this._screenSpaceCameraController;
- },
- },
- /**
- * Get the map projection to use in 2D and Columbus View modes.
- * @memberof Scene.prototype
- *
- * @type {MapProjection}
- * @readonly
- *
- * @default new GeographicProjection()
- */
- mapProjection: {
- get: function () {
- return this._mapProjection;
- },
- },
- /**
- * Gets the job scheduler
- * @memberof Scene.prototype
- * @type {JobScheduler}
- * @readonly
- *
- * @private
- */
- jobScheduler: {
- get: function () {
- return this._jobScheduler;
- },
- },
- /**
- * Gets state information about the current scene. If called outside of a primitive's <code>update</code>
- * function, the previous frame's state is returned.
- * @memberof Scene.prototype
- *
- * @type {FrameState}
- * @readonly
- *
- * @private
- */
- frameState: {
- get: function () {
- return this._frameState;
- },
- },
- /**
- * Gets the environment state.
- * @memberof Scene.prototype
- *
- * @type {EnvironmentState}
- * @readonly
- *
- * @private
- */
- environmentState: {
- get: function () {
- return this._environmentState;
- },
- },
- /**
- * Gets the collection of tweens taking place in the scene.
- * @memberof Scene.prototype
- *
- * @type {TweenCollection}
- * @readonly
- *
- * @private
- */
- tweens: {
- get: function () {
- return this._tweens;
- },
- },
- /**
- * Gets the collection of image layers that will be rendered on the globe.
- * @memberof Scene.prototype
- *
- * @type {ImageryLayerCollection}
- * @readonly
- */
- imageryLayers: {
- get: function () {
- if (!defined(this.globe)) {
- return undefined;
- }
- return this.globe.imageryLayers;
- },
- },
- /**
- * The terrain provider providing surface geometry for the globe.
- * @memberof Scene.prototype
- *
- * @type {TerrainProvider}
- */
- terrainProvider: {
- get: function () {
- if (!defined(this.globe)) {
- return undefined;
- }
- return this.globe.terrainProvider;
- },
- set: function (terrainProvider) {
- if (defined(this.globe)) {
- this.globe.terrainProvider = terrainProvider;
- }
- },
- },
- /**
- * Gets an event that's raised when the terrain provider is changed
- * @memberof Scene.prototype
- *
- * @type {Event}
- * @readonly
- */
- terrainProviderChanged: {
- get: function () {
- if (!defined(this.globe)) {
- return undefined;
- }
- return this.globe.terrainProviderChanged;
- },
- },
- /**
- * Gets the event that will be raised before the scene is updated or rendered. Subscribers to the event
- * receive the Scene instance as the first parameter and the current time as the second parameter.
- * @memberof Scene.prototype
- *
- * @see {@link https://cesium.com/blog/2018/01/24/cesium-scene-rendering-performance/|Improving Performance with Explicit Rendering}
- * @see Scene#postUpdate
- * @see Scene#preRender
- * @see Scene#postRender
- *
- * @type {Event}
- * @readonly
- */
- preUpdate: {
- get: function () {
- return this._preUpdate;
- },
- },
- /**
- * Gets the event that will be raised immediately after the scene is updated and before the scene is rendered.
- * Subscribers to the event receive the Scene instance as the first parameter and the current time as the second
- * parameter.
- * @memberof Scene.prototype
- *
- * @see {@link https://cesium.com/blog/2018/01/24/cesium-scene-rendering-performance/|Improving Performance with Explicit Rendering}
- * @see Scene#preUpdate
- * @see Scene#preRender
- * @see Scene#postRender
- *
- * @type {Event}
- * @readonly
- */
- postUpdate: {
- get: function () {
- return this._postUpdate;
- },
- },
- /**
- * Gets the event that will be raised when an error is thrown inside the <code>render</code> function.
- * The Scene instance and the thrown error are the only two parameters passed to the event handler.
- * By default, errors are not rethrown after this event is raised, but that can be changed by setting
- * the <code>rethrowRenderErrors</code> property.
- * @memberof Scene.prototype
- *
- * @type {Event}
- * @readonly
- */
- renderError: {
- get: function () {
- return this._renderError;
- },
- },
- /**
- * Gets the event that will be raised after the scene is updated and immediately before the scene is rendered.
- * Subscribers to the event receive the Scene instance as the first parameter and the current time as the second
- * parameter.
- * @memberof Scene.prototype
- *
- * @see {@link https://cesium.com/blog/2018/01/24/cesium-scene-rendering-performance/|Improving Performance with Explicit Rendering}
- * @see Scene#preUpdate
- * @see Scene#postUpdate
- * @see Scene#postRender
- *
- * @type {Event}
- * @readonly
- */
- preRender: {
- get: function () {
- return this._preRender;
- },
- },
- /**
- * Gets the event that will be raised immediately after the scene is rendered. Subscribers to the event
- * receive the Scene instance as the first parameter and the current time as the second parameter.
- * @memberof Scene.prototype
- *
- * @see {@link https://cesium.com/blog/2018/01/24/cesium-scene-rendering-performance/|Improving Performance with Explicit Rendering}
- * @see Scene#preUpdate
- * @see Scene#postUpdate
- * @see Scene#postRender
- *
- * @type {Event}
- * @readonly
- */
- postRender: {
- get: function () {
- return this._postRender;
- },
- },
- /**
- * Gets the simulation time when the scene was last rendered. Returns undefined if the scene has not yet been
- * rendered.
- * @memberof Scene.prototype
- *
- * @type {JulianDate}
- * @readonly
- */
- lastRenderTime: {
- get: function () {
- return this._lastRenderTime;
- },
- },
- /**
- * @memberof Scene.prototype
- * @private
- * @readonly
- */
- context: {
- get: function () {
- return this._context;
- },
- },
- /**
- * This property is for debugging only; it is not for production use.
- * <p>
- * When {@link Scene.debugShowFrustums} is <code>true</code>, this contains
- * properties with statistics about the number of command execute per frustum.
- * <code>totalCommands</code> is the total number of commands executed, ignoring
- * overlap. <code>commandsInFrustums</code> is an array with the number of times
- * commands are executed redundantly, e.g., how many commands overlap two or
- * three frustums.
- * </p>
- *
- * @memberof Scene.prototype
- *
- * @type {Object}
- * @readonly
- *
- * @default undefined
- */
- debugFrustumStatistics: {
- get: function () {
- return this._view.debugFrustumStatistics;
- },
- },
- /**
- * Gets whether or not the scene is optimized for 3D only viewing.
- * @memberof Scene.prototype
- * @type {Boolean}
- * @readonly
- */
- scene3DOnly: {
- get: function () {
- return this._frameState.scene3DOnly;
- },
- },
- /**
- * Gets whether or not the scene has order independent translucency enabled.
- * Note that this only reflects the original construction option, and there are
- * other factors that could prevent OIT from functioning on a given system configuration.
- * @memberof Scene.prototype
- * @type {Boolean}
- * @readonly
- */
- orderIndependentTranslucency: {
- get: function () {
- return this._useOIT;
- },
- },
- /**
- * Gets the unique identifier for this scene.
- * @memberof Scene.prototype
- * @type {String}
- * @readonly
- */
- id: {
- get: function () {
- return this._id;
- },
- },
- /**
- * Gets or sets the current mode of the scene.
- * @memberof Scene.prototype
- * @type {SceneMode}
- * @default {@link SceneMode.SCENE3D}
- */
- mode: {
- get: function () {
- return this._mode;
- },
- set: function (value) {
- //>>includeStart('debug', pragmas.debug);
- if (this.scene3DOnly && value !== SceneMode.SCENE3D) {
- throw new DeveloperError(
- "Only SceneMode.SCENE3D is valid when scene3DOnly is true."
- );
- }
- //>>includeEnd('debug');
- if (value === SceneMode.SCENE2D) {
- this.morphTo2D(0);
- } else if (value === SceneMode.SCENE3D) {
- this.morphTo3D(0);
- } else if (value === SceneMode.COLUMBUS_VIEW) {
- this.morphToColumbusView(0);
- //>>includeStart('debug', pragmas.debug);
- } else {
- throw new DeveloperError(
- "value must be a valid SceneMode enumeration."
- );
- //>>includeEnd('debug');
- }
- this._mode = value;
- },
- },
- /**
- * Gets the number of frustums used in the last frame.
- * @memberof Scene.prototype
- * @type {FrustumCommands[]}
- *
- * @private
- */
- frustumCommandsList: {
- get: function () {
- return this._view.frustumCommandsList;
- },
- },
- /**
- * Gets the number of frustums used in the last frame.
- * @memberof Scene.prototype
- * @type {Number}
- *
- * @private
- */
- numberOfFrustums: {
- get: function () {
- return this._view.frustumCommandsList.length;
- },
- },
- /**
- * Gets the scalar used to exaggerate the terrain.
- * @memberof Scene.prototype
- * @type {Number}
- * @readonly
- */
- terrainExaggeration: {
- get: function () {
- return this._terrainExaggeration;
- },
- },
- /**
- * When <code>true</code>, splits the scene into two viewports with steroscopic views for the left and right eyes.
- * Used for cardboard and WebVR.
- * @memberof Scene.prototype
- * @type {Boolean}
- * @default false
- */
- useWebVR: {
- get: function () {
- return this._useWebVR;
- },
- set: function (value) {
- //>>includeStart('debug', pragmas.debug);
- if (this.camera.frustum instanceof OrthographicFrustum) {
- throw new DeveloperError(
- "VR is unsupported with an orthographic projection."
- );
- }
- //>>includeEnd('debug');
- this._useWebVR = value;
- if (this._useWebVR) {
- this._frameState.creditDisplay.container.style.visibility = "hidden";
- this._cameraVR = new Camera(this);
- if (!defined(this._deviceOrientationCameraController)) {
- this._deviceOrientationCameraController = new DeviceOrientationCameraController(
- this
- );
- }
- this._aspectRatioVR = this.camera.frustum.aspectRatio;
- } else {
- this._frameState.creditDisplay.container.style.visibility = "visible";
- this._cameraVR = undefined;
- this._deviceOrientationCameraController =
- this._deviceOrientationCameraController &&
- !this._deviceOrientationCameraController.isDestroyed() &&
- this._deviceOrientationCameraController.destroy();
- this.camera.frustum.aspectRatio = this._aspectRatioVR;
- this.camera.frustum.xOffset = 0.0;
- }
- },
- },
- /**
- * Determines if the 2D map is rotatable or can be scrolled infinitely in the horizontal direction.
- * @memberof Scene.prototype
- * @type {MapMode2D}
- * @readonly
- */
- mapMode2D: {
- get: function () {
- return this._mapMode2D;
- },
- },
- /**
- * Gets or sets the position of the Imagery splitter within the viewport. Valid values are between 0.0 and 1.0.
- * @memberof Scene.prototype
- *
- * @type {Number}
- */
- imagerySplitPosition: {
- get: function () {
- return this._frameState.imagerySplitPosition;
- },
- set: function (value) {
- this._frameState.imagerySplitPosition = value;
- },
- },
- /**
- * The distance from the camera at which to disable the depth test of billboards, labels and points
- * to, for example, prevent clipping against terrain. When set to zero, the depth test should always
- * be applied. When less than zero, the depth test should never be applied. Setting the disableDepthTestDistance
- * property of a billboard, label or point will override this value.
- * @memberof Scene.prototype
- * @type {Number}
- * @default 0.0
- */
- minimumDisableDepthTestDistance: {
- get: function () {
- return this._minimumDisableDepthTestDistance;
- },
- set: function (value) {
- //>>includeStart('debug', pragmas.debug);
- if (!defined(value) || value < 0.0) {
- throw new DeveloperError(
- "minimumDisableDepthTestDistance must be greater than or equal to 0.0."
- );
- }
- //>>includeEnd('debug');
- this._minimumDisableDepthTestDistance = value;
- },
- },
- /**
- * Whether or not to use a logarithmic depth buffer. Enabling this option will allow for less frustums in the multi-frustum,
- * increasing performance. This property relies on fragmentDepth being supported.
- * @memberof Scene.prototype
- * @type {Boolean}
- */
- logarithmicDepthBuffer: {
- get: function () {
- return this._logDepthBuffer;
- },
- set: function (value) {
- value = this._context.fragmentDepth && value;
- if (this._logDepthBuffer !== value) {
- this._logDepthBuffer = value;
- this._logDepthBufferDirty = true;
- }
- },
- },
- /**
- * The value used for gamma correction. This is only used when rendering with high dynamic range.
- * @memberof Scene.prototype
- * @type {Number}
- * @default 2.2
- */
- gamma: {
- get: function () {
- return this._context.uniformState.gamma;
- },
- set: function (value) {
- this._context.uniformState.gamma = value;
- },
- },
- /**
- * Whether or not to use high dynamic range rendering.
- * @memberof Scene.prototype
- * @type {Boolean}
- * @default true
- */
- highDynamicRange: {
- get: function () {
- return this._hdr;
- },
- set: function (value) {
- var context = this._context;
- var hdr =
- value &&
- context.depthTexture &&
- (context.colorBufferFloat || context.colorBufferHalfFloat);
- this._hdrDirty = hdr !== this._hdr;
- this._hdr = hdr;
- },
- },
- /**
- * Whether or not high dynamic range rendering is supported.
- * @memberof Scene.prototype
- * @type {Boolean}
- * @readonly
- * @default true
- */
- highDynamicRangeSupported: {
- get: function () {
- var context = this._context;
- return (
- context.depthTexture &&
- (context.colorBufferFloat || context.colorBufferHalfFloat)
- );
- },
- },
- /**
- * Whether or not the camera is underneath the globe.
- * @memberof Scene.prototype
- * @type {Boolean}
- * @readonly
- * @default false
- */
- cameraUnderground: {
- get: function () {
- return this._cameraUnderground;
- },
- },
- /**
- * Ratio between a pixel and a density-independent pixel. Provides a standard unit of
- * measure for real pixel measurements appropriate to a particular device.
- *
- * @memberof Scene.prototype
- * @type {Number}
- * @default 1.0
- * @private
- */
- pixelRatio: {
- get: function () {
- return this._frameState.pixelRatio;
- },
- set: function (value) {
- this._frameState.pixelRatio = value;
- },
- },
- /**
- * @private
- */
- opaqueFrustumNearOffset: {
- get: function () {
- return 0.9999;
- },
- },
- /**
- * @private
- */
- globeHeight: {
- get: function () {
- return this._globeHeight;
- },
- },
- });
- /**
- * Determines if a compressed texture format is supported.
- * @param {String} format The texture format. May be the name of the format or the WebGL extension name, e.g. s3tc or WEBGL_compressed_texture_s3tc.
- * @return {boolean} Whether or not the format is supported.
- */
- Scene.prototype.getCompressedTextureFormatSupported = function (format) {
- var context = this.context;
- return (
- ((format === "WEBGL_compressed_texture_s3tc" || format === "s3tc") &&
- context.s3tc) ||
- ((format === "WEBGL_compressed_texture_pvrtc" || format === "pvrtc") &&
- context.pvrtc) ||
- ((format === "WEBGL_compressed_texture_etc1" || format === "etc1") &&
- context.etc1)
- );
- };
- function updateDerivedCommands(scene, command, shadowsDirty) {
- var frameState = scene._frameState;
- var context = scene._context;
- var oit = scene._view.oit;
- var lightShadowMaps = frameState.shadowState.lightShadowMaps;
- var lightShadowsEnabled = frameState.shadowState.lightShadowsEnabled;
- var derivedCommands = command.derivedCommands;
- if (defined(command.pickId)) {
- derivedCommands.picking = DerivedCommand.createPickDerivedCommand(
- scene,
- command,
- context,
- derivedCommands.picking
- );
- }
- if (!command.pickOnly) {
- derivedCommands.depth = DerivedCommand.createDepthOnlyDerivedCommand(
- scene,
- command,
- context,
- derivedCommands.depth
- );
- }
- derivedCommands.originalCommand = command;
- if (scene._hdr) {
- derivedCommands.hdr = DerivedCommand.createHdrCommand(
- command,
- context,
- derivedCommands.hdr
- );
- command = derivedCommands.hdr.command;
- derivedCommands = command.derivedCommands;
- }
- if (lightShadowsEnabled && command.receiveShadows) {
- derivedCommands.shadows = ShadowMap.createReceiveDerivedCommand(
- lightShadowMaps,
- command,
- shadowsDirty,
- context,
- derivedCommands.shadows
- );
- }
- if (command.pass === Pass.TRANSLUCENT && defined(oit) && oit.isSupported()) {
- if (lightShadowsEnabled && command.receiveShadows) {
- derivedCommands.oit = defined(derivedCommands.oit)
- ? derivedCommands.oit
- : {};
- derivedCommands.oit.shadows = oit.createDerivedCommands(
- derivedCommands.shadows.receiveCommand,
- context,
- derivedCommands.oit.shadows
- );
- } else {
- derivedCommands.oit = oit.createDerivedCommands(
- command,
- context,
- derivedCommands.oit
- );
- }
- }
- }
- /**
- * @private
- */
- Scene.prototype.updateDerivedCommands = function (command) {
- if (!defined(command.derivedCommands)) {
- // Is not a DrawCommand
- return;
- }
- var frameState = this._frameState;
- var context = this._context;
- // Update derived commands when any shadow maps become dirty
- var shadowsDirty = false;
- var lastDirtyTime = frameState.shadowState.lastDirtyTime;
- if (command.lastDirtyTime !== lastDirtyTime) {
- command.lastDirtyTime = lastDirtyTime;
- command.dirty = true;
- shadowsDirty = true;
- }
- var useLogDepth = frameState.useLogDepth;
- var useHdr = this._hdr;
- var derivedCommands = command.derivedCommands;
- var hasLogDepthDerivedCommands = defined(derivedCommands.logDepth);
- var hasHdrCommands = defined(derivedCommands.hdr);
- var hasDerivedCommands = defined(derivedCommands.originalCommand);
- var needsLogDepthDerivedCommands = useLogDepth && !hasLogDepthDerivedCommands;
- var needsHdrCommands = useHdr && !hasHdrCommands;
- var needsDerivedCommands = (!useLogDepth || !useHdr) && !hasDerivedCommands;
- command.dirty =
- command.dirty ||
- needsLogDepthDerivedCommands ||
- needsHdrCommands ||
- needsDerivedCommands;
- if (command.dirty) {
- command.dirty = false;
- var shadowMaps = frameState.shadowState.shadowMaps;
- var shadowsEnabled = frameState.shadowState.shadowsEnabled;
- if (shadowsEnabled && command.castShadows) {
- derivedCommands.shadows = ShadowMap.createCastDerivedCommand(
- shadowMaps,
- command,
- shadowsDirty,
- context,
- derivedCommands.shadows
- );
- }
- if (hasLogDepthDerivedCommands || needsLogDepthDerivedCommands) {
- derivedCommands.logDepth = DerivedCommand.createLogDepthCommand(
- command,
- context,
- derivedCommands.logDepth
- );
- updateDerivedCommands(
- this,
- derivedCommands.logDepth.command,
- shadowsDirty
- );
- }
- if (hasDerivedCommands || needsDerivedCommands) {
- updateDerivedCommands(this, command, shadowsDirty);
- }
- }
- };
- var renderTilesetPassState = new Cesium3DTilePassState({
- pass: Cesium3DTilePass.RENDER,
- });
- var preloadTilesetPassState = new Cesium3DTilePassState({
- pass: Cesium3DTilePass.PRELOAD,
- });
- var preloadFlightTilesetPassState = new Cesium3DTilePassState({
- pass: Cesium3DTilePass.PRELOAD_FLIGHT,
- });
- var requestRenderModeDeferCheckPassState = new Cesium3DTilePassState({
- pass: Cesium3DTilePass.REQUEST_RENDER_MODE_DEFER_CHECK,
- });
- var scratchOccluderBoundingSphere = new BoundingSphere();
- var scratchOccluder;
- function getOccluder(scene) {
- // TODO: The occluder is the top-level globe. When we add
- // support for multiple central bodies, this should be the closest one.
- var globe = scene.globe;
- if (
- scene._mode === SceneMode.SCENE3D &&
- defined(globe) &&
- globe.show &&
- !scene._cameraUnderground &&
- !scene._globeTranslucencyState.translucent
- ) {
- var ellipsoid = globe.ellipsoid;
- var minimumTerrainHeight = scene.frameState.minimumTerrainHeight;
- scratchOccluderBoundingSphere.radius =
- ellipsoid.minimumRadius + minimumTerrainHeight;
- scratchOccluder = Occluder.fromBoundingSphere(
- scratchOccluderBoundingSphere,
- scene.camera.positionWC,
- scratchOccluder
- );
- return scratchOccluder;
- }
- return undefined;
- }
- /**
- * @private
- */
- Scene.prototype.clearPasses = function (passes) {
- passes.render = false;
- passes.pick = false;
- passes.depth = false;
- passes.postProcess = false;
- passes.offscreen = false;
- };
- function updateFrameNumber(scene, frameNumber, time) {
- var frameState = scene._frameState;
- frameState.frameNumber = frameNumber;
- frameState.time = JulianDate.clone(time, frameState.time);
- }
- /**
- * @private
- */
- Scene.prototype.updateFrameState = function () {
- var camera = this.camera;
- var frameState = this._frameState;
- frameState.commandList.length = 0;
- frameState.shadowMaps.length = 0;
- frameState.brdfLutGenerator = this._brdfLutGenerator;
- frameState.environmentMap = this.skyBox && this.skyBox._cubeMap;
- frameState.mode = this._mode;
- frameState.morphTime = this.morphTime;
- frameState.mapProjection = this.mapProjection;
- frameState.camera = camera;
- frameState.cullingVolume = camera.frustum.computeCullingVolume(
- camera.positionWC,
- camera.directionWC,
- camera.upWC
- );
- frameState.occluder = getOccluder(this);
- frameState.terrainExaggeration = this._terrainExaggeration;
- frameState.minimumTerrainHeight = 0.0;
- frameState.minimumDisableDepthTestDistance = this._minimumDisableDepthTestDistance;
- frameState.invertClassification = this.invertClassification;
- frameState.useLogDepth =
- this._logDepthBuffer &&
- !(
- this.camera.frustum instanceof OrthographicFrustum ||
- this.camera.frustum instanceof OrthographicOffCenterFrustum
- );
- frameState.light = this.light;
- frameState.cameraUnderground = this._cameraUnderground;
- frameState.globeTranslucencyState = this._globeTranslucencyState;
- if (
- defined(this._specularEnvironmentMapAtlas) &&
- this._specularEnvironmentMapAtlas.ready
- ) {
- frameState.specularEnvironmentMaps = this._specularEnvironmentMapAtlas.texture;
- frameState.specularEnvironmentMapsMaximumLOD = this._specularEnvironmentMapAtlas.maximumMipmapLevel;
- } else {
- frameState.specularEnvironmentMaps = undefined;
- frameState.specularEnvironmentMapsMaximumLOD = undefined;
- }
- frameState.sphericalHarmonicCoefficients = this.sphericalHarmonicCoefficients;
- this._actualInvertClassificationColor = Color.clone(
- this.invertClassificationColor,
- this._actualInvertClassificationColor
- );
- if (!InvertClassification.isTranslucencySupported(this._context)) {
- this._actualInvertClassificationColor.alpha = 1.0;
- }
- frameState.invertClassificationColor = this._actualInvertClassificationColor;
- if (defined(this.globe)) {
- frameState.maximumScreenSpaceError = this.globe.maximumScreenSpaceError;
- } else {
- frameState.maximumScreenSpaceError = 2;
- }
- this.clearPasses(frameState.passes);
- frameState.tilesetPassState = undefined;
- };
- /**
- * @private
- */
- Scene.prototype.isVisible = function (command, cullingVolume, occluder) {
- return (
- defined(command) &&
- (!defined(command.boundingVolume) ||
- !command.cull ||
- (cullingVolume.computeVisibility(command.boundingVolume) !==
- Intersect.OUTSIDE &&
- (!defined(occluder) ||
- !command.occlude ||
- !command.boundingVolume.isOccluded(occluder))))
- );
- };
- var transformFrom2D = new Matrix4(
- 0.0,
- 0.0,
- 1.0,
- 0.0,
- 1.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 1.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 1.0
- );
- transformFrom2D = Matrix4.inverseTransformation(
- transformFrom2D,
- transformFrom2D
- );
- function debugShowBoundingVolume(command, scene, passState, debugFramebuffer) {
- // Debug code to draw bounding volume for command. Not optimized!
- // Assumes bounding volume is a bounding sphere or box
- var frameState = scene._frameState;
- var context = frameState.context;
- var boundingVolume = command.boundingVolume;
- if (defined(scene._debugVolume)) {
- scene._debugVolume.destroy();
- }
- var geometry;
- var center = Cartesian3.clone(boundingVolume.center);
- if (frameState.mode !== SceneMode.SCENE3D) {
- center = Matrix4.multiplyByPoint(transformFrom2D, center, center);
- var projection = frameState.mapProjection;
- var centerCartographic = projection.unproject(center);
- center = projection.ellipsoid.cartographicToCartesian(centerCartographic);
- }
- if (defined(boundingVolume.radius)) {
- var radius = boundingVolume.radius;
- geometry = GeometryPipeline.toWireframe(
- EllipsoidGeometry.createGeometry(
- new EllipsoidGeometry({
- radii: new Cartesian3(radius, radius, radius),
- vertexFormat: PerInstanceColorAppearance.FLAT_VERTEX_FORMAT,
- })
- )
- );
- scene._debugVolume = new Primitive({
- geometryInstances: new GeometryInstance({
- geometry: geometry,
- modelMatrix: Matrix4.fromTranslation(center),
- attributes: {
- color: new ColorGeometryInstanceAttribute(1.0, 0.0, 0.0, 1.0),
- },
- }),
- appearance: new PerInstanceColorAppearance({
- flat: true,
- translucent: false,
- }),
- asynchronous: false,
- });
- } else {
- var halfAxes = boundingVolume.halfAxes;
- geometry = GeometryPipeline.toWireframe(
- BoxGeometry.createGeometry(
- BoxGeometry.fromDimensions({
- dimensions: new Cartesian3(2.0, 2.0, 2.0),
- vertexFormat: PerInstanceColorAppearance.FLAT_VERTEX_FORMAT,
- })
- )
- );
- scene._debugVolume = new Primitive({
- geometryInstances: new GeometryInstance({
- geometry: geometry,
- modelMatrix: Matrix4.fromRotationTranslation(
- halfAxes,
- center,
- new Matrix4()
- ),
- attributes: {
- color: new ColorGeometryInstanceAttribute(1.0, 0.0, 0.0, 1.0),
- },
- }),
- appearance: new PerInstanceColorAppearance({
- flat: true,
- translucent: false,
- }),
- asynchronous: false,
- });
- }
- var savedCommandList = frameState.commandList;
- var commandList = (frameState.commandList = []);
- scene._debugVolume.update(frameState);
- command = commandList[0];
- if (frameState.useLogDepth) {
- var logDepth = DerivedCommand.createLogDepthCommand(command, context);
- command = logDepth.command;
- }
- var framebuffer;
- if (defined(debugFramebuffer)) {
- framebuffer = passState.framebuffer;
- passState.framebuffer = debugFramebuffer;
- }
- command.execute(context, passState);
- if (defined(framebuffer)) {
- passState.framebuffer = framebuffer;
- }
- frameState.commandList = savedCommandList;
- }
- function executeCommand(command, scene, context, passState, debugFramebuffer) {
- var frameState = scene._frameState;
- if (defined(scene.debugCommandFilter) && !scene.debugCommandFilter(command)) {
- return;
- }
- if (command instanceof ClearCommand) {
- command.execute(context, passState);
- return;
- }
- if (command.debugShowBoundingVolume && defined(command.boundingVolume)) {
- debugShowBoundingVolume(command, scene, passState, debugFramebuffer);
- }
- if (frameState.useLogDepth && defined(command.derivedCommands.logDepth)) {
- command = command.derivedCommands.logDepth.command;
- }
- var passes = frameState.passes;
- if (
- !passes.pick &&
- !passes.depth &&
- scene._hdr &&
- defined(command.derivedCommands) &&
- defined(command.derivedCommands.hdr)
- ) {
- command = command.derivedCommands.hdr.command;
- }
- if (passes.pick || passes.depth) {
- if (
- passes.pick &&
- !passes.depth &&
- defined(command.derivedCommands.picking)
- ) {
- command = command.derivedCommands.picking.pickCommand;
- command.execute(context, passState);
- return;
- } else if (defined(command.derivedCommands.depth)) {
- command = command.derivedCommands.depth.depthOnlyCommand;
- command.execute(context, passState);
- return;
- }
- }
- if (scene.debugShowCommands || scene.debugShowFrustums) {
- scene._debugInspector.executeDebugShowFrustumsCommand(
- scene,
- command,
- passState
- );
- return;
- }
- if (
- frameState.shadowState.lightShadowsEnabled &&
- command.receiveShadows &&
- defined(command.derivedCommands.shadows)
- ) {
- // If the command receives shadows, execute the derived shadows command.
- // Some commands, such as OIT derived commands, do not have derived shadow commands themselves
- // and instead shadowing is built-in. In this case execute the command regularly below.
- command.derivedCommands.shadows.receiveCommand.execute(context, passState);
- } else {
- command.execute(context, passState);
- }
- }
- function executeIdCommand(command, scene, context, passState) {
- var frameState = scene._frameState;
- var derivedCommands = command.derivedCommands;
- if (!defined(derivedCommands)) {
- return;
- }
- if (frameState.useLogDepth && defined(derivedCommands.logDepth)) {
- command = derivedCommands.logDepth.command;
- }
- derivedCommands = command.derivedCommands;
- if (defined(derivedCommands.picking)) {
- command = derivedCommands.picking.pickCommand;
- command.execute(context, passState);
- } else if (defined(derivedCommands.depth)) {
- command = derivedCommands.depth.depthOnlyCommand;
- command.execute(context, passState);
- }
- }
- function backToFront(a, b, position) {
- return (
- b.boundingVolume.distanceSquaredTo(position) -
- a.boundingVolume.distanceSquaredTo(position)
- );
- }
- function frontToBack(a, b, position) {
- // When distances are equal equal favor sorting b before a. This gives render priority to commands later in the list.
- return (
- a.boundingVolume.distanceSquaredTo(position) -
- b.boundingVolume.distanceSquaredTo(position) +
- CesiumMath.EPSILON12
- );
- }
- function executeTranslucentCommandsBackToFront(
- scene,
- executeFunction,
- passState,
- commands,
- invertClassification
- ) {
- var context = scene.context;
- mergeSort(commands, backToFront, scene.camera.positionWC);
- if (defined(invertClassification)) {
- executeFunction(
- invertClassification.unclassifiedCommand,
- scene,
- context,
- passState
- );
- }
- var length = commands.length;
- for (var i = 0; i < length; ++i) {
- executeFunction(commands[i], scene, context, passState);
- }
- }
- function executeTranslucentCommandsFrontToBack(
- scene,
- executeFunction,
- passState,
- commands,
- invertClassification
- ) {
- var context = scene.context;
- mergeSort(commands, frontToBack, scene.camera.positionWC);
- if (defined(invertClassification)) {
- executeFunction(
- invertClassification.unclassifiedCommand,
- scene,
- context,
- passState
- );
- }
- var length = commands.length;
- for (var i = 0; i < length; ++i) {
- executeFunction(commands[i], scene, context, passState);
- }
- }
- function getDebugGlobeDepth(scene, index) {
- var globeDepths = scene._view.debugGlobeDepths;
- var globeDepth = globeDepths[index];
- if (!defined(globeDepth) && scene.context.depthTexture) {
- globeDepth = new GlobeDepth();
- globeDepths[index] = globeDepth;
- }
- return globeDepth;
- }
- var scratchPerspectiveFrustum = new PerspectiveFrustum();
- var scratchPerspectiveOffCenterFrustum = new PerspectiveOffCenterFrustum();
- var scratchOrthographicFrustum = new OrthographicFrustum();
- var scratchOrthographicOffCenterFrustum = new OrthographicOffCenterFrustum();
- function executeCommands(scene, passState) {
- var camera = scene.camera;
- var context = scene.context;
- var frameState = scene.frameState;
- var us = context.uniformState;
- us.updateCamera(camera);
- // Create a working frustum from the original camera frustum.
- var frustum;
- if (defined(camera.frustum.fov)) {
- frustum = camera.frustum.clone(scratchPerspectiveFrustum);
- } else if (defined(camera.frustum.infiniteProjectionMatrix)) {
- frustum = camera.frustum.clone(scratchPerspectiveOffCenterFrustum);
- } else if (defined(camera.frustum.width)) {
- frustum = camera.frustum.clone(scratchOrthographicFrustum);
- } else {
- frustum = camera.frustum.clone(scratchOrthographicOffCenterFrustum);
- }
- // Ideally, we would render the sky box and atmosphere last for
- // early-z, but we would have to draw it in each frustum
- frustum.near = camera.frustum.near;
- frustum.far = camera.frustum.far;
- us.updateFrustum(frustum);
- us.updatePass(Pass.ENVIRONMENT);
- var passes = frameState.passes;
- var picking = passes.pick;
- var environmentState = scene._environmentState;
- var view = scene._view;
- var renderTranslucentDepthForPick =
- environmentState.renderTranslucentDepthForPick;
- var useWebVR = environmentState.useWebVR;
- // Do not render environment primitives during a pick pass since they do not generate picking commands.
- if (!picking) {
- var skyBoxCommand = environmentState.skyBoxCommand;
- if (defined(skyBoxCommand)) {
- executeCommand(skyBoxCommand, scene, context, passState);
- }
- if (environmentState.isSkyAtmosphereVisible) {
- executeCommand(
- environmentState.skyAtmosphereCommand,
- scene,
- context,
- passState
- );
- }
- if (environmentState.isSunVisible) {
- environmentState.sunDrawCommand.execute(context, passState);
- if (scene.sunBloom && !useWebVR) {
- var framebuffer;
- if (environmentState.useGlobeDepthFramebuffer) {
- framebuffer = view.globeDepth.framebuffer;
- } else if (environmentState.usePostProcess) {
- framebuffer = view.sceneFramebuffer.getFramebuffer();
- } else {
- framebuffer = environmentState.originalFramebuffer;
- }
- scene._sunPostProcess.execute(context);
- scene._sunPostProcess.copy(context, framebuffer);
- passState.framebuffer = framebuffer;
- }
- }
- // Moon can be seen through the atmosphere, since the sun is rendered after the atmosphere.
- if (environmentState.isMoonVisible) {
- environmentState.moonCommand.execute(context, passState);
- }
- }
- // Determine how translucent surfaces will be handled.
- var executeTranslucentCommands;
- if (environmentState.useOIT) {
- if (!defined(scene._executeOITFunction)) {
- scene._executeOITFunction = function (
- scene,
- executeFunction,
- passState,
- commands,
- invertClassification
- ) {
- view.oit.executeCommands(
- scene,
- executeFunction,
- passState,
- commands,
- invertClassification
- );
- };
- }
- executeTranslucentCommands = scene._executeOITFunction;
- } else if (passes.render) {
- executeTranslucentCommands = executeTranslucentCommandsBackToFront;
- } else {
- executeTranslucentCommands = executeTranslucentCommandsFrontToBack;
- }
- var frustumCommandsList = view.frustumCommandsList;
- var numFrustums = frustumCommandsList.length;
- var clearGlobeDepth = environmentState.clearGlobeDepth;
- var useDepthPlane = environmentState.useDepthPlane;
- var globeTranslucencyState = scene._globeTranslucencyState;
- var globeTranslucent = globeTranslucencyState.translucent;
- var globeTranslucencyFramebuffer = scene._view.globeTranslucencyFramebuffer;
- var separatePrimitiveFramebuffer = (environmentState.separatePrimitiveFramebuffer = false);
- var clearDepth = scene._depthClearCommand;
- var clearStencil = scene._stencilClearCommand;
- var clearClassificationStencil = scene._classificationStencilClearCommand;
- var depthPlane = scene._depthPlane;
- var usePostProcessSelected = environmentState.usePostProcessSelected;
- var height2D = camera.position.z;
- // Execute commands in each frustum in back to front order
- var j;
- for (var i = 0; i < numFrustums; ++i) {
- var index = numFrustums - i - 1;
- var frustumCommands = frustumCommandsList[index];
- if (scene.mode === SceneMode.SCENE2D) {
- // To avoid z-fighting in 2D, move the camera to just before the frustum
- // and scale the frustum depth to be in [1.0, nearToFarDistance2D].
- camera.position.z = height2D - frustumCommands.near + 1.0;
- frustum.far = Math.max(1.0, frustumCommands.far - frustumCommands.near);
- frustum.near = 1.0;
- us.update(frameState);
- us.updateFrustum(frustum);
- } else {
- // Avoid tearing artifacts between adjacent frustums in the opaque passes
- frustum.near =
- index !== 0
- ? frustumCommands.near * scene.opaqueFrustumNearOffset
- : frustumCommands.near;
- frustum.far = frustumCommands.far;
- us.updateFrustum(frustum);
- }
- var globeDepth = scene.debugShowGlobeDepth
- ? getDebugGlobeDepth(scene, index)
- : view.globeDepth;
- if (separatePrimitiveFramebuffer) {
- // Render to globe framebuffer in GLOBE pass
- passState.framebuffer = globeDepth.framebuffer;
- }
- var fb;
- if (
- scene.debugShowGlobeDepth &&
- defined(globeDepth) &&
- environmentState.useGlobeDepthFramebuffer
- ) {
- globeDepth.update(
- context,
- passState,
- view.viewport,
- scene._hdr,
- clearGlobeDepth
- );
- globeDepth.clear(context, passState, scene._clearColorCommand.color);
- fb = passState.framebuffer;
- passState.framebuffer = globeDepth.framebuffer;
- }
- clearDepth.execute(context, passState);
- if (context.stencilBuffer) {
- clearStencil.execute(context, passState);
- }
- us.updatePass(Pass.GLOBE);
- var commands = frustumCommands.commands[Pass.GLOBE];
- var length = frustumCommands.indices[Pass.GLOBE];
- if (globeTranslucent) {
- globeTranslucencyState.executeGlobeCommands(
- frustumCommands,
- executeCommand,
- globeTranslucencyFramebuffer,
- scene,
- passState
- );
- } else {
- for (j = 0; j < length; ++j) {
- executeCommand(commands[j], scene, context, passState);
- }
- }
- if (defined(globeDepth) && environmentState.useGlobeDepthFramebuffer) {
- globeDepth.executeCopyDepth(context, passState);
- }
- if (
- scene.debugShowGlobeDepth &&
- defined(globeDepth) &&
- environmentState.useGlobeDepthFramebuffer
- ) {
- passState.framebuffer = fb;
- }
- // Draw terrain classification
- if (!environmentState.renderTranslucentDepthForPick) {
- us.updatePass(Pass.TERRAIN_CLASSIFICATION);
- commands = frustumCommands.commands[Pass.TERRAIN_CLASSIFICATION];
- length = frustumCommands.indices[Pass.TERRAIN_CLASSIFICATION];
- if (globeTranslucent) {
- globeTranslucencyState.executeGlobeClassificationCommands(
- frustumCommands,
- executeCommand,
- globeTranslucencyFramebuffer,
- scene,
- passState
- );
- } else {
- for (j = 0; j < length; ++j) {
- executeCommand(commands[j], scene, context, passState);
- }
- }
- }
- if (clearGlobeDepth) {
- clearDepth.execute(context, passState);
- if (useDepthPlane) {
- depthPlane.execute(context, passState);
- }
- }
- if (separatePrimitiveFramebuffer) {
- // Render to primitive framebuffer in all other passes
- passState.framebuffer = globeDepth.primitiveFramebuffer;
- }
- if (
- !environmentState.useInvertClassification ||
- picking ||
- environmentState.renderTranslucentDepthForPick
- ) {
- // Common/fastest path. Draw 3D Tiles and classification normally.
- // Draw 3D Tiles
- us.updatePass(Pass.CESIUM_3D_TILE);
- commands = frustumCommands.commands[Pass.CESIUM_3D_TILE];
- length = frustumCommands.indices[Pass.CESIUM_3D_TILE];
- for (j = 0; j < length; ++j) {
- executeCommand(commands[j], scene, context, passState);
- }
- if (length > 0) {
- if (defined(globeDepth) && environmentState.useGlobeDepthFramebuffer) {
- globeDepth.executeUpdateDepth(context, passState, clearGlobeDepth);
- }
- // Draw classifications. Modifies 3D Tiles color.
- if (!environmentState.renderTranslucentDepthForPick) {
- us.updatePass(Pass.CESIUM_3D_TILE_CLASSIFICATION);
- commands =
- frustumCommands.commands[Pass.CESIUM_3D_TILE_CLASSIFICATION];
- length = frustumCommands.indices[Pass.CESIUM_3D_TILE_CLASSIFICATION];
- for (j = 0; j < length; ++j) {
- executeCommand(commands[j], scene, context, passState);
- }
- }
- }
- } else {
- // When the invert classification color is opaque:
- // Main FBO (FBO1): Main_Color + Main_DepthStencil
- // Invert classification FBO (FBO2) : Invert_Color + Main_DepthStencil
- //
- // 1. Clear FBO2 color to vec4(0.0) for each frustum
- // 2. Draw 3D Tiles to FBO2
- // 3. Draw classification to FBO2
- // 4. Fullscreen pass to FBO1, draw Invert_Color when:
- // * Main_DepthStencil has the stencil bit set > 0 (classified)
- // 5. Fullscreen pass to FBO1, draw Invert_Color * czm_invertClassificationColor when:
- // * Main_DepthStencil has stencil bit set to 0 (unclassified) and
- // * Invert_Color !== vec4(0.0)
- //
- // When the invert classification color is translucent:
- // Main FBO (FBO1): Main_Color + Main_DepthStencil
- // Invert classification FBO (FBO2): Invert_Color + Invert_DepthStencil
- // IsClassified FBO (FBO3): IsClassified_Color + Invert_DepthStencil
- //
- // 1. Clear FBO2 and FBO3 color to vec4(0.0), stencil to 0, and depth to 1.0
- // 2. Draw 3D Tiles to FBO2
- // 3. Draw classification to FBO2
- // 4. Fullscreen pass to FBO3, draw any color when
- // * Invert_DepthStencil has the stencil bit set > 0 (classified)
- // 5. Fullscreen pass to FBO1, draw Invert_Color when:
- // * Invert_Color !== vec4(0.0) and
- // * IsClassified_Color !== vec4(0.0)
- // 6. Fullscreen pass to FBO1, draw Invert_Color * czm_invertClassificationColor when:
- // * Invert_Color !== vec4(0.0) and
- // * IsClassified_Color === vec4(0.0)
- //
- // NOTE: Step six when translucent invert color occurs after the TRANSLUCENT pass
- //
- scene._invertClassification.clear(context, passState);
- var opaqueClassificationFramebuffer = passState.framebuffer;
- passState.framebuffer = scene._invertClassification._fbo;
- // Draw normally
- us.updatePass(Pass.CESIUM_3D_TILE);
- commands = frustumCommands.commands[Pass.CESIUM_3D_TILE];
- length = frustumCommands.indices[Pass.CESIUM_3D_TILE];
- for (j = 0; j < length; ++j) {
- executeCommand(commands[j], scene, context, passState);
- }
- if (defined(globeDepth) && environmentState.useGlobeDepthFramebuffer) {
- globeDepth.executeUpdateDepth(context, passState, clearGlobeDepth);
- }
- // Set stencil
- us.updatePass(Pass.CESIUM_3D_TILE_CLASSIFICATION_IGNORE_SHOW);
- commands =
- frustumCommands.commands[
- Pass.CESIUM_3D_TILE_CLASSIFICATION_IGNORE_SHOW
- ];
- length =
- frustumCommands.indices[Pass.CESIUM_3D_TILE_CLASSIFICATION_IGNORE_SHOW];
- for (j = 0; j < length; ++j) {
- executeCommand(commands[j], scene, context, passState);
- }
- passState.framebuffer = opaqueClassificationFramebuffer;
- // Fullscreen pass to copy classified fragments
- scene._invertClassification.executeClassified(context, passState);
- if (frameState.invertClassificationColor.alpha === 1.0) {
- // Fullscreen pass to copy unclassified fragments when alpha == 1.0
- scene._invertClassification.executeUnclassified(context, passState);
- }
- // Clear stencil set by the classification for the next classification pass
- if (length > 0 && context.stencilBuffer) {
- clearClassificationStencil.execute(context, passState);
- }
- // Draw style over classification.
- us.updatePass(Pass.CESIUM_3D_TILE_CLASSIFICATION);
- commands = frustumCommands.commands[Pass.CESIUM_3D_TILE_CLASSIFICATION];
- length = frustumCommands.indices[Pass.CESIUM_3D_TILE_CLASSIFICATION];
- for (j = 0; j < length; ++j) {
- executeCommand(commands[j], scene, context, passState);
- }
- }
- if (length > 0 && context.stencilBuffer) {
- clearStencil.execute(context, passState);
- }
- us.updatePass(Pass.OPAQUE);
- commands = frustumCommands.commands[Pass.OPAQUE];
- length = frustumCommands.indices[Pass.OPAQUE];
- for (j = 0; j < length; ++j) {
- executeCommand(commands[j], scene, context, passState);
- }
- if (index !== 0 && scene.mode !== SceneMode.SCENE2D) {
- // Do not overlap frustums in the translucent pass to avoid blending artifacts
- frustum.near = frustumCommands.near;
- us.updateFrustum(frustum);
- }
- var invertClassification;
- if (
- !picking &&
- environmentState.useInvertClassification &&
- frameState.invertClassificationColor.alpha < 1.0
- ) {
- // Fullscreen pass to copy unclassified fragments when alpha < 1.0.
- // Not executed when undefined.
- invertClassification = scene._invertClassification;
- }
- us.updatePass(Pass.TRANSLUCENT);
- commands = frustumCommands.commands[Pass.TRANSLUCENT];
- commands.length = frustumCommands.indices[Pass.TRANSLUCENT];
- executeTranslucentCommands(
- scene,
- executeCommand,
- passState,
- commands,
- invertClassification
- );
- if (
- context.depthTexture &&
- scene.useDepthPicking &&
- (environmentState.useGlobeDepthFramebuffer ||
- renderTranslucentDepthForPick)
- ) {
- // PERFORMANCE_IDEA: Use MRT to avoid the extra copy.
- var depthStencilTexture = renderTranslucentDepthForPick
- ? passState.framebuffer.depthStencilTexture
- : globeDepth.framebuffer.depthStencilTexture;
- var pickDepth = scene._picking.getPickDepth(scene, index);
- pickDepth.update(context, depthStencilTexture);
- pickDepth.executeCopyDepth(context, passState);
- }
- if (separatePrimitiveFramebuffer) {
- // Reset framebuffer
- passState.framebuffer = globeDepth.framebuffer;
- }
- if (picking || !usePostProcessSelected) {
- continue;
- }
- var originalFramebuffer = passState.framebuffer;
- passState.framebuffer = view.sceneFramebuffer.getIdFramebuffer();
- // reset frustum
- frustum.near =
- index !== 0
- ? frustumCommands.near * scene.opaqueFrustumNearOffset
- : frustumCommands.near;
- frustum.far = frustumCommands.far;
- us.updateFrustum(frustum);
- us.updatePass(Pass.GLOBE);
- commands = frustumCommands.commands[Pass.GLOBE];
- length = frustumCommands.indices[Pass.GLOBE];
- if (globeTranslucent) {
- globeTranslucencyState.executeGlobeCommands(
- frustumCommands,
- executeIdCommand,
- globeTranslucencyFramebuffer,
- scene,
- passState
- );
- } else {
- for (j = 0; j < length; ++j) {
- executeIdCommand(commands[j], scene, context, passState);
- }
- }
- if (clearGlobeDepth) {
- clearDepth.framebuffer = passState.framebuffer;
- clearDepth.execute(context, passState);
- clearDepth.framebuffer = undefined;
- }
- if (clearGlobeDepth && useDepthPlane) {
- depthPlane.execute(context, passState);
- }
- us.updatePass(Pass.CESIUM_3D_TILE);
- commands = frustumCommands.commands[Pass.CESIUM_3D_TILE];
- length = frustumCommands.indices[Pass.CESIUM_3D_TILE];
- for (j = 0; j < length; ++j) {
- executeIdCommand(commands[j], scene, context, passState);
- }
- us.updatePass(Pass.OPAQUE);
- commands = frustumCommands.commands[Pass.OPAQUE];
- length = frustumCommands.indices[Pass.OPAQUE];
- for (j = 0; j < length; ++j) {
- executeIdCommand(commands[j], scene, context, passState);
- }
- us.updatePass(Pass.TRANSLUCENT);
- commands = frustumCommands.commands[Pass.TRANSLUCENT];
- length = frustumCommands.indices[Pass.TRANSLUCENT];
- for (j = 0; j < length; ++j) {
- executeIdCommand(commands[j], scene, context, passState);
- }
- passState.framebuffer = originalFramebuffer;
- }
- }
- function executeComputeCommands(scene) {
- var us = scene.context.uniformState;
- us.updatePass(Pass.COMPUTE);
- var sunComputeCommand = scene._environmentState.sunComputeCommand;
- if (defined(sunComputeCommand)) {
- sunComputeCommand.execute(scene._computeEngine);
- }
- var commandList = scene._computeCommandList;
- var length = commandList.length;
- for (var i = 0; i < length; ++i) {
- commandList[i].execute(scene._computeEngine);
- }
- }
- function executeOverlayCommands(scene, passState) {
- var us = scene.context.uniformState;
- us.updatePass(Pass.OVERLAY);
- var context = scene.context;
- var commandList = scene._overlayCommandList;
- var length = commandList.length;
- for (var i = 0; i < length; ++i) {
- commandList[i].execute(context, passState);
- }
- }
- function insertShadowCastCommands(scene, commandList, shadowMap) {
- var shadowVolume = shadowMap.shadowMapCullingVolume;
- var isPointLight = shadowMap.isPointLight;
- var passes = shadowMap.passes;
- var numberOfPasses = passes.length;
- var length = commandList.length;
- for (var i = 0; i < length; ++i) {
- var command = commandList[i];
- scene.updateDerivedCommands(command);
- if (
- command.castShadows &&
- (command.pass === Pass.GLOBE ||
- command.pass === Pass.CESIUM_3D_TILE ||
- command.pass === Pass.OPAQUE ||
- command.pass === Pass.TRANSLUCENT)
- ) {
- if (scene.isVisible(command, shadowVolume)) {
- if (isPointLight) {
- for (var k = 0; k < numberOfPasses; ++k) {
- passes[k].commandList.push(command);
- }
- } else if (numberOfPasses === 1) {
- passes[0].commandList.push(command);
- } else {
- var wasVisible = false;
- // Loop over cascades from largest to smallest
- for (var j = numberOfPasses - 1; j >= 0; --j) {
- var cascadeVolume = passes[j].cullingVolume;
- if (scene.isVisible(command, cascadeVolume)) {
- passes[j].commandList.push(command);
- wasVisible = true;
- } else if (wasVisible) {
- // If it was visible in the previous cascade but now isn't
- // then there is no need to check any more cascades
- break;
- }
- }
- }
- }
- }
- }
- }
- function executeShadowMapCastCommands(scene) {
- var frameState = scene.frameState;
- var shadowMaps = frameState.shadowState.shadowMaps;
- var shadowMapLength = shadowMaps.length;
- if (!frameState.shadowState.shadowsEnabled) {
- return;
- }
- var context = scene.context;
- var uniformState = context.uniformState;
- for (var i = 0; i < shadowMapLength; ++i) {
- var shadowMap = shadowMaps[i];
- if (shadowMap.outOfView) {
- continue;
- }
- // Reset the command lists
- var j;
- var passes = shadowMap.passes;
- var numberOfPasses = passes.length;
- for (j = 0; j < numberOfPasses; ++j) {
- passes[j].commandList.length = 0;
- }
- // Insert the primitive/model commands into the command lists
- var sceneCommands = scene.frameState.commandList;
- insertShadowCastCommands(scene, sceneCommands, shadowMap);
- for (j = 0; j < numberOfPasses; ++j) {
- var pass = shadowMap.passes[j];
- uniformState.updateCamera(pass.camera);
- shadowMap.updatePass(context, j);
- var numberOfCommands = pass.commandList.length;
- for (var k = 0; k < numberOfCommands; ++k) {
- var command = pass.commandList[k];
- // Set the correct pass before rendering into the shadow map because some shaders
- // conditionally render based on whether the pass is translucent or opaque.
- uniformState.updatePass(command.pass);
- executeCommand(
- command.derivedCommands.shadows.castCommands[i],
- scene,
- context,
- pass.passState
- );
- }
- }
- }
- }
- var scratchEyeTranslation = new Cartesian3();
- /**
- * @private
- */
- Scene.prototype.updateAndExecuteCommands = function (
- passState,
- backgroundColor
- ) {
- var frameState = this._frameState;
- var mode = frameState.mode;
- var useWebVR = this._environmentState.useWebVR;
- if (useWebVR) {
- executeWebVRCommands(this, passState, backgroundColor);
- } else if (
- mode !== SceneMode.SCENE2D ||
- this._mapMode2D === MapMode2D.ROTATE
- ) {
- executeCommandsInViewport(true, this, passState, backgroundColor);
- } else {
- updateAndClearFramebuffers(this, passState, backgroundColor);
- execute2DViewportCommands(this, passState);
- }
- };
- function executeWebVRCommands(scene, passState, backgroundColor) {
- var view = scene._view;
- var camera = view.camera;
- var environmentState = scene._environmentState;
- var renderTranslucentDepthForPick =
- environmentState.renderTranslucentDepthForPick;
- updateAndClearFramebuffers(scene, passState, backgroundColor);
- if (!renderTranslucentDepthForPick) {
- updateAndRenderPrimitives(scene);
- }
- view.createPotentiallyVisibleSet(scene);
- if (!renderTranslucentDepthForPick) {
- executeComputeCommands(scene);
- executeShadowMapCastCommands(scene);
- }
- // Based on Calculating Stereo pairs by Paul Bourke
- // http://paulbourke.net/stereographics/stereorender/
- var viewport = passState.viewport;
- viewport.x = 0;
- viewport.y = 0;
- viewport.width = viewport.width * 0.5;
- var savedCamera = Camera.clone(camera, scene._cameraVR);
- savedCamera.frustum = camera.frustum;
- var near = camera.frustum.near;
- var fo = near * defaultValue(scene.focalLength, 5.0);
- var eyeSeparation = defaultValue(scene.eyeSeparation, fo / 30.0);
- var eyeTranslation = Cartesian3.multiplyByScalar(
- savedCamera.right,
- eyeSeparation * 0.5,
- scratchEyeTranslation
- );
- camera.frustum.aspectRatio = viewport.width / viewport.height;
- var offset = (0.5 * eyeSeparation * near) / fo;
- Cartesian3.add(savedCamera.position, eyeTranslation, camera.position);
- camera.frustum.xOffset = offset;
- executeCommands(scene, passState);
- viewport.x = viewport.width;
- Cartesian3.subtract(savedCamera.position, eyeTranslation, camera.position);
- camera.frustum.xOffset = -offset;
- executeCommands(scene, passState);
- Camera.clone(savedCamera, camera);
- }
- var scratch2DViewportCartographic = new Cartographic(
- Math.PI,
- CesiumMath.PI_OVER_TWO
- );
- var scratch2DViewportMaxCoord = new Cartesian3();
- var scratch2DViewportSavedPosition = new Cartesian3();
- var scratch2DViewportTransform = new Matrix4();
- var scratch2DViewportCameraTransform = new Matrix4();
- var scratch2DViewportEyePoint = new Cartesian3();
- var scratch2DViewportWindowCoords = new Cartesian3();
- var scratch2DViewport = new BoundingRectangle();
- function execute2DViewportCommands(scene, passState) {
- var context = scene.context;
- var frameState = scene.frameState;
- var camera = scene.camera;
- var originalViewport = passState.viewport;
- var viewport = BoundingRectangle.clone(originalViewport, scratch2DViewport);
- passState.viewport = viewport;
- var maxCartographic = scratch2DViewportCartographic;
- var maxCoord = scratch2DViewportMaxCoord;
- var projection = scene.mapProjection;
- projection.project(maxCartographic, maxCoord);
- var position = Cartesian3.clone(
- camera.position,
- scratch2DViewportSavedPosition
- );
- var transform = Matrix4.clone(
- camera.transform,
- scratch2DViewportCameraTransform
- );
- var frustum = camera.frustum.clone();
- camera._setTransform(Matrix4.IDENTITY);
- var viewportTransformation = Matrix4.computeViewportTransformation(
- viewport,
- 0.0,
- 1.0,
- scratch2DViewportTransform
- );
- var projectionMatrix = camera.frustum.projectionMatrix;
- var x = camera.positionWC.y;
- var eyePoint = Cartesian3.fromElements(
- CesiumMath.sign(x) * maxCoord.x - x,
- 0.0,
- -camera.positionWC.x,
- scratch2DViewportEyePoint
- );
- var windowCoordinates = Transforms.pointToGLWindowCoordinates(
- projectionMatrix,
- viewportTransformation,
- eyePoint,
- scratch2DViewportWindowCoords
- );
- windowCoordinates.x = Math.floor(windowCoordinates.x);
- var viewportX = viewport.x;
- var viewportWidth = viewport.width;
- if (
- x === 0.0 ||
- windowCoordinates.x <= viewportX ||
- windowCoordinates.x >= viewportX + viewportWidth
- ) {
- executeCommandsInViewport(true, scene, passState);
- } else if (
- Math.abs(viewportX + viewportWidth * 0.5 - windowCoordinates.x) < 1.0
- ) {
- viewport.width = windowCoordinates.x - viewport.x;
- camera.position.x *= CesiumMath.sign(camera.position.x);
- camera.frustum.right = 0.0;
- frameState.cullingVolume = camera.frustum.computeCullingVolume(
- camera.positionWC,
- camera.directionWC,
- camera.upWC
- );
- context.uniformState.update(frameState);
- executeCommandsInViewport(true, scene, passState);
- viewport.x = windowCoordinates.x;
- camera.position.x = -camera.position.x;
- camera.frustum.right = -camera.frustum.left;
- camera.frustum.left = 0.0;
- frameState.cullingVolume = camera.frustum.computeCullingVolume(
- camera.positionWC,
- camera.directionWC,
- camera.upWC
- );
- context.uniformState.update(frameState);
- executeCommandsInViewport(false, scene, passState);
- } else if (windowCoordinates.x > viewportX + viewportWidth * 0.5) {
- viewport.width = windowCoordinates.x - viewportX;
- var right = camera.frustum.right;
- camera.frustum.right = maxCoord.x - x;
- frameState.cullingVolume = camera.frustum.computeCullingVolume(
- camera.positionWC,
- camera.directionWC,
- camera.upWC
- );
- context.uniformState.update(frameState);
- executeCommandsInViewport(true, scene, passState);
- viewport.x = windowCoordinates.x;
- viewport.width = viewportX + viewportWidth - windowCoordinates.x;
- camera.position.x = -camera.position.x;
- camera.frustum.left = -camera.frustum.right;
- camera.frustum.right = right - camera.frustum.right * 2.0;
- frameState.cullingVolume = camera.frustum.computeCullingVolume(
- camera.positionWC,
- camera.directionWC,
- camera.upWC
- );
- context.uniformState.update(frameState);
- executeCommandsInViewport(false, scene, passState);
- } else {
- viewport.x = windowCoordinates.x;
- viewport.width = viewportX + viewportWidth - windowCoordinates.x;
- var left = camera.frustum.left;
- camera.frustum.left = -maxCoord.x - x;
- frameState.cullingVolume = camera.frustum.computeCullingVolume(
- camera.positionWC,
- camera.directionWC,
- camera.upWC
- );
- context.uniformState.update(frameState);
- executeCommandsInViewport(true, scene, passState);
- viewport.x = viewportX;
- viewport.width = windowCoordinates.x - viewportX;
- camera.position.x = -camera.position.x;
- camera.frustum.right = -camera.frustum.left;
- camera.frustum.left = left - camera.frustum.left * 2.0;
- frameState.cullingVolume = camera.frustum.computeCullingVolume(
- camera.positionWC,
- camera.directionWC,
- camera.upWC
- );
- context.uniformState.update(frameState);
- executeCommandsInViewport(false, scene, passState);
- }
- camera._setTransform(transform);
- Cartesian3.clone(position, camera.position);
- camera.frustum = frustum.clone();
- passState.viewport = originalViewport;
- }
- function executeCommandsInViewport(
- firstViewport,
- scene,
- passState,
- backgroundColor
- ) {
- var environmentState = scene._environmentState;
- var view = scene._view;
- var renderTranslucentDepthForPick =
- environmentState.renderTranslucentDepthForPick;
- if (!firstViewport && !renderTranslucentDepthForPick) {
- scene.frameState.commandList.length = 0;
- }
- if (!renderTranslucentDepthForPick) {
- updateAndRenderPrimitives(scene);
- }
- view.createPotentiallyVisibleSet(scene);
- if (firstViewport) {
- if (defined(backgroundColor)) {
- updateAndClearFramebuffers(scene, passState, backgroundColor);
- }
- if (!renderTranslucentDepthForPick) {
- executeComputeCommands(scene);
- executeShadowMapCastCommands(scene);
- }
- }
- executeCommands(scene, passState);
- }
- var scratchCullingVolume = new CullingVolume();
- /**
- * @private
- */
- Scene.prototype.updateEnvironment = function () {
- var frameState = this._frameState;
- var view = this._view;
- // Update celestial and terrestrial environment effects.
- var environmentState = this._environmentState;
- var renderPass = frameState.passes.render;
- var offscreenPass = frameState.passes.offscreen;
- var skyAtmosphere = this.skyAtmosphere;
- var globe = this.globe;
- var globeTranslucencyState = this._globeTranslucencyState;
- if (
- !renderPass ||
- (this._mode !== SceneMode.SCENE2D &&
- view.camera.frustum instanceof OrthographicFrustum) ||
- !globeTranslucencyState.environmentVisible
- ) {
- environmentState.skyAtmosphereCommand = undefined;
- environmentState.skyBoxCommand = undefined;
- environmentState.sunDrawCommand = undefined;
- environmentState.sunComputeCommand = undefined;
- environmentState.moonCommand = undefined;
- } else {
- if (defined(skyAtmosphere)) {
- if (defined(globe)) {
- skyAtmosphere.setDynamicAtmosphereColor(
- globe.enableLighting && globe.dynamicAtmosphereLighting,
- globe.dynamicAtmosphereLightingFromSun
- );
- environmentState.isReadyForAtmosphere =
- environmentState.isReadyForAtmosphere ||
- globe._surface._tilesToRender.length > 0;
- }
- environmentState.skyAtmosphereCommand = skyAtmosphere.update(
- frameState,
- globe
- );
- if (defined(environmentState.skyAtmosphereCommand)) {
- this.updateDerivedCommands(environmentState.skyAtmosphereCommand);
- }
- } else {
- environmentState.skyAtmosphereCommand = undefined;
- }
- environmentState.skyBoxCommand = defined(this.skyBox)
- ? this.skyBox.update(frameState, this._hdr)
- : undefined;
- var sunCommands = defined(this.sun)
- ? this.sun.update(frameState, view.passState, this._hdr)
- : undefined;
- environmentState.sunDrawCommand = defined(sunCommands)
- ? sunCommands.drawCommand
- : undefined;
- environmentState.sunComputeCommand = defined(sunCommands)
- ? sunCommands.computeCommand
- : undefined;
- environmentState.moonCommand = defined(this.moon)
- ? this.moon.update(frameState)
- : undefined;
- }
- var clearGlobeDepth = (environmentState.clearGlobeDepth =
- defined(globe) &&
- globe.show &&
- (!globe.depthTestAgainstTerrain || this.mode === SceneMode.SCENE2D));
- var useDepthPlane = (environmentState.useDepthPlane =
- clearGlobeDepth &&
- this.mode === SceneMode.SCENE3D &&
- globeTranslucencyState.useDepthPlane);
- if (useDepthPlane) {
- // Update the depth plane that is rendered in 3D when the primitives are
- // not depth tested against terrain so primitives on the backface
- // of the globe are not picked.
- this._depthPlane.update(frameState);
- }
- environmentState.renderTranslucentDepthForPick = false;
- environmentState.useWebVR =
- this._useWebVR && this.mode !== SceneMode.SCENE2D && !offscreenPass;
- var occluder =
- frameState.mode === SceneMode.SCENE3D &&
- !globeTranslucencyState.sunVisibleThroughGlobe
- ? frameState.occluder
- : undefined;
- var cullingVolume = frameState.cullingVolume;
- // get user culling volume minus the far plane.
- var planes = scratchCullingVolume.planes;
- for (var k = 0; k < 5; ++k) {
- planes[k] = cullingVolume.planes[k];
- }
- cullingVolume = scratchCullingVolume;
- // Determine visibility of celestial and terrestrial environment effects.
- environmentState.isSkyAtmosphereVisible =
- defined(environmentState.skyAtmosphereCommand) &&
- environmentState.isReadyForAtmosphere;
- environmentState.isSunVisible = this.isVisible(
- environmentState.sunDrawCommand,
- cullingVolume,
- occluder
- );
- environmentState.isMoonVisible = this.isVisible(
- environmentState.moonCommand,
- cullingVolume,
- occluder
- );
- var envMaps = this.specularEnvironmentMaps;
- var envMapAtlas = this._specularEnvironmentMapAtlas;
- if (
- defined(envMaps) &&
- (!defined(envMapAtlas) || envMapAtlas.url !== envMaps)
- ) {
- envMapAtlas = envMapAtlas && envMapAtlas.destroy();
- this._specularEnvironmentMapAtlas = new OctahedralProjectedCubeMap(envMaps);
- } else if (!defined(envMaps) && defined(envMapAtlas)) {
- envMapAtlas.destroy();
- this._specularEnvironmentMapAtlas = undefined;
- }
- if (defined(this._specularEnvironmentMapAtlas)) {
- this._specularEnvironmentMapAtlas.update(frameState);
- }
- };
- function updateDebugFrustumPlanes(scene) {
- var frameState = scene._frameState;
- if (scene.debugShowFrustumPlanes !== scene._debugShowFrustumPlanes) {
- if (scene.debugShowFrustumPlanes) {
- scene._debugFrustumPlanes = new DebugCameraPrimitive({
- camera: scene.camera,
- updateOnChange: false,
- frustumSplits: frameState.frustumSplits,
- });
- } else {
- scene._debugFrustumPlanes =
- scene._debugFrustumPlanes && scene._debugFrustumPlanes.destroy();
- }
- scene._debugShowFrustumPlanes = scene.debugShowFrustumPlanes;
- }
- if (defined(scene._debugFrustumPlanes)) {
- scene._debugFrustumPlanes.update(frameState);
- }
- }
- function updateShadowMaps(scene) {
- var frameState = scene._frameState;
- var shadowMaps = frameState.shadowMaps;
- var length = shadowMaps.length;
- var shadowsEnabled =
- length > 0 && !frameState.passes.pick && scene.mode === SceneMode.SCENE3D;
- if (shadowsEnabled !== frameState.shadowState.shadowsEnabled) {
- // Update derived commands when shadowsEnabled changes
- ++frameState.shadowState.lastDirtyTime;
- frameState.shadowState.shadowsEnabled = shadowsEnabled;
- }
- frameState.shadowState.lightShadowsEnabled = false;
- if (!shadowsEnabled) {
- return;
- }
- // Check if the shadow maps are different than the shadow maps last frame.
- // If so, the derived commands need to be updated.
- for (var j = 0; j < length; ++j) {
- if (shadowMaps[j] !== frameState.shadowState.shadowMaps[j]) {
- ++frameState.shadowState.lastDirtyTime;
- break;
- }
- }
- frameState.shadowState.shadowMaps.length = 0;
- frameState.shadowState.lightShadowMaps.length = 0;
- for (var i = 0; i < length; ++i) {
- var shadowMap = shadowMaps[i];
- shadowMap.update(frameState);
- frameState.shadowState.shadowMaps.push(shadowMap);
- if (shadowMap.fromLightSource) {
- frameState.shadowState.lightShadowMaps.push(shadowMap);
- frameState.shadowState.lightShadowsEnabled = true;
- }
- if (shadowMap.dirty) {
- ++frameState.shadowState.lastDirtyTime;
- shadowMap.dirty = false;
- }
- }
- }
- function updateAndRenderPrimitives(scene) {
- var frameState = scene._frameState;
- scene._groundPrimitives.update(frameState);
- scene._primitives.update(frameState);
- updateDebugFrustumPlanes(scene);
- updateShadowMaps(scene);
- if (scene._globe) {
- scene._globe.render(frameState);
- }
- }
- function updateAndClearFramebuffers(scene, passState, clearColor) {
- var context = scene._context;
- var frameState = scene._frameState;
- var environmentState = scene._environmentState;
- var view = scene._view;
- var passes = scene._frameState.passes;
- var picking = passes.pick;
- var useWebVR = environmentState.useWebVR;
- // Preserve the reference to the original framebuffer.
- environmentState.originalFramebuffer = passState.framebuffer;
- // Manage sun bloom post-processing effect.
- if (defined(scene.sun) && scene.sunBloom !== scene._sunBloom) {
- if (scene.sunBloom && !useWebVR) {
- scene._sunPostProcess = new SunPostProcess();
- } else if (defined(scene._sunPostProcess)) {
- scene._sunPostProcess = scene._sunPostProcess.destroy();
- }
- scene._sunBloom = scene.sunBloom;
- } else if (!defined(scene.sun) && defined(scene._sunPostProcess)) {
- scene._sunPostProcess = scene._sunPostProcess.destroy();
- scene._sunBloom = false;
- }
- // Clear the pass state framebuffer.
- var clear = scene._clearColorCommand;
- Color.clone(clearColor, clear.color);
- clear.execute(context, passState);
- // Update globe depth rendering based on the current context and clear the globe depth framebuffer.
- // Globe depth is copied for the pick pass to support picking batched geometries in GroundPrimitives.
- var useGlobeDepthFramebuffer = (environmentState.useGlobeDepthFramebuffer = defined(
- view.globeDepth
- ));
- if (useGlobeDepthFramebuffer) {
- view.globeDepth.update(
- context,
- passState,
- view.viewport,
- scene._hdr,
- environmentState.clearGlobeDepth
- );
- view.globeDepth.clear(context, passState, clearColor);
- }
- // If supported, configure OIT to use the globe depth framebuffer and clear the OIT framebuffer.
- var oit = view.oit;
- var useOIT = (environmentState.useOIT =
- !picking && defined(oit) && oit.isSupported());
- if (useOIT) {
- oit.update(context, passState, view.globeDepth.framebuffer, scene._hdr);
- oit.clear(context, passState, clearColor);
- environmentState.useOIT = oit.isSupported();
- }
- var postProcess = scene.postProcessStages;
- var usePostProcess = (environmentState.usePostProcess =
- !picking &&
- (scene._hdr ||
- postProcess.length > 0 ||
- postProcess.ambientOcclusion.enabled ||
- postProcess.fxaa.enabled ||
- postProcess.bloom.enabled));
- environmentState.usePostProcessSelected = false;
- if (usePostProcess) {
- view.sceneFramebuffer.update(context, view.viewport, scene._hdr);
- view.sceneFramebuffer.clear(context, passState, clearColor);
- postProcess.update(context, frameState.useLogDepth, scene._hdr);
- postProcess.clear(context);
- usePostProcess = environmentState.usePostProcess = postProcess.ready;
- environmentState.usePostProcessSelected =
- usePostProcess && postProcess.hasSelected;
- }
- if (environmentState.isSunVisible && scene.sunBloom && !useWebVR) {
- passState.framebuffer = scene._sunPostProcess.update(passState);
- scene._sunPostProcess.clear(context, passState, clearColor);
- } else if (useGlobeDepthFramebuffer) {
- passState.framebuffer = view.globeDepth.framebuffer;
- } else if (usePostProcess) {
- passState.framebuffer = view.sceneFramebuffer.getFramebuffer();
- }
- if (defined(passState.framebuffer)) {
- clear.execute(context, passState);
- }
- var useInvertClassification = (environmentState.useInvertClassification =
- !picking && defined(passState.framebuffer) && scene.invertClassification);
- if (useInvertClassification) {
- var depthFramebuffer;
- if (scene.frameState.invertClassificationColor.alpha === 1.0) {
- if (environmentState.useGlobeDepthFramebuffer) {
- depthFramebuffer = view.globeDepth.framebuffer;
- }
- }
- if (defined(depthFramebuffer) || context.depthTexture) {
- scene._invertClassification.previousFramebuffer = depthFramebuffer;
- scene._invertClassification.update(context);
- scene._invertClassification.clear(context, passState);
- if (scene.frameState.invertClassificationColor.alpha < 1.0 && useOIT) {
- var command = scene._invertClassification.unclassifiedCommand;
- var derivedCommands = command.derivedCommands;
- derivedCommands.oit = oit.createDerivedCommands(
- command,
- context,
- derivedCommands.oit
- );
- }
- } else {
- environmentState.useInvertClassification = false;
- }
- }
- if (scene._globeTranslucencyState.translucent) {
- view.globeTranslucencyFramebuffer.updateAndClear(
- scene._hdr,
- view.viewport,
- context,
- passState
- );
- }
- }
- /**
- * @private
- */
- Scene.prototype.resolveFramebuffers = function (passState) {
- var context = this._context;
- var frameState = this._frameState;
- var environmentState = this._environmentState;
- var view = this._view;
- var globeDepth = view.globeDepth;
- var useOIT = environmentState.useOIT;
- var useGlobeDepthFramebuffer = environmentState.useGlobeDepthFramebuffer;
- var usePostProcess = environmentState.usePostProcess;
- var defaultFramebuffer = environmentState.originalFramebuffer;
- var globeFramebuffer = useGlobeDepthFramebuffer
- ? globeDepth.framebuffer
- : undefined;
- var sceneFramebuffer = view.sceneFramebuffer.getFramebuffer();
- var idFramebuffer = view.sceneFramebuffer.getIdFramebuffer();
- if (environmentState.separatePrimitiveFramebuffer) {
- // Merge primitive framebuffer into globe framebuffer
- globeDepth.executeMergeColor(context, passState);
- }
- if (useOIT) {
- passState.framebuffer = usePostProcess
- ? sceneFramebuffer
- : defaultFramebuffer;
- view.oit.execute(context, passState);
- }
- if (usePostProcess) {
- var inputFramebuffer = sceneFramebuffer;
- if (useGlobeDepthFramebuffer && !useOIT) {
- inputFramebuffer = globeFramebuffer;
- }
- var postProcess = this.postProcessStages;
- var colorTexture = inputFramebuffer.getColorTexture(0);
- var idTexture = idFramebuffer.getColorTexture(0);
- var depthTexture = defaultValue(globeFramebuffer, sceneFramebuffer)
- .depthStencilTexture;
- postProcess.execute(context, colorTexture, depthTexture, idTexture);
- postProcess.copy(context, defaultFramebuffer);
- }
- if (!useOIT && !usePostProcess && useGlobeDepthFramebuffer) {
- passState.framebuffer = defaultFramebuffer;
- globeDepth.executeCopyColor(context, passState);
- }
- var useLogDepth = frameState.useLogDepth;
- if (this.debugShowGlobeDepth && useGlobeDepthFramebuffer) {
- var gd = getDebugGlobeDepth(this, this.debugShowDepthFrustum - 1);
- gd.executeDebugGlobeDepth(context, passState, useLogDepth);
- }
- if (this.debugShowPickDepth && useGlobeDepthFramebuffer) {
- var pd = this._picking.getPickDepth(this, this.debugShowDepthFrustum - 1);
- pd.executeDebugPickDepth(context, passState, useLogDepth);
- }
- };
- function callAfterRenderFunctions(scene) {
- // Functions are queued up during primitive update and executed here in case
- // the function modifies scene state that should remain constant over the frame.
- var functions = scene._frameState.afterRender;
- for (var i = 0, length = functions.length; i < length; ++i) {
- functions[i]();
- scene.requestRender();
- }
- functions.length = 0;
- }
- function getGlobeHeight(scene) {
- var globe = scene._globe;
- var camera = scene.camera;
- var cartographic = camera.positionCartographic;
- if (defined(globe) && globe.show && defined(cartographic)) {
- return globe.getHeight(cartographic);
- }
- return undefined;
- }
- function isCameraUnderground(scene) {
- var camera = scene.camera;
- var mode = scene._mode;
- var globe = scene.globe;
- var cameraController = scene._screenSpaceCameraController;
- var cartographic = camera.positionCartographic;
- if (!defined(cartographic)) {
- return false;
- }
- if (!cameraController.onMap() && cartographic.height < 0.0) {
- // The camera can go off the map while in Columbus View.
- // Make a best guess as to whether it's underground by checking if its height is less than zero.
- return true;
- }
- if (
- !defined(globe) ||
- !globe.show ||
- mode === SceneMode.SCENE2D ||
- mode === SceneMode.MORPHING
- ) {
- return false;
- }
- var globeHeight = scene._globeHeight;
- return defined(globeHeight) && cartographic.height < globeHeight;
- }
- /**
- * @private
- */
- Scene.prototype.initializeFrame = function () {
- // Destroy released shaders and textures once every 120 frames to avoid thrashing the cache
- if (this._shaderFrameCount++ === 120) {
- this._shaderFrameCount = 0;
- this._context.shaderCache.destroyReleasedShaderPrograms();
- this._context.textureCache.destroyReleasedTextures();
- }
- this._tweens.update();
- this._globeHeight = getGlobeHeight(this);
- this._cameraUnderground = isCameraUnderground(this);
- this._globeTranslucencyState.update(this);
- this._screenSpaceCameraController.update();
- if (defined(this._deviceOrientationCameraController)) {
- this._deviceOrientationCameraController.update();
- }
- this.camera.update(this._mode);
- this.camera._updateCameraChanged();
- };
- function updateDebugShowFramesPerSecond(scene, renderedThisFrame) {
- if (scene.debugShowFramesPerSecond) {
- if (!defined(scene._performanceDisplay)) {
- var performanceContainer = document.createElement("div");
- performanceContainer.className =
- "cesium-performanceDisplay-defaultContainer";
- var container = scene._canvas.parentNode;
- container.appendChild(performanceContainer);
- var performanceDisplay = new PerformanceDisplay({
- container: performanceContainer,
- });
- scene._performanceDisplay = performanceDisplay;
- scene._performanceContainer = performanceContainer;
- }
- scene._performanceDisplay.throttled = scene.requestRenderMode;
- scene._performanceDisplay.update(renderedThisFrame);
- } else if (defined(scene._performanceDisplay)) {
- scene._performanceDisplay =
- scene._performanceDisplay && scene._performanceDisplay.destroy();
- scene._performanceContainer.parentNode.removeChild(
- scene._performanceContainer
- );
- }
- }
- function prePassesUpdate(scene) {
- scene._jobScheduler.resetBudgets();
- var frameState = scene._frameState;
- var primitives = scene.primitives;
- primitives.prePassesUpdate(frameState);
- if (defined(scene.globe)) {
- scene.globe.update(frameState);
- }
- scene._picking.update();
- frameState.creditDisplay.update();
- }
- function postPassesUpdate(scene) {
- var frameState = scene._frameState;
- var primitives = scene.primitives;
- primitives.postPassesUpdate(frameState);
- RequestScheduler.update();
- }
- var scratchBackgroundColor = new Color();
- function render(scene) {
- var frameState = scene._frameState;
- var context = scene.context;
- var us = context.uniformState;
- var view = scene._defaultView;
- scene._view = view;
- scene.updateFrameState();
- frameState.passes.render = true;
- frameState.passes.postProcess = scene.postProcessStages.hasSelected;
- frameState.tilesetPassState = renderTilesetPassState;
- var backgroundColor = defaultValue(scene.backgroundColor, Color.BLACK);
- if (scene._hdr) {
- backgroundColor = Color.clone(backgroundColor, scratchBackgroundColor);
- backgroundColor.red = Math.pow(backgroundColor.red, scene.gamma);
- backgroundColor.green = Math.pow(backgroundColor.green, scene.gamma);
- backgroundColor.blue = Math.pow(backgroundColor.blue, scene.gamma);
- }
- frameState.backgroundColor = backgroundColor;
- scene.fog.update(frameState);
- us.update(frameState);
- var shadowMap = scene.shadowMap;
- if (defined(shadowMap) && shadowMap.enabled) {
- if (!defined(scene.light) || scene.light instanceof SunLight) {
- // Negate the sun direction so that it is from the Sun, not to the Sun
- Cartesian3.negate(us.sunDirectionWC, scene._shadowMapCamera.direction);
- } else {
- Cartesian3.clone(scene.light.direction, scene._shadowMapCamera.direction);
- }
- frameState.shadowMaps.push(shadowMap);
- }
- scene._computeCommandList.length = 0;
- scene._overlayCommandList.length = 0;
- var viewport = view.viewport;
- viewport.x = 0;
- viewport.y = 0;
- viewport.width = context.drawingBufferWidth;
- viewport.height = context.drawingBufferHeight;
- var passState = view.passState;
- passState.framebuffer = undefined;
- passState.blendingEnabled = undefined;
- passState.scissorTest = undefined;
- passState.viewport = BoundingRectangle.clone(viewport, passState.viewport);
- if (defined(scene.globe)) {
- scene.globe.beginFrame(frameState);
- }
- scene.updateEnvironment();
- scene.updateAndExecuteCommands(passState, backgroundColor);
- scene.resolveFramebuffers(passState);
- passState.framebuffer = undefined;
- executeOverlayCommands(scene, passState);
- if (defined(scene.globe)) {
- scene.globe.endFrame(frameState);
- if (!scene.globe.tilesLoaded) {
- scene._renderRequested = true;
- }
- }
- context.endFrame();
- }
- function tryAndCatchError(scene, functionToExecute) {
- try {
- functionToExecute(scene);
- } catch (error) {
- scene._renderError.raiseEvent(scene, error);
- if (scene.rethrowRenderErrors) {
- throw error;
- }
- }
- }
- function updateMostDetailedRayPicks(scene) {
- return scene._picking.updateMostDetailedRayPicks(scene);
- }
- /**
- * Update and render the scene. It is usually not necessary to call this function
- * directly because {@link CesiumWidget} or {@link Viewer} do it automatically.
- * @param {JulianDate} [time] The simulation time at which to render.
- */
- Scene.prototype.render = function (time) {
- /**
- *
- * Pre passes update. Execute any pass invariant code that should run before the passes here.
- *
- */
- this._preUpdate.raiseEvent(this, time);
- var frameState = this._frameState;
- frameState.newFrame = false;
- if (!defined(time)) {
- time = JulianDate.now();
- }
- // Determine if shouldRender
- var cameraChanged = this._view.checkForCameraUpdates(this);
- var shouldRender =
- !this.requestRenderMode ||
- this._renderRequested ||
- cameraChanged ||
- this._logDepthBufferDirty ||
- this._hdrDirty ||
- this.mode === SceneMode.MORPHING;
- if (
- !shouldRender &&
- defined(this.maximumRenderTimeChange) &&
- defined(this._lastRenderTime)
- ) {
- var difference = Math.abs(
- JulianDate.secondsDifference(this._lastRenderTime, time)
- );
- shouldRender = shouldRender || difference > this.maximumRenderTimeChange;
- }
- if (shouldRender) {
- this._lastRenderTime = JulianDate.clone(time, this._lastRenderTime);
- this._renderRequested = false;
- this._logDepthBufferDirty = false;
- this._hdrDirty = false;
- var frameNumber = CesiumMath.incrementWrap(
- frameState.frameNumber,
- 15000000.0,
- 1.0
- );
- updateFrameNumber(this, frameNumber, time);
- frameState.newFrame = true;
- }
- tryAndCatchError(this, prePassesUpdate);
- /**
- *
- * Passes update. Add any passes here
- *
- */
- if (this.primitives.show) {
- tryAndCatchError(this, updateMostDetailedRayPicks);
- tryAndCatchError(this, updatePreloadPass);
- tryAndCatchError(this, updatePreloadFlightPass);
- if (!shouldRender) {
- tryAndCatchError(this, updateRequestRenderModeDeferCheckPass);
- }
- }
- this._postUpdate.raiseEvent(this, time);
- if (shouldRender) {
- this._preRender.raiseEvent(this, time);
- frameState.creditDisplay.beginFrame();
- tryAndCatchError(this, render);
- }
- /**
- *
- * Post passes update. Execute any pass invariant code that should run after the passes here.
- *
- */
- updateDebugShowFramesPerSecond(this, shouldRender);
- tryAndCatchError(this, postPassesUpdate);
- // Often used to trigger events (so don't want in trycatch) that the user might be subscribed to. Things like the tile load events, ready promises, etc.
- // We don't want those events to resolve during the render loop because the events might add new primitives
- callAfterRenderFunctions(this);
- if (shouldRender) {
- this._postRender.raiseEvent(this, time);
- frameState.creditDisplay.endFrame();
- }
- };
- /**
- * Update and render the scene. Always forces a new render frame regardless of whether a render was
- * previously requested.
- * @param {JulianDate} [time] The simulation time at which to render.
- *
- * @private
- */
- Scene.prototype.forceRender = function (time) {
- this._renderRequested = true;
- this.render(time);
- };
- /**
- * Requests a new rendered frame when {@link Scene#requestRenderMode} is set to <code>true</code>.
- * The render rate will not exceed the {@link CesiumWidget#targetFrameRate}.
- *
- * @see Scene#requestRenderMode
- */
- Scene.prototype.requestRender = function () {
- this._renderRequested = true;
- };
- /**
- * @private
- */
- Scene.prototype.clampLineWidth = function (width) {
- return Math.max(
- ContextLimits.minimumAliasedLineWidth,
- Math.min(width, ContextLimits.maximumAliasedLineWidth)
- );
- };
- /**
- * Returns an object with a `primitive` property that contains the first (top) primitive in the scene
- * at a particular window coordinate or undefined if nothing is at the location. Other properties may
- * potentially be set depending on the type of primitive and may be used to further identify the picked object.
- * <p>
- * When a feature of a 3D Tiles tileset is picked, <code>pick</code> returns a {@link Cesium3DTileFeature} object.
- * </p>
- *
- * @example
- * // On mouse over, color the feature yellow.
- * handler.setInputAction(function(movement) {
- * var feature = scene.pick(movement.endPosition);
- * if (feature instanceof Cesium.Cesium3DTileFeature) {
- * feature.color = Cesium.Color.YELLOW;
- * }
- * }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
- *
- * @param {Cartesian2} windowPosition Window coordinates to perform picking on.
- * @param {Number} [width=3] Width of the pick rectangle.
- * @param {Number} [height=3] Height of the pick rectangle.
- * @returns {Object} Object containing the picked primitive.
- */
- Scene.prototype.pick = function (windowPosition, width, height) {
- return this._picking.pick(this, windowPosition, width, height);
- };
- /**
- * Returns the cartesian position reconstructed from the depth buffer and window position.
- * The returned position is in world coordinates. Used internally by camera functions to
- * prevent conversion to projected 2D coordinates and then back.
- * <p>
- * Set {@link Scene#pickTranslucentDepth} to <code>true</code> to include the depth of
- * translucent primitives; otherwise, this essentially picks through translucent primitives.
- * </p>
- *
- * @private
- *
- * @param {Cartesian2} windowPosition Window coordinates to perform picking on.
- * @param {Cartesian3} [result] The object on which to restore the result.
- * @returns {Cartesian3} The cartesian position in world coordinates.
- *
- * @exception {DeveloperError} Picking from the depth buffer is not supported. Check pickPositionSupported.
- */
- Scene.prototype.pickPositionWorldCoordinates = function (
- windowPosition,
- result
- ) {
- return this._picking.pickPositionWorldCoordinates(
- this,
- windowPosition,
- result
- );
- };
- /**
- * Returns the cartesian position reconstructed from the depth buffer and window position.
- * <p>
- * The position reconstructed from the depth buffer in 2D may be slightly different from those
- * reconstructed in 3D and Columbus view. This is caused by the difference in the distribution
- * of depth values of perspective and orthographic projection.
- * </p>
- * <p>
- * Set {@link Scene#pickTranslucentDepth} to <code>true</code> to include the depth of
- * translucent primitives; otherwise, this essentially picks through translucent primitives.
- * </p>
- *
- * @param {Cartesian2} windowPosition Window coordinates to perform picking on.
- * @param {Cartesian3} [result] The object on which to restore the result.
- * @returns {Cartesian3} The cartesian position.
- *
- * @exception {DeveloperError} Picking from the depth buffer is not supported. Check pickPositionSupported.
- */
- Scene.prototype.pickPosition = function (windowPosition, result) {
- return this._picking.pickPosition(this, windowPosition, result);
- };
- /**
- * Returns a list of objects, each containing a `primitive` property, for all primitives at
- * a particular window coordinate position. Other properties may also be set depending on the
- * type of primitive and may be used to further identify the picked object. The primitives in
- * the list are ordered by their visual order in the scene (front to back).
- *
- * @param {Cartesian2} windowPosition Window coordinates to perform picking on.
- * @param {Number} [limit] If supplied, stop drilling after collecting this many picks.
- * @param {Number} [width=3] Width of the pick rectangle.
- * @param {Number} [height=3] Height of the pick rectangle.
- * @returns {Array.<*>} Array of objects, each containing 1 picked primitives.
- *
- * @exception {DeveloperError} windowPosition is undefined.
- *
- * @example
- * var pickedObjects = scene.drillPick(new Cesium.Cartesian2(100.0, 200.0));
- *
- * @see Scene#pick
- */
- Scene.prototype.drillPick = function (windowPosition, limit, width, height) {
- return this._picking.drillPick(this, windowPosition, limit, width, height);
- };
- function updatePreloadPass(scene) {
- var frameState = scene._frameState;
- preloadTilesetPassState.camera = frameState.camera;
- preloadTilesetPassState.cullingVolume = frameState.cullingVolume;
- var primitives = scene.primitives;
- primitives.updateForPass(frameState, preloadTilesetPassState);
- }
- function updatePreloadFlightPass(scene) {
- var frameState = scene._frameState;
- var camera = frameState.camera;
- if (!camera.canPreloadFlight()) {
- return;
- }
- preloadFlightTilesetPassState.camera = scene.preloadFlightCamera;
- preloadFlightTilesetPassState.cullingVolume =
- scene.preloadFlightCullingVolume;
- var primitives = scene.primitives;
- primitives.updateForPass(frameState, preloadFlightTilesetPassState);
- }
- function updateRequestRenderModeDeferCheckPass(scene) {
- // Check if any ignored requests are ready to go (to wake rendering up again)
- scene.primitives.updateForPass(
- scene._frameState,
- requestRenderModeDeferCheckPassState
- );
- }
- /**
- * Returns an object containing the first object intersected by the ray and the position of intersection,
- * or <code>undefined</code> if there were no intersections. The intersected object has a <code>primitive</code>
- * property that contains the intersected primitive. Other properties may be set depending on the type of primitive
- * and may be used to further identify the picked object. The ray must be given in world coordinates.
- * <p>
- * This function only picks globe tiles and 3D Tiles that are rendered in the current view. Picks all other
- * primitives regardless of their visibility.
- * </p>
- *
- * @private
- *
- * @param {Ray} ray The ray.
- * @param {Object[]} [objectsToExclude] A list of primitives, entities, or 3D Tiles features to exclude from the ray intersection.
- * @param {Number} [width=0.1] Width of the intersection volume in meters.
- * @returns {Object} An object containing the object and position of the first intersection.
- *
- * @exception {DeveloperError} Ray intersections are only supported in 3D mode.
- */
- Scene.prototype.pickFromRay = function (ray, objectsToExclude, width) {
- return this._picking.pickFromRay(this, ray, objectsToExclude, width);
- };
- /**
- * Returns a list of objects, each containing the object intersected by the ray and the position of intersection.
- * The intersected object has a <code>primitive</code> property that contains the intersected primitive. Other
- * properties may also be set depending on the type of primitive and may be used to further identify the picked object.
- * The primitives in the list are ordered by first intersection to last intersection. The ray must be given in
- * world coordinates.
- * <p>
- * This function only picks globe tiles and 3D Tiles that are rendered in the current view. Picks all other
- * primitives regardless of their visibility.
- * </p>
- *
- * @private
- *
- * @param {Ray} ray The ray.
- * @param {Number} [limit=Number.MAX_VALUE] If supplied, stop finding intersections after this many intersections.
- * @param {Object[]} [objectsToExclude] A list of primitives, entities, or 3D Tiles features to exclude from the ray intersection.
- * @param {Number} [width=0.1] Width of the intersection volume in meters.
- * @returns {Object[]} List of objects containing the object and position of each intersection.
- *
- * @exception {DeveloperError} Ray intersections are only supported in 3D mode.
- */
- Scene.prototype.drillPickFromRay = function (
- ray,
- limit,
- objectsToExclude,
- width
- ) {
- return this._picking.drillPickFromRay(
- this,
- ray,
- limit,
- objectsToExclude,
- width
- );
- };
- /**
- * Initiates an asynchronous {@link Scene#pickFromRay} request using the maximum level of detail for 3D Tilesets
- * regardless of visibility.
- *
- * @private
- *
- * @param {Ray} ray The ray.
- * @param {Object[]} [objectsToExclude] A list of primitives, entities, or 3D Tiles features to exclude from the ray intersection.
- * @param {Number} [width=0.1] Width of the intersection volume in meters.
- * @returns {Promise.<Object>} A promise that resolves to an object containing the object and position of the first intersection.
- *
- * @exception {DeveloperError} Ray intersections are only supported in 3D mode.
- */
- Scene.prototype.pickFromRayMostDetailed = function (
- ray,
- objectsToExclude,
- width
- ) {
- return this._picking.pickFromRayMostDetailed(
- this,
- ray,
- objectsToExclude,
- width
- );
- };
- /**
- * Initiates an asynchronous {@link Scene#drillPickFromRay} request using the maximum level of detail for 3D Tilesets
- * regardless of visibility.
- *
- * @private
- *
- * @param {Ray} ray The ray.
- * @param {Number} [limit=Number.MAX_VALUE] If supplied, stop finding intersections after this many intersections.
- * @param {Object[]} [objectsToExclude] A list of primitives, entities, or 3D Tiles features to exclude from the ray intersection.
- * @param {Number} [width=0.1] Width of the intersection volume in meters.
- * @returns {Promise.<Object[]>} A promise that resolves to a list of objects containing the object and position of each intersection.
- *
- * @exception {DeveloperError} Ray intersections are only supported in 3D mode.
- */
- Scene.prototype.drillPickFromRayMostDetailed = function (
- ray,
- limit,
- objectsToExclude,
- width
- ) {
- return this._picking.drillPickFromRayMostDetailed(
- this,
- ray,
- limit,
- objectsToExclude,
- width
- );
- };
- /**
- * Returns the height of scene geometry at the given cartographic position or <code>undefined</code> if there was no
- * scene geometry to sample height from. The height of the input position is ignored. May be used to clamp objects to
- * the globe, 3D Tiles, or primitives in the scene.
- * <p>
- * This function only samples height from globe tiles and 3D Tiles that are rendered in the current view. Samples height
- * from all other primitives regardless of their visibility.
- * </p>
- *
- * @param {Cartographic} position The cartographic position to sample height from.
- * @param {Object[]} [objectsToExclude] A list of primitives, entities, or 3D Tiles features to not sample height from.
- * @param {Number} [width=0.1] Width of the intersection volume in meters.
- * @returns {Number} The height. This may be <code>undefined</code> if there was no scene geometry to sample height from.
- *
- * @example
- * var position = new Cesium.Cartographic(-1.31968, 0.698874);
- * var height = viewer.scene.sampleHeight(position);
- * console.log(height);
- *
- * @see Scene#clampToHeight
- * @see Scene#clampToHeightMostDetailed
- * @see Scene#sampleHeightMostDetailed
- *
- * @exception {DeveloperError} sampleHeight is only supported in 3D mode.
- * @exception {DeveloperError} sampleHeight requires depth texture support. Check sampleHeightSupported.
- */
- Scene.prototype.sampleHeight = function (position, objectsToExclude, width) {
- return this._picking.sampleHeight(this, position, objectsToExclude, width);
- };
- /**
- * Clamps the given cartesian position to the scene geometry along the geodetic surface normal. Returns the
- * clamped position or <code>undefined</code> if there was no scene geometry to clamp to. May be used to clamp
- * objects to the globe, 3D Tiles, or primitives in the scene.
- * <p>
- * This function only clamps to globe tiles and 3D Tiles that are rendered in the current view. Clamps to
- * all other primitives regardless of their visibility.
- * </p>
- *
- * @param {Cartesian3} cartesian The cartesian position.
- * @param {Object[]} [objectsToExclude] A list of primitives, entities, or 3D Tiles features to not clamp to.
- * @param {Number} [width=0.1] Width of the intersection volume in meters.
- * @param {Cartesian3} [result] An optional object to return the clamped position.
- * @returns {Cartesian3} The modified result parameter or a new Cartesian3 instance if one was not provided. This may be <code>undefined</code> if there was no scene geometry to clamp to.
- *
- * @example
- * // Clamp an entity to the underlying scene geometry
- * var position = entity.position.getValue(Cesium.JulianDate.now());
- * entity.position = viewer.scene.clampToHeight(position);
- *
- * @see Scene#sampleHeight
- * @see Scene#sampleHeightMostDetailed
- * @see Scene#clampToHeightMostDetailed
- *
- * @exception {DeveloperError} clampToHeight is only supported in 3D mode.
- * @exception {DeveloperError} clampToHeight requires depth texture support. Check clampToHeightSupported.
- */
- Scene.prototype.clampToHeight = function (
- cartesian,
- objectsToExclude,
- width,
- result
- ) {
- return this._picking.clampToHeight(
- this,
- cartesian,
- objectsToExclude,
- width,
- result
- );
- };
- /**
- * Initiates an asynchronous {@link Scene#sampleHeight} query for an array of {@link Cartographic} positions
- * using the maximum level of detail for 3D Tilesets in the scene. The height of the input positions is ignored.
- * Returns a promise that is resolved when the query completes. Each point height is modified in place.
- * If a height cannot be determined because no geometry can be sampled at that location, or another error occurs,
- * the height is set to undefined.
- *
- * @param {Cartographic[]} positions The cartographic positions to update with sampled heights.
- * @param {Object[]} [objectsToExclude] A list of primitives, entities, or 3D Tiles features to not sample height from.
- * @param {Number} [width=0.1] Width of the intersection volume in meters.
- * @returns {Promise.<Cartographic[]>} A promise that resolves to the provided list of positions when the query has completed.
- *
- * @example
- * var positions = [
- * new Cesium.Cartographic(-1.31968, 0.69887),
- * new Cesium.Cartographic(-1.10489, 0.83923)
- * ];
- * var promise = viewer.scene.sampleHeightMostDetailed(positions);
- * promise.then(function(updatedPosition) {
- * // positions[0].height and positions[1].height have been updated.
- * // updatedPositions is just a reference to positions.
- * }
- *
- * @see Scene#sampleHeight
- *
- * @exception {DeveloperError} sampleHeightMostDetailed is only supported in 3D mode.
- * @exception {DeveloperError} sampleHeightMostDetailed requires depth texture support. Check sampleHeightSupported.
- */
- Scene.prototype.sampleHeightMostDetailed = function (
- positions,
- objectsToExclude,
- width
- ) {
- return this._picking.sampleHeightMostDetailed(
- this,
- positions,
- objectsToExclude,
- width
- );
- };
- /**
- * Initiates an asynchronous {@link Scene#clampToHeight} query for an array of {@link Cartesian3} positions
- * using the maximum level of detail for 3D Tilesets in the scene. Returns a promise that is resolved when
- * the query completes. Each position is modified in place. If a position cannot be clamped because no geometry
- * can be sampled at that location, or another error occurs, the element in the array is set to undefined.
- *
- * @param {Cartesian3[]} cartesians The cartesian positions to update with clamped positions.
- * @param {Object[]} [objectsToExclude] A list of primitives, entities, or 3D Tiles features to not clamp to.
- * @param {Number} [width=0.1] Width of the intersection volume in meters.
- * @returns {Promise.<Cartesian3[]>} A promise that resolves to the provided list of positions when the query has completed.
- *
- * @example
- * var cartesians = [
- * entities[0].position.getValue(Cesium.JulianDate.now()),
- * entities[1].position.getValue(Cesium.JulianDate.now())
- * ];
- * var promise = viewer.scene.clampToHeightMostDetailed(cartesians);
- * promise.then(function(updatedCartesians) {
- * entities[0].position = updatedCartesians[0];
- * entities[1].position = updatedCartesians[1];
- * }
- *
- * @see Scene#clampToHeight
- *
- * @exception {DeveloperError} clampToHeightMostDetailed is only supported in 3D mode.
- * @exception {DeveloperError} clampToHeightMostDetailed requires depth texture support. Check clampToHeightSupported.
- */
- Scene.prototype.clampToHeightMostDetailed = function (
- cartesians,
- objectsToExclude,
- width
- ) {
- return this._picking.clampToHeightMostDetailed(
- this,
- cartesians,
- objectsToExclude,
- width
- );
- };
- /**
- * Transforms a position in cartesian coordinates to canvas coordinates. This is commonly used to place an
- * HTML element at the same screen position as an object in the scene.
- *
- * @param {Cartesian3} position The position in cartesian coordinates.
- * @param {Cartesian2} [result] An optional object to return the input position transformed to canvas coordinates.
- * @returns {Cartesian2} The modified result parameter or a new Cartesian2 instance if one was not provided. This may be <code>undefined</code> if the input position is near the center of the ellipsoid.
- *
- * @example
- * // Output the canvas position of longitude/latitude (0, 0) every time the mouse moves.
- * var scene = widget.scene;
- * var ellipsoid = scene.globe.ellipsoid;
- * var position = Cesium.Cartesian3.fromDegrees(0.0, 0.0);
- * var handler = new Cesium.ScreenSpaceEventHandler(scene.canvas);
- * handler.setInputAction(function(movement) {
- * console.log(scene.cartesianToCanvasCoordinates(position));
- * }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
- */
- Scene.prototype.cartesianToCanvasCoordinates = function (position, result) {
- return SceneTransforms.wgs84ToWindowCoordinates(this, position, result);
- };
- /**
- * Instantly completes an active transition.
- */
- Scene.prototype.completeMorph = function () {
- this._transitioner.completeMorph();
- };
- /**
- * Asynchronously transitions the scene to 2D.
- * @param {Number} [duration=2.0] The amount of time, in seconds, for transition animations to complete.
- */
- Scene.prototype.morphTo2D = function (duration) {
- var ellipsoid;
- var globe = this.globe;
- if (defined(globe)) {
- ellipsoid = globe.ellipsoid;
- } else {
- ellipsoid = this.mapProjection.ellipsoid;
- }
- duration = defaultValue(duration, 2.0);
- this._transitioner.morphTo2D(duration, ellipsoid);
- };
- /**
- * Asynchronously transitions the scene to Columbus View.
- * @param {Number} [duration=2.0] The amount of time, in seconds, for transition animations to complete.
- */
- Scene.prototype.morphToColumbusView = function (duration) {
- var ellipsoid;
- var globe = this.globe;
- if (defined(globe)) {
- ellipsoid = globe.ellipsoid;
- } else {
- ellipsoid = this.mapProjection.ellipsoid;
- }
- duration = defaultValue(duration, 2.0);
- this._transitioner.morphToColumbusView(duration, ellipsoid);
- };
- /**
- * Asynchronously transitions the scene to 3D.
- * @param {Number} [duration=2.0] The amount of time, in seconds, for transition animations to complete.
- */
- Scene.prototype.morphTo3D = function (duration) {
- var ellipsoid;
- var globe = this.globe;
- if (defined(globe)) {
- ellipsoid = globe.ellipsoid;
- } else {
- ellipsoid = this.mapProjection.ellipsoid;
- }
- duration = defaultValue(duration, 2.0);
- this._transitioner.morphTo3D(duration, ellipsoid);
- };
- /**
- * Returns true if this object was destroyed; otherwise, false.
- * <br /><br />
- * If this object was destroyed, it should not be used; calling any function other than
- * <code>isDestroyed</code> will result in a {@link DeveloperError} exception.
- *
- * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>.
- *
- * @see Scene#destroy
- */
- Scene.prototype.isDestroyed = function () {
- return false;
- };
- /**
- * Destroys the WebGL resources held by this object. Destroying an object allows for deterministic
- * release of WebGL resources, instead of relying on the garbage collector to destroy this object.
- * <br /><br />
- * Once an object is destroyed, it should not be used; calling any function other than
- * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore,
- * assign the return value (<code>undefined</code>) to the object as done in the example.
- *
- * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called.
- *
- *
- * @example
- * scene = scene && scene.destroy();
- *
- * @see Scene#isDestroyed
- */
- Scene.prototype.destroy = function () {
- this._tweens.removeAll();
- this._computeEngine = this._computeEngine && this._computeEngine.destroy();
- this._screenSpaceCameraController =
- this._screenSpaceCameraController &&
- this._screenSpaceCameraController.destroy();
- this._deviceOrientationCameraController =
- this._deviceOrientationCameraController &&
- !this._deviceOrientationCameraController.isDestroyed() &&
- this._deviceOrientationCameraController.destroy();
- this._primitives = this._primitives && this._primitives.destroy();
- this._groundPrimitives =
- this._groundPrimitives && this._groundPrimitives.destroy();
- this._globe = this._globe && this._globe.destroy();
- this.skyBox = this.skyBox && this.skyBox.destroy();
- this.skyAtmosphere = this.skyAtmosphere && this.skyAtmosphere.destroy();
- this._debugSphere = this._debugSphere && this._debugSphere.destroy();
- this.sun = this.sun && this.sun.destroy();
- this._sunPostProcess = this._sunPostProcess && this._sunPostProcess.destroy();
- this._depthPlane = this._depthPlane && this._depthPlane.destroy();
- this._transitioner = this._transitioner && this._transitioner.destroy();
- this._debugFrustumPlanes =
- this._debugFrustumPlanes && this._debugFrustumPlanes.destroy();
- this._brdfLutGenerator =
- this._brdfLutGenerator && this._brdfLutGenerator.destroy();
- this._picking = this._picking && this._picking.destroy();
- this._defaultView = this._defaultView && this._defaultView.destroy();
- this._view = undefined;
- if (this._removeCreditContainer) {
- this._canvas.parentNode.removeChild(this._creditContainer);
- }
- this.postProcessStages =
- this.postProcessStages && this.postProcessStages.destroy();
- this._context = this._context && this._context.destroy();
- this._frameState.creditDisplay =
- this._frameState.creditDisplay && this._frameState.creditDisplay.destroy();
- if (defined(this._performanceDisplay)) {
- this._performanceDisplay =
- this._performanceDisplay && this._performanceDisplay.destroy();
- this._performanceContainer.parentNode.removeChild(
- this._performanceContainer
- );
- }
- this._removeRequestListenerCallback();
- this._removeTaskProcessorListenerCallback();
- for (var i = 0; i < this._removeGlobeCallbacks.length; ++i) {
- this._removeGlobeCallbacks[i]();
- }
- this._removeGlobeCallbacks.length = 0;
- return destroyObject(this);
- };
- export default Scene;
|