diff --git a/Source/Scene/FXAA.js b/Source/Scene/FXAA.js index 46f1342678a1..6696c6651820 100644 --- a/Source/Scene/FXAA.js +++ b/Source/Scene/FXAA.js @@ -54,6 +54,9 @@ define([ this._viewport = new BoundingRectangle(); this._rs = undefined; + this._useScissorTest = false; + this._scissorRectangle = undefined; + var clearCommand = new ClearCommand({ color : new Color(0.0, 0.0, 0.0, 0.0), depth : 1.0, @@ -81,7 +84,7 @@ define([ } } - FXAA.prototype.update = function(context) { + FXAA.prototype.update = function(context, passState) { var width = context.drawingBufferWidth; var height = context.drawingBufferHeight; @@ -150,9 +153,22 @@ define([ this._viewport.width = width; this._viewport.height = height; - if (!defined(this._rs) || !BoundingRectangle.equals(this._rs.viewport, this._viewport)) { + var useScissorTest = !BoundingRectangle.equals(this._viewport, passState.viewport); + var updateScissor = useScissorTest !== this._useScissorTest; + this._useScissorTest = useScissorTest; + + if (!BoundingRectangle.equals(this._scissorRectangle, passState.viewport)) { + this._scissorRectangle = BoundingRectangle.clone(passState.viewport, this._scissorRectangle); + updateScissor = true; + } + + if (!defined(this._rs) || !BoundingRectangle.equals(this._rs.viewport, this._viewport) || updateScissor) { this._rs = RenderState.fromCache({ - viewport : this._viewport + viewport : this._viewport, + scissorTest : { + enabled : this._useScissorTest, + rectangle : this._scissorRectangle + } }); } diff --git a/Source/Scene/GlobeDepth.js b/Source/Scene/GlobeDepth.js index 20fa390c0bdf..2254e270b81f 100644 --- a/Source/Scene/GlobeDepth.js +++ b/Source/Scene/GlobeDepth.js @@ -43,6 +43,9 @@ define([ this._viewport = new BoundingRectangle(); this._rs = undefined; + this._useScissorTest = false; + this._scissorRectangle = undefined; + this._debugGlobeDepthViewportCommand = undefined; } @@ -111,7 +114,7 @@ define([ }); } - function createFramebuffers(globeDepth, context, width, height) { + function createFramebuffers(globeDepth, context) { globeDepth.framebuffer = new Framebuffer({ context : context, colorTextures : [globeDepth._colorTexture], @@ -133,17 +136,30 @@ define([ destroyTextures(globeDepth); destroyFramebuffers(globeDepth); createTextures(globeDepth, context, width, height); - createFramebuffers(globeDepth, context, width, height); + createFramebuffers(globeDepth, context); } } - function updateCopyCommands(globeDepth, context, width, height) { + function updateCopyCommands(globeDepth, context, width, height, passState) { globeDepth._viewport.width = width; globeDepth._viewport.height = height; - if (!defined(globeDepth._rs) || !BoundingRectangle.equals(globeDepth._viewport, globeDepth._rs.viewport)) { + var useScissorTest = !BoundingRectangle.equals(globeDepth._viewport, passState.viewport); + var updateScissor = useScissorTest !== globeDepth._useScissorTest; + globeDepth._useScissorTest = useScissorTest; + + if (!BoundingRectangle.equals(globeDepth._scissorRectangle, passState.viewport)) { + globeDepth._scissorRectangle = BoundingRectangle.clone(passState.viewport, globeDepth._scissorRectangle); + updateScissor = true; + } + + if (!defined(globeDepth._rs) || !BoundingRectangle.equals(globeDepth._viewport, globeDepth._rs.viewport) || updateScissor) { globeDepth._rs = RenderState.fromCache({ - viewport : globeDepth._viewport + viewport : globeDepth._viewport, + scissorTest : { + enabled : globeDepth._useScissorTest, + rectangle : globeDepth._scissorRectangle + } }); } @@ -196,12 +212,12 @@ define([ executeDebugGlobeDepth(this, context, passState); }; - GlobeDepth.prototype.update = function(context) { + GlobeDepth.prototype.update = function(context, passState) { var width = context.drawingBufferWidth; var height = context.drawingBufferHeight; updateFramebuffers(this, context, width, height); - updateCopyCommands(this, context, width, height); + updateCopyCommands(this, context, width, height, passState); context.uniformState.globeDepthTexture = undefined; }; diff --git a/Source/Scene/OIT.js b/Source/Scene/OIT.js index c74b7e945611..8f0131f6cae2 100644 --- a/Source/Scene/OIT.js +++ b/Source/Scene/OIT.js @@ -87,6 +87,9 @@ define([ this._viewport = new BoundingRectangle(); this._rs = undefined; + + this._useScissorTest = false; + this._scissorRectangle = undefined; } function destroyTextures(oit) { @@ -200,7 +203,7 @@ define([ return supported; } - OIT.prototype.update = function(context, framebuffer) { + OIT.prototype.update = function(context, passState, framebuffer) { if (!this.isSupported()) { return; } @@ -312,9 +315,22 @@ define([ this._viewport.width = width; this._viewport.height = height; - if (!defined(this._rs) || !BoundingRectangle.equals(this._viewport, this._rs.viewport)) { + var useScissorTest = !BoundingRectangle.equals(this._viewport, passState.viewport); + var updateScissor = useScissorTest !== this._useScissorTest; + this._useScissorTest = useScissorTest; + + if (!BoundingRectangle.equals(this._scissorRectangle, passState.viewport)) { + this._scissorRectangle = BoundingRectangle.clone(passState.viewport, this._scissorRectangle); + updateScissor = true; + } + + if (!defined(this._rs) || !BoundingRectangle.equals(this._viewport, this._rs.viewport) || updateScissor) { this._rs = RenderState.fromCache({ - viewport : this._viewport + viewport : this._viewport, + scissorTest : { + enabled : this._useScissorTest, + rectangle : this._scissorRectangle + } }); } diff --git a/Source/Scene/Scene.js b/Source/Scene/Scene.js index d0bcf630c963..8312c7617a36 100644 --- a/Source/Scene/Scene.js +++ b/Source/Scene/Scene.js @@ -1422,12 +1422,6 @@ define([ } cullingVolume = scratchCullingVolume; - // Determine visibility of celestial and terrestrial environment effects. - var environmentState = scene._environmentState; - environmentState.isSkyAtmosphereVisible = defined(environmentState.skyAtmosphereCommand) && environmentState.isReadyForAtmosphere; - environmentState.isSunVisible = isVisible(environmentState.sunDrawCommand, cullingVolume, occluder); - environmentState.isMoonVisible = isVisible(environmentState.moonCommand, cullingVolume, occluder); - var length = commandList.length; for (var i = 0; i < length; ++i) { var command = commandList[i]; @@ -1899,7 +1893,7 @@ define([ } if (defined(globeDepth) && environmentState.useGlobeDepthFramebuffer && (scene.copyGlobeDepth || scene.debugShowGlobeDepth)) { - globeDepth.update(context); + globeDepth.update(context, passState); globeDepth.executeCopyDepth(context, passState); } @@ -2077,6 +2071,10 @@ define([ var context = scene._context; var viewport = passState.viewport; + viewport.x = 0; + viewport.y = 0; + viewport.width = context.drawingBufferWidth; + viewport.height = context.drawingBufferHeight; var frameState = scene._frameState; var camera = frameState.camera; @@ -2084,12 +2082,13 @@ define([ var depthOnly = frameState.passes.depth; if (scene._useWebVR && mode !== SceneMode.SCENE2D) { + updateAndClearFramebuffers(scene, passState, backgroundColor); + if (!depthOnly) { updatePrimitives(scene); } createPotentiallyVisibleSet(scene); - updateAndClearFramebuffers(scene, passState, backgroundColor); if (!depthOnly) { executeComputeCommands(scene); @@ -2129,15 +2128,11 @@ define([ Camera.clone(savedCamera, camera); } else { - viewport.x = 0; - viewport.y = 0; - viewport.width = context.drawingBufferWidth; - viewport.height = context.drawingBufferHeight; - + updateAndClearFramebuffers(scene, passState, backgroundColor); if (mode !== SceneMode.SCENE2D || scene._mapMode2D === MapMode2D.ROTATE) { - executeCommandsInViewport(true, scene, passState, backgroundColor); + executeCommandsInViewport(true, scene, passState); } else { - execute2DViewportCommands(scene, passState, backgroundColor); + execute2DViewportCommands(scene, passState); } } } @@ -2149,12 +2144,16 @@ define([ var scratch2DViewportCameraTransform = new Matrix4(); var scratch2DViewportEyePoint = new Cartesian3(); var scratch2DViewportWindowCoords = new Cartesian3(); + var scratch2DViewport = new BoundingRectangle(); - function execute2DViewportCommands(scene, passState, backgroundColor) { + function execute2DViewportCommands(scene, passState) { var context = scene.context; var frameState = scene.frameState; var camera = scene.camera; - var viewport = passState.viewport; + + var originalViewport = passState.viewport; + var viewport = BoundingRectangle.clone(originalViewport, scratch2DViewport); + passState.viewport = viewport; var maxCartographic = scratch2DViewportCartographic; var maxCoord = scratch2DViewportMaxCoord; @@ -2180,10 +2179,10 @@ define([ var viewportX = viewport.x; var viewportWidth = viewport.width; - if (x === 0.0 || windowCoordinates.x <= 0.0 || windowCoordinates.x >= context.drawingBufferWidth) { - executeCommandsInViewport(true, scene, passState, backgroundColor); - } else if (Math.abs(context.drawingBufferWidth * 0.5 - windowCoordinates.x) < 1.0) { - viewport.width = windowCoordinates.x; + 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); @@ -2192,9 +2191,9 @@ define([ frameState.cullingVolume = camera.frustum.computeCullingVolume(camera.positionWC, camera.directionWC, camera.upWC); context.uniformState.update(frameState); - executeCommandsInViewport(true, scene, passState, backgroundColor); + executeCommandsInViewport(true, scene, passState); - viewport.x = viewport.width; + viewport.x = windowCoordinates.x; camera.position.x = -camera.position.x; @@ -2204,9 +2203,9 @@ define([ frameState.cullingVolume = camera.frustum.computeCullingVolume(camera.positionWC, camera.directionWC, camera.upWC); context.uniformState.update(frameState); - executeCommandsInViewport(false, scene, passState, backgroundColor); - } else if (windowCoordinates.x > context.drawingBufferWidth * 0.5) { - viewport.width = windowCoordinates.x; + 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; @@ -2214,10 +2213,10 @@ define([ frameState.cullingVolume = camera.frustum.computeCullingVolume(camera.positionWC, camera.directionWC, camera.upWC); context.uniformState.update(frameState); - executeCommandsInViewport(true, scene, passState, backgroundColor); + executeCommandsInViewport(true, scene, passState); - viewport.x += windowCoordinates.x; - viewport.width = context.drawingBufferWidth - windowCoordinates.x; + viewport.x = windowCoordinates.x; + viewport.width = viewportX + viewportWidth - windowCoordinates.x; camera.position.x = -camera.position.x; @@ -2227,10 +2226,10 @@ define([ frameState.cullingVolume = camera.frustum.computeCullingVolume(camera.positionWC, camera.directionWC, camera.upWC); context.uniformState.update(frameState); - executeCommandsInViewport(false, scene, passState, backgroundColor); + executeCommandsInViewport(false, scene, passState); } else { viewport.x = windowCoordinates.x; - viewport.width = context.drawingBufferWidth - windowCoordinates.x; + viewport.width = viewportX + viewportWidth - windowCoordinates.x; var left = camera.frustum.left; camera.frustum.left = -maxCoord.x - x; @@ -2238,10 +2237,10 @@ define([ frameState.cullingVolume = camera.frustum.computeCullingVolume(camera.positionWC, camera.directionWC, camera.upWC); context.uniformState.update(frameState); - executeCommandsInViewport(true, scene, passState, backgroundColor); + executeCommandsInViewport(true, scene, passState); - viewport.x = 0; - viewport.width = windowCoordinates.x; + viewport.x = viewportX; + viewport.width = windowCoordinates.x - viewportX; camera.position.x = -camera.position.x; @@ -2251,18 +2250,16 @@ define([ frameState.cullingVolume = camera.frustum.computeCullingVolume(camera.positionWC, camera.directionWC, camera.upWC); context.uniformState.update(frameState); - executeCommandsInViewport(false, scene, passState, backgroundColor); + executeCommandsInViewport(false, scene, passState); } camera._setTransform(transform); Cartesian3.clone(position, camera.position); camera.frustum = frustum.clone(); - - viewport.x = viewportX; - viewport.width = viewportWidth; + passState.viewport = originalViewport; } - function executeCommandsInViewport(firstViewport, scene, passState, backgroundColor) { + function executeCommandsInViewport(firstViewport, scene, passState) { var depthOnly = scene.frameState.passes.depth; if (!firstViewport && !depthOnly) { @@ -2275,18 +2272,15 @@ define([ createPotentiallyVisibleSet(scene); - if (firstViewport) { - updateAndClearFramebuffers(scene, passState, backgroundColor); - if (!depthOnly) { - executeComputeCommands(scene); - executeShadowMapCastCommands(scene); - } + if (firstViewport && !depthOnly) { + executeComputeCommands(scene); + executeShadowMapCastCommands(scene); } executeCommands(scene, passState); } - function updateEnvironment(scene) { + function updateEnvironment(scene, passState) { var frameState = scene._frameState; // Update celestial and terrestrial environment effects. @@ -2308,7 +2302,7 @@ define([ } environmentState.skyAtmosphereCommand = defined(skyAtmosphere) ? skyAtmosphere.update(frameState) : undefined; environmentState.skyBoxCommand = defined(scene.skyBox) ? scene.skyBox.update(frameState) : undefined; - var sunCommands = defined(scene.sun) ? scene.sun.update(scene) : undefined; + var sunCommands = defined(scene.sun) ? scene.sun.update(frameState, passState) : undefined; environmentState.sunDrawCommand = defined(sunCommands) ? sunCommands.drawCommand : undefined; environmentState.sunComputeCommand = defined(sunCommands) ? sunCommands.computeCommand : undefined; environmentState.moonCommand = defined(scene.moon) ? scene.moon.update(frameState) : undefined; @@ -2322,6 +2316,21 @@ define([ // of the globe are not picked. scene._depthPlane.update(frameState); } + + var occluder = (frameState.mode === SceneMode.SCENE3D) ? 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 = isVisible(environmentState.sunDrawCommand, cullingVolume, occluder); + environmentState.isMoonVisible = isVisible(environmentState.moonCommand, cullingVolume, occluder); } function updateDebugFrustumPlanes(scene) { @@ -2435,7 +2444,7 @@ define([ // Update globe depth rendering based on the current context and clear the globe depth framebuffer. var useGlobeDepthFramebuffer = environmentState.useGlobeDepthFramebuffer = !picking && defined(scene._globeDepth); if (useGlobeDepthFramebuffer) { - scene._globeDepth.update(context); + scene._globeDepth.update(context, passState); scene._globeDepth.clear(context, passState, clearColor); } @@ -2453,7 +2462,7 @@ define([ // If supported, configure OIT to use the globe depth framebuffer and clear the OIT framebuffer. var useOIT = environmentState.useOIT = !picking && renderTranslucentCommands && defined(scene._oit) && scene._oit.isSupported(); if (useOIT) { - scene._oit.update(context, scene._globeDepth.framebuffer); + scene._oit.update(context, passState, scene._globeDepth.framebuffer); scene._oit.clear(context, passState, clearColor); environmentState.useOIT = scene._oit.isSupported(); } @@ -2461,7 +2470,7 @@ define([ // If supported, configure FXAA to use the globe depth color texture and clear the FXAA framebuffer. var useFXAA = environmentState.useFXAA = !picking && scene.fxaa; if (useFXAA) { - scene._fxaa.update(context); + scene._fxaa.update(context, passState); scene._fxaa.clear(context, passState, clearColor); } @@ -2608,7 +2617,7 @@ define([ scene.globe.beginFrame(frameState); } - updateEnvironment(scene); + updateEnvironment(scene, passState); updateAndExecuteCommands(scene, passState, backgroundColor); resolveFramebuffers(scene, passState); executeOverlayCommands(scene, passState); diff --git a/Source/Scene/Sun.js b/Source/Scene/Sun.js index e0e13a079827..30bc89760f35 100644 --- a/Source/Scene/Sun.js +++ b/Source/Scene/Sun.js @@ -139,11 +139,7 @@ define([ /** * @private */ - Sun.prototype.update = function(scene) { - var passState = scene._passState; - var frameState = scene.frameState; - var context = scene.context; - + Sun.prototype.update = function(frameState, passState) { if (!this.show) { return undefined; } @@ -157,6 +153,7 @@ define([ return undefined; } + var context = frameState.context; var drawingBufferWidth = passState.viewport.width; var drawingBufferHeight = passState.viewport.height; @@ -289,7 +286,7 @@ define([ var position = SceneTransforms.computeActualWgs84Position(frameState, sunPosition, scratchCartesian4); - var dist = Cartesian3.magnitude(Cartesian3.subtract(position, scene.camera.position, scratchCartesian4)); + var dist = Cartesian3.magnitude(Cartesian3.subtract(position, frameState.camera.position, scratchCartesian4)); var projMatrix = context.uniformState.projection; var positionEC = scratchPositionEC; diff --git a/Specs/Scene/SunSpec.js b/Specs/Scene/SunSpec.js index 6d8d3515a9c4..fafe8d9691f2 100644 --- a/Specs/Scene/SunSpec.js +++ b/Specs/Scene/SunSpec.js @@ -87,7 +87,7 @@ defineSuite([ viewSun(scene.camera, scene.context.uniformState); scene.frameState.passes.render = false; - var command = scene.sun.update(scene); + var command = scene.sun.update(scene.frameState, scene._passState); expect(command).not.toBeDefined(); });