From 59ead5523f2df5be296175db91365229b8f0e22f Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Fri, 18 Oct 2013 14:44:18 -0400 Subject: [PATCH 1/9] Add lighting to the earth. --- Source/Shaders/CentralBodyFS.glsl | 10 ++++++---- Source/Shaders/CentralBodyVS.glsl | 4 +--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Source/Shaders/CentralBodyFS.glsl b/Source/Shaders/CentralBodyFS.glsl index 2ff9c8e53687..f5db7ff0bd17 100644 --- a/Source/Shaders/CentralBodyFS.glsl +++ b/Source/Shaders/CentralBodyFS.glsl @@ -122,6 +122,9 @@ void main() #endif vec4 color = vec4(startDayColor, 1.0); + + vec3 normalMC = normalize(czm_geodeticSurfaceNormal(v_positionMC, vec3(0.0), vec3(1.0))); // normalized surface normal in model coordinates + vec3 normalEC = normalize(czm_normal3D * normalMC); // normalized surface normal in eye coordiantes #ifdef SHOW_REFLECTIVE_OCEAN vec2 waterMaskTranslation = u_waterMaskTranslationAndScale.xy; @@ -132,10 +135,8 @@ void main() if (mask > 0.0) { - vec3 normalMC = normalize(czm_geodeticSurfaceNormal(v_positionMC, vec3(0.0), vec3(1.0))); // normalized surface normal in model coordinates - vec3 normalEC = normalize(czm_normal3D * normalMC); // normalized surface normal in eye coordiantes mat3 enuToEye = czm_eastNorthUpToEyeCoordinates(v_positionMC, normalEC); - + vec2 ellipsoidTextureCoordinates = czm_ellipsoidWgs84TextureCoordinates(normalMC); vec2 ellipsoidFlippedTextureCoordinates = czm_ellipsoidWgs84TextureCoordinates(normalMC.zyx); @@ -145,7 +146,8 @@ void main() } #endif - gl_FragColor = color; + float diffuseIntensity = clamp(czm_getLambertDiffuse(czm_sunDirectionEC, normalEC) + 0.2, 0.0, 1.0); + gl_FragColor = vec4(color.rgb * diffuseIntensity, 1.0); } #ifdef SHOW_REFLECTIVE_OCEAN diff --git a/Source/Shaders/CentralBodyVS.glsl b/Source/Shaders/CentralBodyVS.glsl index 315ddac4e7d7..530556da999e 100644 --- a/Source/Shaders/CentralBodyVS.glsl +++ b/Source/Shaders/CentralBodyVS.glsl @@ -84,11 +84,9 @@ void main() vec3 position3DWC = position3DAndHeight.xyz + u_center3D; gl_Position = getPosition(position3DWC); - -#ifdef SHOW_REFLECTIVE_OCEAN + v_positionEC = (czm_modelView3D * vec4(position3DWC, 1.0)).xyz; v_positionMC = position3DWC; // position in model coordinates -#endif v_textureCoordinates = textureCoordinates; } From 69e00ebdbe2f67d3e7bd52bd07a2e51d06d8bc86 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Fri, 18 Oct 2013 16:21:06 -0400 Subject: [PATCH 2/9] Add option to enable/disable globe lighting. --- Source/Scene/CentralBody.js | 19 +++++++++++++++++-- Source/Shaders/CentralBodyFS.glsl | 10 ++++++++-- Source/Shaders/CentralBodyVS.glsl | 2 ++ 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/Source/Scene/CentralBody.js b/Source/Scene/CentralBody.js index f8c658a41b66..5a6be6eb2bf2 100644 --- a/Source/Scene/CentralBody.js +++ b/Source/Scene/CentralBody.js @@ -213,6 +213,15 @@ define([ */ this.tileCacheSize = 100; + /** + * Enable lighting the globe with the sun as a light source. + * + * @type {Boolean} + * @default false + */ + this.enableLighting = false; + this._enableLighting = false; + this._lastOceanNormalMapUrl = undefined; this._oceanNormalMap = undefined; this._zoomedOutOceanSpecularIntensity = 0.5; @@ -619,6 +628,7 @@ define([ var projectionChanged = this._projection !== projection; var hasWaterMask = this._surface._terrainProvider.hasWaterMask(); var hasWaterMaskChanged = this._hasWaterMask !== hasWaterMask; + var hasEnableLightingChanged = this._enableLighting !== this.enableLighting; if (!defined(this._surfaceShaderSet) || !defined(this._northPoleCommand.shaderProgram) || @@ -626,6 +636,7 @@ define([ modeChanged || projectionChanged || hasWaterMaskChanged || + hasEnableLightingChanged || (defined(this._oceanNormalMap)) !== this._showingPrettyOcean) { var getPosition3DMode = 'vec4 getPosition(vec3 position3DWC) { return getPosition3DMode(position3DWC); }'; @@ -662,7 +673,10 @@ define([ } this._surfaceShaderSet.baseVertexShaderString = createShaderSource({ - defines : [hasWaterMask ? 'SHOW_REFLECTIVE_OCEAN' : ''], + defines : [ + (hasWaterMask ? 'SHOW_REFLECTIVE_OCEAN' : ''), + (this.enableLighting ? 'ENABLE_LIGHTING' : '') + ], sources : [CentralBodyVS, getPositionMode, get2DYPositionFraction] }); @@ -671,7 +685,8 @@ define([ this._surfaceShaderSet.baseFragmentShaderString = createShaderSource({ defines : [ (hasWaterMask ? 'SHOW_REFLECTIVE_OCEAN' : ''), - (showPrettyOcean ? 'SHOW_OCEAN_WAVES' : '') + (showPrettyOcean ? 'SHOW_OCEAN_WAVES' : ''), + (this.enableLighting ? 'ENABLE_LIGHTING' : '') ], sources : [CentralBodyFS] }); diff --git a/Source/Shaders/CentralBodyFS.glsl b/Source/Shaders/CentralBodyFS.glsl index f5db7ff0bd17..f9c7bcad423e 100644 --- a/Source/Shaders/CentralBodyFS.glsl +++ b/Source/Shaders/CentralBodyFS.glsl @@ -123,8 +123,10 @@ void main() vec4 color = vec4(startDayColor, 1.0); +#if defined(SHOW_REFLECTIVE_OCEAN) || defined(ENABLE_LIGHTING) vec3 normalMC = normalize(czm_geodeticSurfaceNormal(v_positionMC, vec3(0.0), vec3(1.0))); // normalized surface normal in model coordinates vec3 normalEC = normalize(czm_normal3D * normalMC); // normalized surface normal in eye coordiantes +#endif #ifdef SHOW_REFLECTIVE_OCEAN vec2 waterMaskTranslation = u_waterMaskTranslationAndScale.xy; @@ -145,9 +147,13 @@ void main() color = computeWaterColor(v_positionEC, textureCoordinates, enuToEye, startDayColor, mask); } #endif - + +#ifdef ENABLE_LIGHTING float diffuseIntensity = clamp(czm_getLambertDiffuse(czm_sunDirectionEC, normalEC) + 0.2, 0.0, 1.0); - gl_FragColor = vec4(color.rgb * diffuseIntensity, 1.0); + gl_FragColor = vec4(color.rgb * diffuseIntensity, color.a); +#else + gl_FragColor = color; +#endif } #ifdef SHOW_REFLECTIVE_OCEAN diff --git a/Source/Shaders/CentralBodyVS.glsl b/Source/Shaders/CentralBodyVS.glsl index 530556da999e..abf503ec9b98 100644 --- a/Source/Shaders/CentralBodyVS.glsl +++ b/Source/Shaders/CentralBodyVS.glsl @@ -85,8 +85,10 @@ void main() gl_Position = getPosition(position3DWC); +#if defined(SHOW_REFLECTIVE_OCEAN) || defined(ENABLE_LIGHTING) v_positionEC = (czm_modelView3D * vec4(position3DWC, 1.0)).xyz; v_positionMC = position3DWC; // position in model coordinates +#endif v_textureCoordinates = textureCoordinates; } From e23ecdeb7b716080de63de65d25d0c633dbcf40d Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Fri, 18 Oct 2013 17:27:57 -0400 Subject: [PATCH 3/9] Make sharper transition from day to night. --- Source/Shaders/CentralBodyFS.glsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Shaders/CentralBodyFS.glsl b/Source/Shaders/CentralBodyFS.glsl index f9c7bcad423e..77584ad5dd7f 100644 --- a/Source/Shaders/CentralBodyFS.glsl +++ b/Source/Shaders/CentralBodyFS.glsl @@ -149,7 +149,7 @@ void main() #endif #ifdef ENABLE_LIGHTING - float diffuseIntensity = clamp(czm_getLambertDiffuse(czm_sunDirectionEC, normalEC) + 0.2, 0.0, 1.0); + float diffuseIntensity = clamp(czm_getLambertDiffuse(czm_sunDirectionEC, normalEC) * 5.0 + 0.3, 0.0, 1.0); gl_FragColor = vec4(color.rgb * diffuseIntensity, color.a); #else gl_FragColor = color; From 19176c08cc47f76715a92ad429f1d05e3cc4d39a Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Fri, 18 Oct 2013 17:50:22 -0400 Subject: [PATCH 4/9] Fade out lighting effect on zoom in. --- Source/Shaders/CentralBodyFS.glsl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Source/Shaders/CentralBodyFS.glsl b/Source/Shaders/CentralBodyFS.glsl index 77584ad5dd7f..8b0fe3f7bda2 100644 --- a/Source/Shaders/CentralBodyFS.glsl +++ b/Source/Shaders/CentralBodyFS.glsl @@ -150,6 +150,8 @@ void main() #ifdef ENABLE_LIGHTING float diffuseIntensity = clamp(czm_getLambertDiffuse(czm_sunDirectionEC, normalEC) * 5.0 + 0.3, 0.0, 1.0); + float cameraDist = length(czm_view[3]); + diffuseIntensity = mix(1.0, diffuseIntensity, clamp((cameraDist - 7500000.0) / (9000000.0 - 7500000.0), 0.0, 1.0)); gl_FragColor = vec4(color.rgb * diffuseIntensity, color.a); #else gl_FragColor = color; From 39ea89f10b294fd5939835aef637f0867c441fe3 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Fri, 18 Oct 2013 18:01:04 -0400 Subject: [PATCH 5/9] Make lighting fade in and out distances configurable. --- Source/Scene/CentralBody.js | 24 ++++++++++++++++++++++++ Source/Shaders/CentralBodyFS.glsl | 8 +++++++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/Source/Scene/CentralBody.js b/Source/Scene/CentralBody.js index 5a6be6eb2bf2..52b0db275007 100644 --- a/Source/Scene/CentralBody.js +++ b/Source/Scene/CentralBody.js @@ -222,6 +222,24 @@ define([ this.enableLighting = false; this._enableLighting = false; + /** + * The distance where everything becomes lit. This only takes effect + * when enableLighting is true. + * + * @type {Number} + * @default 7500000.0 + */ + this.lightingFadeOutDistance = 7500000.0; + + /** + * The distance where lighting resumes. This only takes effect + * when enableLighting is true. + * + * @type {Number} + * @default 9000000.0 + */ + this.lightingFadeInDistance = 9000000.0; + this._lastOceanNormalMapUrl = undefined; this._oceanNormalMap = undefined; this._zoomedOutOceanSpecularIntensity = 0.5; @@ -236,6 +254,12 @@ define([ }, u_oceanNormalMap : function() { return that._oceanNormalMap; + }, + u_lightingFadeOutDistance : function() { + return that.lightingFadeOutDistance; + }, + u_lightingFadeInDistance : function() { + return that.lightingFadeInDistance; } }; }; diff --git a/Source/Shaders/CentralBodyFS.glsl b/Source/Shaders/CentralBodyFS.glsl index 8b0fe3f7bda2..d731c7958e9c 100644 --- a/Source/Shaders/CentralBodyFS.glsl +++ b/Source/Shaders/CentralBodyFS.glsl @@ -41,6 +41,11 @@ uniform float u_zoomedOutOceanSpecularIntensity; uniform sampler2D u_oceanNormalMap; #endif +#ifdef ENABLE_LIGHTING +uniform float u_lightingFadeOutDistance; +uniform float u_lightingFadeInDistance; +#endif + varying vec3 v_positionMC; varying vec3 v_positionEC; varying vec2 v_textureCoordinates; @@ -151,7 +156,8 @@ void main() #ifdef ENABLE_LIGHTING float diffuseIntensity = clamp(czm_getLambertDiffuse(czm_sunDirectionEC, normalEC) * 5.0 + 0.3, 0.0, 1.0); float cameraDist = length(czm_view[3]); - diffuseIntensity = mix(1.0, diffuseIntensity, clamp((cameraDist - 7500000.0) / (9000000.0 - 7500000.0), 0.0, 1.0)); + float t = clamp((cameraDist - u_lightingFadeOutDistance) / (u_lightingFadeInDistance - u_lightingFadeOutDistance), 0.0, 1.0); + diffuseIntensity = mix(1.0, diffuseIntensity, t); gl_FragColor = vec4(color.rgb * diffuseIntensity, color.a); #else gl_FragColor = color; From ca6aa05845c4d9e989ecc779c99b1b7387398c57 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Fri, 18 Oct 2013 18:02:42 -0400 Subject: [PATCH 6/9] Update CHANGES.md. --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index c8337f6c0fe5..980548935e24 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -55,6 +55,7 @@ Beta Releases * Added prototype equals function to `NearFarScalar`, and `TimeIntervalCollection`. * Added `Matrix4.fromTranslationQuaternionRotationScale` and `Matrix4.multiplyByScale`. * Added `FrameState.events`. +* Added `enableLighting`, `lightingFadeOutDistance`, and `lightingFadeInDistance` properties to `CentralBody` to configure lighting. ### b21 - 2013-10-01 From 50d6b2628e6e35270f1c2155631268db29e88050 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Mon, 21 Oct 2013 14:31:38 -0400 Subject: [PATCH 7/9] Make the fading distances a vec2 uniform. --- Source/Scene/CentralBody.js | 11 ++++++----- Source/Shaders/CentralBodyFS.glsl | 7 ++++--- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/Source/Scene/CentralBody.js b/Source/Scene/CentralBody.js index 52b0db275007..366615d70c6b 100644 --- a/Source/Scene/CentralBody.js +++ b/Source/Scene/CentralBody.js @@ -245,6 +245,7 @@ define([ this._zoomedOutOceanSpecularIntensity = 0.5; this._showingPrettyOcean = false; this._hasWaterMask = false; + this._lightingFadeDistance = new Cartesian2(this.lightingFadeOutDistance, this.lightingFadeInDistance); var that = this; @@ -255,11 +256,8 @@ define([ u_oceanNormalMap : function() { return that._oceanNormalMap; }, - u_lightingFadeOutDistance : function() { - return that.lightingFadeOutDistance; - }, - u_lightingFadeInDistance : function() { - return that.lightingFadeInDistance; + u_lightingFadeDistance : function() { + return that._lightingFadeDistance; } }; }; @@ -760,6 +758,9 @@ define([ this._zoomedOutOceanSpecularIntensity = 0.0; } + this._lightingFadeDistance.x = this.lightingFadeOutDistance; + this._lightingFadeDistance.y = this.lightingFadeInDistance; + this._surface._tileCacheSize = this.tileCacheSize; this._surface.setTerrainProvider(this.terrainProvider); this._surface.update(context, diff --git a/Source/Shaders/CentralBodyFS.glsl b/Source/Shaders/CentralBodyFS.glsl index d731c7958e9c..fbe78a7a2596 100644 --- a/Source/Shaders/CentralBodyFS.glsl +++ b/Source/Shaders/CentralBodyFS.glsl @@ -42,8 +42,7 @@ uniform sampler2D u_oceanNormalMap; #endif #ifdef ENABLE_LIGHTING -uniform float u_lightingFadeOutDistance; -uniform float u_lightingFadeInDistance; +uniform vec2 u_lightingFadeDistance; #endif varying vec3 v_positionMC; @@ -156,7 +155,9 @@ void main() #ifdef ENABLE_LIGHTING float diffuseIntensity = clamp(czm_getLambertDiffuse(czm_sunDirectionEC, normalEC) * 5.0 + 0.3, 0.0, 1.0); float cameraDist = length(czm_view[3]); - float t = clamp((cameraDist - u_lightingFadeOutDistance) / (u_lightingFadeInDistance - u_lightingFadeOutDistance), 0.0, 1.0); + float fadeOutDist = u_lightingFadeDistance.x; + float fadeInDist = u_lightingFadeDistance.y; + float t = clamp((cameraDist - fadeOutDist) / (fadeInDist - fadeOutDist), 0.0, 1.0); diffuseIntensity = mix(1.0, diffuseIntensity, t); gl_FragColor = vec4(color.rgb * diffuseIntensity, color.a); #else From dcae4d650dbf2ada1097f107173dd2076a8d5b0c Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Mon, 21 Oct 2013 14:46:39 -0400 Subject: [PATCH 8/9] Made lighting fade slightly slower. --- Source/Scene/CentralBody.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Scene/CentralBody.js b/Source/Scene/CentralBody.js index 366615d70c6b..9d63a2f2b016 100644 --- a/Source/Scene/CentralBody.js +++ b/Source/Scene/CentralBody.js @@ -227,9 +227,9 @@ define([ * when enableLighting is true. * * @type {Number} - * @default 7500000.0 + * @default 6500000.0 */ - this.lightingFadeOutDistance = 7500000.0; + this.lightingFadeOutDistance = 6500000.0; /** * The distance where lighting resumes. This only takes effect From 26ed1aa781a4054ff901e26593d28a800e7c3a5e Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Mon, 21 Oct 2013 15:51:42 -0400 Subject: [PATCH 9/9] Add CentralBody enableLighting test. --- Specs/Scene/CentralBodySpec.js | 81 ++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 Specs/Scene/CentralBodySpec.js diff --git a/Specs/Scene/CentralBodySpec.js b/Specs/Scene/CentralBodySpec.js new file mode 100644 index 000000000000..9f3d6aa87201 --- /dev/null +++ b/Specs/Scene/CentralBodySpec.js @@ -0,0 +1,81 @@ +/*global defineSuite*/ +defineSuite([ + 'Scene/CentralBody', + 'Core/defined', + 'Core/Ellipsoid', + 'Core/Extent', + 'Renderer/ClearCommand', + 'Scene/SingleTileImageryProvider', + 'Specs/createContext', + 'Specs/createFrameState', + 'Specs/destroyContext', + 'Specs/render' + ], function( + CentralBody, + defined, + Ellipsoid, + Extent, + ClearCommand, + SingleTileImageryProvider, + createContext, + createFrameState, + destroyContext, + render) { + "use strict"; + /*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn,runs,waits,waitsFor*/ + + var context; + var frameState; + var cb; + + beforeAll(function() { + context = createContext(); + }); + + afterAll(function() { + destroyContext(context); + }); + + beforeEach(function() { + frameState = createFrameState(); + cb = new CentralBody(); + }); + + afterEach(function() { + cb.destroy(); + }); + + /** + * Repeatedly calls update until the load queue is empty. You must wrap any code to follow + * this in a "runs" function. + */ + function updateUntilDone(cb) { + // update until the load queue is empty. + waitsFor(function() { + cb._surface._debug.enableDebugOutput = true; + var commandLists = []; + cb.update(context, frameState, commandLists); + return !defined(cb._surface._tileLoadQueue.head) && cb._surface._debug.tilesWaitingForChildren === 0; + }, 'updating to complete'); + } + + it('renders with enableLighting', function() { + cb.enableLighting = true; + + var layerCollection = cb.getImageryLayers(); + layerCollection.removeAll(); + layerCollection.addImageryProvider(new SingleTileImageryProvider({url : 'Data/Images/Red16x16.png'})); + + frameState.camera.controller.viewExtent(new Extent(0.0001, 0.0001, 0.0025, 0.0025), Ellipsoid.WGS84); + + updateUntilDone(cb); + + runs(function() { + ClearCommand.ALL.execute(context); + expect(context.readPixels()).toEqual([0, 0, 0, 0]); + + render(context, frameState, cb); + expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); + }); + }); +}, 'WebGL'); \ No newline at end of file