diff --git a/CHANGES.md b/CHANGES.md index 588ebdd54a2a..198e51dab9eb 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -12,6 +12,7 @@ Change Log ##### Fixes :wrench: * The Geocoder widget now takes terrain altitude into account when calculating its final destination. * Fixed bug that caused a new `ClippingPlaneCollection` to be created every frame when used with a model entity [#6872](https://github.com/AnalyticalGraphicsInc/cesium/pull/6872) +* Fixed crash when rendering translucent objects when all shadow maps in the scene set `fromLightSource` to false. [#6883](https://github.com/AnalyticalGraphicsInc/cesium/pull/6883) ### 1.48 - 2018-08-01 diff --git a/Source/Scene/FrameState.js b/Source/Scene/FrameState.js index d463cf162201..6d0c3d8da2b3 100644 --- a/Source/Scene/FrameState.js +++ b/Source/Scene/FrameState.js @@ -239,6 +239,12 @@ define([ */ shadowsEnabled : true, + /** + * Whether there are any active shadow maps that originate from light sources. Does not + * include shadow maps that are used for analytical purposes. + */ + lightShadowsEnabled : true, + /** * All shadow maps that are enabled this frame. */ diff --git a/Source/Scene/OIT.js b/Source/Scene/OIT.js index 1326d8e95bd9..57e083efe409 100644 --- a/Source/Scene/OIT.js +++ b/Source/Scene/OIT.js @@ -540,7 +540,7 @@ define([ var framebuffer = passState.framebuffer; var length = commands.length; - var shadowsEnabled = scene.frameState.shadowHints.shadowsEnabled; + var lightShadowsEnabled = scene.frameState.shadowHints.lightShadowsEnabled; passState.framebuffer = oit._adjustTranslucentFBO; oit._adjustTranslucentCommand.execute(context, passState); @@ -553,14 +553,14 @@ define([ for (j = 0; j < length; ++j) { command = commands[j]; command = defined(command.derivedCommands.logDepth) ? command.derivedCommands.logDepth.command : command; - derivedCommand = (shadowsEnabled && command.receiveShadows) ? command.derivedCommands.oit.shadows.translucentCommand : command.derivedCommands.oit.translucentCommand; + derivedCommand = (lightShadowsEnabled && command.receiveShadows) ? command.derivedCommands.oit.shadows.translucentCommand : command.derivedCommands.oit.translucentCommand; executeFunction(derivedCommand, scene, context, passState, debugFramebuffer); } if (defined(invertClassification)) { command = invertClassification.unclassifiedCommand; command = defined(command.derivedCommands.logDepth) ? command.derivedCommands.logDepth.command : command; - derivedCommand = (shadowsEnabled && command.receiveShadows) ? command.derivedCommands.oit.shadows.translucentCommand : command.derivedCommands.oit.translucentCommand; + derivedCommand = (lightShadowsEnabled && command.receiveShadows) ? command.derivedCommands.oit.shadows.translucentCommand : command.derivedCommands.oit.translucentCommand; executeFunction(derivedCommand, scene, context, passState, debugFramebuffer); } @@ -569,14 +569,14 @@ define([ for (j = 0; j < length; ++j) { command = commands[j]; command = defined(command.derivedCommands.logDepth) ? command.derivedCommands.logDepth.command : command; - derivedCommand = (shadowsEnabled && command.receiveShadows) ? command.derivedCommands.oit.shadows.alphaCommand : command.derivedCommands.oit.alphaCommand; + derivedCommand = (lightShadowsEnabled && command.receiveShadows) ? command.derivedCommands.oit.shadows.alphaCommand : command.derivedCommands.oit.alphaCommand; executeFunction(derivedCommand, scene, context, passState, debugFramebuffer); } if (defined(invertClassification)) { command = invertClassification.unclassifiedCommand; command = defined(command.derivedCommands.logDepth) ? command.derivedCommands.logDepth.command : command; - derivedCommand = (shadowsEnabled && command.receiveShadows) ? command.derivedCommands.oit.shadows.alphaCommand : command.derivedCommands.oit.alphaCommand; + derivedCommand = (lightShadowsEnabled && command.receiveShadows) ? command.derivedCommands.oit.shadows.alphaCommand : command.derivedCommands.oit.alphaCommand; executeFunction(derivedCommand, scene, context, passState, debugFramebuffer); } @@ -588,7 +588,7 @@ define([ var framebuffer = passState.framebuffer; var length = commands.length; - var shadowsEnabled = scene.frameState.shadowHints.shadowsEnabled; + var lightShadowsEnabled = scene.frameState.shadowHints.lightShadowsEnabled; passState.framebuffer = oit._adjustTranslucentFBO; oit._adjustTranslucentCommand.execute(context, passState); @@ -602,14 +602,14 @@ define([ for (var j = 0; j < length; ++j) { command = commands[j]; command = defined(command.derivedCommands.logDepth) ? command.derivedCommands.logDepth.command : command; - derivedCommand = (shadowsEnabled && command.receiveShadows) ? command.derivedCommands.oit.shadows.translucentCommand : command.derivedCommands.oit.translucentCommand; + derivedCommand = (lightShadowsEnabled && command.receiveShadows) ? command.derivedCommands.oit.shadows.translucentCommand : command.derivedCommands.oit.translucentCommand; executeFunction(derivedCommand, scene, context, passState, debugFramebuffer); } if (defined(invertClassification)) { command = invertClassification.unclassifiedCommand; command = defined(command.derivedCommands.logDepth) ? command.derivedCommands.logDepth.command : command; - derivedCommand = (shadowsEnabled && command.receiveShadows) ? command.derivedCommands.oit.shadows.translucentCommand : command.derivedCommands.oit.translucentCommand; + derivedCommand = (lightShadowsEnabled && command.receiveShadows) ? command.derivedCommands.oit.shadows.translucentCommand : command.derivedCommands.oit.translucentCommand; executeFunction(derivedCommand, scene, context, passState, debugFramebuffer); } diff --git a/Source/Scene/Scene.js b/Source/Scene/Scene.js index 4340e5100f03..8f16aefef198 100644 --- a/Source/Scene/Scene.js +++ b/Source/Scene/Scene.js @@ -1498,7 +1498,7 @@ define([ var shadowsEnabled = frameState.shadowHints.shadowsEnabled; var shadowMaps = frameState.shadowHints.shadowMaps; var lightShadowMaps = frameState.shadowHints.lightShadowMaps; - var lightShadowsEnabled = shadowsEnabled && (lightShadowMaps.length > 0); + var lightShadowsEnabled = frameState.shadowHints.lightShadowsEnabled; // Update derived commands when any shadow maps become dirty var shadowsDirty = false; @@ -2082,10 +2082,7 @@ define([ return; } - var shadowsEnabled = scene.frameState.shadowHints.shadowsEnabled; - var lightShadowsEnabled = shadowsEnabled && (scene.frameState.shadowHints.lightShadowMaps.length > 0); - - if (lightShadowsEnabled && command.receiveShadows && defined(command.derivedCommands.shadows)) { + if (frameState.shadowHints.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. @@ -2940,6 +2937,8 @@ define([ frameState.shadowHints.shadowsEnabled = shadowsEnabled; } + frameState.shadowHints.lightShadowsEnabled = false; + if (!shadowsEnabled) { return; } @@ -2964,6 +2963,7 @@ define([ if (shadowMap.fromLightSource) { frameState.shadowHints.lightShadowMaps.push(shadowMap); + frameState.shadowHints.lightShadowsEnabled = true; } if (shadowMap.dirty) { diff --git a/Specs/Scene/ShadowMapSpec.js b/Specs/Scene/ShadowMapSpec.js index 1546688f390d..06ea1505f331 100644 --- a/Specs/Scene/ShadowMapSpec.js +++ b/Specs/Scene/ShadowMapSpec.js @@ -1134,6 +1134,28 @@ defineSuite([ floor.show = false; }); + it('does not receive shadows if fromLightSource is false', function() { + box.show = true; + floorTranslucent.show = true; + createCascadedShadowMap(); + scene.shadowMap.fromLightSource = false; + + // Render without shadows + scene.shadowMap.enabled = false; + var unshadowedColor; + renderAndCall(function(rgba) { + unshadowedColor = rgba; + expect(rgba).not.toEqual(backgroundColor); + }); + + // Render with shadows + scene.shadowMap.enabled = true; + renderAndCall(function(rgba) { + expect(rgba).not.toEqual(backgroundColor); + expect(rgba).toEqual(unshadowedColor); + }); + }); + it('tweaking shadow bias parameters works', function() { box.show = true; floor.show = true;