Scene中的render方法
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(); } };
看完是不是一头雾水。。渲染管线里面那么多步骤去哪了?传值在哪里?输出结果在哪里?怎么控制场景的投影转换到view?
不如先看一下Scene有哪些参数和方法构成吧。
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(); }