From a5ef38bdbfb2572bcc38d21f8d1a433242543ac2 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Fri, 18 May 2018 20:00:44 -0400 Subject: [PATCH 01/76] HDR WIP. Add Reinhard tonemapping. [ci skip] --- Source/Scene/GlobeDepth.js | 17 ++++++---- Source/Scene/PostProcessStageCollection.js | 33 ++++++++++++++++--- Source/Scene/PostProcessStageLibrary.js | 12 +++++++ Source/Scene/PostProcessStageTextureCache.js | 5 ++- Source/Scene/Scene.js | 9 +++-- Source/Scene/SceneFramebuffer.js | 8 +++-- .../ReinhardTonemapping.glsl | 11 +++++++ 7 files changed, 77 insertions(+), 18 deletions(-) create mode 100644 Source/Shaders/PostProcessStages/ReinhardTonemapping.glsl diff --git a/Source/Scene/GlobeDepth.js b/Source/Scene/GlobeDepth.js index ce4d238c25bb..72deeae03086 100644 --- a/Source/Scene/GlobeDepth.js +++ b/Source/Scene/GlobeDepth.js @@ -60,6 +60,7 @@ define([ this._scissorRectangle = undefined; this._useLogDepth = undefined; + this._useHDR = undefined; this._debugGlobeDepthViewportCommand = undefined; } @@ -110,13 +111,13 @@ define([ globeDepth._copyDepthFramebuffer = globeDepth._copyDepthFramebuffer && !globeDepth._copyDepthFramebuffer.isDestroyed() && globeDepth._copyDepthFramebuffer.destroy(); } - function createTextures(globeDepth, context, width, height) { + function createTextures(globeDepth, context, width, height, hdr) { globeDepth._colorTexture = new Texture({ context : context, width : width, height : height, pixelFormat : PixelFormat.RGBA, - pixelDatatype : PixelDatatype.UNSIGNED_BYTE, + pixelDatatype : hdr ? PixelDatatype.HALF_FLOAT : PixelDatatype.UNSIGNED_BYTE, sampler : new Sampler({ wrapS : TextureWrap.CLAMP_TO_EDGE, wrapT : TextureWrap.CLAMP_TO_EDGE, @@ -157,13 +158,13 @@ define([ }); } - function updateFramebuffers(globeDepth, context, width, height) { + function updateFramebuffers(globeDepth, context, width, height, hdr) { var colorTexture = globeDepth._colorTexture; - var textureChanged = !defined(colorTexture) || colorTexture.width !== width || colorTexture.height !== height; + var textureChanged = !defined(colorTexture) || colorTexture.width !== width || colorTexture.height !== height || hdr !== globeDepth._useHDR; if (!defined(globeDepth.framebuffer) || textureChanged) { destroyTextures(globeDepth); destroyFramebuffers(globeDepth); - createTextures(globeDepth, context, width, height); + createTextures(globeDepth, context, width, height, hdr); createFramebuffers(globeDepth, context); } } @@ -233,13 +234,15 @@ define([ executeDebugGlobeDepth(this, context, passState, useLogDepth); }; - GlobeDepth.prototype.update = function(context, passState) { + GlobeDepth.prototype.update = function(context, passState, hdr) { var width = context.drawingBufferWidth; var height = context.drawingBufferHeight; - updateFramebuffers(this, context, width, height); + updateFramebuffers(this, context, width, height, hdr); updateCopyCommands(this, context, width, height, passState); context.uniformState.globeDepthTexture = undefined; + + this._useHDR = hdr; }; GlobeDepth.prototype.executeCopyDepth = function(context, passState) { diff --git a/Source/Scene/PostProcessStageCollection.js b/Source/Scene/PostProcessStageCollection.js index b23acfb816ae..6d994ce07590 100644 --- a/Source/Scene/PostProcessStageCollection.js +++ b/Source/Scene/PostProcessStageCollection.js @@ -56,15 +56,17 @@ define([ var fxaa = PostProcessStageLibrary.createFXAAStage(); var ao = PostProcessStageLibrary.createAmbientOcclusionStage(); var bloom = PostProcessStageLibrary.createBloomStage(); + var tonemapping = PostProcessStageLibrary.createReinhardTonemappingStage(); ao.enabled = false; bloom.enabled = false; + tonemapping.enabled = false; var textureCache = new PostProcessStageTextureCache(this); var stageNames = {}; var stack = stackScratch; - stack.push(fxaa, ao, bloom); + stack.push(fxaa, ao, bloom, tonemapping); while (stack.length > 0) { var stage = stack.pop(); stageNames[stage.name] = stage; @@ -90,11 +92,13 @@ define([ this._ao = ao; this._bloom = bloom; + this._tonemapping = tonemapping; this._fxaa = fxaa; this._lastLength = undefined; this._aoEnabled = undefined; this._bloomEnabled = undefined; + this._tonemappingEnabled = undefined; this._fxaaEnabled = undefined; this._stagesRemoved = false; @@ -125,10 +129,12 @@ define([ var fxaa = this._fxaa; var ao = this._ao; var bloom = this._bloom; + var tonemapping = this._tonemapping; readyAndEnabled = readyAndEnabled || (fxaa.ready && fxaa.enabled); readyAndEnabled = readyAndEnabled || (ao.ready && ao.enabled); readyAndEnabled = readyAndEnabled || (bloom.ready && bloom.enabled); + readyAndEnabled = readyAndEnabled || (tonemapping.ready && tonemapping.enabled); return readyAndEnabled; } @@ -265,6 +271,11 @@ define([ } } + var tonemapping = this._tonemapping; + if (tonemapping.enabled && tonemapping.ready) { + return this.getOutputTexture(tonemapping.name); + } + var bloom = this._bloom; if (bloom.enabled && bloom.ready) { return this.getOutputTexture(bloom.name); @@ -438,7 +449,7 @@ define([ * * @private */ - PostProcessStageCollection.prototype.update = function(context, useLogDepth) { + PostProcessStageCollection.prototype.update = function(context, useLogDepth, useHDR) { removeStages(this); var activeStages = this._activeStages; @@ -458,13 +469,18 @@ define([ var ao = this._ao; var bloom = this._bloom; + var tonemapping = this._tonemapping; var fxaa = this._fxaa; + tonemapping.enabled = useHDR; + var aoEnabled = ao.enabled && ao._isSupported(context); var bloomEnabled = bloom.enabled && bloom._isSupported(context); + var tonemappingEnabled = tonemapping.enabled && tonemapping._isSupported(context); var fxaaEnabled = fxaa.enabled && fxaa._isSupported(context); - if (this._textureCacheDirty || count !== this._lastLength || aoEnabled !== this._aoEnabled || bloomEnabled !== this._bloomEnabled || fxaaEnabled !== this._fxaaEnabled) { + if (this._textureCacheDirty || count !== this._lastLength || aoEnabled !== this._aoEnabled || + bloomEnabled !== this._bloomEnabled || tonemappingEnabled !== this._tonemappingEnabled || fxaaEnabled !== this._fxaaEnabled) { // The number of stages to execute has changed. // Update dependencies and recreate framebuffers. this._textureCache.updateDependencies(); @@ -472,6 +488,7 @@ define([ this._lastLength = count; this._aoEnabled = aoEnabled; this._bloomEnabled = bloomEnabled; + this._tonemappingEnabled = tonemappingEnabled; this._fxaaEnabled = fxaaEnabled; this._textureCacheDirty = false; } @@ -511,6 +528,7 @@ define([ fxaa.update(context, useLogDepth); ao.update(context, useLogDepth); bloom.update(context, useLogDepth); + tonemapping.update(context, useLogDepth); length = stages.length; for (i = 0; i < length; ++i) { @@ -589,12 +607,14 @@ define([ var fxaa = this._fxaa; var ao = this._ao; var bloom = this._bloom; + var tonemapping = this._tonemapping; var aoEnabled = ao.enabled && ao._isSupported(context); var bloomEnabled = bloom.enabled && bloom._isSupported(context); + var tonemappingEnabled = tonemapping.enabled && tonemapping._isSupported(context); var fxaaEnabled = fxaa.enabled && fxaa._isSupported(context); - if (!fxaaEnabled && !aoEnabled && !bloomEnabled && length === 0) { + if (!fxaaEnabled && !aoEnabled && !bloomEnabled && !tonemappingEnabled && length === 0) { return; } @@ -607,6 +627,10 @@ define([ execute(bloom, context, initialTexture, depthTexture); initialTexture = getOutputTexture(bloom); } + if (tonemappingEnabled && tonemapping.ready) { + execute(tonemapping, context, initialTexture, depthTexture); + initialTexture = getOutputTexture(tonemapping); + } var lastTexture = initialTexture; @@ -680,6 +704,7 @@ define([ this._fxaa.destroy(); this._ao.destroy(); this._bloom.destroy(); + this._tonemapping.destroy(); this.removeAll(); this._textureCache = this._textureCache && this._textureCache.destroy(); return destroyObject(this); diff --git a/Source/Scene/PostProcessStageLibrary.js b/Source/Scene/PostProcessStageLibrary.js index 66b8aa877bf9..e7735b42d2fb 100644 --- a/Source/Scene/PostProcessStageLibrary.js +++ b/Source/Scene/PostProcessStageLibrary.js @@ -18,6 +18,7 @@ define([ '../Shaders/PostProcessStages/LensFlare', '../Shaders/PostProcessStages/LinearDepth', '../Shaders/PostProcessStages/NightVision', + '../shaders/PostProcessStages/ReinhardTonemapping', '../Shaders/PostProcessStages/Silhouette', '../ThirdParty/Shaders/FXAA3_11', './PostProcessStage', @@ -43,6 +44,7 @@ define([ LensFlare, LinearDepth, NightVision, + ReinhardTonemapping, Silhouette, FXAA3_11, PostProcessStage, @@ -559,6 +561,16 @@ define([ }); }; + PostProcessStageLibrary.createReinhardTonemappingStage = function() { + return new PostProcessStage({ + name : 'czm_reinhard', + fragmentShader : ReinhardTonemapping, + uniforms : { + exposure : 1.0 + } + }); + }; + /** * Creates a post-process stage that renders the input texture with black and white gradations. *

diff --git a/Source/Scene/PostProcessStageTextureCache.js b/Source/Scene/PostProcessStageTextureCache.js index 4dfd70997373..ecdb8b2d3174 100644 --- a/Source/Scene/PostProcessStageTextureCache.js +++ b/Source/Scene/PostProcessStageTextureCache.js @@ -113,10 +113,12 @@ define([ if (defined(collection.ambientOcclusion)) { var ao = collection.ambientOcclusion; var bloom = collection.bloom; + var tonemapping = collection._tonemapping; var fxaa = collection.fxaa; var previousName = getCompositeDependencies(collection, context, dependencies, ao, undefined); previousName = getCompositeDependencies(collection, context, dependencies, bloom, previousName); + previousName = getStageDependencies(collection, context, dependencies, tonemapping, previousName); previousName = getCompositeDependencies(collection, context, dependencies, collection, previousName); getStageDependencies(collection, context, dependencies, fxaa, previousName); } else { @@ -256,8 +258,9 @@ define([ var updateDependencies = this._updateDependencies; var aoEnabled = defined(collection.ambientOcclusion) && collection.ambientOcclusion.enabled && collection.ambientOcclusion._isSupported(context); var bloomEnabled = defined(collection.bloom) && collection.bloom.enabled && collection.bloom._isSupported(context); + var tonemappingEnabled = defined(collection._tonemapping) && collection._tonemapping.enabled && collection._tonemapping._isSupported(context); var fxaaEnabled = defined(collection.fxaa) && collection.fxaa.enabled && collection.fxaa._isSupported(context); - var needsCheckDimensionsUpdate = !defined(collection._activeStages) || collection._activeStages.length > 0 || aoEnabled || bloomEnabled || fxaaEnabled; + var needsCheckDimensionsUpdate = !defined(collection._activeStages) || collection._activeStages.length > 0 || aoEnabled || bloomEnabled || tonemappingEnabled || fxaaEnabled; if (updateDependencies || (!needsCheckDimensionsUpdate && this._framebuffers.length > 0)) { releaseResources(this); this._framebuffers.length = 0; diff --git a/Source/Scene/Scene.js b/Source/Scene/Scene.js index bef9dbfccadd..0d38790949d4 100644 --- a/Source/Scene/Scene.js +++ b/Source/Scene/Scene.js @@ -325,6 +325,8 @@ define([ this._oit = oit; this._sceneFramebuffer = new SceneFramebuffer(); + this._hdr = context.depthTexture && (context.colorBufferFloat || context.colorBufferHalfFloat); + this._clearColorCommand = new ClearCommand({ color : new Color(), stencil : 0, @@ -430,7 +432,8 @@ define([ * @type {Boolean} * @default true */ - this.sunBloom = true; + this.sunBloom = !this._hdr; + //this.sunBloom = true; this._sunBloom = undefined; /** @@ -2933,7 +2936,7 @@ define([ } var postProcess = scene.postProcessStages; - var usePostProcess = environmentState.usePostProcess = !picking && (postProcess.length > 0 || postProcess.ambientOcclusion.enabled || postProcess.fxaa.enabled || postProcess.bloom.enabled); + var usePostProcess = environmentState.usePostProcess = !picking && (scene._hdr || postProcess.length > 0 || postProcess.ambientOcclusion.enabled || postProcess.fxaa.enabled || postProcess.bloom.enabled); if (usePostProcess) { scene._sceneFramebuffer.update(context, passState); scene._sceneFramebuffer.clear(context, passState, clearColor); @@ -2941,7 +2944,7 @@ define([ var camera = scene.camera; var useLogDepth = scene._logDepthBuffer && !(camera.frustum instanceof OrthographicFrustum || camera.frustum instanceof OrthographicOffCenterFrustum); - postProcess.update(context, useLogDepth); + postProcess.update(context, useLogDepth, scene._hdr); postProcess.clear(context); usePostProcess = environmentState.usePostProcess = postProcess.ready; diff --git a/Source/Scene/SceneFramebuffer.js b/Source/Scene/SceneFramebuffer.js index e3f7784e6d5d..018dc7233126 100644 --- a/Source/Scene/SceneFramebuffer.js +++ b/Source/Scene/SceneFramebuffer.js @@ -41,6 +41,8 @@ define([ this._depthStencilRenderbuffer = undefined; this._framebuffer = undefined; + this._useHDR = undefined; + this._clearCommand = new ClearCommand({ color : new Color(0.0, 0.0, 0.0, 0.0), depth : 1.0, @@ -60,12 +62,12 @@ define([ post._depthStencilRenderbuffer = undefined; } - SceneFramebuffer.prototype.update = function(context) { + SceneFramebuffer.prototype.update = function(context, hdr) { var width = context.drawingBufferWidth; var height = context.drawingBufferHeight; var colorTexture = this._colorTexture; - var textureChanged = !defined(colorTexture) || colorTexture.width !== width || colorTexture.height !== height; + var textureChanged = !defined(colorTexture) || colorTexture.width !== width || colorTexture.height !== height || hdr !== this._useHDR; if (textureChanged) { this._colorTexture = this._colorTexture && this._colorTexture.destroy(); this._depthStencilTexture = this._depthStencilTexture && this._depthStencilTexture.destroy(); @@ -76,7 +78,7 @@ define([ width : width, height : height, pixelFormat : PixelFormat.RGBA, - pixelDatatype : PixelDatatype.UNSIGNED_BYTE, + pixelDatatype : hdr ? PixelDatatype.HALF_FLOAT : PixelDatatype.UNSIGNED_BYTE, sampler : new Sampler({ wrapS : TextureWrap.CLAMP_TO_EDGE, wrapT : TextureWrap.CLAMP_TO_EDGE, diff --git a/Source/Shaders/PostProcessStages/ReinhardTonemapping.glsl b/Source/Shaders/PostProcessStages/ReinhardTonemapping.glsl new file mode 100644 index 000000000000..5573ed6ae955 --- /dev/null +++ b/Source/Shaders/PostProcessStages/ReinhardTonemapping.glsl @@ -0,0 +1,11 @@ +uniform sampler2D colorTexture; +uniform float exposure; + +varying vec2 v_textureCoordinates; + +void main() +{ + vec3 color = texture2D(colorTexture, v_textureCoordinates).rgb; + vec3 toneMapped = vec3(1.0) - exp(-color * exposure); + gl_FragColor = vec4(toneMapped, 1.0); +} From f0ddfd84df535804bfcf27118386898b2acfd1b1 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Mon, 21 May 2018 15:23:08 -0400 Subject: [PATCH 02/76] Output sun texture to floating point texture. --- Source/Scene/Globe.js | 3 ++- Source/Scene/Scene.js | 2 +- Source/Scene/Sun.js | 7 +++++-- Source/Shaders/Builtin/Functions/phong.glsl | 6 +++--- Source/Shaders/SunTextureFS.glsl | 12 +++++++++++- 5 files changed, 22 insertions(+), 8 deletions(-) diff --git a/Source/Scene/Globe.js b/Source/Scene/Globe.js index 29b77bbac8f5..0b7481c3c844 100644 --- a/Source/Scene/Globe.js +++ b/Source/Scene/Globe.js @@ -133,7 +133,8 @@ define([ * @type {Boolean} * @default false */ - this.enableLighting = false; + this.enableLighting = true; + //this.enableLighting = false; /** * The distance where everything becomes lit. This only takes effect diff --git a/Source/Scene/Scene.js b/Source/Scene/Scene.js index 0d38790949d4..48c4d5ad3496 100644 --- a/Source/Scene/Scene.js +++ b/Source/Scene/Scene.js @@ -2779,7 +2779,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(frameState, passState) : undefined; + var sunCommands = defined(scene.sun) ? scene.sun.update(frameState, passState, scene._hdr) : 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; diff --git a/Source/Scene/Sun.js b/Source/Scene/Sun.js index 383001aa558f..32df9b30870a 100644 --- a/Source/Scene/Sun.js +++ b/Source/Scene/Sun.js @@ -16,6 +16,7 @@ define([ '../Renderer/BufferUsage', '../Renderer/ComputeCommand', '../Renderer/DrawCommand', + '../Renderer/PixelDatatype', '../Renderer/RenderState', '../Renderer/ShaderProgram', '../Renderer/Texture', @@ -44,6 +45,7 @@ define([ BufferUsage, ComputeCommand, DrawCommand, + PixelDatatype, RenderState, ShaderProgram, Texture, @@ -138,7 +140,7 @@ define([ /** * @private */ - Sun.prototype.update = function(frameState, passState) { + Sun.prototype.update = function(frameState, passState, useHDR) { if (!this.show) { return undefined; } @@ -177,7 +179,8 @@ define([ context : context, width : size, height : size, - pixelFormat : PixelFormat.RGBA + pixelFormat : PixelFormat.RGBA, + pixelDatatype : useHDR ? PixelDatatype.HALF_FLOAT : PixelFormat.UNSIGNED_BYTE }); this._glowLengthTS = this._glowFactor * 5.0; diff --git a/Source/Shaders/Builtin/Functions/phong.glsl b/Source/Shaders/Builtin/Functions/phong.glsl index 9dc2dbc1a8e6..f3f68cd10948 100644 --- a/Source/Shaders/Builtin/Functions/phong.glsl +++ b/Source/Shaders/Builtin/Functions/phong.glsl @@ -16,9 +16,9 @@ float czm_private_getSpecularOfMaterial(vec3 lightDirectionEC, vec3 toEyeEC, czm * * @param {vec3} toEye A normalized vector from the fragment to the eye in eye coordinates. * @param {czm_material} material The fragment's material. - * + * * @returns {vec4} The computed color. - * + * * @example * vec3 positionToEyeEC = // ... * czm_material material = // ... @@ -40,7 +40,7 @@ vec4 czm_phong(vec3 toEye, czm_material material) // Temporary workaround for adding ambient. vec3 materialDiffuse = material.diffuse * 0.5; - + vec3 ambient = materialDiffuse; vec3 color = ambient + material.emission; color += materialDiffuse * diffuse; diff --git a/Source/Shaders/SunTextureFS.glsl b/Source/Shaders/SunTextureFS.glsl index 05a674e7d4a6..e950ec427e55 100644 --- a/Source/Shaders/SunTextureFS.glsl +++ b/Source/Shaders/SunTextureFS.glsl @@ -17,6 +17,9 @@ vec4 addBurst(vec2 position, vec2 direction) return vec4(burst); } +// TODO +#define HDR + void main() { vec2 position = v_textureCoordinates - vec2(0.5); @@ -25,7 +28,11 @@ void main() vec4 color = vec4(1.0, 1.0, surface + 0.2, surface); float glow = 1.0 - smoothstep(0.0, 0.55, radius); +#ifdef HDR + color.ba += glow; +#else color.ba += mix(vec2(0.0), vec2(1.0), glow) * 0.75; +#endif vec4 burst = vec4(0.0); @@ -50,7 +57,10 @@ void main() // End of manual loop unrolling. +#ifdef HDR + gl_FragColor = color + burst; +#else color += clamp(burst, vec4(0.0), vec4(1.0)) * 0.15; - gl_FragColor = clamp(color, vec4(0.0), vec4(1.0)); +#endif } From 6882ea6a61a66b7c1a2e783f3dafb220c331b4e0 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Mon, 21 May 2018 16:56:32 -0400 Subject: [PATCH 03/76] Actually render to float texture. [ci skip] --- Source/Scene/Globe.js | 2 +- Source/Scene/GlobeDepth.js | 3 ++- Source/Scene/PostProcessStageCollection.js | 3 +++ Source/Scene/Scene.js | 5 ++--- Source/Scene/SceneFramebuffer.js | 3 ++- Source/Scene/Sun.js | 3 ++- .../Materials/PolylineGlowMaterial.glsl | 5 ++++- .../ReinhardTonemapping.glsl | 4 ++++ Source/Shaders/SkyAtmosphereFS.glsl | 21 ++++++++++++------- Source/Shaders/SunTextureFS.glsl | 2 +- .../processPbrMetallicRoughness.js | 12 +++++++---- 11 files changed, 42 insertions(+), 21 deletions(-) diff --git a/Source/Scene/Globe.js b/Source/Scene/Globe.js index 0b7481c3c844..bcfd7f88bf03 100644 --- a/Source/Scene/Globe.js +++ b/Source/Scene/Globe.js @@ -133,7 +133,7 @@ define([ * @type {Boolean} * @default false */ - this.enableLighting = true; + this.enableLighting = true; // TODO HDR //this.enableLighting = false; /** diff --git a/Source/Scene/GlobeDepth.js b/Source/Scene/GlobeDepth.js index 72deeae03086..2bb0b81faa8b 100644 --- a/Source/Scene/GlobeDepth.js +++ b/Source/Scene/GlobeDepth.js @@ -117,7 +117,8 @@ define([ width : width, height : height, pixelFormat : PixelFormat.RGBA, - pixelDatatype : hdr ? PixelDatatype.HALF_FLOAT : PixelDatatype.UNSIGNED_BYTE, + //pixelDatatype : hdr ? PixelDatatype.HALF_FLOAT : PixelDatatype.UNSIGNED_BYTE, + pixelDatatype : hdr ? PixelDatatype.FLOAT : PixelDatatype.UNSIGNED_BYTE, sampler : new Sampler({ wrapS : TextureWrap.CLAMP_TO_EDGE, wrapT : TextureWrap.CLAMP_TO_EDGE, diff --git a/Source/Scene/PostProcessStageCollection.js b/Source/Scene/PostProcessStageCollection.js index 6d994ce07590..4d509effe6a6 100644 --- a/Source/Scene/PostProcessStageCollection.js +++ b/Source/Scene/PostProcessStageCollection.js @@ -62,6 +62,9 @@ define([ bloom.enabled = false; tonemapping.enabled = false; + // TODO HDR + fxaa.enabled = false; + var textureCache = new PostProcessStageTextureCache(this); var stageNames = {}; diff --git a/Source/Scene/Scene.js b/Source/Scene/Scene.js index 48c4d5ad3496..f3d07680a1a2 100644 --- a/Source/Scene/Scene.js +++ b/Source/Scene/Scene.js @@ -432,7 +432,7 @@ define([ * @type {Boolean} * @default true */ - this.sunBloom = !this._hdr; + this.sunBloom = !this._hdr; // TODO HDR //this.sunBloom = true; this._sunBloom = undefined; @@ -2244,7 +2244,6 @@ define([ } if (defined(globeDepth) && environmentState.useGlobeDepthFramebuffer) { - globeDepth.update(context, passState); globeDepth.executeCopyDepth(context, passState); } @@ -2923,7 +2922,7 @@ define([ // Globe depth needs is copied for Pick to support picking batched geometries in GroundPrimitives. var useGlobeDepthFramebuffer = environmentState.useGlobeDepthFramebuffer = defined(scene._globeDepth); if (useGlobeDepthFramebuffer) { - scene._globeDepth.update(context, passState); + scene._globeDepth.update(context, passState, scene._hdr); scene._globeDepth.clear(context, passState, clearColor); } diff --git a/Source/Scene/SceneFramebuffer.js b/Source/Scene/SceneFramebuffer.js index 018dc7233126..216dbb783ce0 100644 --- a/Source/Scene/SceneFramebuffer.js +++ b/Source/Scene/SceneFramebuffer.js @@ -78,7 +78,8 @@ define([ width : width, height : height, pixelFormat : PixelFormat.RGBA, - pixelDatatype : hdr ? PixelDatatype.HALF_FLOAT : PixelDatatype.UNSIGNED_BYTE, + //pixelDatatype : hdr ? PixelDatatype.HALF_FLOAT : PixelDatatype.UNSIGNED_BYTE, + pixelDatatype : hdr ? PixelDatatype.FLOAT : PixelDatatype.UNSIGNED_BYTE, sampler : new Sampler({ wrapS : TextureWrap.CLAMP_TO_EDGE, wrapT : TextureWrap.CLAMP_TO_EDGE, diff --git a/Source/Scene/Sun.js b/Source/Scene/Sun.js index 32df9b30870a..54b10c365380 100644 --- a/Source/Scene/Sun.js +++ b/Source/Scene/Sun.js @@ -180,7 +180,8 @@ define([ width : size, height : size, pixelFormat : PixelFormat.RGBA, - pixelDatatype : useHDR ? PixelDatatype.HALF_FLOAT : PixelFormat.UNSIGNED_BYTE + //pixelDatatype : useHDR ? PixelDatatype.HALF_FLOAT : PixelFormat.UNSIGNED_BYTE + pixelDatatype : useHDR ? PixelDatatype.FLOAT : PixelFormat.UNSIGNED_BYTE }); this._glowLengthTS = this._glowFactor * 5.0; diff --git a/Source/Shaders/Materials/PolylineGlowMaterial.glsl b/Source/Shaders/Materials/PolylineGlowMaterial.glsl index 5c717701b4e9..df8b7191c871 100644 --- a/Source/Shaders/Materials/PolylineGlowMaterial.glsl +++ b/Source/Shaders/Materials/PolylineGlowMaterial.glsl @@ -10,7 +10,10 @@ czm_material czm_getMaterial(czm_materialInput materialInput) vec2 st = materialInput.st; float glow = glowPower / abs(st.t - 0.5) - (glowPower / 0.5); - material.emission = max(vec3(glow - 1.0 + color.rgb), color.rgb); + //material.emission = max(vec3(glow - 1.0 + color.rgb), color.rgb); + + // TODO HDR + material.emission = vec3(glow - 1.0 + color.rgb); material.alpha = clamp(0.0, 1.0, glow) * color.a; return material; diff --git a/Source/Shaders/PostProcessStages/ReinhardTonemapping.glsl b/Source/Shaders/PostProcessStages/ReinhardTonemapping.glsl index 5573ed6ae955..4f5dbef69039 100644 --- a/Source/Shaders/PostProcessStages/ReinhardTonemapping.glsl +++ b/Source/Shaders/PostProcessStages/ReinhardTonemapping.glsl @@ -6,6 +6,10 @@ varying vec2 v_textureCoordinates; void main() { vec3 color = texture2D(colorTexture, v_textureCoordinates).rgb; + + //if (length(color) > length(vec3(1.0))) { gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); return; } + if (color.r > 10.0 || color.g > 10.0 || color.b > 10.0) { gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); return; } + vec3 toneMapped = vec3(1.0) - exp(-color * exposure); gl_FragColor = vec4(toneMapped, 1.0); } diff --git a/Source/Shaders/SkyAtmosphereFS.glsl b/Source/Shaders/SkyAtmosphereFS.glsl index 678ec9b35432..9c993fba6535 100644 --- a/Source/Shaders/SkyAtmosphereFS.glsl +++ b/Source/Shaders/SkyAtmosphereFS.glsl @@ -47,6 +47,9 @@ varying vec3 v_mieColor; varying vec3 v_toCamera; varying vec3 v_positionEC; +// TODO HDR +#define HDR + void main (void) { // Extra normalize added for Android @@ -54,13 +57,15 @@ void main (void) float rayleighPhase = 0.75 * (1.0 + cosAngle * cosAngle); float miePhase = 1.5 * ((1.0 - g2) / (2.0 + g2)) * (1.0 + cosAngle * cosAngle) / pow(1.0 + g2 - 2.0 * g * cosAngle, 1.5); - const float exposure = 2.0; - vec3 rgb = rayleighPhase * v_rayleighColor + miePhase * v_mieColor; + +#ifndef HDR + const float exposure = 2.0; rgb = vec3(1.0) - exp(-exposure * rgb); - // Compute luminance before color correction to avoid strangely gray night skies - float l = czm_luminance(rgb); +#endif +// TODO HDR +/* #ifdef COLOR_CORRECT // Convert rgb color to hsb vec3 hsb = czm_RGBToHSB(rgb); @@ -70,10 +75,8 @@ void main (void) hsb.z = hsb.z > czm_epsilon7 ? hsb.z + u_hsbShift.z : 0.0; // brightness // Convert shifted hsb back to rgb rgb = czm_HSBToRGB(hsb); - - // Check if correction decreased the luminance to 0 - l = min(l, czm_luminance(rgb)); #endif +*/ // Alter alpha based on how close the viewer is to the ground (1.0 = on ground, 0.0 = at edge of atmosphere) float atmosphereAlpha = clamp((u_cameraAndRadiiAndDynamicAtmosphereColor.y - u_cameraAndRadiiAndDynamicAtmosphereColor.x) / (u_cameraAndRadiiAndDynamicAtmosphereColor.y - u_cameraAndRadiiAndDynamicAtmosphereColor.z), 0.0, 1.0); @@ -82,5 +85,7 @@ void main (void) float nightAlpha = (u_cameraAndRadiiAndDynamicAtmosphereColor.w > 0.0) ? clamp(dot(normalize(czm_viewerPositionWC), normalize(czm_sunPositionWC)), 0.0, 1.0) : 1.0; atmosphereAlpha *= pow(nightAlpha, 0.5); - gl_FragColor = vec4(rgb, mix(rgb.b, 1.0, atmosphereAlpha) * smoothstep(0.0, 1.0, czm_morphTime)); + //gl_FragColor = vec4(rgb, mix(rgb.b, 1.0, atmosphereAlpha) * smoothstep(0.0, 1.0, czm_morphTime)); + + gl_FragColor = vec4(vec3(11.0), 1.0); } diff --git a/Source/Shaders/SunTextureFS.glsl b/Source/Shaders/SunTextureFS.glsl index e950ec427e55..e71f01529607 100644 --- a/Source/Shaders/SunTextureFS.glsl +++ b/Source/Shaders/SunTextureFS.glsl @@ -17,7 +17,7 @@ vec4 addBurst(vec2 position, vec2 direction) return vec4(burst); } -// TODO +// TODO HDR #define HDR void main() diff --git a/Source/ThirdParty/GltfPipeline/processPbrMetallicRoughness.js b/Source/ThirdParty/GltfPipeline/processPbrMetallicRoughness.js index 54383682051f..68056ab4c1bf 100644 --- a/Source/ThirdParty/GltfPipeline/processPbrMetallicRoughness.js +++ b/Source/ThirdParty/GltfPipeline/processPbrMetallicRoughness.js @@ -442,20 +442,24 @@ define([ '}\n\n'; } + // TODO HDR fragmentShader += 'vec3 SRGBtoLINEAR3(vec3 srgbIn) \n' + '{\n' + - ' return pow(srgbIn, vec3(2.2));\n' + + //' return pow(srgbIn, vec3(2.2));\n' + + ' return srgbIn;\n' + '}\n\n'; fragmentShader += 'vec4 SRGBtoLINEAR4(vec4 srgbIn) \n' + '{\n' + - ' vec3 linearOut = pow(srgbIn.rgb, vec3(2.2));\n' + - ' return vec4(linearOut, srgbIn.a);\n' + + //' vec3 linearOut = pow(srgbIn.rgb, vec3(2.2));\n' + + //' return vec4(linearOut, srgbIn.a);\n' + + ' return srgbIn;\n' + '}\n\n'; fragmentShader += 'vec3 LINEARtoSRGB(vec3 linearIn) \n' + '{\n' + - ' return pow(linearIn, vec3(1.0/2.2));\n' + + //' return pow(linearIn, vec3(1.0/2.2));\n' + + ' return linearIn;\n' + '}\n\n'; fragmentShader += 'void main(void) \n{\n'; From 1698aade2d0775d49afbcb7230f12443e3bb013d Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Tue, 22 May 2018 15:15:36 -0400 Subject: [PATCH 04/76] Bloom WIP. [ci skip]. --- Source/Renderer/Context.js | 4 ++ Source/Scene/PostProcessStageCollection.js | 3 +- Source/Scene/PostProcessStageLibrary.js | 69 ++++++++++++++++++- .../ReinhardTonemapping.glsl | 3 +- Source/Shaders/SkyAtmosphereFS.glsl | 4 +- Source/Shaders/SunTextureFS.glsl | 27 ++++---- 6 files changed, 90 insertions(+), 20 deletions(-) diff --git a/Source/Renderer/Context.js b/Source/Renderer/Context.js index 6ff2322a7a00..f4fd8f02576d 100644 --- a/Source/Renderer/Context.js +++ b/Source/Renderer/Context.js @@ -281,6 +281,10 @@ define([ this._fragDepth = !!getExtension(gl, ['EXT_frag_depth']); this._debugShaders = getExtension(gl, ['WEBGL_debug_shaders']); + // TODO HDR + this._textureFloatLinear = !!getExtension(gl, ['OES_texture_float_linear']); + this._textureHalfFloatLinear = !!getExtension(gl, ['OES_texture_half_float_linear']); + this._colorBufferFloat = !!getExtension(gl, ['EXT_color_buffer_float', 'WEBGL_color_buffer_float']); this._colorBufferHalfFloat = !!getExtension(gl, ['EXT_color_buffer_half_float']); diff --git a/Source/Scene/PostProcessStageCollection.js b/Source/Scene/PostProcessStageCollection.js index 4d509effe6a6..58b5f48c1d96 100644 --- a/Source/Scene/PostProcessStageCollection.js +++ b/Source/Scene/PostProcessStageCollection.js @@ -59,7 +59,8 @@ define([ var tonemapping = PostProcessStageLibrary.createReinhardTonemappingStage(); ao.enabled = false; - bloom.enabled = false; + //bloom.enabled = false; // TODO HDR + bloom.enabled = true; tonemapping.enabled = false; // TODO HDR diff --git a/Source/Scene/PostProcessStageLibrary.js b/Source/Scene/PostProcessStageLibrary.js index e7735b42d2fb..e11e328c0bca 100644 --- a/Source/Scene/PostProcessStageLibrary.js +++ b/Source/Scene/PostProcessStageLibrary.js @@ -4,6 +4,7 @@ define([ '../Core/defineProperties', '../Core/destroyObject', '../Core/Ellipsoid', + '../Renderer/PixelDatatype', '../Shaders/PostProcessStages/AmbientOcclusionGenerate', '../Shaders/PostProcessStages/AmbientOcclusionModulate', '../Shaders/PostProcessStages/BlackAndWhite', @@ -30,6 +31,7 @@ define([ defineProperties, destroyObject, Ellipsoid, + PixelDatatype, AmbientOcclusionGenerate, AmbientOcclusionModulate, BlackAndWhite, @@ -59,7 +61,7 @@ define([ */ var PostProcessStageLibrary = {}; - function createBlur(name) { + function createBlur(name, pixelDatatype, forcePowerOfTwo) { var delta = 1.0; var sigma = 2.0; var stepSize = 1.0; @@ -74,7 +76,9 @@ define([ stepSize : stepSize, direction : 0.0 }, - sampleMode : PostProcessStageSampleMode.LINEAR + sampleMode : PostProcessStageSampleMode.LINEAR, + pixelDatatype : pixelDatatype, + forcePowerOfTwo : forcePowerOfTwo }); var blurY = new PostProcessStage({ name : name + '_y_direction', @@ -85,7 +89,9 @@ define([ stepSize : stepSize, direction : 1.0 }, - sampleMode : PostProcessStageSampleMode.LINEAR + sampleMode : PostProcessStageSampleMode.LINEAR, + pixelDatatype : pixelDatatype, + forcePowerOfTwo : forcePowerOfTwo }); var uniforms = {}; @@ -305,6 +311,8 @@ define([ * * @private */ + // TODO HDR + /* PostProcessStageLibrary.createBloomStage = function() { var contrastBias = new PostProcessStage({ name : 'czm_bloom_contrast_bias', @@ -388,6 +396,61 @@ define([ uniforms : uniforms }); }; + */ + + PostProcessStageLibrary.createBloomStage = function() { + var brightFS = + 'uniform sampler2D colorTexture; \n' + + 'varying vec2 v_textureCoordinates; \n' + + 'void main() { \n' + + ' vec4 color = texture2D(colorTexture, v_textureCoordinates); \n' + + ' float brightness = dot(color.rgb, vec3(0.2126, 0.7152, 0.0722)); \n' + + ' if (brightness > 1.0) { \n' + + ' gl_FragColor = vec4(color.rgb, 1.0); \n' + + ' } else { \n' + + ' gl_FragColor = vec4(vec3(0.0), 1.0); \n' + + ' } \n' + + '} \n'; + var powerOfTwo = false; + var brightPass = new PostProcessStage({ + fragmentShader : brightFS, + forcePowerOfTwo : powerOfTwo, + pixelDatatype : PixelDatatype.FLOAT + }); + var blur0 = createBlur('czm_bloom_blur0', PixelDatatype.FLOAT, powerOfTwo); + var blur1 = createBlur('czm_bloom_blur1', PixelDatatype.FLOAT, powerOfTwo); + var blur2 = createBlur('czm_bloom_blur2', PixelDatatype.FLOAT, powerOfTwo); + var blur3 = createBlur('czm_bloom_blur3', PixelDatatype.FLOAT, powerOfTwo); + var blur4 = createBlur('czm_bloom_blur4', PixelDatatype.FLOAT, powerOfTwo); + var brightBlur = new PostProcessStageComposite({ + name : 'czm_brightness_blur', + stages : [brightPass, blur0, blur1, blur2, blur3, blur4] + }); + + var addFS = + 'uniform sampler2D colorTexture; \n' + + 'uniform sampler2D brightTexture; \n' + + 'varying vec2 v_textureCoordinates; \n' + + 'void main() { \n' + + ' vec4 color = texture2D(colorTexture, v_textureCoordinates); \n' + + ' vec4 bloom = texture2D(brightTexture, v_textureCoordinates); \n' + + ' gl_FragColor = vec4(color.rgb + bloom.rgb, 1.0); \n' + + '} \n'; + var add = new PostProcessStage({ + fragmentShader : addFS, + forcePowerOfTwo : powerOfTwo, + pixelDatatype : PixelDatatype.FLOAT, + uniforms : { + brightTexture : brightBlur.name + } + }); + + return new PostProcessStageComposite({ + name : 'czm_bloom', + stages : [brightBlur, add], + inputPreviousStageTexture : false + }); + }; /** * Creates a post-process stage that Horizon-based Ambient Occlusion (HBAO) to the input texture. diff --git a/Source/Shaders/PostProcessStages/ReinhardTonemapping.glsl b/Source/Shaders/PostProcessStages/ReinhardTonemapping.glsl index 4f5dbef69039..a6b4c530aa45 100644 --- a/Source/Shaders/PostProcessStages/ReinhardTonemapping.glsl +++ b/Source/Shaders/PostProcessStages/ReinhardTonemapping.glsl @@ -7,8 +7,9 @@ void main() { vec3 color = texture2D(colorTexture, v_textureCoordinates).rgb; + // TODO HDR //if (length(color) > length(vec3(1.0))) { gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); return; } - if (color.r > 10.0 || color.g > 10.0 || color.b > 10.0) { gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); return; } + //if (color.r > 1.0 && color.g > 1.0 && color.b > 1.0) { gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); return; } vec3 toneMapped = vec3(1.0) - exp(-color * exposure); gl_FragColor = vec4(toneMapped, 1.0); diff --git a/Source/Shaders/SkyAtmosphereFS.glsl b/Source/Shaders/SkyAtmosphereFS.glsl index 9c993fba6535..c6c3fded3604 100644 --- a/Source/Shaders/SkyAtmosphereFS.glsl +++ b/Source/Shaders/SkyAtmosphereFS.glsl @@ -85,7 +85,5 @@ void main (void) float nightAlpha = (u_cameraAndRadiiAndDynamicAtmosphereColor.w > 0.0) ? clamp(dot(normalize(czm_viewerPositionWC), normalize(czm_sunPositionWC)), 0.0, 1.0) : 1.0; atmosphereAlpha *= pow(nightAlpha, 0.5); - //gl_FragColor = vec4(rgb, mix(rgb.b, 1.0, atmosphereAlpha) * smoothstep(0.0, 1.0, czm_morphTime)); - - gl_FragColor = vec4(vec3(11.0), 1.0); + gl_FragColor = vec4(rgb, mix(rgb.b, 1.0, atmosphereAlpha) * smoothstep(0.0, 1.0, czm_morphTime)); } diff --git a/Source/Shaders/SunTextureFS.glsl b/Source/Shaders/SunTextureFS.glsl index e71f01529607..24ef866cdaf2 100644 --- a/Source/Shaders/SunTextureFS.glsl +++ b/Source/Shaders/SunTextureFS.glsl @@ -28,13 +28,10 @@ void main() vec4 color = vec4(1.0, 1.0, surface + 0.2, surface); float glow = 1.0 - smoothstep(0.0, 0.55, radius); -#ifdef HDR - color.ba += glow; -#else color.ba += mix(vec2(0.0), vec2(1.0), glow) * 0.75; -#endif - vec4 burst = vec4(0.0); + vec4 burst0 = vec4(0.0); + vec4 burst1 = vec4(0.0); // The following loop has been manually unrolled for speed, to // avoid sin() and cos(). @@ -47,19 +44,25 @@ void main() // burst += 0.3 * addBurst(position, direction); //} - burst += 0.4 * addBurst(position, vec2(0.38942, 0.92106)); // angle == 0.4 - burst += 0.4 * addBurst(position, vec2(0.99235, 0.12348)); // angle == 0.4 + 1.047 - burst += 0.4 * addBurst(position, vec2(0.60327, -0.79754)); // angle == 0.4 + 1.047 * 2.0 + burst0 += addBurst(position, vec2(0.38942, 0.92106)); // angle == 0.4 + burst0 += addBurst(position, vec2(0.99235, 0.12348)); // angle == 0.4 + 1.047 + burst0 += addBurst(position, vec2(0.60327, -0.79754)); // angle == 0.4 + 1.047 * 2.0 - burst += 0.3 * addBurst(position, vec2(0.31457, 0.94924)); // angle == 0.4 - 0.08 - burst += 0.3 * addBurst(position, vec2(0.97931, 0.20239)); // angle == 0.4 + 1.047 - 0.08 - burst += 0.3 * addBurst(position, vec2(0.66507, -0.74678)); // angle == 0.4 + 1.047 * 2.0 - 0.08 + burst1 += addBurst(position, vec2(0.31457, 0.94924)); // angle == 0.4 - 0.08 + burst1 += addBurst(position, vec2(0.97931, 0.20239)); // angle == 0.4 + 1.047 - 0.08 + burst1 += addBurst(position, vec2(0.66507, -0.74678)); // angle == 0.4 + 1.047 * 2.0 - 0.08 // End of manual loop unrolling. #ifdef HDR - gl_FragColor = color + burst; + vec4 burst = burst0 + burst1; + color += burst; + + vec3 lightColor = vec3(1.5, 1.4, 1.2); + color.rgb *= lightColor; + gl_FragColor = color; #else + vec4 burst = burst0 * 0.4 + burst1 * 0.3; color += clamp(burst, vec4(0.0), vec4(1.0)) * 0.15; gl_FragColor = clamp(color, vec4(0.0), vec4(1.0)); #endif From e003b9eeb7052c5328c08176e5ac6fca37e78f75 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Tue, 22 May 2018 16:58:36 -0400 Subject: [PATCH 05/76] Testing different blur. --- Source/Scene/PostProcessStageLibrary.js | 68 +++++++++++++++++++++---- Source/Shaders/SkyAtmosphereFS.glsl | 3 -- 2 files changed, 58 insertions(+), 13 deletions(-) diff --git a/Source/Scene/PostProcessStageLibrary.js b/Source/Scene/PostProcessStageLibrary.js index e11e328c0bca..484c10caba71 100644 --- a/Source/Scene/PostProcessStageLibrary.js +++ b/Source/Scene/PostProcessStageLibrary.js @@ -61,7 +61,7 @@ define([ */ var PostProcessStageLibrary = {}; - function createBlur(name, pixelDatatype, forcePowerOfTwo) { + function createBlur(name, pixelDatatype, forcePowerOfTwo, textureScale) { var delta = 1.0; var sigma = 2.0; var stepSize = 1.0; @@ -78,7 +78,8 @@ define([ }, sampleMode : PostProcessStageSampleMode.LINEAR, pixelDatatype : pixelDatatype, - forcePowerOfTwo : forcePowerOfTwo + forcePowerOfTwo : forcePowerOfTwo, + textureScale : textureScale }); var blurY = new PostProcessStage({ name : name + '_y_direction', @@ -91,7 +92,8 @@ define([ }, sampleMode : PostProcessStageSampleMode.LINEAR, pixelDatatype : pixelDatatype, - forcePowerOfTwo : forcePowerOfTwo + forcePowerOfTwo : forcePowerOfTwo, + textureScale : textureScale }); var uniforms = {}; @@ -412,19 +414,65 @@ define([ ' } \n' + '} \n'; var powerOfTwo = false; + var scale = 0.75; var brightPass = new PostProcessStage({ fragmentShader : brightFS, forcePowerOfTwo : powerOfTwo, - pixelDatatype : PixelDatatype.FLOAT + pixelDatatype : PixelDatatype.FLOAT, + textureScale : scale + }); + var blurFS = + 'uniform sampler2D colorTexture; \n' + + 'uniform vec2 colorTextureDimensions; \n' + + 'uniform bool horizontal; \n' + + 'varying vec2 v_textureCoordinates; \n' + + 'void main() { \n' + + 'float weights[5]; \n' + + 'weights[0] = 0.227027; \n' + + 'weights[1] = 0.1945946; \n' + + 'weights[2] = 0.1216216; \n' + + 'weights[3] = 0.054054; \n' + + 'weights[4] = 0.016216; \n' + + ' vec2 offset = 1.0 / colorTextureDimensions; \n' + + ' vec3 result = texture2D(colorTexture, v_textureCoordinates).rgb * weights[0]; \n' + + ' if(horizontal) { \n' + + ' for(int i = 1; i < 5; ++i) { \n' + + ' result += texture2D(colorTexture, v_textureCoordinates + vec2(offset.x * float(i), 0.0)).rgb * weights[i]; \n' + + ' result += texture2D(colorTexture, v_textureCoordinates - vec2(offset.x * float(i), 0.0)).rgb * weights[i]; \n' + + ' } \n' + + ' } else { \n' + + ' for(int i = 1; i < 5; ++i) { \n' + + ' result += texture2D(colorTexture, v_textureCoordinates + vec2(0.0, offset.y * float(i))).rgb * weights[i]; \n' + + ' result += texture2D(colorTexture, v_textureCoordinates - vec2(0.0, offset.y * float(i))).rgb * weights[i]; \n' + + ' } \n' + + ' } \n' + + ' gl_FragColor = vec4(result, 1.0); \n' + + '} \n'; + var blurX = new PostProcessStage({ + fragmentShader : blurFS, + uniforms : { + horizontal : true + }, + forcePowerOfTwo : powerOfTwo, + pixelDatatype : PixelDatatype.FLOAT, + textureScale : scale + }); + var blurY = new PostProcessStage({ + fragmentShader : blurFS, + uniforms : { + horizontal : false + }, + forcePowerOfTwo : powerOfTwo, + pixelDatatype : PixelDatatype.FLOAT, + textureScale : scale + }); + var blur = new PostProcessStageComposite({ + stages : [blurX, blurY, blurX, blurY, blurX, blurY, blurX, blurY, blurX, blurY] }); - var blur0 = createBlur('czm_bloom_blur0', PixelDatatype.FLOAT, powerOfTwo); - var blur1 = createBlur('czm_bloom_blur1', PixelDatatype.FLOAT, powerOfTwo); - var blur2 = createBlur('czm_bloom_blur2', PixelDatatype.FLOAT, powerOfTwo); - var blur3 = createBlur('czm_bloom_blur3', PixelDatatype.FLOAT, powerOfTwo); - var blur4 = createBlur('czm_bloom_blur4', PixelDatatype.FLOAT, powerOfTwo); + //var blur = createBlur('czm_bloom_blur0', PixelDatatype.FLOAT, powerOfTwo, scale); var brightBlur = new PostProcessStageComposite({ name : 'czm_brightness_blur', - stages : [brightPass, blur0, blur1, blur2, blur3, blur4] + stages : [brightPass, blur] }); var addFS = diff --git a/Source/Shaders/SkyAtmosphereFS.glsl b/Source/Shaders/SkyAtmosphereFS.glsl index c6c3fded3604..8ae88f76b69e 100644 --- a/Source/Shaders/SkyAtmosphereFS.glsl +++ b/Source/Shaders/SkyAtmosphereFS.glsl @@ -64,8 +64,6 @@ void main (void) rgb = vec3(1.0) - exp(-exposure * rgb); #endif -// TODO HDR -/* #ifdef COLOR_CORRECT // Convert rgb color to hsb vec3 hsb = czm_RGBToHSB(rgb); @@ -76,7 +74,6 @@ void main (void) // Convert shifted hsb back to rgb rgb = czm_HSBToRGB(hsb); #endif -*/ // Alter alpha based on how close the viewer is to the ground (1.0 = on ground, 0.0 = at edge of atmosphere) float atmosphereAlpha = clamp((u_cameraAndRadiiAndDynamicAtmosphereColor.y - u_cameraAndRadiiAndDynamicAtmosphereColor.x) / (u_cameraAndRadiiAndDynamicAtmosphereColor.y - u_cameraAndRadiiAndDynamicAtmosphereColor.z), 0.0, 1.0); From 0cd0862ff78d1fec4c1da19919e738c6ad500fc6 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 23 May 2018 17:49:29 -0400 Subject: [PATCH 06/76] Revert shaders. Use another bright pass filter WIP. [ci skip] --- Source/Scene/PostProcessStageLibrary.js | 91 ++++++++++++++++++++++--- Source/Shaders/SkyAtmosphereFS.glsl | 5 -- Source/Shaders/SunTextureFS.glsl | 33 ++++----- 3 files changed, 99 insertions(+), 30 deletions(-) diff --git a/Source/Scene/PostProcessStageLibrary.js b/Source/Scene/PostProcessStageLibrary.js index 484c10caba71..3ffee52fb5a4 100644 --- a/Source/Scene/PostProcessStageLibrary.js +++ b/Source/Scene/PostProcessStageLibrary.js @@ -10,6 +10,7 @@ define([ '../Shaders/PostProcessStages/BlackAndWhite', '../Shaders/PostProcessStages/BloomComposite', '../Shaders/PostProcessStages/Brightness', + '../Shaders/PostProcessStages/BrightPass', '../Shaders/PostProcessStages/ContrastBias', '../Shaders/PostProcessStages/DepthOfField', '../Shaders/PostProcessStages/DepthView', @@ -37,6 +38,7 @@ define([ BlackAndWhite, BloomComposite, Brightness, + BrightPass, ContrastBias, DepthOfField, DepthView, @@ -401,26 +403,99 @@ define([ */ PostProcessStageLibrary.createBloomStage = function() { + var scale = 0.75; + + var toLuminance = 'uniform sampler2D colorTexture; varying vec2 v_textureCoordinates; void main() { gl_FragColor = vec4(czm_luminance(texture2D(colorTexture, v_textureCoordinates).rgb)); }'; + var luminance = new PostProcessStage({ + fragmentShader : toLuminance, + textureScale : 0.5, + pixelDatatype : PixelDatatype.FLOAT + }); + var passThrough = 'uniform sampler2D colorTexture; varying vec2 v_textureCoordinates; void main() { gl_FragColor = texture2D(colorTexture, v_textureCoordinates); }'; + var downsample = new PostProcessStage({ + fragmentShader : passThrough, + textureScale : 0.5, + pixelDatatype : PixelDatatype.FLOAT + }); + var downsample2 = new PostProcessStage({ + fragmentShader : passThrough, + textureScale : 0.25, + pixelDatatype : PixelDatatype.FLOAT + }); + var downsample3 = new PostProcessStage({ + fragmentShader : passThrough, + textureScale : 0.125, + pixelDatatype : PixelDatatype.FLOAT + }); + var downsample4 = new PostProcessStage({ + fragmentShader : passThrough, + textureScale : 0.0625, + pixelDatatype : PixelDatatype.FLOAT + }); + + var avgLuminance = new PostProcessStageComposite({ + stages : [luminance, downsample, downsample2, downsample3, downsample4] + }); + + var brightPassFS = + 'uniform sampler2D colorTexture; \n' + + 'uniform sampler2D luminanceTexture; \n' + + 'uniform float threshold; \n' + + 'uniform float offset; \n' + + 'varying vec2 v_textureCoordinates; \n' + + 'float key(float avg) { \n' + + ' float guess = 1.5 - (1.5 / (avg * 0.1 + 1.0)); \n' + + ' return max(0.0, guess) + 0.1; \n' + + '} \n' + + 'void main() { \n' + + ' vec4 color = texture2D(colorTexture, v_textureCoordinates); \n' + + //' float avgLuminance = texture2D(luminanceTexture, vec2(0.5)).r; \n' + + ' float avgLuminance = 1.5; \n' + + ' vec3 Yxy = czm_RGBToXYZ(color.rgb); \n' + + ' float luminance = Yxy.r; \n' + + ' float scaledLum = key(avgLuminance) * luminance / avgLuminance; \n' + + ' float brightLum = max(scaledLum - threshold, 0.0); \n' + + ' float brightness = brightLum / (offset + brightLum); \n' + + ' Yxy.r = brightness; \n' + + ' gl_FragColor = vec4(czm_XYZToRGB(Yxy), 1.0); \n' + + '} \n'; + + var brightPass = new PostProcessStage({ + fragmentShader : brightPassFS, + uniforms : { + luminanceTexture : avgLuminance.name, + threshold : 0.25, + offset : 0.1 + }, + pixelDatatype : PixelDatatype.FLOAT, + textureScale : scale + }); + + var brightPassComposite = new PostProcessStageComposite({ + stages : [avgLuminance, brightPass], + inputPreviousStageTexture : false + }); + + /* var brightFS = 'uniform sampler2D colorTexture; \n' + 'varying vec2 v_textureCoordinates; \n' + 'void main() { \n' + ' vec4 color = texture2D(colorTexture, v_textureCoordinates); \n' + - ' float brightness = dot(color.rgb, vec3(0.2126, 0.7152, 0.0722)); \n' + - ' if (brightness > 1.0) { \n' + + ' if (color.r > 1.0 || color.g > 1.0 || color.b > 1.0) { \n' + ' gl_FragColor = vec4(color.rgb, 1.0); \n' + ' } else { \n' + ' gl_FragColor = vec4(vec3(0.0), 1.0); \n' + ' } \n' + '} \n'; - var powerOfTwo = false; var scale = 0.75; var brightPass = new PostProcessStage({ fragmentShader : brightFS, - forcePowerOfTwo : powerOfTwo, pixelDatatype : PixelDatatype.FLOAT, textureScale : scale }); + */ + var blurFS = 'uniform sampler2D colorTexture; \n' + 'uniform vec2 colorTextureDimensions; \n' + @@ -453,7 +528,6 @@ define([ uniforms : { horizontal : true }, - forcePowerOfTwo : powerOfTwo, pixelDatatype : PixelDatatype.FLOAT, textureScale : scale }); @@ -462,17 +536,17 @@ define([ uniforms : { horizontal : false }, - forcePowerOfTwo : powerOfTwo, pixelDatatype : PixelDatatype.FLOAT, textureScale : scale }); var blur = new PostProcessStageComposite({ - stages : [blurX, blurY, blurX, blurY, blurX, blurY, blurX, blurY, blurX, blurY] + stages : [blurX, blurY] }); //var blur = createBlur('czm_bloom_blur0', PixelDatatype.FLOAT, powerOfTwo, scale); var brightBlur = new PostProcessStageComposite({ name : 'czm_brightness_blur', - stages : [brightPass, blur] + //stages : [brightPass, blur] + stages : [brightPassComposite, blur] }); var addFS = @@ -486,7 +560,6 @@ define([ '} \n'; var add = new PostProcessStage({ fragmentShader : addFS, - forcePowerOfTwo : powerOfTwo, pixelDatatype : PixelDatatype.FLOAT, uniforms : { brightTexture : brightBlur.name diff --git a/Source/Shaders/SkyAtmosphereFS.glsl b/Source/Shaders/SkyAtmosphereFS.glsl index 8ae88f76b69e..68b57600ffb5 100644 --- a/Source/Shaders/SkyAtmosphereFS.glsl +++ b/Source/Shaders/SkyAtmosphereFS.glsl @@ -47,9 +47,6 @@ varying vec3 v_mieColor; varying vec3 v_toCamera; varying vec3 v_positionEC; -// TODO HDR -#define HDR - void main (void) { // Extra normalize added for Android @@ -59,10 +56,8 @@ void main (void) vec3 rgb = rayleighPhase * v_rayleighColor + miePhase * v_mieColor; -#ifndef HDR const float exposure = 2.0; rgb = vec3(1.0) - exp(-exposure * rgb); -#endif #ifdef COLOR_CORRECT // Convert rgb color to hsb diff --git a/Source/Shaders/SunTextureFS.glsl b/Source/Shaders/SunTextureFS.glsl index 24ef866cdaf2..243bdc477c39 100644 --- a/Source/Shaders/SunTextureFS.glsl +++ b/Source/Shaders/SunTextureFS.glsl @@ -25,13 +25,19 @@ void main() vec2 position = v_textureCoordinates - vec2(0.5); float radius = length(position); float surface = step(radius, u_radiusTS); - vec4 color = vec4(1.0, 1.0, surface + 0.2, surface); + +#ifdef HDR + vec2 rg = vec2(1.5, 1.2); +#else + vec2 rg = vec2(1.0); +#endif + + vec4 color = vec4(rg, surface + 0.2, surface); float glow = 1.0 - smoothstep(0.0, 0.55, radius); color.ba += mix(vec2(0.0), vec2(1.0), glow) * 0.75; - vec4 burst0 = vec4(0.0); - vec4 burst1 = vec4(0.0); + vec4 burst = vec4(0.0); // The following loop has been manually unrolled for speed, to // avoid sin() and cos(). @@ -44,26 +50,21 @@ void main() // burst += 0.3 * addBurst(position, direction); //} - burst0 += addBurst(position, vec2(0.38942, 0.92106)); // angle == 0.4 - burst0 += addBurst(position, vec2(0.99235, 0.12348)); // angle == 0.4 + 1.047 - burst0 += addBurst(position, vec2(0.60327, -0.79754)); // angle == 0.4 + 1.047 * 2.0 + burst += 0.4 * addBurst(position, vec2(0.38942, 0.92106)); // angle == 0.4 + burst += 0.4 * addBurst(position, vec2(0.99235, 0.12348)); // angle == 0.4 + 1.047 + burst += 0.4 * addBurst(position, vec2(0.60327, -0.79754)); // angle == 0.4 + 1.047 * 2.0 - burst1 += addBurst(position, vec2(0.31457, 0.94924)); // angle == 0.4 - 0.08 - burst1 += addBurst(position, vec2(0.97931, 0.20239)); // angle == 0.4 + 1.047 - 0.08 - burst1 += addBurst(position, vec2(0.66507, -0.74678)); // angle == 0.4 + 1.047 * 2.0 - 0.08 + burst += 0.3 * addBurst(position, vec2(0.31457, 0.94924)); // angle == 0.4 - 0.08 + burst += 0.3 * addBurst(position, vec2(0.97931, 0.20239)); // angle == 0.4 + 1.047 - 0.08 + burst += 0.3 * addBurst(position, vec2(0.66507, -0.74678)); // angle == 0.4 + 1.047 * 2.0 - 0.08 // End of manual loop unrolling. -#ifdef HDR - vec4 burst = burst0 + burst1; - color += burst; + color += clamp(burst, vec4(0.0), vec4(1.0)) * 0.15; - vec3 lightColor = vec3(1.5, 1.4, 1.2); - color.rgb *= lightColor; +#ifdef HDR gl_FragColor = color; #else - vec4 burst = burst0 * 0.4 + burst1 * 0.3; - color += clamp(burst, vec4(0.0), vec4(1.0)) * 0.15; gl_FragColor = clamp(color, vec4(0.0), vec4(1.0)); #endif } From adbf66724a3fac8a5b25759526fcc7b0661510ad Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Fri, 25 May 2018 18:49:53 -0400 Subject: [PATCH 07/76] Add different tonemappers WIP. [ci skip] --- Source/Scene/PostProcessStageCollection.js | 9 ++++-- Source/Scene/PostProcessStageLibrary.js | 31 +++++++++++++++++-- .../PostProcessStages/ACESTonemapping.glsl | 16 ++++++++++ .../PostProcessStages/FilmicTonemapping.glsl | 25 +++++++++++++++ .../ModifiedReinhardTonemapping.glsl | 14 +++++++++ .../ReinhardTonemapping.glsl | 13 +++----- Source/Shaders/SkyAtmosphereFS.glsl | 5 +++ 7 files changed, 100 insertions(+), 13 deletions(-) create mode 100644 Source/Shaders/PostProcessStages/ACESTonemapping.glsl create mode 100644 Source/Shaders/PostProcessStages/FilmicTonemapping.glsl create mode 100644 Source/Shaders/PostProcessStages/ModifiedReinhardTonemapping.glsl diff --git a/Source/Scene/PostProcessStageCollection.js b/Source/Scene/PostProcessStageCollection.js index 58b5f48c1d96..2abd83313d22 100644 --- a/Source/Scene/PostProcessStageCollection.js +++ b/Source/Scene/PostProcessStageCollection.js @@ -56,11 +56,14 @@ define([ var fxaa = PostProcessStageLibrary.createFXAAStage(); var ao = PostProcessStageLibrary.createAmbientOcclusionStage(); var bloom = PostProcessStageLibrary.createBloomStage(); - var tonemapping = PostProcessStageLibrary.createReinhardTonemappingStage(); + //var tonemapping = PostProcessStageLibrary.createReinhardTonemappingStage(); + //var tonemapping = PostProcessStageLibrary.createModifiedReinhardTonemappingStage(); + //var tonemapping = PostProcessStageLibrary.createFilmicTonemappingStage(); + var tonemapping = PostProcessStageLibrary.createACESTonemappingStage(); ao.enabled = false; - //bloom.enabled = false; // TODO HDR - bloom.enabled = true; + bloom.enabled = false; // TODO HDR + //bloom.enabled = true; tonemapping.enabled = false; // TODO HDR diff --git a/Source/Scene/PostProcessStageLibrary.js b/Source/Scene/PostProcessStageLibrary.js index 3ffee52fb5a4..5591dfcd7fa3 100644 --- a/Source/Scene/PostProcessStageLibrary.js +++ b/Source/Scene/PostProcessStageLibrary.js @@ -5,6 +5,7 @@ define([ '../Core/destroyObject', '../Core/Ellipsoid', '../Renderer/PixelDatatype', + '../Shaders/PostProcessStages/ACESTonemapping', '../Shaders/PostProcessStages/AmbientOcclusionGenerate', '../Shaders/PostProcessStages/AmbientOcclusionModulate', '../Shaders/PostProcessStages/BlackAndWhite', @@ -15,10 +16,12 @@ define([ '../Shaders/PostProcessStages/DepthOfField', '../Shaders/PostProcessStages/DepthView', '../Shaders/PostProcessStages/EdgeDetection', + '../Shaders/PostProcessStages/FilmicTonemapping', '../Shaders/PostProcessStages/FXAA', '../Shaders/PostProcessStages/GaussianBlur1D', '../Shaders/PostProcessStages/LensFlare', '../Shaders/PostProcessStages/LinearDepth', + '../Shaders/PostProcessStages/ModifiedReinhardTonemapping', '../Shaders/PostProcessStages/NightVision', '../shaders/PostProcessStages/ReinhardTonemapping', '../Shaders/PostProcessStages/Silhouette', @@ -33,6 +36,7 @@ define([ destroyObject, Ellipsoid, PixelDatatype, + ACESTonemapping, AmbientOcclusionGenerate, AmbientOcclusionModulate, BlackAndWhite, @@ -43,10 +47,12 @@ define([ DepthOfField, DepthView, EdgeDetection, + FilmicTonemapping, FXAA, GaussianBlur1D, LensFlare, LinearDepth, + ModifiedReinhardTonemapping, NightVision, ReinhardTonemapping, Silhouette, @@ -745,12 +751,33 @@ define([ }); }; + PostProcessStageLibrary.createACESTonemappingStage = function() { + return new PostProcessStage({ + name : 'czm_aces', + fragmentShader : ACESTonemapping + }); + }; + + PostProcessStageLibrary.createFilmicTonemappingStage = function() { + return new PostProcessStage({ + name : 'czm_filmic', + fragmentShader : FilmicTonemapping + }); + }; + PostProcessStageLibrary.createReinhardTonemappingStage = function() { return new PostProcessStage({ name : 'czm_reinhard', - fragmentShader : ReinhardTonemapping, + fragmentShader : ReinhardTonemapping + }); + }; + + PostProcessStageLibrary.createModifiedReinhardTonemappingStage = function() { + return new PostProcessStage({ + name : 'czm_modified_reinhard', + fragmentShader : ModifiedReinhardTonemapping, uniforms : { - exposure : 1.0 + white : Color.WHITE } }); }; diff --git a/Source/Shaders/PostProcessStages/ACESTonemapping.glsl b/Source/Shaders/PostProcessStages/ACESTonemapping.glsl new file mode 100644 index 000000000000..38c52a0587f3 --- /dev/null +++ b/Source/Shaders/PostProcessStages/ACESTonemapping.glsl @@ -0,0 +1,16 @@ +uniform sampler2D colorTexture; + +varying vec2 v_textureCoordinates; + +void main() +{ + vec3 color = texture2D(colorTexture, v_textureCoordinates).rgb; + + float a = 2.51; + float b = 0.03; + float c = 2.43; + float d = 0.59; + float e = 0.14; + color = (color * (a * color + b)) / (color * (c * color + d) + e); + gl_FragColor = vec4(clamp(color, 0.0, 1.0), 1.0); +} diff --git a/Source/Shaders/PostProcessStages/FilmicTonemapping.glsl b/Source/Shaders/PostProcessStages/FilmicTonemapping.glsl new file mode 100644 index 000000000000..40d3e13017af --- /dev/null +++ b/Source/Shaders/PostProcessStages/FilmicTonemapping.glsl @@ -0,0 +1,25 @@ +uniform sampler2D colorTexture; + +varying vec2 v_textureCoordinates; + +// See slides 142 and 143: +// http://www.gdcvault.com/play/1012459/Uncharted_2__HDR_Lighting + +void main() +{ + vec3 color = texture2D(colorTexture, v_textureCoordinates).rgb; + + const float A = 0.22; // shoulder strength + const float B = 0.30; // linear strength + const float C = 0.10; // linear angle + const float D = 0.20; // toe strength + const float E = 0.01; // toe numerator + const float F = 0.30; // toe denominator + + const float white = 11.2; // linear white point value + + vec3 c = ((color * (A * color + C * B) + D * E) / (color * ( A * color + B) + D * F)) - E / F; + float w = ((white * (A * white + C * B) + D * E) / (white * ( A * white + B) + D * F)) - E / F; + + gl_FragColor = vec4(c / w, 1.0); +} diff --git a/Source/Shaders/PostProcessStages/ModifiedReinhardTonemapping.glsl b/Source/Shaders/PostProcessStages/ModifiedReinhardTonemapping.glsl new file mode 100644 index 000000000000..ca3dbebc448a --- /dev/null +++ b/Source/Shaders/PostProcessStages/ModifiedReinhardTonemapping.glsl @@ -0,0 +1,14 @@ +uniform sampler2D colorTexture; +uniform vec3 white; + +varying vec2 v_textureCoordinates; + +// See equation 4: +// http://www.cs.utah.edu/~reinhard/cdrom/tonemap.pdf + +void main() +{ + vec3 color = texture2D(colorTexture, v_textureCoordinates).rgb; + color = (color * (1.0 + color / white)) / (1.0 + color); + gl_FragColor = vec4(color, 1.0); +} diff --git a/Source/Shaders/PostProcessStages/ReinhardTonemapping.glsl b/Source/Shaders/PostProcessStages/ReinhardTonemapping.glsl index a6b4c530aa45..9f8cb88fc6ed 100644 --- a/Source/Shaders/PostProcessStages/ReinhardTonemapping.glsl +++ b/Source/Shaders/PostProcessStages/ReinhardTonemapping.glsl @@ -1,16 +1,13 @@ uniform sampler2D colorTexture; -uniform float exposure; varying vec2 v_textureCoordinates; +// See equation 3: +// http://www.cs.utah.edu/~reinhard/cdrom/tonemap.pdf + void main() { vec3 color = texture2D(colorTexture, v_textureCoordinates).rgb; - - // TODO HDR - //if (length(color) > length(vec3(1.0))) { gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); return; } - //if (color.r > 1.0 && color.g > 1.0 && color.b > 1.0) { gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); return; } - - vec3 toneMapped = vec3(1.0) - exp(-color * exposure); - gl_FragColor = vec4(toneMapped, 1.0); + color = color / (1.0 + color); + gl_FragColor = vec4(color, 1.0); } diff --git a/Source/Shaders/SkyAtmosphereFS.glsl b/Source/Shaders/SkyAtmosphereFS.glsl index 68b57600ffb5..8ae88f76b69e 100644 --- a/Source/Shaders/SkyAtmosphereFS.glsl +++ b/Source/Shaders/SkyAtmosphereFS.glsl @@ -47,6 +47,9 @@ varying vec3 v_mieColor; varying vec3 v_toCamera; varying vec3 v_positionEC; +// TODO HDR +#define HDR + void main (void) { // Extra normalize added for Android @@ -56,8 +59,10 @@ void main (void) vec3 rgb = rayleighPhase * v_rayleighColor + miePhase * v_mieColor; +#ifndef HDR const float exposure = 2.0; rgb = vec3(1.0) - exp(-exposure * rgb); +#endif #ifdef COLOR_CORRECT // Convert rgb color to hsb From 7d48a5f0617972cb22007bf4b1acee87d981c38a Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 7 Jun 2018 16:32:15 -0400 Subject: [PATCH 08/76] Fix after merge. --- Source/Scene/SceneFramebuffer.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Scene/SceneFramebuffer.js b/Source/Scene/SceneFramebuffer.js index 186528b0a5a4..94376cca54bc 100644 --- a/Source/Scene/SceneFramebuffer.js +++ b/Source/Scene/SceneFramebuffer.js @@ -44,7 +44,7 @@ define([ this._idFramebuffer = undefined; this._idClearColor = new Color(0.0, 0.0, 0.0, 0.0); - + this._useHDR = undefined; this._clearCommand = new ClearCommand({ @@ -78,7 +78,7 @@ define([ var width = context.drawingBufferWidth; var height = context.drawingBufferHeight; var colorTexture = this._colorTexture; - if (defined(colorTexture) && colorTexture.width === width && colorTexture.height === height || hdr !== this._useHDR) { + if (defined(colorTexture) && colorTexture.width === width && colorTexture.height === height && hdr === this._useHDR) { return; } From 4d47dccce22581b616bd10c330919dde39e41a30 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Tue, 26 Jun 2018 15:10:14 -0400 Subject: [PATCH 09/76] Auto exposure WIP. [ci skip] --- Source/Scene/AutoExposure.js | 210 ++++++++++++++++++ Source/Scene/PostProcessStageCollection.js | 36 ++- Source/Scene/PostProcessStageLibrary.js | 86 ++++++- .../PostProcessStages/ACESTonemapping.glsl | 8 + .../PostProcessStages/FilmicTonemapping.glsl | 8 + .../ModifiedReinhardTonemapping.glsl | 7 + .../ReinhardTonemapping.glsl | 7 + 7 files changed, 347 insertions(+), 15 deletions(-) create mode 100644 Source/Scene/AutoExposure.js diff --git a/Source/Scene/AutoExposure.js b/Source/Scene/AutoExposure.js new file mode 100644 index 000000000000..3cfe7579baf4 --- /dev/null +++ b/Source/Scene/AutoExposure.js @@ -0,0 +1,210 @@ +define([ + '../Core/BoundingRectangle', + '../Core/Check', + '../Core/Color', + '../Core/combine', + '../Core/createGuid', + '../Core/defaultValue', + '../Core/defined', + '../Core/defineProperties', + '../Core/destroyObject', + '../Core/DeveloperError', + '../Core/Math', + '../Core/PixelFormat', + '../Core/Resource', + '../Renderer/PassState', + '../Renderer/PixelDatatype', + '../Renderer/RenderState', + '../Renderer/Sampler', + '../Renderer/ShaderSource', + '../Renderer/Texture', + '../Renderer/TextureMagnificationFilter', + '../Renderer/TextureMinificationFilter', + '../Renderer/TextureWrap', + '../ThirdParty/when', + './PostProcessStageSampleMode' + ], function( + BoundingRectangle, + Check, + Color, + combine, + createGuid, + defaultValue, + defined, + defineProperties, + destroyObject, + DeveloperError, + CesiumMath, + PixelFormat, + Resource, + PassState, + PixelDatatype, + RenderState, + Sampler, + ShaderSource, + Texture, + TextureMagnificationFilter, + TextureMinificationFilter, + TextureWrap, + when, + PostProcessStageSampleMode) { + 'use strict'; + + function AutoExposure(options) { + this._clearColor = defaultValue(options.clearColor, Color.BLACK); + + this._uniformMap = undefined; + this._command = undefined; + + this._colorTexture = undefined; + this._depthTexture = undefined; + + this._ready = false; + + this._name = 'czm_autoexposure'; + + this._logDepthChanged = undefined; + this._useLogDepth = undefined; + + this.enabled = true; + this._enabled = true; + + this._framebuffers = undefined; + this._commands = undefined; + } + + defineProperties(AutoExposure.prototype, { + ready : { + get : function() { + return this._ready; + } + }, + name : { + get : function() { + return this._name; + } + }, + outputTexture : { + get : function() { + return undefined; + } + } + }); + + function destroyFramebuffers(autoexposure) { + var framebuffers = autoexposure._framebuffers; + if (!defined(framebuffers)) { + return; + } + + var length = framebuffers.length; + for (var i = 0; i < length; ++i) { + framebuffers[i].destroy(); + } + autoexposure._framebuffers = undefined; + } + + function createFramebuffers(autoexposure, context) { + destroyFramebuffers(autoexposure); + + var width = autoexposure._width; + var height = autoexposure._height; + + var length = Math.ceil(Math.max(width, height) / 3.0); + var framebuffers = new Array(length); + for (var i = 0; i < length; ++i) { + width = Math.max(Math.ceil(width / 3.0), 1.0); + height = Math.max(Math.ceil(height / 3.0), 1.0); + framebuffers[i] = new Framebuffer({ + context : context, + colorTextures : [new Texture({ + context : context, + width : width, + height : height, + pixelFormat : PixelFormat.RGBA, + pixelDatatype : PixelDatatype.FLOAT + })] + }); + } + + autoexposure._framebuffers = framebuffers; + } + + function destroyCommands(autoexposure) { + var commands = autoexposure._commands; + if (!defined(commands)) { + return; + } + + var length = commands.length; + for (var i = 0; i < length; ++i) { + commands[i].shaderProgram.destroy(); + } + autoexposure._commands = undefined; + } + + function createUniformMap(autoexposure, index) { + if (index === 0) { + return { + colorTexture : function() { + return autoexposure._colorTexture; + } + }; + } + return { + colorTexture : function() { + return autoexposure._framebuffers[index - 1].getColorTexture(0); + } + }; + } + + function getShaderSource(autoexposure, index) { + var framebuffers = autoexposure._framebuffers; + if (index === 0) { + + } + } + + function createCommands(autoexposure, context) { + destroyCommands(autoexposure); + var framebuffers = autoexposure._framebuffers; + var length = framebuffers.length; + + var commands = new Array(length); + + for (var i = 1; i < length; ++i) { + commands[i] = context.createViewportQuadCommand(getShaderSource(i), { + framebuffer : framebuffers[i], + uniformMap : createUniformMap(i) + }); + } + } + + AutoExposure.prototype.update = function(context, useLogDepth) { + var width = context.drawingBufferWidth; + var height = context.drawingBufferHeight; + + if (width === this._width || height === this._height) { + return; + } + + this._width = width; + this._height = height; + + createFramebuffers(this, context); + createCommands(this, context); + }; + + AutoExposure.prototype.execute = function(context, colorTexture, depthTexture, idTexture) { + }; + + AutoExposure.prototype.isDestroyed = function() { + return false; + }; + + AutoExposure.prototype.destroy = function() { + return destroyObject(this); + }; + + return AutoExposure; +}); diff --git a/Source/Scene/PostProcessStageCollection.js b/Source/Scene/PostProcessStageCollection.js index 20f27c45a6e5..ab2696b285fb 100644 --- a/Source/Scene/PostProcessStageCollection.js +++ b/Source/Scene/PostProcessStageCollection.js @@ -58,10 +58,14 @@ define([ var fxaa = PostProcessStageLibrary.createFXAAStage(); var ao = PostProcessStageLibrary.createAmbientOcclusionStage(); var bloom = PostProcessStageLibrary.createBloomStage(); - //var tonemapping = PostProcessStageLibrary.createReinhardTonemappingStage(); - //var tonemapping = PostProcessStageLibrary.createModifiedReinhardTonemappingStage(); - //var tonemapping = PostProcessStageLibrary.createFilmicTonemappingStage(); - var tonemapping = PostProcessStageLibrary.createACESTonemappingStage(); + var tonemapping = PostProcessStageLibrary.createReinhardTonemappingStage(true); + //var tonemapping = PostProcessStageLibrary.createModifiedReinhardTonemappingStage(true); + //var tonemapping = PostProcessStageLibrary.createFilmicTonemappingStage(true); + //var tonemapping = PostProcessStageLibrary.createACESTonemappingStage(true); + + //var autoexposure = PostProcessStageLibrary.createAutoExposureStage(); + + //tonemapping.uniforms.autoExposure = autoexposure.name; ao.enabled = false; bloom.enabled = false; // TODO HDR @@ -75,7 +79,7 @@ define([ var stageNames = {}; var stack = stackScratch; - stack.push(fxaa, ao, bloom, tonemapping); + stack.push(fxaa, ao, bloom, /*autoexposure,*/ tonemapping); while (stack.length > 0) { var stage = stack.pop(); stageNames[stage.name] = stage; @@ -102,12 +106,14 @@ define([ this._ao = ao; this._bloom = bloom; + //this._autoExposure = autoexposure; this._tonemapping = tonemapping; this._fxaa = fxaa; this._lastLength = undefined; this._aoEnabled = undefined; this._bloomEnabled = undefined; + //this._autoExposureEnabled = undefined; this._tonemappingEnabled = undefined; this._fxaaEnabled = undefined; @@ -139,11 +145,13 @@ define([ var fxaa = this._fxaa; var ao = this._ao; var bloom = this._bloom; + //var autoexposure = this._autoExposure; var tonemapping = this._tonemapping; readyAndEnabled = readyAndEnabled || (fxaa.ready && fxaa.enabled); readyAndEnabled = readyAndEnabled || (ao.ready && ao.enabled); readyAndEnabled = readyAndEnabled || (bloom.ready && bloom.enabled); + //readyAndEnabled = readyAndEnabled || (autoexposure.ready && autoexposure.enabled); readyAndEnabled = readyAndEnabled || (tonemapping.ready && tonemapping.enabled); return readyAndEnabled; @@ -286,6 +294,11 @@ define([ return this.getOutputTexture(tonemapping.name); } + //var autoexposure = this._autoExposure; + //if (autoexposure.enable && autoexposure.ready) { + // return this.getOutputTexture(autoexposure.name); + //} + var bloom = this._bloom; if (bloom.enabled && bloom.ready) { return this.getOutputTexture(bloom.name); @@ -518,17 +531,20 @@ define([ var ao = this._ao; var bloom = this._bloom; + //var autoexposure = this._autoExposure; var tonemapping = this._tonemapping; var fxaa = this._fxaa; + //autoexposure.enabled = useHDR; tonemapping.enabled = useHDR; var aoEnabled = ao.enabled && ao._isSupported(context); var bloomEnabled = bloom.enabled && bloom._isSupported(context); + //var autoexposureEnabled = autoexposure.enabled && autoexposure._isSupported(context); var tonemappingEnabled = tonemapping.enabled && tonemapping._isSupported(context); var fxaaEnabled = fxaa.enabled && fxaa._isSupported(context); - if (activeStagesChanged || this._textureCacheDirty || count !== this._lastLength || aoEnabled !== this._aoEnabled || + if (activeStagesChanged || this._textureCacheDirty || count !== this._lastLength || aoEnabled !== this._aoEnabled || /*autoexposureEnabled !== this._autoExposureEnabled ||*/ bloomEnabled !== this._bloomEnabled || tonemappingEnabled !== this._tonemappingEnabled || fxaaEnabled !== this._fxaaEnabled) { // The number of stages to execute has changed. // Update dependencies and recreate framebuffers. @@ -537,6 +553,7 @@ define([ this._lastLength = count; this._aoEnabled = aoEnabled; this._bloomEnabled = bloomEnabled; + //this._autoExposureEnabled = autoexposureEnabled; this._tonemappingEnabled = tonemappingEnabled; this._fxaaEnabled = fxaaEnabled; this._textureCacheDirty = false; @@ -577,6 +594,7 @@ define([ fxaa.update(context, useLogDepth); ao.update(context, useLogDepth); bloom.update(context, useLogDepth); + //autoexposure.update(context, useLogDepth); tonemapping.update(context, useLogDepth); length = stages.length; @@ -656,10 +674,12 @@ define([ var fxaa = this._fxaa; var ao = this._ao; var bloom = this._bloom; + //var autoexposure = this._autoExposure; var tonemapping = this._tonemapping; var aoEnabled = ao.enabled && ao._isSupported(context); var bloomEnabled = bloom.enabled && bloom._isSupported(context); + //var autoexposureEnabled = autoexposure.enabled && autoexposure._isSupported(context); var tonemappingEnabled = tonemapping.enabled && tonemapping._isSupported(context); var fxaaEnabled = fxaa.enabled && fxaa._isSupported(context); @@ -676,6 +696,9 @@ define([ execute(bloom, context, initialTexture, depthTexture, idTexture); initialTexture = getOutputTexture(bloom); } + //if (autoexposureEnabled && autoexposure.ready) { + // execute(autoexposure, context, initialTexture, depthTexture, idTexture); + //} if (tonemappingEnabled && tonemapping.ready) { execute(tonemapping, context, initialTexture, depthTexture); initialTexture = getOutputTexture(tonemapping); @@ -753,6 +776,7 @@ define([ this._fxaa.destroy(); this._ao.destroy(); this._bloom.destroy(); + //this._autoExposure.destroy(); this._tonemapping.destroy(); this.removeAll(); this._textureCache = this._textureCache && this._textureCache.destroy(); diff --git a/Source/Scene/PostProcessStageLibrary.js b/Source/Scene/PostProcessStageLibrary.js index 79b29742aaba..7d12d335880e 100644 --- a/Source/Scene/PostProcessStageLibrary.js +++ b/Source/Scene/PostProcessStageLibrary.js @@ -875,37 +875,105 @@ define([ }); }; - PostProcessStageLibrary.createACESTonemappingStage = function() { + PostProcessStageLibrary.createACESTonemappingStage = function(useAutoExposure) { + var fs = useAutoExposure ? '#define AUTO_EXPOSURE\n' : ''; + fs += ACESTonemapping; return new PostProcessStage({ name : 'czm_aces', - fragmentShader : ACESTonemapping + fragmentShader : fs, + uniforms : { + autoExposure : undefined + } }); }; - PostProcessStageLibrary.createFilmicTonemappingStage = function() { + PostProcessStageLibrary.createFilmicTonemappingStage = function(useAutoExposure) { + var fs = useAutoExposure ? '#define AUTO_EXPOSURE\n' : ''; + fs += FilmicTonemapping; return new PostProcessStage({ name : 'czm_filmic', - fragmentShader : FilmicTonemapping + fragmentShader : fs, + uniforms : { + autoExposure : undefined + } }); }; - PostProcessStageLibrary.createReinhardTonemappingStage = function() { + PostProcessStageLibrary.createReinhardTonemappingStage = function(useAutoExposure) { + var autoExposure = PostProcessStageLibrary.createAutoExposureStage(); + + useAutoExposure = false; + + var fs = useAutoExposure ? '#define AUTO_EXPOSURE\n' : ''; + fs += ReinhardTonemapping; return new PostProcessStage({ name : 'czm_reinhard', - fragmentShader : ReinhardTonemapping + fragmentShader : fs + }); + + var tonemapping = new PostProcessStage({ + name : 'czm_reinhard', + fragmentShader : fs, + uniforms : { + autoExposure : autoExposure.name + } + }); + + return new PostProcessStageComposite({ + name : 'czm_tonemapping', + stages : [autoExposure, tonemapping], + inputPreviousStageTexture : false }); }; - PostProcessStageLibrary.createModifiedReinhardTonemappingStage = function() { + PostProcessStageLibrary.createModifiedReinhardTonemappingStage = function(useAutoExposure) { + var fs = useAutoExposure ? '#define AUTO_EXPOSURE\n' : ''; + fs += ModifiedReinhardTonemapping; return new PostProcessStage({ name : 'czm_modified_reinhard', - fragmentShader : ModifiedReinhardTonemapping, + fragmentShader : fs, uniforms : { - white : Color.WHITE + white : Color.WHITE, + autoExposure : undefined } }); }; + PostProcessStageLibrary.createAutoExposureStage = function() { + var toLuminance = 'uniform sampler2D colorTexture; varying vec2 v_textureCoordinates; void main() { gl_FragColor = vec4(czm_luminance(texture2D(colorTexture, v_textureCoordinates).rgb)); }'; + var luminance = new PostProcessStage({ + fragmentShader : toLuminance, + textureScale : 0.5, + pixelDatatype : PixelDatatype.FLOAT + }); + var passThrough = 'uniform sampler2D colorTexture; varying vec2 v_textureCoordinates; void main() { gl_FragColor = texture2D(colorTexture, v_textureCoordinates); }'; + var downsample = new PostProcessStage({ + fragmentShader : passThrough, + textureScale : 0.5, + pixelDatatype : PixelDatatype.FLOAT + }); + var downsample2 = new PostProcessStage({ + fragmentShader : passThrough, + textureScale : 0.25, + pixelDatatype : PixelDatatype.FLOAT + }); + var downsample3 = new PostProcessStage({ + fragmentShader : passThrough, + textureScale : 0.125, + pixelDatatype : PixelDatatype.FLOAT + }); + var downsample4 = new PostProcessStage({ + fragmentShader : passThrough, + textureScale : 0.0625, + pixelDatatype : PixelDatatype.FLOAT + }); + + return new PostProcessStageComposite({ + name : 'czm_auto_exposure', + stages : [luminance, downsample, downsample2, downsample3, downsample4] + }); + }; + /** * Creates a post-process stage that renders the input texture with black and white gradations. *

diff --git a/Source/Shaders/PostProcessStages/ACESTonemapping.glsl b/Source/Shaders/PostProcessStages/ACESTonemapping.glsl index 38c52a0587f3..07f69cb5309f 100644 --- a/Source/Shaders/PostProcessStages/ACESTonemapping.glsl +++ b/Source/Shaders/PostProcessStages/ACESTonemapping.glsl @@ -2,10 +2,18 @@ uniform sampler2D colorTexture; varying vec2 v_textureCoordinates; +#ifdef AUTO_EXPOSURE +uniform sampler2D autoExposure; +#endif + void main() { vec3 color = texture2D(colorTexture, v_textureCoordinates).rgb; +#ifdef AUTO_EXPOSURE + color /= texture2D(autoExposure, vec2(0.5)).r; +#endif + float a = 2.51; float b = 0.03; float c = 2.43; diff --git a/Source/Shaders/PostProcessStages/FilmicTonemapping.glsl b/Source/Shaders/PostProcessStages/FilmicTonemapping.glsl index 40d3e13017af..bee615ea8db1 100644 --- a/Source/Shaders/PostProcessStages/FilmicTonemapping.glsl +++ b/Source/Shaders/PostProcessStages/FilmicTonemapping.glsl @@ -2,6 +2,10 @@ uniform sampler2D colorTexture; varying vec2 v_textureCoordinates; +#ifdef AUTO_EXPOSURE +uniform sampler2D autoExposure; +#endif + // See slides 142 and 143: // http://www.gdcvault.com/play/1012459/Uncharted_2__HDR_Lighting @@ -9,6 +13,10 @@ void main() { vec3 color = texture2D(colorTexture, v_textureCoordinates).rgb; +#ifdef AUTO_EXPOSURE + color /= texture2D(autoExposure, vec2(0.5)).r; +#endif + const float A = 0.22; // shoulder strength const float B = 0.30; // linear strength const float C = 0.10; // linear angle diff --git a/Source/Shaders/PostProcessStages/ModifiedReinhardTonemapping.glsl b/Source/Shaders/PostProcessStages/ModifiedReinhardTonemapping.glsl index ca3dbebc448a..42954e88d967 100644 --- a/Source/Shaders/PostProcessStages/ModifiedReinhardTonemapping.glsl +++ b/Source/Shaders/PostProcessStages/ModifiedReinhardTonemapping.glsl @@ -3,12 +3,19 @@ uniform vec3 white; varying vec2 v_textureCoordinates; +#ifdef AUTO_EXPOSURE +uniform sampler2D autoExposure; +#endif + // See equation 4: // http://www.cs.utah.edu/~reinhard/cdrom/tonemap.pdf void main() { vec3 color = texture2D(colorTexture, v_textureCoordinates).rgb; +#ifdef AUTO_EXPOSURE + color /= texture2D(autoExposure, vec2(0.5)).r; +#endif color = (color * (1.0 + color / white)) / (1.0 + color); gl_FragColor = vec4(color, 1.0); } diff --git a/Source/Shaders/PostProcessStages/ReinhardTonemapping.glsl b/Source/Shaders/PostProcessStages/ReinhardTonemapping.glsl index 9f8cb88fc6ed..72ffe0916a10 100644 --- a/Source/Shaders/PostProcessStages/ReinhardTonemapping.glsl +++ b/Source/Shaders/PostProcessStages/ReinhardTonemapping.glsl @@ -2,12 +2,19 @@ uniform sampler2D colorTexture; varying vec2 v_textureCoordinates; +#ifdef AUTO_EXPOSURE +uniform sampler2D autoExposure; +#endif + // See equation 3: // http://www.cs.utah.edu/~reinhard/cdrom/tonemap.pdf void main() { vec3 color = texture2D(colorTexture, v_textureCoordinates).rgb; +#ifdef AUTO_EXPOSURE + color /= texture2D(autoExposure, vec2(0.5)).r; +#endif color = color / (1.0 + color); gl_FragColor = vec4(color, 1.0); } From 6496236c189be02af58de89379c5c99607d614f4 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 5 Jul 2018 17:32:44 -0400 Subject: [PATCH 10/76] Gamma correction. --- Source/Shaders/GlobeFS.glsl | 8 +++++--- .../PostProcessStages/ACESTonemapping.glsl | 16 +++++++++------- .../PostProcessStages/FilmicTonemapping.glsl | 16 +++++++++------- .../ModifiedReinhardTonemapping.glsl | 13 +++++++------ .../PostProcessStages/ReinhardTonemapping.glsl | 13 +++++++------ Source/Shaders/SkyBoxFS.glsl | 1 + 6 files changed, 38 insertions(+), 29 deletions(-) diff --git a/Source/Shaders/GlobeFS.glsl b/Source/Shaders/GlobeFS.glsl index 8364c94ad007..690d873bc7c4 100644 --- a/Source/Shaders/GlobeFS.glsl +++ b/Source/Shaders/GlobeFS.glsl @@ -112,6 +112,8 @@ vec4 sampleAndBlend( vec3 color = value.rgb; float alpha = value.a; + color = pow(color, vec3(2.2)); + #ifdef APPLY_SPLIT float splitPosition = czm_imagerySplitPosition; // Split to the left @@ -140,9 +142,9 @@ vec4 sampleAndBlend( color = czm_saturation(color, textureSaturation); #endif -#ifdef APPLY_GAMMA - color = pow(color, vec3(textureOneOverGamma)); -#endif +//#ifdef APPLY_GAMMA +// color = pow(color, vec3(textureOneOverGamma)); +//#endif float sourceAlpha = alpha * textureAlpha; float outAlpha = mix(previousColor.a, 1.0, sourceAlpha); diff --git a/Source/Shaders/PostProcessStages/ACESTonemapping.glsl b/Source/Shaders/PostProcessStages/ACESTonemapping.glsl index 07f69cb5309f..5e9c611cdeab 100644 --- a/Source/Shaders/PostProcessStages/ACESTonemapping.glsl +++ b/Source/Shaders/PostProcessStages/ACESTonemapping.glsl @@ -2,17 +2,17 @@ uniform sampler2D colorTexture; varying vec2 v_textureCoordinates; -#ifdef AUTO_EXPOSURE -uniform sampler2D autoExposure; -#endif +//#ifdef AUTO_EXPOSURE +//uniform sampler2D autoExposure; +//#endif void main() { vec3 color = texture2D(colorTexture, v_textureCoordinates).rgb; -#ifdef AUTO_EXPOSURE - color /= texture2D(autoExposure, vec2(0.5)).r; -#endif +//#ifdef AUTO_EXPOSURE +// color /= texture2D(autoExposure, vec2(0.5)).r; +//#endif float a = 2.51; float b = 0.03; @@ -20,5 +20,7 @@ void main() float d = 0.59; float e = 0.14; color = (color * (a * color + b)) / (color * (c * color + d) + e); - gl_FragColor = vec4(clamp(color, 0.0, 1.0), 1.0); + color = clamp(color, 0.0, 1.0); + color = pow(color, vec3(1.0 / 2.2)); + gl_FragColor = vec4(color, 1.0); } diff --git a/Source/Shaders/PostProcessStages/FilmicTonemapping.glsl b/Source/Shaders/PostProcessStages/FilmicTonemapping.glsl index bee615ea8db1..4ce7b2ed33d3 100644 --- a/Source/Shaders/PostProcessStages/FilmicTonemapping.glsl +++ b/Source/Shaders/PostProcessStages/FilmicTonemapping.glsl @@ -2,9 +2,9 @@ uniform sampler2D colorTexture; varying vec2 v_textureCoordinates; -#ifdef AUTO_EXPOSURE -uniform sampler2D autoExposure; -#endif +//#ifdef AUTO_EXPOSURE +//uniform sampler2D autoExposure; +//#endif // See slides 142 and 143: // http://www.gdcvault.com/play/1012459/Uncharted_2__HDR_Lighting @@ -13,9 +13,9 @@ void main() { vec3 color = texture2D(colorTexture, v_textureCoordinates).rgb; -#ifdef AUTO_EXPOSURE - color /= texture2D(autoExposure, vec2(0.5)).r; -#endif +//#ifdef AUTO_EXPOSURE +// color /= texture2D(autoExposure, vec2(0.5)).r; +//#endif const float A = 0.22; // shoulder strength const float B = 0.30; // linear strength @@ -29,5 +29,7 @@ void main() vec3 c = ((color * (A * color + C * B) + D * E) / (color * ( A * color + B) + D * F)) - E / F; float w = ((white * (A * white + C * B) + D * E) / (white * ( A * white + B) + D * F)) - E / F; - gl_FragColor = vec4(c / w, 1.0); + c = c / w; + c = pow(c, vec3(1.0 / 2.2)); + gl_FragColor = vec4(c, 1.0); } diff --git a/Source/Shaders/PostProcessStages/ModifiedReinhardTonemapping.glsl b/Source/Shaders/PostProcessStages/ModifiedReinhardTonemapping.glsl index 42954e88d967..b520e34b30f3 100644 --- a/Source/Shaders/PostProcessStages/ModifiedReinhardTonemapping.glsl +++ b/Source/Shaders/PostProcessStages/ModifiedReinhardTonemapping.glsl @@ -3,9 +3,9 @@ uniform vec3 white; varying vec2 v_textureCoordinates; -#ifdef AUTO_EXPOSURE -uniform sampler2D autoExposure; -#endif +//#ifdef AUTO_EXPOSURE +//uniform sampler2D autoExposure; +//#endif // See equation 4: // http://www.cs.utah.edu/~reinhard/cdrom/tonemap.pdf @@ -13,9 +13,10 @@ uniform sampler2D autoExposure; void main() { vec3 color = texture2D(colorTexture, v_textureCoordinates).rgb; -#ifdef AUTO_EXPOSURE - color /= texture2D(autoExposure, vec2(0.5)).r; -#endif +//#ifdef AUTO_EXPOSURE +// color /= texture2D(autoExposure, vec2(0.5)).r; +//#endif color = (color * (1.0 + color / white)) / (1.0 + color); + color = pow(color, vec3(1.0 / 2.2)); gl_FragColor = vec4(color, 1.0); } diff --git a/Source/Shaders/PostProcessStages/ReinhardTonemapping.glsl b/Source/Shaders/PostProcessStages/ReinhardTonemapping.glsl index 72ffe0916a10..2cfc1d9a2d58 100644 --- a/Source/Shaders/PostProcessStages/ReinhardTonemapping.glsl +++ b/Source/Shaders/PostProcessStages/ReinhardTonemapping.glsl @@ -2,9 +2,9 @@ uniform sampler2D colorTexture; varying vec2 v_textureCoordinates; -#ifdef AUTO_EXPOSURE -uniform sampler2D autoExposure; -#endif +//#ifdef AUTO_EXPOSURE +//uniform sampler2D autoExposure; +//#endif // See equation 3: // http://www.cs.utah.edu/~reinhard/cdrom/tonemap.pdf @@ -12,9 +12,10 @@ uniform sampler2D autoExposure; void main() { vec3 color = texture2D(colorTexture, v_textureCoordinates).rgb; -#ifdef AUTO_EXPOSURE - color /= texture2D(autoExposure, vec2(0.5)).r; -#endif +//#ifdef AUTO_EXPOSURE +// color /= texture2D(autoExposure, vec2(0.5)).r; +//#endif color = color / (1.0 + color); + color = pow(color, vec3(1.0 / 2.2)); gl_FragColor = vec4(color, 1.0); } diff --git a/Source/Shaders/SkyBoxFS.glsl b/Source/Shaders/SkyBoxFS.glsl index 4a4e3b52c3bc..a34c6a7e61c8 100644 --- a/Source/Shaders/SkyBoxFS.glsl +++ b/Source/Shaders/SkyBoxFS.glsl @@ -5,5 +5,6 @@ varying vec3 v_texCoord; void main() { vec3 rgb = textureCube(u_cubeMap, normalize(v_texCoord)).rgb; + rgb = pow(rgb, vec3(2.2)); gl_FragColor = vec4(rgb, czm_morphTime); } From 3b1fc7e2cbe02cc462eaa1277d4ebc7427661c6d Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Fri, 6 Jul 2018 15:16:08 -0400 Subject: [PATCH 11/76] Auto exposure WIP. [ci skip] --- Source/Scene/AutoExposure.js | 101 ++++++++++++++++++++--------------- 1 file changed, 57 insertions(+), 44 deletions(-) diff --git a/Source/Scene/AutoExposure.js b/Source/Scene/AutoExposure.js index 3cfe7579baf4..b5d12ef39ae6 100644 --- a/Source/Scene/AutoExposure.js +++ b/Source/Scene/AutoExposure.js @@ -1,53 +1,23 @@ define([ - '../Core/BoundingRectangle', - '../Core/Check', '../Core/Color', - '../Core/combine', - '../Core/createGuid', '../Core/defaultValue', '../Core/defined', '../Core/defineProperties', '../Core/destroyObject', - '../Core/DeveloperError', - '../Core/Math', '../Core/PixelFormat', - '../Core/Resource', - '../Renderer/PassState', + '../Renderer/Framebuffer', '../Renderer/PixelDatatype', - '../Renderer/RenderState', - '../Renderer/Sampler', - '../Renderer/ShaderSource', - '../Renderer/Texture', - '../Renderer/TextureMagnificationFilter', - '../Renderer/TextureMinificationFilter', - '../Renderer/TextureWrap', - '../ThirdParty/when', - './PostProcessStageSampleMode' + '../Renderer/Texture' ], function( - BoundingRectangle, - Check, Color, - combine, - createGuid, defaultValue, defined, defineProperties, destroyObject, - DeveloperError, - CesiumMath, PixelFormat, - Resource, - PassState, + Framebuffer, PixelDatatype, - RenderState, - Sampler, - ShaderSource, - Texture, - TextureMagnificationFilter, - TextureMinificationFilter, - TextureWrap, - when, - PostProcessStageSampleMode) { + Texture) { 'use strict'; function AutoExposure(options) { @@ -144,25 +114,55 @@ define([ } function createUniformMap(autoexposure, index) { + var texture; if (index === 0) { - return { - colorTexture : function() { - return autoexposure._colorTexture; - } - }; + texture = autoexposure._colorTexture; + } else { + texture = autoexposure._framebuffers[index - 1].getColorTexture(0); } return { colorTexture : function() { - return autoexposure._framebuffers[index - 1].getColorTexture(0); + return texture; + }, + colorTextureDimensions : function() { + return texture.dimensions; } }; } - function getShaderSource(autoexposure, index) { - var framebuffers = autoexposure._framebuffers; + function getShaderSource(index) { + var source; if (index === 0) { - + source = + 'uniform sampler2D colorTexture; \n' + + 'varying vec2 v_textureCoordinates; \n' + + 'void main() { \n' + + ' vec4 color = texture2D(colorTexture, v_textureCoordinates); \n' + + ' gl_FragColor = max(color.r, max(color.g, color.b)); \n' + + '} \n'; + return source; } + + source = + 'uniform sampler2D colorTexture; \n' + + 'uniform vec2 colorTextureDimensions; \n' + + 'varying vec2 v_textureCoordinates; \n' + + 'void main() { \n' + + ' float color = 0.0; \n' + + ' float xStep = 1.0 /colorTextureDimensions.x; \n' + + ' float yStep = 1.0 /colorTextureDimensions.y; \n' + + ' color += texture2D(colorTexture, v_textureCoordinates + vec2(-xStep, yStep)).r; \n' + + ' color += texture2D(colorTexture, v_textureCoordinates + vec2(0.0, yStep)).r; \n' + + ' color += texture2D(colorTexture, v_textureCoordinates + vec2(xStep, yStep)).r; \n' + + ' color += texture2D(colorTexture, v_textureCoordinates + vec2(-xStep, 0.0)).r; \n' + + ' color += texture2D(colorTexture, v_textureCoordinates + vec2(0.0, 0.0)).r; \n' + + ' color += texture2D(colorTexture, v_textureCoordinates + vec2(xStep, 0.0)).r; \n' + + ' color += texture2D(colorTexture, v_textureCoordinates + vec2(-xStep, -yStep)).r; \n' + + ' color += texture2D(colorTexture, v_textureCoordinates + vec2(0.0, -yStep)).r; \n' + + ' color += texture2D(colorTexture, v_textureCoordinates + vec2(xStep, -yStep)).r; \n' + + ' gl_FragColor = vec4(color / 9.0); \n' + + '} \n'; + return source; } function createCommands(autoexposure, context) { @@ -175,7 +175,7 @@ define([ for (var i = 1; i < length; ++i) { commands[i] = context.createViewportQuadCommand(getShaderSource(i), { framebuffer : framebuffers[i], - uniformMap : createUniformMap(i) + uniformMap : createUniformMap(autoexposure, i) }); } } @@ -196,6 +196,17 @@ define([ }; AutoExposure.prototype.execute = function(context, colorTexture, depthTexture, idTexture) { + this._colorTexture = colorTexture; + + var commands = this._commands; + if (!defined(commands)) { + return; + } + + var length = commands.length; + for (var i = 0; i < length; ++i) { + commands[i].execute(context); + } }; AutoExposure.prototype.isDestroyed = function() { @@ -203,6 +214,8 @@ define([ }; AutoExposure.prototype.destroy = function() { + destroyFramebuffers(this); + destroyCommands(this); return destroyObject(this); }; From 7ebf78cfee05f329d7026e1a3243a25d2583c4e2 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Mon, 9 Jul 2018 16:41:52 -0400 Subject: [PATCH 12/76] Auto exposure WIP. [ci skip] --- Source/Scene/AutoExposure.js | 142 ++++++++++++------ Source/Scene/PostProcessStageCollection.js | 19 ++- Source/Scene/PostProcessStageLibrary.js | 14 +- .../ReinhardTonemapping.glsl | 13 +- 4 files changed, 128 insertions(+), 60 deletions(-) diff --git a/Source/Scene/AutoExposure.js b/Source/Scene/AutoExposure.js index b5d12ef39ae6..2cdead8fa2ba 100644 --- a/Source/Scene/AutoExposure.js +++ b/Source/Scene/AutoExposure.js @@ -7,7 +7,11 @@ define([ '../Core/PixelFormat', '../Renderer/Framebuffer', '../Renderer/PixelDatatype', - '../Renderer/Texture' + '../Renderer/Sampler', + '../Renderer/Texture', + '../Renderer/TextureMagnificationFilter', + '../Renderer/TextureMinificationFilter', + '../Renderer/TextureWrap' ], function( Color, defaultValue, @@ -17,11 +21,15 @@ define([ PixelFormat, Framebuffer, PixelDatatype, - Texture) { + Sampler, + Texture, + TextureMagnificationFilter, + TextureMinificationFilter, + TextureWrap) { 'use strict'; - function AutoExposure(options) { - this._clearColor = defaultValue(options.clearColor, Color.BLACK); + function AutoExposure() { + this._clearColor = new Color(0.0, 0.0, 0.0, 0.0); this._uniformMap = undefined; this._command = undefined; @@ -36,11 +44,14 @@ define([ this._logDepthChanged = undefined; this._useLogDepth = undefined; + this._framebuffers = undefined; + this._commands = undefined; + this.enabled = true; this._enabled = true; - this._framebuffers = undefined; - this._commands = undefined; + this.minimumLuminance = 0.1; + this.maximumLuminance = 10.0; } defineProperties(AutoExposure.prototype, { @@ -56,7 +67,11 @@ define([ }, outputTexture : { get : function() { - return undefined; + var framebuffers = this._framebuffers; + if (!defined(framebuffers)) { + return undefined; + } + return framebuffers[framebuffers.length - 1].getColorTexture(0); } } }); @@ -80,7 +95,7 @@ define([ var width = autoexposure._width; var height = autoexposure._height; - var length = Math.ceil(Math.max(width, height) / 3.0); + var length = Math.ceil(Math.log(Math.max(width, height)) / Math.log(3.0)); var framebuffers = new Array(length); for (var i = 0; i < length; ++i) { width = Math.max(Math.ceil(width / 3.0), 1.0); @@ -92,7 +107,13 @@ define([ width : width, height : height, pixelFormat : PixelFormat.RGBA, - pixelDatatype : PixelDatatype.FLOAT + pixelDatatype : PixelDatatype.FLOAT, + sampler : new Sampler({ + wrapS : TextureWrap.CLAMP_TO_EDGE, + wrapT : TextureWrap.CLAMP_TO_EDGE, + minificationFilter : TextureMinificationFilter.NEAREST, + magnificationFilter : TextureMagnificationFilter.NEAREST + }) })] }); } @@ -114,53 +135,81 @@ define([ } function createUniformMap(autoexposure, index) { - var texture; + var uniforms; if (index === 0) { - texture = autoexposure._colorTexture; + uniforms = { + colorTexture : function() { + return autoexposure._colorTexture; + }, + colorTextureDimensions : function() { + return autoexposure._colorTexture.dimensions; + } + }; } else { - texture = autoexposure._framebuffers[index - 1].getColorTexture(0); + var texture = autoexposure._framebuffers[index - 1].getColorTexture(0); + uniforms = { + colorTexture : function() { + return texture; + }, + colorTextureDimensions : function() { + return texture.dimensions; + } + }; } - return { - colorTexture : function() { - return texture; - }, - colorTextureDimensions : function() { - return texture.dimensions; - } + + uniforms.minimumLuminance = function() { + return autoexposure.minimumLuminance; + }; + uniforms.maximumLuminance = function() { + return autoexposure.maximumLuminance; }; + + return uniforms; } - function getShaderSource(index) { - var source; + function getShaderSource(index, length) { + var source = + 'uniform sampler2D colorTexture; \n' + + 'varying vec2 v_textureCoordinates; \n' + + 'float sampleTexture(vec2 offset) { \n'; + if (index === 0) { - source = - 'uniform sampler2D colorTexture; \n' + - 'varying vec2 v_textureCoordinates; \n' + - 'void main() { \n' + - ' vec4 color = texture2D(colorTexture, v_textureCoordinates); \n' + - ' gl_FragColor = max(color.r, max(color.g, color.b)); \n' + - '} \n'; - return source; + source += + ' vec4 color = texture2D(colorTexture, v_textureCoordinates + offset); \n' + + ' return max(color.r, max(color.g, color.b)); \n'; + } else { + source += + ' return texture2D(colorTexture, v_textureCoordinates + offset).r; \n'; } - source = - 'uniform sampler2D colorTexture; \n' + + source += '}\n\n'; + + source += 'uniform vec2 colorTextureDimensions; \n' + - 'varying vec2 v_textureCoordinates; \n' + + 'uniform float minimumLuminance; \n' + + 'uniform float maximumLuminance; \n' + 'void main() { \n' + ' float color = 0.0; \n' + ' float xStep = 1.0 /colorTextureDimensions.x; \n' + ' float yStep = 1.0 /colorTextureDimensions.y; \n' + - ' color += texture2D(colorTexture, v_textureCoordinates + vec2(-xStep, yStep)).r; \n' + - ' color += texture2D(colorTexture, v_textureCoordinates + vec2(0.0, yStep)).r; \n' + - ' color += texture2D(colorTexture, v_textureCoordinates + vec2(xStep, yStep)).r; \n' + - ' color += texture2D(colorTexture, v_textureCoordinates + vec2(-xStep, 0.0)).r; \n' + - ' color += texture2D(colorTexture, v_textureCoordinates + vec2(0.0, 0.0)).r; \n' + - ' color += texture2D(colorTexture, v_textureCoordinates + vec2(xStep, 0.0)).r; \n' + - ' color += texture2D(colorTexture, v_textureCoordinates + vec2(-xStep, -yStep)).r; \n' + - ' color += texture2D(colorTexture, v_textureCoordinates + vec2(0.0, -yStep)).r; \n' + - ' color += texture2D(colorTexture, v_textureCoordinates + vec2(xStep, -yStep)).r; \n' + - ' gl_FragColor = vec4(color / 9.0); \n' + + ' color += sampleTexture(vec2(-xStep, yStep)); \n' + + ' color += sampleTexture(vec2(0.0, yStep)); \n' + + ' color += sampleTexture(vec2(xStep, yStep)); \n' + + ' color += sampleTexture(vec2(-xStep, 0.0)); \n' + + ' color += sampleTexture(vec2(0.0, 0.0)); \n' + + ' color += sampleTexture(vec2(xStep, 0.0)); \n' + + ' color += sampleTexture(vec2(-xStep, -yStep)); \n' + + ' color += sampleTexture(vec2(0.0, -yStep)); \n' + + ' color += sampleTexture(vec2(xStep, -yStep)); \n' + + ' color /= 9.0; \n'; + + if (index === length - 1) { + source += + ' color = clamp(color, minimumLuminance, maximumLuminance); \n'; + } + + source += + ' gl_FragColor = vec4(color); \n' + '} \n'; return source; } @@ -172,12 +221,13 @@ define([ var commands = new Array(length); - for (var i = 1; i < length; ++i) { - commands[i] = context.createViewportQuadCommand(getShaderSource(i), { + for (var i = 0; i < length; ++i) { + commands[i] = context.createViewportQuadCommand(getShaderSource(i, length), { framebuffer : framebuffers[i], uniformMap : createUniformMap(autoexposure, i) }); } + autoexposure._commands = commands; } AutoExposure.prototype.update = function(context, useLogDepth) { @@ -193,6 +243,10 @@ define([ createFramebuffers(this, context); createCommands(this, context); + + if (!this._ready) { + this._ready = true; + } }; AutoExposure.prototype.execute = function(context, colorTexture, depthTexture, idTexture) { diff --git a/Source/Scene/PostProcessStageCollection.js b/Source/Scene/PostProcessStageCollection.js index ab2696b285fb..874480fa2a9a 100644 --- a/Source/Scene/PostProcessStageCollection.js +++ b/Source/Scene/PostProcessStageCollection.js @@ -63,9 +63,12 @@ define([ //var tonemapping = PostProcessStageLibrary.createFilmicTonemappingStage(true); //var tonemapping = PostProcessStageLibrary.createACESTonemappingStage(true); - //var autoexposure = PostProcessStageLibrary.createAutoExposureStage(); + var autoexposure = PostProcessStageLibrary.createAutoExposureStage(); //tonemapping.uniforms.autoExposure = autoexposure.name; + tonemapping.uniforms.autoExposure = function() { + return autoexposure.outputTexture; + }; ao.enabled = false; bloom.enabled = false; // TODO HDR @@ -106,7 +109,7 @@ define([ this._ao = ao; this._bloom = bloom; - //this._autoExposure = autoexposure; + this._autoExposure = autoexposure; this._tonemapping = tonemapping; this._fxaa = fxaa; @@ -531,7 +534,7 @@ define([ var ao = this._ao; var bloom = this._bloom; - //var autoexposure = this._autoExposure; + var autoexposure = this._autoExposure; var tonemapping = this._tonemapping; var fxaa = this._fxaa; @@ -594,7 +597,7 @@ define([ fxaa.update(context, useLogDepth); ao.update(context, useLogDepth); bloom.update(context, useLogDepth); - //autoexposure.update(context, useLogDepth); + autoexposure.update(context, useLogDepth); tonemapping.update(context, useLogDepth); length = stages.length; @@ -674,7 +677,7 @@ define([ var fxaa = this._fxaa; var ao = this._ao; var bloom = this._bloom; - //var autoexposure = this._autoExposure; + var autoexposure = this._autoExposure; var tonemapping = this._tonemapping; var aoEnabled = ao.enabled && ao._isSupported(context); @@ -696,9 +699,9 @@ define([ execute(bloom, context, initialTexture, depthTexture, idTexture); initialTexture = getOutputTexture(bloom); } - //if (autoexposureEnabled && autoexposure.ready) { - // execute(autoexposure, context, initialTexture, depthTexture, idTexture); - //} + if (/*autoexposureEnabled &&*/ autoexposure.ready) { + execute(autoexposure, context, initialTexture, depthTexture, idTexture); + } if (tonemappingEnabled && tonemapping.ready) { execute(tonemapping, context, initialTexture, depthTexture); initialTexture = getOutputTexture(tonemapping); diff --git a/Source/Scene/PostProcessStageLibrary.js b/Source/Scene/PostProcessStageLibrary.js index 7d12d335880e..52280742d21e 100644 --- a/Source/Scene/PostProcessStageLibrary.js +++ b/Source/Scene/PostProcessStageLibrary.js @@ -27,6 +27,7 @@ define([ '../shaders/PostProcessStages/ReinhardTonemapping', '../Shaders/PostProcessStages/Silhouette', '../ThirdParty/Shaders/FXAA3_11', + './AutoExposure', './PostProcessStage', './PostProcessStageComposite', './PostProcessStageSampleMode' @@ -59,6 +60,7 @@ define([ ReinhardTonemapping, Silhouette, FXAA3_11, + AutoExposure, PostProcessStage, PostProcessStageComposite, PostProcessStageSampleMode) { @@ -900,30 +902,35 @@ define([ }; PostProcessStageLibrary.createReinhardTonemappingStage = function(useAutoExposure) { - var autoExposure = PostProcessStageLibrary.createAutoExposureStage(); + //var autoExposure = PostProcessStageLibrary.createAutoExposureStage(); useAutoExposure = false; var fs = useAutoExposure ? '#define AUTO_EXPOSURE\n' : ''; fs += ReinhardTonemapping; + /* return new PostProcessStage({ name : 'czm_reinhard', fragmentShader : fs }); + */ var tonemapping = new PostProcessStage({ name : 'czm_reinhard', fragmentShader : fs, uniforms : { - autoExposure : autoExposure.name + autoExposure : undefined//autoExposure.name } }); + /* return new PostProcessStageComposite({ name : 'czm_tonemapping', stages : [autoExposure, tonemapping], inputPreviousStageTexture : false }); + */ + return tonemapping; }; PostProcessStageLibrary.createModifiedReinhardTonemappingStage = function(useAutoExposure) { @@ -940,6 +947,8 @@ define([ }; PostProcessStageLibrary.createAutoExposureStage = function() { + return new AutoExposure(); + /* var toLuminance = 'uniform sampler2D colorTexture; varying vec2 v_textureCoordinates; void main() { gl_FragColor = vec4(czm_luminance(texture2D(colorTexture, v_textureCoordinates).rgb)); }'; var luminance = new PostProcessStage({ fragmentShader : toLuminance, @@ -972,6 +981,7 @@ define([ name : 'czm_auto_exposure', stages : [luminance, downsample, downsample2, downsample3, downsample4] }); + */ }; /** diff --git a/Source/Shaders/PostProcessStages/ReinhardTonemapping.glsl b/Source/Shaders/PostProcessStages/ReinhardTonemapping.glsl index 2cfc1d9a2d58..6ae4b5e7937c 100644 --- a/Source/Shaders/PostProcessStages/ReinhardTonemapping.glsl +++ b/Source/Shaders/PostProcessStages/ReinhardTonemapping.glsl @@ -2,9 +2,9 @@ uniform sampler2D colorTexture; varying vec2 v_textureCoordinates; -//#ifdef AUTO_EXPOSURE -//uniform sampler2D autoExposure; -//#endif +#ifdef AUTO_EXPOSURE +uniform sampler2D autoExposure; +#endif // See equation 3: // http://www.cs.utah.edu/~reinhard/cdrom/tonemap.pdf @@ -12,9 +12,10 @@ varying vec2 v_textureCoordinates; void main() { vec3 color = texture2D(colorTexture, v_textureCoordinates).rgb; -//#ifdef AUTO_EXPOSURE -// color /= texture2D(autoExposure, vec2(0.5)).r; -//#endif +#ifdef AUTO_EXPOSURE + float exposure = texture2D(autoExposure, vec2(0.5)).r; + color /= exposure; +#endif color = color / (1.0 + color); color = pow(color, vec3(1.0 / 2.2)); gl_FragColor = vec4(color, 1.0); From 2ac1f3245b17e5705a9cfcd8bd393063fe5e5437 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Mon, 9 Jul 2018 19:35:40 -0400 Subject: [PATCH 13/76] Fix auto exposure flicker. [ci skip] --- Source/Scene/AutoExposure.js | 94 +++++++++++++++++----- Source/Scene/PostProcessStageCollection.js | 1 + 2 files changed, 73 insertions(+), 22 deletions(-) diff --git a/Source/Scene/AutoExposure.js b/Source/Scene/AutoExposure.js index 2cdead8fa2ba..35542ca9f6ae 100644 --- a/Source/Scene/AutoExposure.js +++ b/Source/Scene/AutoExposure.js @@ -5,6 +5,7 @@ define([ '../Core/defineProperties', '../Core/destroyObject', '../Core/PixelFormat', + '../Renderer/ClearCommand', '../Renderer/Framebuffer', '../Renderer/PixelDatatype', '../Renderer/Sampler', @@ -19,6 +20,7 @@ define([ defineProperties, destroyObject, PixelFormat, + ClearCommand, Framebuffer, PixelDatatype, Sampler, @@ -29,8 +31,6 @@ define([ 'use strict'; function AutoExposure() { - this._clearColor = new Color(0.0, 0.0, 0.0, 0.0); - this._uniformMap = undefined; this._command = undefined; @@ -45,12 +45,18 @@ define([ this._useLogDepth = undefined; this._framebuffers = undefined; + this._previousLuminance = undefined; + this._commands = undefined; + this._clearCommand = new ClearCommand({ + color : new Color(0.0, 0.0, 0.0, 0.0), + framebuffer : undefined + }); this.enabled = true; this._enabled = true; - this.minimumLuminance = 0.1; + this.minimumLuminance = 0.05; this.maximumLuminance = 10.0; } @@ -87,6 +93,9 @@ define([ framebuffers[i].destroy(); } autoexposure._framebuffers = undefined; + + autoexposure._previousLuminance.destroy(); + autoexposure._previousLuminance = undefined; } function createFramebuffers(autoexposure, context) { @@ -95,6 +104,15 @@ define([ var width = autoexposure._width; var height = autoexposure._height; + var pixelFormat = PixelFormat.RGBA; + var pixelDatatype = PixelDatatype.FLOAT; + var sampler = new Sampler({ + wrapS : TextureWrap.CLAMP_TO_EDGE, + wrapT : TextureWrap.CLAMP_TO_EDGE, + minificationFilter : TextureMinificationFilter.NEAREST, + magnificationFilter : TextureMagnificationFilter.NEAREST + }); + var length = Math.ceil(Math.log(Math.max(width, height)) / Math.log(3.0)); var framebuffers = new Array(length); for (var i = 0; i < length; ++i) { @@ -106,18 +124,26 @@ define([ context : context, width : width, height : height, - pixelFormat : PixelFormat.RGBA, - pixelDatatype : PixelDatatype.FLOAT, - sampler : new Sampler({ - wrapS : TextureWrap.CLAMP_TO_EDGE, - wrapT : TextureWrap.CLAMP_TO_EDGE, - minificationFilter : TextureMinificationFilter.NEAREST, - magnificationFilter : TextureMagnificationFilter.NEAREST - }) + pixelFormat : pixelFormat, + pixelDatatype : pixelDatatype, + sampler : sampler })] }); } + var lastTexture = framebuffers[length - 1].getColorTexture(0); + autoexposure._previousLuminance = new Framebuffer({ + context : context, + colorTextures : [new Texture({ + context : context, + width : lastTexture.width, + height : lastTexture.height, + pixelFormat : pixelFormat, + pixelDatatype : pixelDatatype, + sampler : sampler + })] + }); + autoexposure._framebuffers = framebuffers; } @@ -163,6 +189,9 @@ define([ uniforms.maximumLuminance = function() { return autoexposure.maximumLuminance; }; + uniforms.previousLuminance = function() { + return autoexposure._previousLuminance; + }; return uniforms; } @@ -176,7 +205,7 @@ define([ if (index === 0) { source += ' vec4 color = texture2D(colorTexture, v_textureCoordinates + offset); \n' + - ' return max(color.r, max(color.g, color.b)); \n'; + ' return czm_luminance(color.rgb); \n'; } else { source += ' return texture2D(colorTexture, v_textureCoordinates + offset).r; \n'; @@ -188,6 +217,7 @@ define([ 'uniform vec2 colorTextureDimensions; \n' + 'uniform float minimumLuminance; \n' + 'uniform float maximumLuminance; \n' + + 'uniform sampler2D previousLuminance; \n' + 'void main() { \n' + ' float color = 0.0; \n' + ' float xStep = 1.0 /colorTextureDimensions.x; \n' + @@ -205,6 +235,8 @@ define([ if (index === length - 1) { source += + ' float previous = texture2D(previousLuminance, vec2(0.5)).r; \n' + + ' color = previous + (color - previous) / (60.0 * 4.0); \n' + ' color = clamp(color, minimumLuminance, maximumLuminance); \n'; } @@ -230,23 +262,41 @@ define([ autoexposure._commands = commands; } + AutoExposure.prototype.clear = function(context) { + var framebuffers = this._framebuffers; + if (!defined(framebuffers)) { + return; + } + + var clearCommand = this._clearCommand; + var length = framebuffers.length; + for (var i = 0; i < length; ++i) { + clearCommand.framebuffer = framebuffers[i]; + clearCommand.execute(context); + } + }; + AutoExposure.prototype.update = function(context, useLogDepth) { var width = context.drawingBufferWidth; var height = context.drawingBufferHeight; - if (width === this._width || height === this._height) { - return; - } - - this._width = width; - this._height = height; + if (width !== this._width || height !== this._height) { + this._width = width; + this._height = height; - createFramebuffers(this, context); - createCommands(this, context); + createFramebuffers(this, context); + createCommands(this, context); - if (!this._ready) { - this._ready = true; + if (!this._ready) { + this._ready = true; + } } + + var framebuffers = this._framebuffers; + var temp = framebuffers[framebuffers.length - 1]; + framebuffers[framebuffers.length - 1] = this._previousLuminance; + this._commands[this._commands.length - 1].framebuffer = this._previousLuminance; + this._previousLuminance = temp; }; AutoExposure.prototype.execute = function(context, colorTexture, depthTexture, idTexture) { diff --git a/Source/Scene/PostProcessStageCollection.js b/Source/Scene/PostProcessStageCollection.js index 874480fa2a9a..0460d3ad82dd 100644 --- a/Source/Scene/PostProcessStageCollection.js +++ b/Source/Scene/PostProcessStageCollection.js @@ -615,6 +615,7 @@ define([ */ PostProcessStageCollection.prototype.clear = function(context) { this._textureCache.clear(context); + this._autoExposure.clear(context); }; function getOutputTexture(stage) { From 4386f78f20e0f15bdbe9829286a65baaee88e377 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Tue, 10 Jul 2018 16:33:27 -0400 Subject: [PATCH 14/76] Clean up. --- Source/Scene/AutoExposure.js | 2 +- Source/Scene/PostProcessStageCollection.js | 19 ++------ Source/Scene/PostProcessStageLibrary.js | 56 +--------------------- 3 files changed, 5 insertions(+), 72 deletions(-) diff --git a/Source/Scene/AutoExposure.js b/Source/Scene/AutoExposure.js index 35542ca9f6ae..05d8ced1ead6 100644 --- a/Source/Scene/AutoExposure.js +++ b/Source/Scene/AutoExposure.js @@ -56,7 +56,7 @@ define([ this.enabled = true; this._enabled = true; - this.minimumLuminance = 0.05; + this.minimumLuminance = 0.1; this.maximumLuminance = 10.0; } diff --git a/Source/Scene/PostProcessStageCollection.js b/Source/Scene/PostProcessStageCollection.js index 0460d3ad82dd..41aa79837b5b 100644 --- a/Source/Scene/PostProcessStageCollection.js +++ b/Source/Scene/PostProcessStageCollection.js @@ -65,7 +65,6 @@ define([ var autoexposure = PostProcessStageLibrary.createAutoExposureStage(); - //tonemapping.uniforms.autoExposure = autoexposure.name; tonemapping.uniforms.autoExposure = function() { return autoexposure.outputTexture; }; @@ -82,7 +81,7 @@ define([ var stageNames = {}; var stack = stackScratch; - stack.push(fxaa, ao, bloom, /*autoexposure,*/ tonemapping); + stack.push(fxaa, ao, bloom, tonemapping); while (stack.length > 0) { var stage = stack.pop(); stageNames[stage.name] = stage; @@ -116,7 +115,6 @@ define([ this._lastLength = undefined; this._aoEnabled = undefined; this._bloomEnabled = undefined; - //this._autoExposureEnabled = undefined; this._tonemappingEnabled = undefined; this._fxaaEnabled = undefined; @@ -148,13 +146,11 @@ define([ var fxaa = this._fxaa; var ao = this._ao; var bloom = this._bloom; - //var autoexposure = this._autoExposure; var tonemapping = this._tonemapping; readyAndEnabled = readyAndEnabled || (fxaa.ready && fxaa.enabled); readyAndEnabled = readyAndEnabled || (ao.ready && ao.enabled); readyAndEnabled = readyAndEnabled || (bloom.ready && bloom.enabled); - //readyAndEnabled = readyAndEnabled || (autoexposure.ready && autoexposure.enabled); readyAndEnabled = readyAndEnabled || (tonemapping.ready && tonemapping.enabled); return readyAndEnabled; @@ -297,11 +293,6 @@ define([ return this.getOutputTexture(tonemapping.name); } - //var autoexposure = this._autoExposure; - //if (autoexposure.enable && autoexposure.ready) { - // return this.getOutputTexture(autoexposure.name); - //} - var bloom = this._bloom; if (bloom.enabled && bloom.ready) { return this.getOutputTexture(bloom.name); @@ -538,16 +529,14 @@ define([ var tonemapping = this._tonemapping; var fxaa = this._fxaa; - //autoexposure.enabled = useHDR; tonemapping.enabled = useHDR; var aoEnabled = ao.enabled && ao._isSupported(context); var bloomEnabled = bloom.enabled && bloom._isSupported(context); - //var autoexposureEnabled = autoexposure.enabled && autoexposure._isSupported(context); var tonemappingEnabled = tonemapping.enabled && tonemapping._isSupported(context); var fxaaEnabled = fxaa.enabled && fxaa._isSupported(context); - if (activeStagesChanged || this._textureCacheDirty || count !== this._lastLength || aoEnabled !== this._aoEnabled || /*autoexposureEnabled !== this._autoExposureEnabled ||*/ + if (activeStagesChanged || this._textureCacheDirty || count !== this._lastLength || aoEnabled !== this._aoEnabled || bloomEnabled !== this._bloomEnabled || tonemappingEnabled !== this._tonemappingEnabled || fxaaEnabled !== this._fxaaEnabled) { // The number of stages to execute has changed. // Update dependencies and recreate framebuffers. @@ -556,7 +545,6 @@ define([ this._lastLength = count; this._aoEnabled = aoEnabled; this._bloomEnabled = bloomEnabled; - //this._autoExposureEnabled = autoexposureEnabled; this._tonemappingEnabled = tonemappingEnabled; this._fxaaEnabled = fxaaEnabled; this._textureCacheDirty = false; @@ -683,7 +671,6 @@ define([ var aoEnabled = ao.enabled && ao._isSupported(context); var bloomEnabled = bloom.enabled && bloom._isSupported(context); - //var autoexposureEnabled = autoexposure.enabled && autoexposure._isSupported(context); var tonemappingEnabled = tonemapping.enabled && tonemapping._isSupported(context); var fxaaEnabled = fxaa.enabled && fxaa._isSupported(context); @@ -780,7 +767,7 @@ define([ this._fxaa.destroy(); this._ao.destroy(); this._bloom.destroy(); - //this._autoExposure.destroy(); + this._autoExposure.destroy(); this._tonemapping.destroy(); this.removeAll(); this._textureCache = this._textureCache && this._textureCache.destroy(); diff --git a/Source/Scene/PostProcessStageLibrary.js b/Source/Scene/PostProcessStageLibrary.js index 52280742d21e..b5af130c418b 100644 --- a/Source/Scene/PostProcessStageLibrary.js +++ b/Source/Scene/PostProcessStageLibrary.js @@ -902,35 +902,15 @@ define([ }; PostProcessStageLibrary.createReinhardTonemappingStage = function(useAutoExposure) { - //var autoExposure = PostProcessStageLibrary.createAutoExposureStage(); - - useAutoExposure = false; - var fs = useAutoExposure ? '#define AUTO_EXPOSURE\n' : ''; fs += ReinhardTonemapping; - /* return new PostProcessStage({ - name : 'czm_reinhard', - fragmentShader : fs - }); - */ - - var tonemapping = new PostProcessStage({ name : 'czm_reinhard', fragmentShader : fs, uniforms : { - autoExposure : undefined//autoExposure.name + autoExposure : undefined } }); - - /* - return new PostProcessStageComposite({ - name : 'czm_tonemapping', - stages : [autoExposure, tonemapping], - inputPreviousStageTexture : false - }); - */ - return tonemapping; }; PostProcessStageLibrary.createModifiedReinhardTonemappingStage = function(useAutoExposure) { @@ -948,40 +928,6 @@ define([ PostProcessStageLibrary.createAutoExposureStage = function() { return new AutoExposure(); - /* - var toLuminance = 'uniform sampler2D colorTexture; varying vec2 v_textureCoordinates; void main() { gl_FragColor = vec4(czm_luminance(texture2D(colorTexture, v_textureCoordinates).rgb)); }'; - var luminance = new PostProcessStage({ - fragmentShader : toLuminance, - textureScale : 0.5, - pixelDatatype : PixelDatatype.FLOAT - }); - var passThrough = 'uniform sampler2D colorTexture; varying vec2 v_textureCoordinates; void main() { gl_FragColor = texture2D(colorTexture, v_textureCoordinates); }'; - var downsample = new PostProcessStage({ - fragmentShader : passThrough, - textureScale : 0.5, - pixelDatatype : PixelDatatype.FLOAT - }); - var downsample2 = new PostProcessStage({ - fragmentShader : passThrough, - textureScale : 0.25, - pixelDatatype : PixelDatatype.FLOAT - }); - var downsample3 = new PostProcessStage({ - fragmentShader : passThrough, - textureScale : 0.125, - pixelDatatype : PixelDatatype.FLOAT - }); - var downsample4 = new PostProcessStage({ - fragmentShader : passThrough, - textureScale : 0.0625, - pixelDatatype : PixelDatatype.FLOAT - }); - - return new PostProcessStageComposite({ - name : 'czm_auto_exposure', - stages : [luminance, downsample, downsample2, downsample3, downsample4] - }); - */ }; /** From 8cf28a6041c115c254a65c129a074036325a2718 Mon Sep 17 00:00:00 2001 From: ggetz Date: Tue, 10 Jul 2018 17:48:59 -0400 Subject: [PATCH 15/76] Modify tonemapping constants, globe, fog, and atmosphere --- Source/Scene/Fog.js | 2 +- Source/Shaders/Builtin/Functions/fog.glsl | 6 +++--- Source/Shaders/GlobeFS.glsl | 11 ++++++++--- .../Shaders/PostProcessStages/ACESTonemapping.glsl | 12 ++++++------ Source/Shaders/SkyAtmosphereFS.glsl | 2 +- 5 files changed, 19 insertions(+), 14 deletions(-) diff --git a/Source/Scene/Fog.js b/Source/Scene/Fog.js index e771a04a9a03..3607baa4822d 100644 --- a/Source/Scene/Fog.js +++ b/Source/Scene/Fog.js @@ -49,7 +49,7 @@ define([ * @type {Number} * @default 0.1 */ - this.minimumBrightness = 0.1; + this.minimumBrightness = 0.01; } // These values were found by sampling the density at certain views and finding at what point culled tiles impacted the view at the horizon. diff --git a/Source/Shaders/Builtin/Functions/fog.glsl b/Source/Shaders/Builtin/Functions/fog.glsl index c89553bc9c00..9bd3ad7c329e 100644 --- a/Source/Shaders/Builtin/Functions/fog.glsl +++ b/Source/Shaders/Builtin/Functions/fog.glsl @@ -1,9 +1,9 @@ /** * Gets the color with fog at a distance from the camera. - * + * * @name czm_fog * @glslFunction - * + * * @param {float} distanceToCamera The distance to the camera in meters. * @param {vec3} color The original color. * @param {vec3} fogColor The color of the fog. @@ -14,6 +14,6 @@ vec3 czm_fog(float distanceToCamera, vec3 color, vec3 fogColor) { float scalar = distanceToCamera * czm_fogDensity; float fog = 1.0 - exp(-(scalar * scalar)); - + return mix(color, fogColor, fog); } diff --git a/Source/Shaders/GlobeFS.glsl b/Source/Shaders/GlobeFS.glsl index 690d873bc7c4..359189c6be86 100644 --- a/Source/Shaders/GlobeFS.glsl +++ b/Source/Shaders/GlobeFS.glsl @@ -238,7 +238,7 @@ void main() #endif #ifdef FOG - const float fExposure = 2.0; + const float fExposure = 1.3; vec3 fogColor = v_mieColor + finalColor.rgb * v_rayleighColor; fogColor = vec3(1.0) - exp(-fExposure * fogColor); @@ -337,9 +337,14 @@ vec4 computeWaterColor(vec3 positionEyeCoordinates, vec2 textureCoordinates, mat // Add specular highlights in 3D, and in all modes when zoomed in. float specularIntensity = czm_getSpecular(czm_sunDirectionEC, normalizedpositionToEyeEC, normalEC, 10.0) + 0.25 * czm_getSpecular(czm_moonDirectionEC, normalizedpositionToEyeEC, normalEC, 10.0); float surfaceReflectance = mix(0.0, mix(u_zoomedOutOceanSpecularIntensity, oceanSpecularIntensity, waveIntensity), maskValue); - float specular = specularIntensity * surfaceReflectance; + float specular = specularIntensity * surfaceReflectance * 1.4; - return vec4(imageryColor.rgb + diffuseHighlight + nonDiffuseHighlight + specular, imageryColor.a); + float e = 0.2; + float d = 3.3; + float c = 1.7; + + return vec4(imageryColor.rgb + (c * (vec3(e) + imageryColor.rgb * d) * (diffuseHighlight + nonDiffuseHighlight + specular)), imageryColor.a); + //return vec4(imageryColor.rgb + diffuseHighlight + nonDiffuseHighlight + specular, imageryColor.a); } #endif // #ifdef SHOW_REFLECTIVE_OCEAN diff --git a/Source/Shaders/PostProcessStages/ACESTonemapping.glsl b/Source/Shaders/PostProcessStages/ACESTonemapping.glsl index 5e9c611cdeab..81798a833ce3 100644 --- a/Source/Shaders/PostProcessStages/ACESTonemapping.glsl +++ b/Source/Shaders/PostProcessStages/ACESTonemapping.glsl @@ -14,13 +14,13 @@ void main() // color /= texture2D(autoExposure, vec2(0.5)).r; //#endif - float a = 2.51; - float b = 0.03; - float c = 2.43; - float d = 0.59; - float e = 0.14; + float a = 2.61; + float b = 0.08; + float c = 2.49; + float d = 0.63; + float e = 0.01; color = (color * (a * color + b)) / (color * (c * color + d) + e); color = clamp(color, 0.0, 1.0); - color = pow(color, vec3(1.0 / 2.2)); + color = pow(color, vec3(1.0 / 1.22)); gl_FragColor = vec4(color, 1.0); } diff --git a/Source/Shaders/SkyAtmosphereFS.glsl b/Source/Shaders/SkyAtmosphereFS.glsl index 8ae88f76b69e..64374654c0ac 100644 --- a/Source/Shaders/SkyAtmosphereFS.glsl +++ b/Source/Shaders/SkyAtmosphereFS.glsl @@ -60,7 +60,7 @@ void main (void) vec3 rgb = rayleighPhase * v_rayleighColor + miePhase * v_mieColor; #ifndef HDR - const float exposure = 2.0; + const float exposure = 1.1; rgb = vec3(1.0) - exp(-exposure * rgb); #endif From 8aee74a168c6aa476b01c27d62f6979ed45e64d4 Mon Sep 17 00:00:00 2001 From: ggetz Date: Fri, 13 Jul 2018 10:53:47 -0400 Subject: [PATCH 16/76] Tweak fog appearance" --- Source/Scene/PostProcessStageCollection.js | 4 ++-- Source/Shaders/Builtin/Functions/fog.glsl | 21 +++++++++++++++++++ Source/Shaders/GlobeFS.glsl | 7 +++++-- .../PostProcessStages/ACESTonemapping.glsl | 2 +- Source/Shaders/SkyAtmosphereFS.glsl | 2 +- 5 files changed, 30 insertions(+), 6 deletions(-) diff --git a/Source/Scene/PostProcessStageCollection.js b/Source/Scene/PostProcessStageCollection.js index 41aa79837b5b..f059300f5ea4 100644 --- a/Source/Scene/PostProcessStageCollection.js +++ b/Source/Scene/PostProcessStageCollection.js @@ -58,10 +58,10 @@ define([ var fxaa = PostProcessStageLibrary.createFXAAStage(); var ao = PostProcessStageLibrary.createAmbientOcclusionStage(); var bloom = PostProcessStageLibrary.createBloomStage(); - var tonemapping = PostProcessStageLibrary.createReinhardTonemappingStage(true); + //var tonemapping = PostProcessStageLibrary.createReinhardTonemappingStage(true); //var tonemapping = PostProcessStageLibrary.createModifiedReinhardTonemappingStage(true); //var tonemapping = PostProcessStageLibrary.createFilmicTonemappingStage(true); - //var tonemapping = PostProcessStageLibrary.createACESTonemappingStage(true); + var tonemapping = PostProcessStageLibrary.createACESTonemappingStage(true); var autoexposure = PostProcessStageLibrary.createAutoExposureStage(); diff --git a/Source/Shaders/Builtin/Functions/fog.glsl b/Source/Shaders/Builtin/Functions/fog.glsl index 9bd3ad7c329e..f9dcf2f6643e 100644 --- a/Source/Shaders/Builtin/Functions/fog.glsl +++ b/Source/Shaders/Builtin/Functions/fog.glsl @@ -17,3 +17,24 @@ vec3 czm_fog(float distanceToCamera, vec3 color, vec3 fogColor) return mix(color, fogColor, fog); } + +/** + * Gets the color with fog at a distance from the camera. + * + * @name czm_fog + * @glslFunction + * + * @param {float} distanceToCamera The distance to the camera in meters. + * @param {vec3} color The original color. + * @param {vec3} fogColor The color of the fog. + * @param {float} fogModifierConstant A constant to modify the appearance of fog. + * + * @returns {vec3} The color adjusted for fog at the distance from the camera. + */ +vec3 czm_fog(float distanceToCamera, vec3 color, vec3 fogColor, float fogModifierConstant) +{ + float scalar = distanceToCamera * czm_fogDensity; + float fog = 1.0 - exp(-((fogModifierConstant * scalar + fogModifierConstant) * (scalar * (1.0 + fogModifierConstant)))); + + return mix(color, fogColor, fog); +} diff --git a/Source/Shaders/GlobeFS.glsl b/Source/Shaders/GlobeFS.glsl index 359189c6be86..e627fbacb75a 100644 --- a/Source/Shaders/GlobeFS.glsl +++ b/Source/Shaders/GlobeFS.glsl @@ -240,14 +240,17 @@ void main() #ifdef FOG const float fExposure = 1.3; vec3 fogColor = v_mieColor + finalColor.rgb * v_rayleighColor; - fogColor = vec3(1.0) - exp(-fExposure * fogColor); + // TODO: disable exposure if using HDR + //fogColor = vec3(1.0) - exp(-fExposure * fogColor); #if defined(ENABLE_VERTEX_LIGHTING) || defined(ENABLE_DAYNIGHT_SHADING) float darken = clamp(dot(normalize(czm_viewerPositionWC), normalize(czm_sunPositionWC)), u_minimumBrightness, 1.0); fogColor *= darken; #endif - gl_FragColor = vec4(czm_fog(v_distance, finalColor.rgb, fogColor), finalColor.a); + // TODO: Only use modified fog function if HDR + const float modifier = 0.15; + gl_FragColor = vec4(czm_fog(v_distance, finalColor.rgb, fogColor, modifier), finalColor.a); #else gl_FragColor = finalColor; #endif diff --git a/Source/Shaders/PostProcessStages/ACESTonemapping.glsl b/Source/Shaders/PostProcessStages/ACESTonemapping.glsl index 81798a833ce3..11342d3baec5 100644 --- a/Source/Shaders/PostProcessStages/ACESTonemapping.glsl +++ b/Source/Shaders/PostProcessStages/ACESTonemapping.glsl @@ -21,6 +21,6 @@ void main() float e = 0.01; color = (color * (a * color + b)) / (color * (c * color + d) + e); color = clamp(color, 0.0, 1.0); - color = pow(color, vec3(1.0 / 1.22)); + color = pow(color, vec3(1.0 / 1.52)); gl_FragColor = vec4(color, 1.0); } diff --git a/Source/Shaders/SkyAtmosphereFS.glsl b/Source/Shaders/SkyAtmosphereFS.glsl index 64374654c0ac..5f6ffb2864c0 100644 --- a/Source/Shaders/SkyAtmosphereFS.glsl +++ b/Source/Shaders/SkyAtmosphereFS.glsl @@ -61,7 +61,7 @@ void main (void) #ifndef HDR const float exposure = 1.1; - rgb = vec3(1.0) - exp(-exposure * rgb); + //rgb = vec3(1.0) - exp(-exposure * rgb); #endif #ifdef COLOR_CORRECT From c5124fe5192dd4ff0763769c1c26a288f389a576 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Fri, 13 Jul 2018 15:33:18 -0400 Subject: [PATCH 17/76] Fix auto exposure decimation. --- Source/Scene/AutoExposure.js | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/Source/Scene/AutoExposure.js b/Source/Scene/AutoExposure.js index 05d8ced1ead6..1097f2539baa 100644 --- a/Source/Scene/AutoExposure.js +++ b/Source/Scene/AutoExposure.js @@ -222,21 +222,27 @@ define([ ' float color = 0.0; \n' + ' float xStep = 1.0 /colorTextureDimensions.x; \n' + ' float yStep = 1.0 /colorTextureDimensions.y; \n' + - ' color += sampleTexture(vec2(-xStep, yStep)); \n' + - ' color += sampleTexture(vec2(0.0, yStep)); \n' + - ' color += sampleTexture(vec2(xStep, yStep)); \n' + - ' color += sampleTexture(vec2(-xStep, 0.0)); \n' + - ' color += sampleTexture(vec2(0.0, 0.0)); \n' + - ' color += sampleTexture(vec2(xStep, 0.0)); \n' + - ' color += sampleTexture(vec2(-xStep, -yStep)); \n' + - ' color += sampleTexture(vec2(0.0, -yStep)); \n' + - ' color += sampleTexture(vec2(xStep, -yStep)); \n' + - ' color /= 9.0; \n'; + ' int count = 0; \n' + + ' for (int i = 0; i < 3; ++i) { \n' + + ' for (int j = 0; j < 3; ++j) { \n' + + ' vec2 offset; \n' + + ' offset.x = -xStep + float(i) * xStep; \n' + + ' offset.y = -yStep + float(j) * yStep; \n' + + ' if (offset.x < 0.0 || offset.x > 1.0 || offset.y < 0.0 || offset.y > 1.0) { \n' + + ' continue; \n' + + ' } \n' + + ' color += sampleTexture(offset); \n' + + ' ++count; \n' + + ' } \n' + + ' } \n' + + ' if (count > 0) { \n' + + ' color /= float(count); \n' + + ' } \n'; if (index === length - 1) { source += - ' float previous = texture2D(previousLuminance, vec2(0.5)).r; \n' + - ' color = previous + (color - previous) / (60.0 * 4.0); \n' + + //' float previous = texture2D(previousLuminance, vec2(0.5)).r; \n' + + //' color = previous + (color - previous) / (60.0 * 3.0); \n' + ' color = clamp(color, minimumLuminance, maximumLuminance); \n'; } From bf2985629fb48fa619e54c151e8fa66ece994221 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Fri, 13 Jul 2018 15:44:40 -0400 Subject: [PATCH 18/76] Fix blend with previous frame luminance. --- Source/Scene/AutoExposure.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Source/Scene/AutoExposure.js b/Source/Scene/AutoExposure.js index 1097f2539baa..03950ac303b0 100644 --- a/Source/Scene/AutoExposure.js +++ b/Source/Scene/AutoExposure.js @@ -190,7 +190,7 @@ define([ return autoexposure.maximumLuminance; }; uniforms.previousLuminance = function() { - return autoexposure._previousLuminance; + return autoexposure._previousLuminance.getColorTexture(0); }; return uniforms; @@ -241,8 +241,9 @@ define([ if (index === length - 1) { source += - //' float previous = texture2D(previousLuminance, vec2(0.5)).r; \n' + - //' color = previous + (color - previous) / (60.0 * 3.0); \n' + + ' float previous = texture2D(previousLuminance, vec2(0.5)).r; \n' + + ' color = clamp(color, minimumLuminance, maximumLuminance); \n' + + ' color = previous + (color - previous) / (60.0 * 3.0); \n' + ' color = clamp(color, minimumLuminance, maximumLuminance); \n'; } From 5992e844a2924badf1e9649e9e2e53b00c26672f Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Fri, 13 Jul 2018 16:48:37 -0400 Subject: [PATCH 19/76] Bloom WIP. [ci skip] --- Source/Scene/PostProcessStageLibrary.js | 230 ++---------------------- 1 file changed, 13 insertions(+), 217 deletions(-) diff --git a/Source/Scene/PostProcessStageLibrary.js b/Source/Scene/PostProcessStageLibrary.js index b5af130c418b..4d2e45e823f4 100644 --- a/Source/Scene/PostProcessStageLibrary.js +++ b/Source/Scene/PostProcessStageLibrary.js @@ -73,7 +73,7 @@ define([ */ var PostProcessStageLibrary = {}; - function createBlur(name, pixelDatatype, forcePowerOfTwo, textureScale) { + function createBlur(name, pixelDatatype, textureScale) { var delta = 1.0; var sigma = 2.0; var stepSize = 1.0; @@ -90,7 +90,6 @@ define([ }, sampleMode : PostProcessStageSampleMode.LINEAR, pixelDatatype : pixelDatatype, - forcePowerOfTwo : forcePowerOfTwo, textureScale : textureScale }); var blurY = new PostProcessStage({ @@ -104,7 +103,6 @@ define([ }, sampleMode : PostProcessStageSampleMode.LINEAR, pixelDatatype : pixelDatatype, - forcePowerOfTwo : forcePowerOfTwo, textureScale : textureScale }); @@ -431,168 +429,8 @@ define([ * * @private */ - // TODO HDR - /* PostProcessStageLibrary.createBloomStage = function() { - var contrastBias = new PostProcessStage({ - name : 'czm_bloom_contrast_bias', - fragmentShader : ContrastBias, - uniforms : { - contrast : 128.0, - brightness : -0.3 - } - }); - var blur = createBlur('czm_bloom_blur'); - var generateComposite = new PostProcessStageComposite({ - name : 'czm_bloom_contrast_bias_blur', - stages : [contrastBias, blur] - }); - - var bloomComposite = new PostProcessStage({ - name : 'czm_bloom_generate_composite', - fragmentShader : BloomComposite, - uniforms : { - glowOnly : false, - bloomTexture : generateComposite.name - } - }); - - var uniforms = {}; - defineProperties(uniforms, { - glowOnly : { - get : function() { - return bloomComposite.uniforms.glowOnly; - }, - set : function(value) { - bloomComposite.uniforms.glowOnly = value; - } - }, - contrast : { - get : function() { - return contrastBias.uniforms.contrast; - }, - set : function(value) { - contrastBias.uniforms.contrast = value; - } - }, - brightness : { - get : function() { - return contrastBias.uniforms.brightness; - }, - set : function(value) { - contrastBias.uniforms.brightness = value; - } - }, - delta : { - get : function() { - return blur.uniforms.delta; - }, - set : function(value) { - blur.uniforms.delta = value; - } - }, - sigma : { - get : function() { - return blur.uniforms.sigma; - }, - set : function(value) { - blur.uniforms.sigma = value; - } - }, - stepSize : { - get : function() { - return blur.uniforms.stepSize; - }, - set : function(value) { - blur.uniforms.stepSize = value; - } - } - }); - - return new PostProcessStageComposite({ - name : 'czm_bloom', - stages : [generateComposite, bloomComposite], - inputPreviousStageTexture : false, - uniforms : uniforms - }); - }; - */ - - PostProcessStageLibrary.createBloomStage = function() { - var scale = 0.75; - - var toLuminance = 'uniform sampler2D colorTexture; varying vec2 v_textureCoordinates; void main() { gl_FragColor = vec4(czm_luminance(texture2D(colorTexture, v_textureCoordinates).rgb)); }'; - var luminance = new PostProcessStage({ - fragmentShader : toLuminance, - textureScale : 0.5, - pixelDatatype : PixelDatatype.FLOAT - }); - var passThrough = 'uniform sampler2D colorTexture; varying vec2 v_textureCoordinates; void main() { gl_FragColor = texture2D(colorTexture, v_textureCoordinates); }'; - var downsample = new PostProcessStage({ - fragmentShader : passThrough, - textureScale : 0.5, - pixelDatatype : PixelDatatype.FLOAT - }); - var downsample2 = new PostProcessStage({ - fragmentShader : passThrough, - textureScale : 0.25, - pixelDatatype : PixelDatatype.FLOAT - }); - var downsample3 = new PostProcessStage({ - fragmentShader : passThrough, - textureScale : 0.125, - pixelDatatype : PixelDatatype.FLOAT - }); - var downsample4 = new PostProcessStage({ - fragmentShader : passThrough, - textureScale : 0.0625, - pixelDatatype : PixelDatatype.FLOAT - }); - - var avgLuminance = new PostProcessStageComposite({ - stages : [luminance, downsample, downsample2, downsample3, downsample4] - }); - - var brightPassFS = - 'uniform sampler2D colorTexture; \n' + - 'uniform sampler2D luminanceTexture; \n' + - 'uniform float threshold; \n' + - 'uniform float offset; \n' + - 'varying vec2 v_textureCoordinates; \n' + - 'float key(float avg) { \n' + - ' float guess = 1.5 - (1.5 / (avg * 0.1 + 1.0)); \n' + - ' return max(0.0, guess) + 0.1; \n' + - '} \n' + - 'void main() { \n' + - ' vec4 color = texture2D(colorTexture, v_textureCoordinates); \n' + - //' float avgLuminance = texture2D(luminanceTexture, vec2(0.5)).r; \n' + - ' float avgLuminance = 1.5; \n' + - ' vec3 Yxy = czm_RGBToXYZ(color.rgb); \n' + - ' float luminance = Yxy.r; \n' + - ' float scaledLum = key(avgLuminance) * luminance / avgLuminance; \n' + - ' float brightLum = max(scaledLum - threshold, 0.0); \n' + - ' float brightness = brightLum / (offset + brightLum); \n' + - ' Yxy.r = brightness; \n' + - ' gl_FragColor = vec4(czm_XYZToRGB(Yxy), 1.0); \n' + - '} \n'; - - var brightPass = new PostProcessStage({ - fragmentShader : brightPassFS, - uniforms : { - luminanceTexture : avgLuminance.name, - threshold : 0.25, - offset : 0.1 - }, - pixelDatatype : PixelDatatype.FLOAT, - textureScale : scale - }); - - var brightPassComposite = new PostProcessStageComposite({ - stages : [avgLuminance, brightPass], - inputPreviousStageTexture : false - }); - - /* + var scale = 1.0; var brightFS = 'uniform sampler2D colorTexture; \n' + 'varying vec2 v_textureCoordinates; \n' + @@ -604,65 +442,23 @@ define([ ' gl_FragColor = vec4(vec3(0.0), 1.0); \n' + ' } \n' + '} \n'; - var scale = 0.75; var brightPass = new PostProcessStage({ fragmentShader : brightFS, pixelDatatype : PixelDatatype.FLOAT, - textureScale : scale - }); - */ - - var blurFS = - 'uniform sampler2D colorTexture; \n' + - 'uniform vec2 colorTextureDimensions; \n' + - 'uniform bool horizontal; \n' + - 'varying vec2 v_textureCoordinates; \n' + - 'void main() { \n' + - 'float weights[5]; \n' + - 'weights[0] = 0.227027; \n' + - 'weights[1] = 0.1945946; \n' + - 'weights[2] = 0.1216216; \n' + - 'weights[3] = 0.054054; \n' + - 'weights[4] = 0.016216; \n' + - ' vec2 offset = 1.0 / colorTextureDimensions; \n' + - ' vec3 result = texture2D(colorTexture, v_textureCoordinates).rgb * weights[0]; \n' + - ' if(horizontal) { \n' + - ' for(int i = 1; i < 5; ++i) { \n' + - ' result += texture2D(colorTexture, v_textureCoordinates + vec2(offset.x * float(i), 0.0)).rgb * weights[i]; \n' + - ' result += texture2D(colorTexture, v_textureCoordinates - vec2(offset.x * float(i), 0.0)).rgb * weights[i]; \n' + - ' } \n' + - ' } else { \n' + - ' for(int i = 1; i < 5; ++i) { \n' + - ' result += texture2D(colorTexture, v_textureCoordinates + vec2(0.0, offset.y * float(i))).rgb * weights[i]; \n' + - ' result += texture2D(colorTexture, v_textureCoordinates - vec2(0.0, offset.y * float(i))).rgb * weights[i]; \n' + - ' } \n' + - ' } \n' + - ' gl_FragColor = vec4(result, 1.0); \n' + - '} \n'; - var blurX = new PostProcessStage({ - fragmentShader : blurFS, - uniforms : { - horizontal : true - }, - pixelDatatype : PixelDatatype.FLOAT, - textureScale : scale - }); - var blurY = new PostProcessStage({ - fragmentShader : blurFS, - uniforms : { - horizontal : false - }, - pixelDatatype : PixelDatatype.FLOAT, - textureScale : scale - }); - var blur = new PostProcessStageComposite({ - stages : [blurX, blurY] + textureScale : scale, + sampleMode : PostProcessStageSampleMode.LINEAR }); - //var blur = createBlur('czm_bloom_blur0', PixelDatatype.FLOAT, powerOfTwo, scale); + var numBlur = 6; + var blurs = new Array(numBlur); + for (var i = 0; i < numBlur; ++i) { + blurs[i] = createBlur('czm_bloom_blur_' + i, PixelDatatype.FLOAT, scale); + blurs[i].uniforms.delta = 1.5; + blurs[i].uniforms.sigma = 5.0; + } var brightBlur = new PostProcessStageComposite({ name : 'czm_brightness_blur', - //stages : [brightPass, blur] - stages : [brightPassComposite, blur] + stages : [brightPass].concat(blurs), + textureScale : scale }); var addFS = From 8c14a73d543d7be73ea7e6ea9301254ee6c442ee Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 18 Jul 2018 16:17:12 -0400 Subject: [PATCH 20/76] Correct gamma correction for glTF 2.0 models, billboards, and materials given by components. Hack for glTF 1.0 models. --- Source/Scene/Material.js | 6 +++- Source/Scene/Model.js | 33 +++++++++++++++++-- Source/Scene/PostProcessStageCollection.js | 18 ++++++---- Source/Shaders/BillboardCollectionFS.glsl | 4 ++- .../PostProcessStages/ACESTonemapping.glsl | 12 +++---- .../PostProcessStages/FilmicTonemapping.glsl | 13 ++++---- .../ModifiedReinhardTonemapping.glsl | 13 ++++---- .../processPbrMetallicRoughness.js | 10 +++--- 8 files changed, 73 insertions(+), 36 deletions(-) diff --git a/Source/Scene/Material.js b/Source/Scene/Material.js index ad3be5466c36..29aeebd42a27 100644 --- a/Source/Scene/Material.js +++ b/Source/Scene/Material.js @@ -695,7 +695,11 @@ define([ if (defined(components)) { for ( var component in components) { if (components.hasOwnProperty(component)) { - material.shaderSource += 'material.' + component + ' = ' + components[component] + ';\n'; + if (component === 'diffuse' || component === 'emission') { + material.shaderSource += 'material.' + component + ' = pow(' + components[component] + ', vec3(2.2)); \n'; + } else { + material.shaderSource += 'material.' + component + ' = ' + components[component] + ';\n'; + } } } } diff --git a/Source/Scene/Model.js b/Source/Scene/Model.js index bcb23f30f26d..3f8b8db32315 100644 --- a/Source/Scene/Model.js +++ b/Source/Scene/Model.js @@ -650,6 +650,8 @@ define([ this._sourceShaders = undefined; this._quantizedVertexShaders = {}; + this._upgrade10To20 = undefined; + this._nodeCommands = []; this._pickIds = []; @@ -2037,6 +2039,17 @@ define([ drawFS = 'uniform vec4 czm_pickColor;\n' + drawFS; } + if (model._upgrade10To20) { + drawFS = ShaderSource.replaceMain(drawFS, 'non_gamma_corrected_main'); + drawFS = + drawFS + + '\n' + + 'void main() { \n' + + ' non_gamma_corrected_main(); \n' + + ' gl_FragColor.rgb = pow(gl_FragColor.rgb, vec3(2.2)); \n' + + '} \n'; + } + createAttributesAndProgram(id, drawFS, drawVS, model, context); } @@ -2076,6 +2089,17 @@ define([ drawFS = 'uniform vec4 czm_pickColor;\n' + drawFS; } + if (model._upgrade10To20) { + drawFS = ShaderSource.replaceMain(drawFS, 'non_gamma_corrected_main'); + drawFS = + drawFS + + '\n' + + 'void main() { \n' + + ' non_gamma_corrected_main(); \n' + + ' gl_FragColor.rgb = pow(gl_FragColor.rgb, vec3(2.2)); \n' + + '} \n'; + } + createAttributesAndProgram(id, drawFS, drawVS, model, context); } @@ -4176,6 +4200,10 @@ define([ this._defaultTexture = context.defaultTexture; if ((this._state === ModelState.NEEDS_LOAD) && defined(this.gltf)) { + if (!defined(this._upgrade10To20)) { + this._upgrade10To20 = defined(this.gltf.asset) && defined(this.gltf.asset.extras) && this.gltf.asset.extras.gltf_pipeline_upgrade_10to20; + } + // Use renderer resources from cache instead of loading/creating them? var cachedRendererResources; var cacheKey = this.cacheKey; @@ -4249,9 +4277,8 @@ define([ }; frameState.brdfLutGenerator.update(frameState); updateVersion(this.gltf); - if (defined(this.gltf.asset) && defined(this.gltf.asset.extras) && - this.gltf.asset.extras.gltf_pipeline_upgrade_10to20) { - this._forwardAxis = Axis.X; + if (this._upgrade10To20) { + this._forwardAxis = Axis.X; } ModelUtility.checkSupportedExtensions(this.extensionsRequired); addPipelineExtras(this.gltf); diff --git a/Source/Scene/PostProcessStageCollection.js b/Source/Scene/PostProcessStageCollection.js index f059300f5ea4..c62a1c7e3279 100644 --- a/Source/Scene/PostProcessStageCollection.js +++ b/Source/Scene/PostProcessStageCollection.js @@ -58,16 +58,20 @@ define([ var fxaa = PostProcessStageLibrary.createFXAAStage(); var ao = PostProcessStageLibrary.createAmbientOcclusionStage(); var bloom = PostProcessStageLibrary.createBloomStage(); - //var tonemapping = PostProcessStageLibrary.createReinhardTonemappingStage(true); - //var tonemapping = PostProcessStageLibrary.createModifiedReinhardTonemappingStage(true); - //var tonemapping = PostProcessStageLibrary.createFilmicTonemappingStage(true); - var tonemapping = PostProcessStageLibrary.createACESTonemappingStage(true); + + var useAutoExposure = false; + var tonemapping = PostProcessStageLibrary.createReinhardTonemappingStage(useAutoExposure); + //var tonemapping = PostProcessStageLibrary.createModifiedReinhardTonemappingStage(useAutoExposure); + //var tonemapping = PostProcessStageLibrary.createFilmicTonemappingStage(useAutoExposure); + //var tonemapping = PostProcessStageLibrary.createACESTonemappingStage(useAutoExposure); var autoexposure = PostProcessStageLibrary.createAutoExposureStage(); - tonemapping.uniforms.autoExposure = function() { - return autoexposure.outputTexture; - }; + if (useAutoExposure) { + tonemapping.uniforms.autoExposure = function() { + return autoexposure.outputTexture; + }; + } ao.enabled = false; bloom.enabled = false; // TODO HDR diff --git a/Source/Shaders/BillboardCollectionFS.glsl b/Source/Shaders/BillboardCollectionFS.glsl index 853a448d94a9..01d0055a1e2b 100644 --- a/Source/Shaders/BillboardCollectionFS.glsl +++ b/Source/Shaders/BillboardCollectionFS.glsl @@ -48,7 +48,9 @@ float getGlobeDepth(vec2 adjustedST, vec2 depthLookupST) void main() { - vec4 color = texture2D(u_atlas, v_textureCoordinates) * v_color; + vec4 color = texture2D(u_atlas, v_textureCoordinates); + color.rgb = pow(color.rgb, vec3(2.2)); + color *= v_color; // Fully transparent parts of the billboard are not pickable. #if !defined(OPAQUE) && !defined(TRANSLUCENT) diff --git a/Source/Shaders/PostProcessStages/ACESTonemapping.glsl b/Source/Shaders/PostProcessStages/ACESTonemapping.glsl index 11342d3baec5..c9ba07221ab7 100644 --- a/Source/Shaders/PostProcessStages/ACESTonemapping.glsl +++ b/Source/Shaders/PostProcessStages/ACESTonemapping.glsl @@ -2,17 +2,17 @@ uniform sampler2D colorTexture; varying vec2 v_textureCoordinates; -//#ifdef AUTO_EXPOSURE -//uniform sampler2D autoExposure; -//#endif +#ifdef AUTO_EXPOSURE +uniform sampler2D autoExposure; +#endif void main() { vec3 color = texture2D(colorTexture, v_textureCoordinates).rgb; -//#ifdef AUTO_EXPOSURE -// color /= texture2D(autoExposure, vec2(0.5)).r; -//#endif +#ifdef AUTO_EXPOSURE + color /= texture2D(autoExposure, vec2(0.5)).r; +#endif float a = 2.61; float b = 0.08; diff --git a/Source/Shaders/PostProcessStages/FilmicTonemapping.glsl b/Source/Shaders/PostProcessStages/FilmicTonemapping.glsl index 4ce7b2ed33d3..3332cf37029b 100644 --- a/Source/Shaders/PostProcessStages/FilmicTonemapping.glsl +++ b/Source/Shaders/PostProcessStages/FilmicTonemapping.glsl @@ -2,9 +2,9 @@ uniform sampler2D colorTexture; varying vec2 v_textureCoordinates; -//#ifdef AUTO_EXPOSURE -//uniform sampler2D autoExposure; -//#endif +#ifdef AUTO_EXPOSURE +uniform sampler2D autoExposure; +#endif // See slides 142 and 143: // http://www.gdcvault.com/play/1012459/Uncharted_2__HDR_Lighting @@ -13,9 +13,10 @@ void main() { vec3 color = texture2D(colorTexture, v_textureCoordinates).rgb; -//#ifdef AUTO_EXPOSURE -// color /= texture2D(autoExposure, vec2(0.5)).r; -//#endif +#ifdef AUTO_EXPOSURE + float exposure = texture2D(autoExposure, vec2(0.5)).r; + color /= exposure; +#endif const float A = 0.22; // shoulder strength const float B = 0.30; // linear strength diff --git a/Source/Shaders/PostProcessStages/ModifiedReinhardTonemapping.glsl b/Source/Shaders/PostProcessStages/ModifiedReinhardTonemapping.glsl index b520e34b30f3..bad1a080fa3b 100644 --- a/Source/Shaders/PostProcessStages/ModifiedReinhardTonemapping.glsl +++ b/Source/Shaders/PostProcessStages/ModifiedReinhardTonemapping.glsl @@ -3,9 +3,9 @@ uniform vec3 white; varying vec2 v_textureCoordinates; -//#ifdef AUTO_EXPOSURE -//uniform sampler2D autoExposure; -//#endif +#ifdef AUTO_EXPOSURE +uniform sampler2D autoExposure; +#endif // See equation 4: // http://www.cs.utah.edu/~reinhard/cdrom/tonemap.pdf @@ -13,9 +13,10 @@ varying vec2 v_textureCoordinates; void main() { vec3 color = texture2D(colorTexture, v_textureCoordinates).rgb; -//#ifdef AUTO_EXPOSURE -// color /= texture2D(autoExposure, vec2(0.5)).r; -//#endif +#ifdef AUTO_EXPOSURE + float exposure = texture2D(autoExposure, vec2(0.5)).r; + color /= exposure; +#endif color = (color * (1.0 + color / white)) / (1.0 + color); color = pow(color, vec3(1.0 / 2.2)); gl_FragColor = vec4(color, 1.0); diff --git a/Source/ThirdParty/GltfPipeline/processPbrMetallicRoughness.js b/Source/ThirdParty/GltfPipeline/processPbrMetallicRoughness.js index 68056ab4c1bf..6c871c64dd6b 100644 --- a/Source/ThirdParty/GltfPipeline/processPbrMetallicRoughness.js +++ b/Source/ThirdParty/GltfPipeline/processPbrMetallicRoughness.js @@ -442,20 +442,18 @@ define([ '}\n\n'; } - // TODO HDR fragmentShader += 'vec3 SRGBtoLINEAR3(vec3 srgbIn) \n' + '{\n' + - //' return pow(srgbIn, vec3(2.2));\n' + - ' return srgbIn;\n' + + ' return pow(srgbIn, vec3(2.2));\n' + '}\n\n'; fragmentShader += 'vec4 SRGBtoLINEAR4(vec4 srgbIn) \n' + '{\n' + - //' vec3 linearOut = pow(srgbIn.rgb, vec3(2.2));\n' + - //' return vec4(linearOut, srgbIn.a);\n' + - ' return srgbIn;\n' + + ' vec3 linearOut = pow(srgbIn.rgb, vec3(2.2));\n' + + ' return vec4(linearOut, srgbIn.a);\n' + '}\n\n'; + // TODO HDR fragmentShader += 'vec3 LINEARtoSRGB(vec3 linearIn) \n' + '{\n' + //' return pow(linearIn, vec3(1.0/2.2));\n' + From f815fe96bb352d20dcedebb157ed3e41ac0a830c Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 19 Jul 2018 17:40:27 -0400 Subject: [PATCH 21/76] Fix remaining gamma correction issues. --- Source/Renderer/AutomaticUniforms.js | 14 ++++++++++ Source/Renderer/UniformState.js | 4 +++ Source/Scene/Scene.js | 11 ++++++++ Source/Shaders/BillboardCollectionFS.glsl | 2 +- .../Builtin/Functions/gammaCorrect.glsl | 3 ++ .../Builtin/Functions/inverseGamma.glsl | 3 ++ Source/Shaders/GlobeFS.glsl | 2 +- .../Materials/CheckerboardMaterial.glsl | 2 +- Source/Shaders/Materials/DotMaterial.glsl | 6 ++-- .../Materials/ElevationContourMaterial.glsl | 2 +- .../Materials/ElevationRampMaterial.glsl | 2 +- Source/Shaders/Materials/FadeMaterial.glsl | 10 +++---- Source/Shaders/Materials/GridMaterial.glsl | 4 +-- .../Materials/PolylineArrowMaterial.glsl | 2 +- .../Materials/PolylineDashMaterial.glsl | 4 +-- .../Materials/PolylineGlowMaterial.glsl | 5 +--- .../Materials/PolylineOutlineMaterial.glsl | 12 ++++---- .../Materials/RimLightingMaterial.glsl | 4 +-- .../Shaders/Materials/SlopeRampMaterial.glsl | 2 +- Source/Shaders/Materials/StripeMaterial.glsl | 8 +++--- Source/Shaders/Materials/Water.glsl | 28 ++++++++++--------- .../Shaders/PointPrimitiveCollectionFS.glsl | 2 +- .../PostProcessStages/ACESTonemapping.glsl | 2 +- .../PostProcessStages/FilmicTonemapping.glsl | 3 +- .../ModifiedReinhardTonemapping.glsl | 2 +- .../ReinhardTonemapping.glsl | 2 +- Source/Shaders/ShadowVolumeAppearanceFS.glsl | 7 +++-- Source/Shaders/SkyBoxFS.glsl | 2 +- Source/Shaders/SunFS.glsl | 3 +- Source/Shaders/SunTextureFS.glsl | 16 +---------- 30 files changed, 95 insertions(+), 74 deletions(-) create mode 100644 Source/Shaders/Builtin/Functions/gammaCorrect.glsl create mode 100644 Source/Shaders/Builtin/Functions/inverseGamma.glsl diff --git a/Source/Renderer/AutomaticUniforms.js b/Source/Renderer/AutomaticUniforms.js index f75b71423600..f5fe0fb366fa 100644 --- a/Source/Renderer/AutomaticUniforms.js +++ b/Source/Renderer/AutomaticUniforms.js @@ -1624,6 +1624,20 @@ define([ getValue : function(uniformState) { return uniformState.invertClassificationColor; } + }), + + /** + * An automatic GLSL uniform that will be used for gamma correction. + * + * @alias czm_gamma + * @glslUniform + */ + czm_gamma : new AutomaticUniform({ + size : 1, + datatype : WebGLConstants.FLOAT, + getValue : function(uniformState) { + return uniformState.gamma; + } }) }; diff --git a/Source/Renderer/UniformState.js b/Source/Renderer/UniformState.js index 0097e65d3dde..dfbebbd246b7 100644 --- a/Source/Renderer/UniformState.js +++ b/Source/Renderer/UniformState.js @@ -46,6 +46,10 @@ define([ * @type {Texture} */ this.globeDepthTexture = undefined; + /** + * @type {Number} + */ + this.gamma = undefined; this._viewport = new BoundingRectangle(); this._viewportCartesian4 = new Cartesian4(); diff --git a/Source/Scene/Scene.js b/Source/Scene/Scene.js index aebaf32f4e48..484d10d30875 100644 --- a/Source/Scene/Scene.js +++ b/Source/Scene/Scene.js @@ -804,6 +804,8 @@ define([ this._removeTaskProcessorListenerCallback = TaskProcessor.taskCompletedEvent.addEventListener(requestRenderAfterFrame(this)); this._removeGlobeCallbacks = []; + this.gamma = 2.2; + // initial guess at frustums. var near = camera.frustum.near; var far = camera.frustum.far; @@ -1452,6 +1454,15 @@ define([ } }, + gamma : { + get : function() { + return this._context.uniformState.gamma; + }, + set : function(value) { + this._context.uniformState.gamma = value; + } + }, + /** * @private */ diff --git a/Source/Shaders/BillboardCollectionFS.glsl b/Source/Shaders/BillboardCollectionFS.glsl index 01d0055a1e2b..e04b1a552c76 100644 --- a/Source/Shaders/BillboardCollectionFS.glsl +++ b/Source/Shaders/BillboardCollectionFS.glsl @@ -49,7 +49,7 @@ float getGlobeDepth(vec2 adjustedST, vec2 depthLookupST) void main() { vec4 color = texture2D(u_atlas, v_textureCoordinates); - color.rgb = pow(color.rgb, vec3(2.2)); + color.rgb = czm_gammaCorrect(color.rgb); color *= v_color; // Fully transparent parts of the billboard are not pickable. diff --git a/Source/Shaders/Builtin/Functions/gammaCorrect.glsl b/Source/Shaders/Builtin/Functions/gammaCorrect.glsl new file mode 100644 index 000000000000..595c6763b330 --- /dev/null +++ b/Source/Shaders/Builtin/Functions/gammaCorrect.glsl @@ -0,0 +1,3 @@ +vec3 czm_gammaCorrect(vec3 rgb) { + return pow(rgb, vec3(czm_gamma)); +} diff --git a/Source/Shaders/Builtin/Functions/inverseGamma.glsl b/Source/Shaders/Builtin/Functions/inverseGamma.glsl new file mode 100644 index 000000000000..461113bc89fc --- /dev/null +++ b/Source/Shaders/Builtin/Functions/inverseGamma.glsl @@ -0,0 +1,3 @@ +vec3 czm_inverseGamma(vec3 rgb) { + return pow(rgb, vec3(1.0 / czm_gamma)); +} diff --git a/Source/Shaders/GlobeFS.glsl b/Source/Shaders/GlobeFS.glsl index e627fbacb75a..24d069a1200a 100644 --- a/Source/Shaders/GlobeFS.glsl +++ b/Source/Shaders/GlobeFS.glsl @@ -112,7 +112,7 @@ vec4 sampleAndBlend( vec3 color = value.rgb; float alpha = value.a; - color = pow(color, vec3(2.2)); + color = czm_gammaCorrect(color); #ifdef APPLY_SPLIT float splitPosition = czm_imagerySplitPosition; diff --git a/Source/Shaders/Materials/CheckerboardMaterial.glsl b/Source/Shaders/Materials/CheckerboardMaterial.glsl index 5c7a566c3132..ea4af75e6fd1 100644 --- a/Source/Shaders/Materials/CheckerboardMaterial.glsl +++ b/Source/Shaders/Materials/CheckerboardMaterial.glsl @@ -21,7 +21,7 @@ czm_material czm_getMaterial(czm_materialInput materialInput) vec4 currentColor = mix(lightColor, darkColor, b); vec4 color = czm_antialias(lightColor, darkColor, currentColor, value, 0.03); - material.diffuse = color.rgb; + material.diffuse = czm_gammaCorrect(color.rgb); material.alpha = color.a; return material; diff --git a/Source/Shaders/Materials/DotMaterial.glsl b/Source/Shaders/Materials/DotMaterial.glsl index 27bfbdea9895..7ad2067b8b8e 100644 --- a/Source/Shaders/Materials/DotMaterial.glsl +++ b/Source/Shaders/Materials/DotMaterial.glsl @@ -5,13 +5,13 @@ uniform vec2 repeat; czm_material czm_getMaterial(czm_materialInput materialInput) { czm_material material = czm_getDefaultMaterial(materialInput); - + // From Stefan Gustavson's Procedural Textures in GLSL in OpenGL Insights float b = smoothstep(0.3, 0.32, length(fract(repeat * materialInput.st) - 0.5)); // 0.0 or 1.0 vec4 color = mix(lightColor, darkColor, b); - material.diffuse = color.rgb; + material.diffuse = czm_gammaCorrect(color.rgb); material.alpha = color.a; - + return material; } diff --git a/Source/Shaders/Materials/ElevationContourMaterial.glsl b/Source/Shaders/Materials/ElevationContourMaterial.glsl index 1634891eb44c..17c2dd63ed58 100644 --- a/Source/Shaders/Materials/ElevationContourMaterial.glsl +++ b/Source/Shaders/Materials/ElevationContourMaterial.glsl @@ -21,7 +21,7 @@ czm_material czm_getMaterial(czm_materialInput materialInput) material.alpha = (distanceToContour < (czm_resolutionScale * width)) ? 1.0 : 0.0; #endif - material.diffuse = color.rgb; + material.diffuse = czm_gammaCorrect(color.rgb); return material; } diff --git a/Source/Shaders/Materials/ElevationRampMaterial.glsl b/Source/Shaders/Materials/ElevationRampMaterial.glsl index 36c017422175..d9d62fe9418f 100644 --- a/Source/Shaders/Materials/ElevationRampMaterial.glsl +++ b/Source/Shaders/Materials/ElevationRampMaterial.glsl @@ -7,7 +7,7 @@ czm_material czm_getMaterial(czm_materialInput materialInput) czm_material material = czm_getDefaultMaterial(materialInput); float scaledHeight = clamp((materialInput.height - minimumHeight) / (maximumHeight - minimumHeight), 0.0, 1.0); vec4 rampColor = texture2D(image, vec2(scaledHeight, 0.5)); - material.diffuse = rampColor.rgb; + material.diffuse = czm_gammaCorrect(rampColor.rgb); material.alpha = rampColor.a; return material; } diff --git a/Source/Shaders/Materials/FadeMaterial.glsl b/Source/Shaders/Materials/FadeMaterial.glsl index d2283cd40c59..fd0f182f5c79 100644 --- a/Source/Shaders/Materials/FadeMaterial.glsl +++ b/Source/Shaders/Materials/FadeMaterial.glsl @@ -21,16 +21,16 @@ float getTime(float t, float coord) czm_material czm_getMaterial(czm_materialInput materialInput) { czm_material material = czm_getDefaultMaterial(materialInput); - + vec2 st = materialInput.st; float s = getTime(time.x, st.s) * fadeDirection.s; float t = getTime(time.y, st.t) * fadeDirection.t; - + float u = length(vec2(s, t)); vec4 color = mix(fadeInColor, fadeOutColor, u); - - material.emission = color.rgb; + + material.emission = czm_gammaCorrect(color.rgb); material.alpha = color.a; - + return material; } diff --git a/Source/Shaders/Materials/GridMaterial.glsl b/Source/Shaders/Materials/GridMaterial.glsl index b9a24e8e1f18..4977db3d77da 100644 --- a/Source/Shaders/Materials/GridMaterial.glsl +++ b/Source/Shaders/Materials/GridMaterial.glsl @@ -49,8 +49,8 @@ czm_material czm_getMaterial(czm_materialInput materialInput) value *= (1.0 - sRim); vec3 halfColor = color.rgb * 0.5; - material.diffuse = halfColor; - material.emission = halfColor; + material.diffuse = czm_gammaCorrect(halfColor); + material.emission = czm_gammaCorrect(halfColor); material.alpha = color.a * (1.0 - ((1.0 - cellAlpha) * value)); return material; diff --git a/Source/Shaders/Materials/PolylineArrowMaterial.glsl b/Source/Shaders/Materials/PolylineArrowMaterial.glsl index e50c80a369e4..e6706c646320 100644 --- a/Source/Shaders/Materials/PolylineArrowMaterial.glsl +++ b/Source/Shaders/Materials/PolylineArrowMaterial.glsl @@ -61,7 +61,7 @@ czm_material czm_getMaterial(czm_materialInput materialInput) vec4 currentColor = mix(outsideColor, color, clamp(s + t, 0.0, 1.0)); vec4 outColor = czm_antialias(outsideColor, color, currentColor, dist); - material.diffuse = outColor.rgb; + material.diffuse = czm_gammaCorrect(outColor.rgb); material.alpha = outColor.a; return material; } diff --git a/Source/Shaders/Materials/PolylineDashMaterial.glsl b/Source/Shaders/Materials/PolylineDashMaterial.glsl index aae66a543d59..933013ae4080 100644 --- a/Source/Shaders/Materials/PolylineDashMaterial.glsl +++ b/Source/Shaders/Materials/PolylineDashMaterial.glsl @@ -32,7 +32,7 @@ czm_material czm_getMaterial(czm_materialInput materialInput) discard; } - material.emission = fragColor.rgb; + material.emission = czm_gammaCorrect(fragColor.rgb); material.alpha = fragColor.a; return material; -} \ No newline at end of file +} diff --git a/Source/Shaders/Materials/PolylineGlowMaterial.glsl b/Source/Shaders/Materials/PolylineGlowMaterial.glsl index df8b7191c871..a2a04c0e0fc0 100644 --- a/Source/Shaders/Materials/PolylineGlowMaterial.glsl +++ b/Source/Shaders/Materials/PolylineGlowMaterial.glsl @@ -10,10 +10,7 @@ czm_material czm_getMaterial(czm_materialInput materialInput) vec2 st = materialInput.st; float glow = glowPower / abs(st.t - 0.5) - (glowPower / 0.5); - //material.emission = max(vec3(glow - 1.0 + color.rgb), color.rgb); - - // TODO HDR - material.emission = vec3(glow - 1.0 + color.rgb); + material.emission = czm_gammaCorrect(max(vec3(glow - 1.0 + color.rgb), color.rgb)); material.alpha = clamp(0.0, 1.0, glow) * color.a; return material; diff --git a/Source/Shaders/Materials/PolylineOutlineMaterial.glsl b/Source/Shaders/Materials/PolylineOutlineMaterial.glsl index afda276626fb..41a8764b4528 100644 --- a/Source/Shaders/Materials/PolylineOutlineMaterial.glsl +++ b/Source/Shaders/Materials/PolylineOutlineMaterial.glsl @@ -7,22 +7,22 @@ varying float v_width; czm_material czm_getMaterial(czm_materialInput materialInput) { czm_material material = czm_getDefaultMaterial(materialInput); - + vec2 st = materialInput.st; float halfInteriorWidth = 0.5 * (v_width - outlineWidth) / v_width; float b = step(0.5 - halfInteriorWidth, st.t); b *= 1.0 - step(0.5 + halfInteriorWidth, st.t); - + // Find the distance from the closest separator (region between two colors) float d1 = abs(st.t - (0.5 - halfInteriorWidth)); float d2 = abs(st.t - (0.5 + halfInteriorWidth)); float dist = min(d1, d2); - + vec4 currentColor = mix(outlineColor, color, b); vec4 outColor = czm_antialias(outlineColor, color, currentColor, dist); - - material.diffuse = outColor.rgb; + + material.diffuse = czm_gammaCorrect(outColor.rgb); material.alpha = outColor.a; - + return material; } diff --git a/Source/Shaders/Materials/RimLightingMaterial.glsl b/Source/Shaders/Materials/RimLightingMaterial.glsl index 3408b61b036c..34b79bce9c56 100644 --- a/Source/Shaders/Materials/RimLightingMaterial.glsl +++ b/Source/Shaders/Materials/RimLightingMaterial.glsl @@ -10,8 +10,8 @@ czm_material czm_getMaterial(czm_materialInput materialInput) float d = 1.0 - dot(materialInput.normalEC, normalize(materialInput.positionToEyeEC)); float s = smoothstep(1.0 - width, 1.0, d); - material.diffuse = color.rgb; - material.emission = rimColor.rgb * s; + material.diffuse = czm_gammaCorrect(color.rgb); + material.emission = czm_gammaCorrect(rimColor.rgb * s); material.alpha = mix(color.a, rimColor.a, s); return material; diff --git a/Source/Shaders/Materials/SlopeRampMaterial.glsl b/Source/Shaders/Materials/SlopeRampMaterial.glsl index 14e30a9086bb..7471965bfc9b 100644 --- a/Source/Shaders/Materials/SlopeRampMaterial.glsl +++ b/Source/Shaders/Materials/SlopeRampMaterial.glsl @@ -4,7 +4,7 @@ czm_material czm_getMaterial(czm_materialInput materialInput) { czm_material material = czm_getDefaultMaterial(materialInput); vec4 rampColor = texture2D(image, vec2(materialInput.slope, 0.5)); - material.diffuse = rampColor.rgb; + material.diffuse = czm_gammaCorrect(rampColor.rgb); material.alpha = rampColor.a; return material; } diff --git a/Source/Shaders/Materials/StripeMaterial.glsl b/Source/Shaders/Materials/StripeMaterial.glsl index 330c92df9a8c..4ff3a70803a3 100644 --- a/Source/Shaders/Materials/StripeMaterial.glsl +++ b/Source/Shaders/Materials/StripeMaterial.glsl @@ -12,12 +12,12 @@ czm_material czm_getMaterial(czm_materialInput materialInput) float coord = mix(materialInput.st.s, materialInput.st.t, float(horizontal)); float value = fract((coord - offset) * (repeat * 0.5)); float dist = min(value, min(abs(value - 0.5), 1.0 - value)); - + vec4 currentColor = mix(evenColor, oddColor, step(0.5, value)); vec4 color = czm_antialias(evenColor, oddColor, currentColor, dist); - - material.diffuse = color.rgb; + + material.diffuse = czm_gammaCorrect(color.rgb); material.alpha = color.a; - + return material; } diff --git a/Source/Shaders/Materials/Water.glsl b/Source/Shaders/Materials/Water.glsl index 50f1b8ce6c37..0ac0f1bc8e44 100644 --- a/Source/Shaders/Materials/Water.glsl +++ b/Source/Shaders/Materials/Water.glsl @@ -16,41 +16,43 @@ czm_material czm_getMaterial(czm_materialInput materialInput) czm_material material = czm_getDefaultMaterial(materialInput); float time = czm_frameNumber * animationSpeed; - + // fade is a function of the distance from the fragment and the frequency of the waves float fade = max(1.0, (length(materialInput.positionToEyeEC) / 10000000000.0) * frequency * fadeFactor); - + float specularMapValue = texture2D(specularMap, materialInput.st).r; - + // note: not using directional motion at this time, just set the angle to 0.0; vec4 noise = czm_getWaterNoise(normalMap, materialInput.st * frequency, time, 0.0); vec3 normalTangentSpace = noise.xyz * vec3(1.0, 1.0, (1.0 / amplitude)); - + // fade out the normal perturbation as we move further from the water surface normalTangentSpace.xy /= fade; - + // attempt to fade out the normal perturbation as we approach non water areas (low specular map value) normalTangentSpace = mix(vec3(0.0, 0.0, 50.0), normalTangentSpace, specularMapValue); - + normalTangentSpace = normalize(normalTangentSpace); - + // get ratios for alignment of the new normal vector with a vector perpendicular to the tangent plane float tsPerturbationRatio = clamp(dot(normalTangentSpace, vec3(0.0, 0.0, 1.0)), 0.0, 1.0); - + // fade out water effect as specular map value decreases material.alpha = specularMapValue; - + // base color is a blend of the water and non-water color based on the value from the specular map // may need a uniform blend factor to better control this material.diffuse = mix(blendColor.rgb, baseWaterColor.rgb, specularMapValue); - + // diffuse highlights are based on how perturbed the normal is material.diffuse += (0.1 * tsPerturbationRatio); - + + material.diffuse = czm_gammaCorrect(material.diffuse); + material.normal = normalize(materialInput.tangentToEyeMatrix * normalTangentSpace); - + material.specular = specularIntensity; material.shininess = 10.0; - + return material; } diff --git a/Source/Shaders/PointPrimitiveCollectionFS.glsl b/Source/Shaders/PointPrimitiveCollectionFS.glsl index 9c3fbb0b58e6..45cead4d3f27 100644 --- a/Source/Shaders/PointPrimitiveCollectionFS.glsl +++ b/Source/Shaders/PointPrimitiveCollectionFS.glsl @@ -38,6 +38,6 @@ void main() #endif #endif - gl_FragColor = color; + gl_FragColor = vec4(czm_gammaCorrect(color.rgb), color.a); czm_writeLogDepth(); } diff --git a/Source/Shaders/PostProcessStages/ACESTonemapping.glsl b/Source/Shaders/PostProcessStages/ACESTonemapping.glsl index c9ba07221ab7..c1bbd32a1986 100644 --- a/Source/Shaders/PostProcessStages/ACESTonemapping.glsl +++ b/Source/Shaders/PostProcessStages/ACESTonemapping.glsl @@ -21,6 +21,6 @@ void main() float e = 0.01; color = (color * (a * color + b)) / (color * (c * color + d) + e); color = clamp(color, 0.0, 1.0); - color = pow(color, vec3(1.0 / 1.52)); + color = czm_inverseGamma(color); gl_FragColor = vec4(color, 1.0); } diff --git a/Source/Shaders/PostProcessStages/FilmicTonemapping.glsl b/Source/Shaders/PostProcessStages/FilmicTonemapping.glsl index 3332cf37029b..4f839848454b 100644 --- a/Source/Shaders/PostProcessStages/FilmicTonemapping.glsl +++ b/Source/Shaders/PostProcessStages/FilmicTonemapping.glsl @@ -30,7 +30,6 @@ void main() vec3 c = ((color * (A * color + C * B) + D * E) / (color * ( A * color + B) + D * F)) - E / F; float w = ((white * (A * white + C * B) + D * E) / (white * ( A * white + B) + D * F)) - E / F; - c = c / w; - c = pow(c, vec3(1.0 / 2.2)); + c = czm_inverseGamma(c / w); gl_FragColor = vec4(c, 1.0); } diff --git a/Source/Shaders/PostProcessStages/ModifiedReinhardTonemapping.glsl b/Source/Shaders/PostProcessStages/ModifiedReinhardTonemapping.glsl index bad1a080fa3b..bfa3988720fe 100644 --- a/Source/Shaders/PostProcessStages/ModifiedReinhardTonemapping.glsl +++ b/Source/Shaders/PostProcessStages/ModifiedReinhardTonemapping.glsl @@ -18,6 +18,6 @@ void main() color /= exposure; #endif color = (color * (1.0 + color / white)) / (1.0 + color); - color = pow(color, vec3(1.0 / 2.2)); + color = czm_inverseGamma(color); gl_FragColor = vec4(color, 1.0); } diff --git a/Source/Shaders/PostProcessStages/ReinhardTonemapping.glsl b/Source/Shaders/PostProcessStages/ReinhardTonemapping.glsl index 6ae4b5e7937c..29f06ea2f6a5 100644 --- a/Source/Shaders/PostProcessStages/ReinhardTonemapping.glsl +++ b/Source/Shaders/PostProcessStages/ReinhardTonemapping.glsl @@ -17,6 +17,6 @@ void main() color /= exposure; #endif color = color / (1.0 + color); - color = pow(color, vec3(1.0 / 2.2)); + color = czm_inverseGamma(color); gl_FragColor = vec4(color, 1.0); } diff --git a/Source/Shaders/ShadowVolumeAppearanceFS.glsl b/Source/Shaders/ShadowVolumeAppearanceFS.glsl index 5fb3f7c4f049..8454748b5572 100644 --- a/Source/Shaders/ShadowVolumeAppearanceFS.glsl +++ b/Source/Shaders/ShadowVolumeAppearanceFS.glsl @@ -94,15 +94,16 @@ void main(void) #ifdef PER_INSTANCE_COLOR + vec4 color = vec4(czm_gammaCorrect(v_color.rgb), v_color.a); #ifdef FLAT - gl_FragColor = v_color; + gl_FragColor = color; #else // FLAT czm_materialInput materialInput; materialInput.normalEC = normalEC; materialInput.positionToEyeEC = -eyeCoordinate.xyz; czm_material material = czm_getDefaultMaterial(materialInput); - material.diffuse = v_color.rgb; - material.alpha = v_color.a; + material.diffuse = color.rgb; + material.alpha = color.a; gl_FragColor = czm_phong(normalize(-eyeCoordinate.xyz), material); #endif // FLAT diff --git a/Source/Shaders/SkyBoxFS.glsl b/Source/Shaders/SkyBoxFS.glsl index a34c6a7e61c8..afc60f4e206b 100644 --- a/Source/Shaders/SkyBoxFS.glsl +++ b/Source/Shaders/SkyBoxFS.glsl @@ -5,6 +5,6 @@ varying vec3 v_texCoord; void main() { vec3 rgb = textureCube(u_cubeMap, normalize(v_texCoord)).rgb; - rgb = pow(rgb, vec3(2.2)); + rgb = czm_gammaCorrect(rgb); gl_FragColor = vec4(rgb, czm_morphTime); } diff --git a/Source/Shaders/SunFS.glsl b/Source/Shaders/SunFS.glsl index 58852482c392..99b973790e54 100644 --- a/Source/Shaders/SunFS.glsl +++ b/Source/Shaders/SunFS.glsl @@ -4,5 +4,6 @@ varying vec2 v_textureCoordinates; void main() { - gl_FragColor = texture2D(u_texture, v_textureCoordinates); + vec4 color = texture2D(u_texture, v_textureCoordinates); + gl_FragColor = vec4(czm_gammaCorrect(color.rgb), color.a); } diff --git a/Source/Shaders/SunTextureFS.glsl b/Source/Shaders/SunTextureFS.glsl index 243bdc477c39..92fd958128e8 100644 --- a/Source/Shaders/SunTextureFS.glsl +++ b/Source/Shaders/SunTextureFS.glsl @@ -17,22 +17,12 @@ vec4 addBurst(vec2 position, vec2 direction) return vec4(burst); } -// TODO HDR -#define HDR - void main() { vec2 position = v_textureCoordinates - vec2(0.5); float radius = length(position); float surface = step(radius, u_radiusTS); - -#ifdef HDR - vec2 rg = vec2(1.5, 1.2); -#else - vec2 rg = vec2(1.0); -#endif - - vec4 color = vec4(rg, surface + 0.2, surface); + vec4 color = vec4(vec2(1.0), surface + 0.2, surface); float glow = 1.0 - smoothstep(0.0, 0.55, radius); color.ba += mix(vec2(0.0), vec2(1.0), glow) * 0.75; @@ -62,9 +52,5 @@ void main() color += clamp(burst, vec4(0.0), vec4(1.0)) * 0.15; -#ifdef HDR - gl_FragColor = color; -#else gl_FragColor = clamp(color, vec4(0.0), vec4(1.0)); -#endif } From 1cc77086e13e19a036bf628e8ddb16fd9dd360e0 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Fri, 20 Jul 2018 17:05:14 -0400 Subject: [PATCH 22/76] Modify sun lighting. Option to use camera as light source. --- Source/Scene/AutoExposure.js | 2 +- Source/Scene/PostProcessStageCollection.js | 4 ++-- Source/Shaders/Builtin/Functions/phong.glsl | 21 +++++++++++++++++++++ Source/Shaders/GlobeFS.glsl | 20 ++++++++++++++++++-- 4 files changed, 42 insertions(+), 5 deletions(-) diff --git a/Source/Scene/AutoExposure.js b/Source/Scene/AutoExposure.js index 03950ac303b0..2dced9b02c55 100644 --- a/Source/Scene/AutoExposure.js +++ b/Source/Scene/AutoExposure.js @@ -243,7 +243,7 @@ define([ source += ' float previous = texture2D(previousLuminance, vec2(0.5)).r; \n' + ' color = clamp(color, minimumLuminance, maximumLuminance); \n' + - ' color = previous + (color - previous) / (60.0 * 3.0); \n' + + ' color = previous + (color - previous) / (60.0 * 1.5); \n' + ' color = clamp(color, minimumLuminance, maximumLuminance); \n'; } diff --git a/Source/Scene/PostProcessStageCollection.js b/Source/Scene/PostProcessStageCollection.js index c62a1c7e3279..a384acb84a63 100644 --- a/Source/Scene/PostProcessStageCollection.js +++ b/Source/Scene/PostProcessStageCollection.js @@ -60,10 +60,10 @@ define([ var bloom = PostProcessStageLibrary.createBloomStage(); var useAutoExposure = false; - var tonemapping = PostProcessStageLibrary.createReinhardTonemappingStage(useAutoExposure); + //var tonemapping = PostProcessStageLibrary.createReinhardTonemappingStage(useAutoExposure); //var tonemapping = PostProcessStageLibrary.createModifiedReinhardTonemappingStage(useAutoExposure); //var tonemapping = PostProcessStageLibrary.createFilmicTonemappingStage(useAutoExposure); - //var tonemapping = PostProcessStageLibrary.createACESTonemappingStage(useAutoExposure); + var tonemapping = PostProcessStageLibrary.createACESTonemappingStage(useAutoExposure); var autoexposure = PostProcessStageLibrary.createAutoExposureStage(); diff --git a/Source/Shaders/Builtin/Functions/phong.glsl b/Source/Shaders/Builtin/Functions/phong.glsl index f3f68cd10948..737af056ed5f 100644 --- a/Source/Shaders/Builtin/Functions/phong.glsl +++ b/Source/Shaders/Builtin/Functions/phong.glsl @@ -28,6 +28,7 @@ float czm_private_getSpecularOfMaterial(vec3 lightDirectionEC, vec3 toEyeEC, czm */ vec4 czm_phong(vec3 toEye, czm_material material) { +/* // Diffuse from directional light sources at eye (for top-down) float diffuse = czm_private_getLambertDiffuseOfMaterial(vec3(0.0, 0.0, 1.0), material); if (czm_sceneMode == czm_sceneMode3D) { @@ -46,6 +47,26 @@ vec4 czm_phong(vec3 toEye, czm_material material) color += materialDiffuse * diffuse; color += material.specular * specular; + return vec4(color, material.alpha); + */ + + vec3 color = material.emission + material.diffuse * 0.25; + + vec3 sunColor = vec3(1.5, 1.4, 1.2); + +#define USE_SUN_LIGHTING + +#ifdef USE_SUN_LIGHTING + float sunDiffuse = czm_private_getLambertDiffuseOfMaterial(czm_sunDirectionEC, material); + float sunSpecular = czm_private_getSpecularOfMaterial(czm_sunDirectionEC, toEye, material); + + color += material.diffuse * sunDiffuse * sunColor; + color += material.specular * sunSpecular; +#else + float cameraDiffuse = czm_private_getLambertDiffuseOfMaterial(vec3(0.0, 0.0, 1.0), material); + color += material.diffuse * cameraDiffuse * sunColor; +#endif + return vec4(color, material.alpha); } diff --git a/Source/Shaders/GlobeFS.glsl b/Source/Shaders/GlobeFS.glsl index 24d069a1200a..7dd8683129ff 100644 --- a/Source/Shaders/GlobeFS.glsl +++ b/Source/Shaders/GlobeFS.glsl @@ -175,10 +175,10 @@ void main() } #endif -#if defined(SHOW_REFLECTIVE_OCEAN) || defined(ENABLE_DAYNIGHT_SHADING) +//#if defined(SHOW_REFLECTIVE_OCEAN) || defined(ENABLE_DAYNIGHT_SHADING) vec3 normalMC = czm_geodeticSurfaceNormal(v_positionMC, vec3(0.0), vec3(1.0)); // normalized surface normal in model coordinates vec3 normalEC = czm_normal3D * normalMC; // normalized surface normal in eye coordiantes -#endif +//#endif #ifdef SHOW_REFLECTIVE_OCEAN vec2 waterMaskTranslation = u_waterMaskTranslationAndScale.xy; @@ -211,6 +211,7 @@ void main() color.xyz = mix(color.xyz, material.diffuse, material.alpha); #endif +/* #ifdef ENABLE_VERTEX_LIGHTING float diffuseIntensity = clamp(czm_getLambertDiffuse(czm_sunDirectionEC, normalize(v_normalEC)) * 0.9 + 0.3, 0.0, 1.0); vec4 finalColor = vec4(color.rgb * diffuseIntensity, color.a); @@ -225,6 +226,20 @@ void main() #else vec4 finalColor = color; #endif +*/ + +//#ifdef ENABLE_VERTEX_LIGHTING + czm_material material; + material.diffuse = color.rgb; + material.alpha = color.a; + material.normal = normalEC; + vec4 finalColor = czm_phong(normalize(-v_positionEC), material); +//#else +// vec4 finalColor = color; +//#endif + + gl_FragColor = finalColor; + return; #ifdef ENABLE_CLIPPING_PLANES vec4 clippingPlanesEdgeColor = vec4(1.0); @@ -347,6 +362,7 @@ vec4 computeWaterColor(vec3 positionEyeCoordinates, vec2 textureCoordinates, mat float c = 1.7; return vec4(imageryColor.rgb + (c * (vec3(e) + imageryColor.rgb * d) * (diffuseHighlight + nonDiffuseHighlight + specular)), imageryColor.a); + //return vec4(0.0, 0.0, 1.0, 1.0); //return vec4(imageryColor.rgb + diffuseHighlight + nonDiffuseHighlight + specular, imageryColor.a); } From bfa7ee4afcc077c6682b01bb67acc0b2305a63ac Mon Sep 17 00:00:00 2001 From: ggetz Date: Fri, 20 Jul 2018 17:39:09 -0400 Subject: [PATCH 23/76] Tweak gamma to neutral and modify ACES values --- Source/Scene/Scene.js | 2 +- Source/Shaders/PostProcessStages/ACESTonemapping.glsl | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Source/Scene/Scene.js b/Source/Scene/Scene.js index 25a737c5c761..b3e2d877d513 100644 --- a/Source/Scene/Scene.js +++ b/Source/Scene/Scene.js @@ -804,7 +804,7 @@ define([ this._removeTaskProcessorListenerCallback = TaskProcessor.taskCompletedEvent.addEventListener(requestRenderAfterFrame(this)); this._removeGlobeCallbacks = []; - this.gamma = 2.2; + this.gamma = 2.5; // initial guess at frustums. var near = camera.frustum.near; diff --git a/Source/Shaders/PostProcessStages/ACESTonemapping.glsl b/Source/Shaders/PostProcessStages/ACESTonemapping.glsl index c1bbd32a1986..3ca1555dc210 100644 --- a/Source/Shaders/PostProcessStages/ACESTonemapping.glsl +++ b/Source/Shaders/PostProcessStages/ACESTonemapping.glsl @@ -15,10 +15,10 @@ void main() #endif float a = 2.61; - float b = 0.08; + float b = 0.07; float c = 2.49; - float d = 0.63; - float e = 0.01; + float d = 0.68; + float e = 0.09; color = (color * (a * color + b)) / (color * (c * color + d) + e); color = clamp(color, 0.0, 1.0); color = czm_inverseGamma(color); From 8b1ac520933d9fffce7d3ae2e9823c68a927a840 Mon Sep 17 00:00:00 2001 From: ggetz Date: Mon, 23 Jul 2018 16:50:18 -0400 Subject: [PATCH 24/76] Better mapping constants, sun color is white-blue --- Source/Renderer/AutomaticUniforms.js | 14 +++++++++++++ Source/Renderer/UniformState.js | 13 ++++++++++++ Source/Scene/Fog.js | 2 +- Source/Scene/FrameState.js | 7 +++++++ Source/Scene/Material.js | 2 +- Source/Scene/Model.js | 4 ++-- Source/Scene/Scene.js | 20 ++++++++++++++++++- Source/Shaders/Builtin/Functions/phong.glsl | 2 +- .../PostProcessStages/ACESTonemapping.glsl | 14 +++++++------ 9 files changed, 66 insertions(+), 12 deletions(-) diff --git a/Source/Renderer/AutomaticUniforms.js b/Source/Renderer/AutomaticUniforms.js index f5fe0fb366fa..e0d97d9c680c 100644 --- a/Source/Renderer/AutomaticUniforms.js +++ b/Source/Renderer/AutomaticUniforms.js @@ -1638,6 +1638,20 @@ define([ getValue : function(uniformState) { return uniformState.gamma; } + }), + + /** + * An automatic GLSL uniform that defines the color of light emitted by the sun. + * + * @alias czm_sunColor + * @glslUniform + */ + czm_sunColor: new AutomaticUniform({ + size: 1, + datatype: WebGLConstants.FLOAT_VEC4, + getValue: function(uniformState) { + return uniformState.sunColor; + } }) }; diff --git a/Source/Renderer/UniformState.js b/Source/Renderer/UniformState.js index dfbebbd246b7..0ec0e682a292 100644 --- a/Source/Renderer/UniformState.js +++ b/Source/Renderer/UniformState.js @@ -147,6 +147,7 @@ define([ this._sunPositionColumbusView = new Cartesian3(); this._sunDirectionWC = new Cartesian3(); this._sunDirectionEC = new Cartesian3(); + this._sunColor = new Color(); this._moonDirectionEC = new Cartesian3(); this._pass = undefined; @@ -741,6 +742,17 @@ define([ } }, + /** + * The color of the light emitted by the sun. + * @memberof UniformState.prototype + * @type {Color} + */ + sunColor: { + get: function() { + return this._sunColor; + } + }, + /** * A normalized vector to the moon in eye coordinates at the current scene time. In 3D mode, this * returns the actual vector from the camera position to the moon position. In 2D and Columbus View, it returns @@ -1073,6 +1085,7 @@ define([ } setSunAndMoonDirections(this, frameState); + this._sunColor = Color.clone(frameState.sunColor, this._sunColor); var brdfLutGenerator = frameState.brdfLutGenerator; var brdfLut = defined(brdfLutGenerator) ? brdfLutGenerator.colorTexture : undefined; diff --git a/Source/Scene/Fog.js b/Source/Scene/Fog.js index 3607baa4822d..24ea5a0ae2a0 100644 --- a/Source/Scene/Fog.js +++ b/Source/Scene/Fog.js @@ -49,7 +49,7 @@ define([ * @type {Number} * @default 0.1 */ - this.minimumBrightness = 0.01; + this.minimumBrightness = 0.03; } // These values were found by sampling the density at certain views and finding at what point culled tiles impacted the view at the horizon. diff --git a/Source/Scene/FrameState.js b/Source/Scene/FrameState.js index d463cf162201..9a46cc71cecc 100644 --- a/Source/Scene/FrameState.js +++ b/Source/Scene/FrameState.js @@ -303,6 +303,13 @@ define([ */ this.backgroundColor = undefined; + /** + * The color of the light emitted by the sun. + * + * @type {Color} + */ + this.sunColor = undefined; + /** * 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 diff --git a/Source/Scene/Material.js b/Source/Scene/Material.js index 29aeebd42a27..01cf65f09ec6 100644 --- a/Source/Scene/Material.js +++ b/Source/Scene/Material.js @@ -696,7 +696,7 @@ define([ for ( var component in components) { if (components.hasOwnProperty(component)) { if (component === 'diffuse' || component === 'emission') { - material.shaderSource += 'material.' + component + ' = pow(' + components[component] + ', vec3(2.2)); \n'; + material.shaderSource += 'material.' + component + ' = czm_gammaCorrect(' + components[component] + '); \n'; } else { material.shaderSource += 'material.' + component + ' = ' + components[component] + ';\n'; } diff --git a/Source/Scene/Model.js b/Source/Scene/Model.js index 30a0bd2da792..699a6df018c4 100644 --- a/Source/Scene/Model.js +++ b/Source/Scene/Model.js @@ -2046,7 +2046,7 @@ define([ '\n' + 'void main() { \n' + ' non_gamma_corrected_main(); \n' + - ' gl_FragColor.rgb = pow(gl_FragColor.rgb, vec3(2.2)); \n' + + ' gl_FragColor.rgb = czm_gammaCorrect(gl_FragColor.rgb); \n' + '} \n'; } @@ -2096,7 +2096,7 @@ define([ '\n' + 'void main() { \n' + ' non_gamma_corrected_main(); \n' + - ' gl_FragColor.rgb = pow(gl_FragColor.rgb, vec3(2.2)); \n' + + ' gl_FragColor.rgb = gl_FragColor.rgb(gl_FragColor.rgb); \n' + '} \n'; } diff --git a/Source/Scene/Scene.js b/Source/Scene/Scene.js index b3e2d877d513..988a9df0c716 100644 --- a/Source/Scene/Scene.js +++ b/Source/Scene/Scene.js @@ -804,7 +804,8 @@ define([ this._removeTaskProcessorListenerCallback = TaskProcessor.taskCompletedEvent.addEventListener(requestRenderAfterFrame(this)); this._removeGlobeCallbacks = []; - this.gamma = 2.5; + this.gamma = 2.4; + this._sunColor = new Color(0.8, 0.85, 1.0, 1.0); // initial guess at frustums. var near = camera.frustum.near; @@ -1463,6 +1464,22 @@ define([ } }, + /** + * Gets or sets the color of the light emitted by the sun. + * + * @memberof Scene.prototype + * @type {Color} + * @default Color(0.8,0.8,0.8) + */ + sunColor: { + get: function() { + return this._sunColor; + }, + set: function(value) { + this._sunColor = value; + } + }, + /** * @private */ @@ -1615,6 +1632,7 @@ define([ frameState.terrainExaggeration = scene._terrainExaggeration; frameState.minimumDisableDepthTestDistance = scene._minimumDisableDepthTestDistance; frameState.invertClassification = scene.invertClassification; + frameState.sunColor = scene._sunColor; scene._actualInvertClassificationColor = Color.clone(scene.invertClassificationColor, scene._actualInvertClassificationColor); if (!InvertClassification.isTranslucencySupported(scene._context)) { diff --git a/Source/Shaders/Builtin/Functions/phong.glsl b/Source/Shaders/Builtin/Functions/phong.glsl index 737af056ed5f..70999aba0c9b 100644 --- a/Source/Shaders/Builtin/Functions/phong.glsl +++ b/Source/Shaders/Builtin/Functions/phong.glsl @@ -52,7 +52,7 @@ vec4 czm_phong(vec3 toEye, czm_material material) vec3 color = material.emission + material.diffuse * 0.25; - vec3 sunColor = vec3(1.5, 1.4, 1.2); + vec3 sunColor = czm_sunColor.rgb + czm_sunColor.a; #define USE_SUN_LIGHTING diff --git a/Source/Shaders/PostProcessStages/ACESTonemapping.glsl b/Source/Shaders/PostProcessStages/ACESTonemapping.glsl index 3ca1555dc210..e9d10b175e1a 100644 --- a/Source/Shaders/PostProcessStages/ACESTonemapping.glsl +++ b/Source/Shaders/PostProcessStages/ACESTonemapping.glsl @@ -13,13 +13,15 @@ void main() #ifdef AUTO_EXPOSURE color /= texture2D(autoExposure, vec2(0.5)).r; #endif + float g = 0.985; + + float a = 0.065; + float b = 0.0001; + float c = 0.433; + float d = 0.238; + + color = (color * (color + a) - b) / (color * (g * color + c) + d); - float a = 2.61; - float b = 0.07; - float c = 2.49; - float d = 0.68; - float e = 0.09; - color = (color * (a * color + b)) / (color * (c * color + d) + e); color = clamp(color, 0.0, 1.0); color = czm_inverseGamma(color); gl_FragColor = vec4(color, 1.0); From d851ce5bbb7ed8cf3229bed58f53600dbfe110a3 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Fri, 3 Aug 2018 15:28:52 -0400 Subject: [PATCH 25/76] Fix after merge. --- Source/Shaders/GlobeFS.glsl | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Source/Shaders/GlobeFS.glsl b/Source/Shaders/GlobeFS.glsl index 5d2bf0ff6cdb..7c343eb1b644 100644 --- a/Source/Shaders/GlobeFS.glsl +++ b/Source/Shaders/GlobeFS.glsl @@ -265,10 +265,9 @@ void main() #if defined(FOG) || defined(GROUND_ATMOSPHERE) const float fExposure = 1.3; vec3 fogColor = v_fogMieColor + finalColor.rgb * v_fogRayleighColor; - fogColor = vec3(1.0) - exp(-fExposure * fogColor); -#endif // TODO: disable exposure if using HDR //fogColor = vec3(1.0) - exp(-fExposure * fogColor); +#endif #ifdef FOG #if defined(ENABLE_VERTEX_LIGHTING) || defined(ENABLE_DAYNIGHT_SHADING) || defined(GROUND_ATMOSPHERE) @@ -289,7 +288,7 @@ void main() } vec3 groundAtmosphereColor = v_mieColor + finalColor.rgb * v_rayleighColor; - groundAtmosphereColor = vec3(1.0) - exp(-fExposure * groundAtmosphereColor); + //groundAtmosphereColor = vec3(1.0) - exp(-fExposure * groundAtmosphereColor); fadeInDist = u_nightFadeDistance.x; fadeOutDist = u_nightFadeDistance.y; From ad648f373aa01788339796cab07a819ef1dcdfbb Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Mon, 20 Aug 2018 16:02:48 -0400 Subject: [PATCH 26/76] Compute the atmosphere color per-fragment for smoother night-day transition. --- Source/Scene/Globe.js | 2 +- Source/Shaders/GlobeFS.glsl | 19 +++++++++++++++++-- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/Source/Scene/Globe.js b/Source/Scene/Globe.js index 60c4041272ef..133cfd547106 100644 --- a/Source/Scene/Globe.js +++ b/Source/Scene/Globe.js @@ -390,7 +390,7 @@ define([ var requireNormals = defined(globe._material) && (globe._material.shaderSource.match(/slope/) || globe._material.shaderSource.match('normalEC')); - var fragmentSources = []; + var fragmentSources = [GroundAtmosphere]; if (defined(globe._material) && (!requireNormals || globe._terrainProvider.requestVertexNormals)) { fragmentSources.push(globe._material.shaderSource); defines.push('APPLY_MATERIAL'); diff --git a/Source/Shaders/GlobeFS.glsl b/Source/Shaders/GlobeFS.glsl index 2d0ee50e04f7..876bf54eadb4 100644 --- a/Source/Shaders/GlobeFS.glsl +++ b/Source/Shaders/GlobeFS.glsl @@ -305,8 +305,23 @@ void main() return; } - vec3 groundAtmosphereColor = v_mieColor + finalColor.rgb * v_rayleighColor; - //groundAtmosphereColor = vec3(1.0) - exp(-fExposure * groundAtmosphereColor); + czm_ellipsoid ellipsoid = czm_getWgs84EllipsoidEC(); + + float mpp = czm_metersPerPixel(vec4(0.0, 0.0, -czm_currentFrustum.x, 1.0)); + vec2 xy = gl_FragCoord.xy / czm_viewport.zw * 2.0 - vec2(1.0); + xy *= czm_viewport.zw * mpp * 0.5; + + vec3 direction = normalize(vec3(xy, -czm_currentFrustum.x)); + czm_ray ray = czm_ray(vec3(0.0), direction); + + czm_raySegment intersection = czm_rayEllipsoidIntersectionInterval(ray, ellipsoid); + + vec3 ellipsoidPosition = czm_pointAlongRay(ray, intersection.start); + ellipsoidPosition = (czm_inverseView * vec4(ellipsoidPosition, 1.0)).xyz; + AtmosphereColor atmosColor = computeGroundAtmosphereFromSpace(ellipsoidPosition, true); + + vec3 groundAtmosphereColor = atmosColor.mie + finalColor.rgb * atmosColor.rayleigh; + groundAtmosphereColor = vec3(1.0) - exp(-fExposure * groundAtmosphereColor); fadeInDist = u_nightFadeDistance.x; fadeOutDist = u_nightFadeDistance.y; From da3bce1daa8800622b02f5714c1a465d59d0d7d0 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 29 Aug 2018 17:12:54 -0400 Subject: [PATCH 27/76] Add ability to change the tonemapping operator, but keep it private for now. Also disable auto-exposure until lighting is redone. --- Source/Renderer/Context.js | 1 - Source/Scene/AutoExposure.js | 94 ++++++++++++++++++++-- Source/Scene/PostProcessStageCollection.js | 78 ++++++++++++++---- Source/Scene/Tonemapper.js | 58 +++++++++++++ 4 files changed, 209 insertions(+), 22 deletions(-) create mode 100644 Source/Scene/Tonemapper.js diff --git a/Source/Renderer/Context.js b/Source/Renderer/Context.js index 8dbf771fae80..30968b0fc632 100644 --- a/Source/Renderer/Context.js +++ b/Source/Renderer/Context.js @@ -282,7 +282,6 @@ define([ this._textureFloat = !!getExtension(gl, ['OES_texture_float']); this._textureHalfFloat = !!getExtension(gl, ['OES_texture_half_float']); - this._textureFloatLinear = !!getExtension(gl, ['OES_texture_float_linear']); this._textureHalfFloatLinear = !!getExtension(gl, ['OES_texture_half_float_linear']); diff --git a/Source/Scene/AutoExposure.js b/Source/Scene/AutoExposure.js index 2dced9b02c55..a6ad222a1c10 100644 --- a/Source/Scene/AutoExposure.js +++ b/Source/Scene/AutoExposure.js @@ -30,6 +30,14 @@ define([ TextureWrap) { 'use strict'; + /** + * A post process stage that will get the luminance value at each pixel and + * uses parallel reduction to get the average luminance in a 1x1 texture. + * This texture can be used as input for tone mapping. + * + * @constructor + * @private + */ function AutoExposure() { this._uniformMap = undefined; this._command = undefined; @@ -48,11 +56,13 @@ define([ this._previousLuminance = undefined; this._commands = undefined; - this._clearCommand = new ClearCommand({ - color : new Color(0.0, 0.0, 0.0, 0.0), - framebuffer : undefined - }); + this._clearCommand = undefined; + /** + * Whether or not to execute this post-process stage when ready. + * + * @type {Boolean} + */ this.enabled = true; this._enabled = true; @@ -61,16 +71,41 @@ define([ } defineProperties(AutoExposure.prototype, { + /** + * Determines if this post-process stage is ready to be executed. A stage is only executed when both ready + * and {@link AutoExposure#enabled} are true. A stage will not be ready while it is waiting on textures + * to load. + * + * @memberof AutoExposure.prototype + * @type {Boolean} + * @readonly + */ ready : { get : function() { return this._ready; } }, + /** + * The unique name of this post-process stage for reference by other stages. + * + * @memberof AutoExposure.prototype + * @type {String} + * @readonly + */ name : { get : function() { return this._name; } }, + + /** + * A reference to the texture written to when executing this post process stage. + * + * @memberof AutoExposure.prototype + * @type {Texture} + * @readonly + * @private + */ outputTexture : { get : function() { var framebuffers = this._framebuffers; @@ -269,6 +304,11 @@ define([ autoexposure._commands = commands; } + /** + * A function that will be called before execute. Used to clear any textures attached to framebuffers. + * @param {Context} context The context. + * @private + */ AutoExposure.prototype.clear = function(context) { var framebuffers = this._framebuffers; if (!defined(framebuffers)) { @@ -276,6 +316,13 @@ define([ } var clearCommand = this._clearCommand; + if (!defined(clearCommand)) { + clearCommand = this._clearCommand = new ClearCommand({ + color : new Color(0.0, 0.0, 0.0, 0.0), + framebuffer : undefined + }); + } + var length = framebuffers.length; for (var i = 0; i < length; ++i) { clearCommand.framebuffer = framebuffers[i]; @@ -283,7 +330,12 @@ define([ } }; - AutoExposure.prototype.update = function(context, useLogDepth) { + /** + * A function that will be called before execute. Used to create WebGL resources and load any textures. + * @param {Context} context The context. + * @private + */ + AutoExposure.prototype.update = function(context) { var width = context.drawingBufferWidth; var height = context.drawingBufferHeight; @@ -306,7 +358,13 @@ define([ this._previousLuminance = temp; }; - AutoExposure.prototype.execute = function(context, colorTexture, depthTexture, idTexture) { + /** + * Executes the post-process stage. The color texture is the texture rendered to by the scene or from the previous stage. + * @param {Context} context The context. + * @param {Texture} colorTexture The input color texture. + * @private + */ + AutoExposure.prototype.execute = function(context, colorTexture) { this._colorTexture = colorTexture; var commands = this._commands; @@ -320,10 +378,34 @@ define([ } }; + /** + * Returns true if this object was destroyed; otherwise, false. + *

+ * If this object was destroyed, it should not be used; calling any function other than + * isDestroyed will result in a {@link DeveloperError} exception. + *

+ * + * @returns {Boolean} true if this object was destroyed; otherwise, false. + * + * @see AutoExposure#destroy + */ AutoExposure.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. + *

+ * Once an object is destroyed, it should not be used; calling any function other than + * isDestroyed will result in a {@link DeveloperError} exception. Therefore, + * assign the return value (undefined) to the object as done in the example. + *

+ * + * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. + * + * @see AutoExposure#isDestroyed + */ AutoExposure.prototype.destroy = function() { destroyFramebuffers(this); destroyCommands(this); diff --git a/Source/Scene/PostProcessStageCollection.js b/Source/Scene/PostProcessStageCollection.js index 2119df1c1408..bd6fa4a103d3 100644 --- a/Source/Scene/PostProcessStageCollection.js +++ b/Source/Scene/PostProcessStageCollection.js @@ -15,7 +15,8 @@ define([ '../Renderer/TextureWrap', '../Shaders/PostProcessStages/PassThrough', './PostProcessStageLibrary', - './PostProcessStageTextureCache' + './PostProcessStageTextureCache', + './Tonemapper' ], function( arraySlice, Check, @@ -33,7 +34,8 @@ define([ TextureWrap, PassThrough, PostProcessStageLibrary, - PostProcessStageTextureCache) { + PostProcessStageTextureCache, + Tonemapper) { 'use strict'; var stackScratch = []; @@ -59,19 +61,17 @@ define([ var ao = PostProcessStageLibrary.createAmbientOcclusionStage(); var bloom = PostProcessStageLibrary.createBloomStage(); - var useAutoExposure = false; - //var tonemapping = PostProcessStageLibrary.createReinhardTonemappingStage(useAutoExposure); - //var tonemapping = PostProcessStageLibrary.createModifiedReinhardTonemappingStage(useAutoExposure); - //var tonemapping = PostProcessStageLibrary.createFilmicTonemappingStage(useAutoExposure); - var tonemapping = PostProcessStageLibrary.createACESTonemappingStage(useAutoExposure); + // Auto-exposure is currently disabled because most shaders output a value in [0.0, 1.0]. + // Some shaders, such as the atmosphere and ground atmosphere, output values slightly over 1.0. + this._autoExposureEnabled = false; + this._autoExposure = PostProcessStageLibrary.createAutoExposureStage(); + this._tonemapping = undefined; + this._tonemapper = undefined; - var autoexposure = PostProcessStageLibrary.createAutoExposureStage(); + // set tonemapper and tonemapping + this.tonemapper = Tonemapper.ACES; - if (useAutoExposure) { - tonemapping.uniforms.autoExposure = function() { - return autoexposure.outputTexture; - }; - } + var tonemapping = this._tonemapping; ao.enabled = false; bloom.enabled = false; // TODO HDR @@ -112,8 +112,6 @@ define([ this._ao = ao; this._bloom = bloom; - this._autoExposure = autoexposure; - this._tonemapping = tonemapping; this._fxaa = fxaa; this._lastLength = undefined; @@ -335,6 +333,56 @@ define([ } return false; } + }, + /** + * Gets and sets the tonemapping algorithm used when rendering with high dynamic range. + * + * @memberof PostProcessStageCollection.prototype + * @type {Tonemapper} + * @private + */ + tonemapper : { + get : function() { + return this._tonemapper; + }, + set : function(value) { + if (this._tonemapper === value) { + return; + } + //>>includeStart('debug', pragmas.debug); + if (!Tonemapper.validate(value)) { + throw new DeveloperError('tonemapper was set to an invalid value.'); + } + //>>includeEnd('debug'); + + var useAutoExposure = this._autoExposureEnabled; + var tonemapper; + + switch(value) { + case Tonemapper.REINHARD: + tonemapper = PostProcessStageLibrary.createReinhardTonemappingStage(useAutoExposure); + break; + case Tonemapper.MODIFIED_REINHARD: + tonemapper = PostProcessStageLibrary.createModifiedReinhardTonemappingStage(useAutoExposure); + break; + case Tonemapper.FILMIC: + tonemapper = PostProcessStageLibrary.createFilmicTonemappingStage(useAutoExposure); + break; + default: + tonemapper = PostProcessStageLibrary.createACESTonemappingStage(useAutoExposure); + break; + } + + if (useAutoExposure) { + var autoexposure = this._autoExposure; + tonemapper.uniforms.autoExposure = function() { + return autoexposure.outputTexture; + }; + } + + this._tonemapper = value; + this._tonemapping = tonemapper; + } } }); diff --git a/Source/Scene/Tonemapper.js b/Source/Scene/Tonemapper.js new file mode 100644 index 000000000000..05b1bce9b565 --- /dev/null +++ b/Source/Scene/Tonemapper.js @@ -0,0 +1,58 @@ +define([ + '../Core/freezeObject' + ], function( + freezeObject) { + 'use strict'; + + /** + * A tonemapping algorithm when rendering with high dynamic range. + * + * @exports Tonemapper + * @private + */ + var Tonemapper = { + /** + * Use the Reinhard tonemapping operator. + * + * @type {Number} + * @constant + */ + REINHARD : 0, + + /** + * Use the modified Reinhard tonemapping operator. + * + * @type {Number} + * @constant + */ + MODIFIED_REINHARD : 1, + + /** + * Use the Filmic tonemapping operator. + * + * @type {Number} + * @constant + */ + FILMIC : 2, + + /** + * Use the ACES tonemapping operator. + * + * @type {Number} + * @constant + */ + ACES : 3, + + /** + * @private + */ + validate : function(tonemapper) { + return tonemapper === Tonemapper.REINHARD || + tonemapper === Tonemapper.MODIFIED_REINHARD || + tonemapper === Tonemapper.FILMIC || + tonemapper === Tonemapper.ACES; + } + }; + + return freezeObject(Tonemapper); +}); From 2d888fe84e477b4691175e363359b3a57b9008b2 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 29 Aug 2018 17:18:23 -0400 Subject: [PATCH 28/76] Switch back to using half-floats. --- Source/Scene/AutoExposure.js | 2 +- Source/Scene/GlobeDepth.js | 3 +-- Source/Scene/SceneFramebuffer.js | 3 +-- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/Source/Scene/AutoExposure.js b/Source/Scene/AutoExposure.js index a6ad222a1c10..016defb1f388 100644 --- a/Source/Scene/AutoExposure.js +++ b/Source/Scene/AutoExposure.js @@ -140,7 +140,7 @@ define([ var height = autoexposure._height; var pixelFormat = PixelFormat.RGBA; - var pixelDatatype = PixelDatatype.FLOAT; + var pixelDatatype = PixelDatatype.HALF_FLOAT; var sampler = new Sampler({ wrapS : TextureWrap.CLAMP_TO_EDGE, wrapT : TextureWrap.CLAMP_TO_EDGE, diff --git a/Source/Scene/GlobeDepth.js b/Source/Scene/GlobeDepth.js index ddabcbc00ca6..31a603280e9a 100644 --- a/Source/Scene/GlobeDepth.js +++ b/Source/Scene/GlobeDepth.js @@ -117,8 +117,7 @@ define([ width : width, height : height, pixelFormat : PixelFormat.RGBA, - //pixelDatatype : hdr ? PixelDatatype.HALF_FLOAT : PixelDatatype.UNSIGNED_BYTE, - pixelDatatype : hdr ? PixelDatatype.FLOAT : PixelDatatype.UNSIGNED_BYTE, + pixelDatatype : hdr ? PixelDatatype.HALF_FLOAT : PixelDatatype.UNSIGNED_BYTE, sampler : new Sampler({ wrapS : TextureWrap.CLAMP_TO_EDGE, wrapT : TextureWrap.CLAMP_TO_EDGE, diff --git a/Source/Scene/SceneFramebuffer.js b/Source/Scene/SceneFramebuffer.js index c90bea42ff21..2a251ee1899a 100644 --- a/Source/Scene/SceneFramebuffer.js +++ b/Source/Scene/SceneFramebuffer.js @@ -89,8 +89,7 @@ define([ width : width, height : height, pixelFormat : PixelFormat.RGBA, - //pixelDatatype : hdr ? PixelDatatype.HALF_FLOAT : PixelDatatype.UNSIGNED_BYTE, - pixelDatatype : hdr ? PixelDatatype.FLOAT : PixelDatatype.UNSIGNED_BYTE, + pixelDatatype : hdr ? PixelDatatype.HALF_FLOAT : PixelDatatype.UNSIGNED_BYTE, sampler : new Sampler({ wrapS : TextureWrap.CLAMP_TO_EDGE, wrapT : TextureWrap.CLAMP_TO_EDGE, From 129e50efb2bfa83d889c971c52e2bd2c023e766a Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 29 Aug 2018 17:22:58 -0400 Subject: [PATCH 29/76] Clean up auto-exposure usage. --- Source/Scene/PostProcessStageCollection.js | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/Source/Scene/PostProcessStageCollection.js b/Source/Scene/PostProcessStageCollection.js index bd6fa4a103d3..677029d118a0 100644 --- a/Source/Scene/PostProcessStageCollection.js +++ b/Source/Scene/PostProcessStageCollection.js @@ -637,9 +637,12 @@ define([ fxaa.update(context, useLogDepth); ao.update(context, useLogDepth); bloom.update(context, useLogDepth); - autoexposure.update(context, useLogDepth); tonemapping.update(context, useLogDepth); + if (this._autoExposureEnabled) { + autoexposure.update(context, useLogDepth); + } + length = stages.length; for (i = 0; i < length; ++i) { stages[i].update(context, useLogDepth); @@ -655,7 +658,10 @@ define([ */ PostProcessStageCollection.prototype.clear = function(context) { this._textureCache.clear(context); - this._autoExposure.clear(context); + + if (this._autoExposureEnabled) { + this._autoExposure.clear(context); + } }; function getOutputTexture(stage) { @@ -723,6 +729,7 @@ define([ var aoEnabled = ao.enabled && ao._isSupported(context); var bloomEnabled = bloom.enabled && bloom._isSupported(context); + var autoExposureEnabled = this._autoExposureEnabled; var tonemappingEnabled = tonemapping.enabled && tonemapping._isSupported(context); var fxaaEnabled = fxaa.enabled && fxaa._isSupported(context); @@ -739,7 +746,7 @@ define([ execute(bloom, context, initialTexture, depthTexture, idTexture); initialTexture = getOutputTexture(bloom); } - if (/*autoexposureEnabled &&*/ autoexposure.ready) { + if (autoExposureEnabled && autoexposure.ready) { execute(autoexposure, context, initialTexture, depthTexture, idTexture); } if (tonemappingEnabled && tonemapping.ready) { From 1e2bcd32a54c17795c33e409eb4694ecf8892d4f Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 29 Aug 2018 19:35:28 -0400 Subject: [PATCH 30/76] Revert bloom changes for now. [ci skip] --- Source/Scene/PostProcessStageCollection.js | 5 +- Source/Scene/PostProcessStageLibrary.js | 124 ++++++++++++--------- 2 files changed, 76 insertions(+), 53 deletions(-) diff --git a/Source/Scene/PostProcessStageCollection.js b/Source/Scene/PostProcessStageCollection.js index 677029d118a0..0205d65c9050 100644 --- a/Source/Scene/PostProcessStageCollection.js +++ b/Source/Scene/PostProcessStageCollection.js @@ -74,9 +74,8 @@ define([ var tonemapping = this._tonemapping; ao.enabled = false; - bloom.enabled = false; // TODO HDR - //bloom.enabled = true; - tonemapping.enabled = false; + bloom.enabled = false; + tonemapping.enabled = false; // will be enabled if necessary in update // TODO HDR fxaa.enabled = false; diff --git a/Source/Scene/PostProcessStageLibrary.js b/Source/Scene/PostProcessStageLibrary.js index fc247d76e91e..fe497049ae29 100644 --- a/Source/Scene/PostProcessStageLibrary.js +++ b/Source/Scene/PostProcessStageLibrary.js @@ -75,7 +75,7 @@ define([ */ var PostProcessStageLibrary = {}; - function createBlur(name, pixelDatatype, textureScale) { + function createBlur(name) { var delta = 1.0; var sigma = 2.0; var stepSize = 1.0; @@ -90,9 +90,7 @@ define([ stepSize : stepSize, direction : 0.0 }, - sampleMode : PostProcessStageSampleMode.LINEAR, - pixelDatatype : pixelDatatype, - textureScale : textureScale + sampleMode : PostProcessStageSampleMode.LINEAR }); var blurY = new PostProcessStage({ name : name + '_y_direction', @@ -103,9 +101,7 @@ define([ stepSize : stepSize, direction : 1.0 }, - sampleMode : PostProcessStageSampleMode.LINEAR, - pixelDatatype : pixelDatatype, - textureScale : textureScale + sampleMode : PostProcessStageSampleMode.LINEAR }); var uniforms = {}; @@ -432,58 +428,86 @@ define([ * @private */ PostProcessStageLibrary.createBloomStage = function() { - var scale = 1.0; - var brightFS = - 'uniform sampler2D colorTexture; \n' + - 'varying vec2 v_textureCoordinates; \n' + - 'void main() { \n' + - ' vec4 color = texture2D(colorTexture, v_textureCoordinates); \n' + - ' if (color.r > 1.0 || color.g > 1.0 || color.b > 1.0) { \n' + - ' gl_FragColor = vec4(color.rgb, 1.0); \n' + - ' } else { \n' + - ' gl_FragColor = vec4(vec3(0.0), 1.0); \n' + - ' } \n' + - '} \n'; - var brightPass = new PostProcessStage({ - fragmentShader : brightFS, - pixelDatatype : PixelDatatype.FLOAT, - textureScale : scale, - sampleMode : PostProcessStageSampleMode.LINEAR + var contrastBias = new PostProcessStage({ + name : 'czm_bloom_contrast_bias', + fragmentShader : ContrastBias, + uniforms : { + contrast : 128.0, + brightness : -0.3 + } }); - var numBlur = 6; - var blurs = new Array(numBlur); - for (var i = 0; i < numBlur; ++i) { - blurs[i] = createBlur('czm_bloom_blur_' + i, PixelDatatype.FLOAT, scale); - blurs[i].uniforms.delta = 1.5; - blurs[i].uniforms.sigma = 5.0; - } - var brightBlur = new PostProcessStageComposite({ - name : 'czm_brightness_blur', - stages : [brightPass].concat(blurs), - textureScale : scale + var blur = createBlur('czm_bloom_blur'); + var generateComposite = new PostProcessStageComposite({ + name : 'czm_bloom_contrast_bias_blur', + stages : [contrastBias, blur] }); - var addFS = - 'uniform sampler2D colorTexture; \n' + - 'uniform sampler2D brightTexture; \n' + - 'varying vec2 v_textureCoordinates; \n' + - 'void main() { \n' + - ' vec4 color = texture2D(colorTexture, v_textureCoordinates); \n' + - ' vec4 bloom = texture2D(brightTexture, v_textureCoordinates); \n' + - ' gl_FragColor = vec4(color.rgb + bloom.rgb, 1.0); \n' + - '} \n'; - var add = new PostProcessStage({ - fragmentShader : addFS, - pixelDatatype : PixelDatatype.FLOAT, + var bloomComposite = new PostProcessStage({ + name : 'czm_bloom_generate_composite', + fragmentShader : BloomComposite, uniforms : { - brightTexture : brightBlur.name + glowOnly : false, + bloomTexture : generateComposite.name + } + }); + + var uniforms = {}; + defineProperties(uniforms, { + glowOnly : { + get : function() { + return bloomComposite.uniforms.glowOnly; + }, + set : function(value) { + bloomComposite.uniforms.glowOnly = value; + } + }, + contrast : { + get : function() { + return contrastBias.uniforms.contrast; + }, + set : function(value) { + contrastBias.uniforms.contrast = value; + } + }, + brightness : { + get : function() { + return contrastBias.uniforms.brightness; + }, + set : function(value) { + contrastBias.uniforms.brightness = value; + } + }, + delta : { + get : function() { + return blur.uniforms.delta; + }, + set : function(value) { + blur.uniforms.delta = value; + } + }, + sigma : { + get : function() { + return blur.uniforms.sigma; + }, + set : function(value) { + blur.uniforms.sigma = value; + } + }, + stepSize : { + get : function() { + return blur.uniforms.stepSize; + }, + set : function(value) { + blur.uniforms.stepSize = value; + } } }); return new PostProcessStageComposite({ name : 'czm_bloom', - stages : [brightBlur, add], - inputPreviousStageTexture : false + stages : [generateComposite, bloomComposite], + inputPreviousStageTexture : false, + uniforms : uniforms }); }; From 2bb0043609147c66f31a4082077b5c51522592d6 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 30 Aug 2018 16:08:21 -0400 Subject: [PATCH 31/76] Add doc. [ci skip] --- Source/Scene/PostProcessStageCollection.js | 3 -- Source/Scene/PostProcessStageLibrary.js | 33 ++++++++++++++++--- Source/Scene/Scene.js | 9 +++-- .../PostProcessStages/ACESTonemapping.glsl | 3 ++ 4 files changed, 39 insertions(+), 9 deletions(-) diff --git a/Source/Scene/PostProcessStageCollection.js b/Source/Scene/PostProcessStageCollection.js index 0205d65c9050..f9d6905e9bfb 100644 --- a/Source/Scene/PostProcessStageCollection.js +++ b/Source/Scene/PostProcessStageCollection.js @@ -77,9 +77,6 @@ define([ bloom.enabled = false; tonemapping.enabled = false; // will be enabled if necessary in update - // TODO HDR - fxaa.enabled = false; - var textureCache = new PostProcessStageTextureCache(this); var stageNames = {}; diff --git a/Source/Scene/PostProcessStageLibrary.js b/Source/Scene/PostProcessStageLibrary.js index fe497049ae29..172616ba1387 100644 --- a/Source/Scene/PostProcessStageLibrary.js +++ b/Source/Scene/PostProcessStageLibrary.js @@ -7,14 +7,12 @@ define([ '../Core/deprecationWarning', '../Core/destroyObject', '../Core/Ellipsoid', - '../Renderer/PixelDatatype', '../Shaders/PostProcessStages/ACESTonemapping', '../Shaders/PostProcessStages/AmbientOcclusionGenerate', '../Shaders/PostProcessStages/AmbientOcclusionModulate', '../Shaders/PostProcessStages/BlackAndWhite', '../Shaders/PostProcessStages/BloomComposite', '../Shaders/PostProcessStages/Brightness', - '../Shaders/PostProcessStages/BrightPass', '../Shaders/PostProcessStages/ContrastBias', '../Shaders/PostProcessStages/DepthOfField', '../Shaders/PostProcessStages/DepthView', @@ -41,14 +39,12 @@ define([ deprecationWarning, destroyObject, Ellipsoid, - PixelDatatype, ACESTonemapping, AmbientOcclusionGenerate, AmbientOcclusionModulate, BlackAndWhite, BloomComposite, Brightness, - BrightPass, ContrastBias, DepthOfField, DepthView, @@ -699,6 +695,12 @@ define([ }); }; + /** + * Creates a post-process stage that applies ACES tonemapping operator. + * @param {Boolean} useAutoExposure Whether or not to use auto-exposure. + * @return {PostProcessStage} A post-process stage that applies ACES tonemapping operator. + * @private + */ PostProcessStageLibrary.createACESTonemappingStage = function(useAutoExposure) { var fs = useAutoExposure ? '#define AUTO_EXPOSURE\n' : ''; fs += ACESTonemapping; @@ -711,6 +713,12 @@ define([ }); }; + /** + * Creates a post-process stage that applies filmic tonemapping operator. + * @param {Boolean} useAutoExposure Whether or not to use auto-exposure. + * @return {PostProcessStage} A post-process stage that applies filmic tonemapping operator. + * @private + */ PostProcessStageLibrary.createFilmicTonemappingStage = function(useAutoExposure) { var fs = useAutoExposure ? '#define AUTO_EXPOSURE\n' : ''; fs += FilmicTonemapping; @@ -723,6 +731,12 @@ define([ }); }; + /** + * Creates a post-process stage that applies Reinhard tonemapping operator. + * @param {Boolean} useAutoExposure Whether or not to use auto-exposure. + * @return {PostProcessStage} A post-process stage that applies Reinhard tonemapping operator. + * @private + */ PostProcessStageLibrary.createReinhardTonemappingStage = function(useAutoExposure) { var fs = useAutoExposure ? '#define AUTO_EXPOSURE\n' : ''; fs += ReinhardTonemapping; @@ -735,6 +749,12 @@ define([ }); }; + /** + * Creates a post-process stage that applies modified Reinhard tonemapping operator. + * @param {Boolean} useAutoExposure Whether or not to use auto-exposure. + * @return {PostProcessStage} A post-process stage that applies modified Reinhard tonemapping operator. + * @private + */ PostProcessStageLibrary.createModifiedReinhardTonemappingStage = function(useAutoExposure) { var fs = useAutoExposure ? '#define AUTO_EXPOSURE\n' : ''; fs += ModifiedReinhardTonemapping; @@ -748,6 +768,11 @@ define([ }); }; + /** + * Creates a post-process stage that finds the average luminance of the input texture. + * @return {PostProcessStage} A post-process stage that finds the average luminance of the input texture. + * @private + */ PostProcessStageLibrary.createAutoExposureStage = function() { return new AutoExposure(); }; diff --git a/Source/Scene/Scene.js b/Source/Scene/Scene.js index 0a42107d3108..2a259817c96c 100644 --- a/Source/Scene/Scene.js +++ b/Source/Scene/Scene.js @@ -433,8 +433,7 @@ define([ * @type {Boolean} * @default true */ - this.sunBloom = !this._hdr; // TODO HDR - //this.sunBloom = true; + this.sunBloom = true; this._sunBloom = undefined; /** @@ -1455,6 +1454,12 @@ define([ } }, + /** + * The value used for gamma correction. + * @memberof Scene.prototype + * @type {Number} + * @default 2.4 + */ gamma : { get : function() { return this._context.uniformState.gamma; diff --git a/Source/Shaders/PostProcessStages/ACESTonemapping.glsl b/Source/Shaders/PostProcessStages/ACESTonemapping.glsl index e9d10b175e1a..94e905ad8012 100644 --- a/Source/Shaders/PostProcessStages/ACESTonemapping.glsl +++ b/Source/Shaders/PostProcessStages/ACESTonemapping.glsl @@ -6,6 +6,9 @@ varying vec2 v_textureCoordinates; uniform sampler2D autoExposure; #endif +// See: +// https://knarkowicz.wordpress.com/2016/01/06/aces-filmic-tone-mapping-curve/ + void main() { vec3 color = texture2D(colorTexture, v_textureCoordinates).rgb; From 51e8523c6028c65ae91b941056c67c317406ccd5 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 30 Aug 2018 16:51:41 -0400 Subject: [PATCH 32/76] Fix sun extending beyond texture. --- Source/Scene/Sun.js | 6 +----- Source/Shaders/SunTextureFS.glsl | 7 ++++--- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/Source/Scene/Sun.js b/Source/Scene/Sun.js index 54b10c365380..e04347d1ab2d 100644 --- a/Source/Scene/Sun.js +++ b/Source/Scene/Sun.js @@ -180,8 +180,7 @@ define([ width : size, height : size, pixelFormat : PixelFormat.RGBA, - //pixelDatatype : useHDR ? PixelDatatype.HALF_FLOAT : PixelFormat.UNSIGNED_BYTE - pixelDatatype : useHDR ? PixelDatatype.FLOAT : PixelFormat.UNSIGNED_BYTE + pixelDatatype : useHDR ? PixelDatatype.HALF_FLOAT : PixelFormat.UNSIGNED_BYTE }); this._glowLengthTS = this._glowFactor * 5.0; @@ -189,9 +188,6 @@ define([ var that = this; var uniformMap = { - u_glowLengthTS : function() { - return that._glowLengthTS; - }, u_radiusTS : function() { return that._radiusTS; } diff --git a/Source/Shaders/SunTextureFS.glsl b/Source/Shaders/SunTextureFS.glsl index 92fd958128e8..fb286f6dee3c 100644 --- a/Source/Shaders/SunTextureFS.glsl +++ b/Source/Shaders/SunTextureFS.glsl @@ -1,4 +1,3 @@ -uniform float u_glowLengthTS; uniform float u_radiusTS; varying vec2 v_textureCoordinates; @@ -8,10 +7,12 @@ vec2 rotate(vec2 p, vec2 direction) return vec2(p.x * direction.x - p.y * direction.y, p.x * direction.y + p.y * direction.x); } +const float lengthScalar = 2.0 / sqrt(2.0); + vec4 addBurst(vec2 position, vec2 direction) { vec2 rotatedPosition = rotate(position, direction) * vec2(25.0, 0.75); - float radius = length(rotatedPosition); + float radius = length(rotatedPosition) * lengthScalar; float burst = 1.0 - smoothstep(0.0, 0.55, radius); return vec4(burst); @@ -20,7 +21,7 @@ vec4 addBurst(vec2 position, vec2 direction) void main() { vec2 position = v_textureCoordinates - vec2(0.5); - float radius = length(position); + float radius = length(position) * lengthScalar; float surface = step(radius, u_radiusTS); vec4 color = vec4(vec2(1.0), surface + 0.2, surface); From 9353d45cf5bc3d03dd0c1692d9194da9cc555ff8 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 30 Aug 2018 16:55:42 -0400 Subject: [PATCH 33/76] Use half-floats when supported. --- Source/Scene/AutoExposure.js | 2 +- Source/Scene/GlobeDepth.js | 3 ++- Source/Scene/SceneFramebuffer.js | 3 ++- Source/Scene/Sun.js | 3 ++- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/Source/Scene/AutoExposure.js b/Source/Scene/AutoExposure.js index 016defb1f388..7ae2b0d01d11 100644 --- a/Source/Scene/AutoExposure.js +++ b/Source/Scene/AutoExposure.js @@ -140,7 +140,7 @@ define([ var height = autoexposure._height; var pixelFormat = PixelFormat.RGBA; - var pixelDatatype = PixelDatatype.HALF_FLOAT; + var pixelDatatype = context.halfFloatingPointTexture ? PixelDatatype.HALF_FLOAT : PixelDatatype.FLOAT; var sampler = new Sampler({ wrapS : TextureWrap.CLAMP_TO_EDGE, wrapT : TextureWrap.CLAMP_TO_EDGE, diff --git a/Source/Scene/GlobeDepth.js b/Source/Scene/GlobeDepth.js index 31a603280e9a..d3d1d4d9e1b0 100644 --- a/Source/Scene/GlobeDepth.js +++ b/Source/Scene/GlobeDepth.js @@ -112,12 +112,13 @@ define([ } function createTextures(globeDepth, context, width, height, hdr) { + var pixelDatatype = hdr ? (context.halfFloatingPointTexture ? PixelDatatype.HALF_FLOAT : PixelDatatype.FLOAT) : PixelDatatype.UNSIGNED_BYTE; globeDepth._colorTexture = new Texture({ context : context, width : width, height : height, pixelFormat : PixelFormat.RGBA, - pixelDatatype : hdr ? PixelDatatype.HALF_FLOAT : PixelDatatype.UNSIGNED_BYTE, + pixelDatatype : pixelDatatype, sampler : new Sampler({ wrapS : TextureWrap.CLAMP_TO_EDGE, wrapT : TextureWrap.CLAMP_TO_EDGE, diff --git a/Source/Scene/SceneFramebuffer.js b/Source/Scene/SceneFramebuffer.js index 2a251ee1899a..0d4305047347 100644 --- a/Source/Scene/SceneFramebuffer.js +++ b/Source/Scene/SceneFramebuffer.js @@ -84,12 +84,13 @@ define([ destroyResources(this); + var pixelDatatype = hdr ? (context.halfFloatingPointTexture ? PixelDatatype.HALF_FLOAT : PixelDatatype.FLOAT) : PixelDatatype.UNSIGNED_BYTE; this._colorTexture = new Texture({ context : context, width : width, height : height, pixelFormat : PixelFormat.RGBA, - pixelDatatype : hdr ? PixelDatatype.HALF_FLOAT : PixelDatatype.UNSIGNED_BYTE, + pixelDatatype : pixelDatatype, sampler : new Sampler({ wrapS : TextureWrap.CLAMP_TO_EDGE, wrapT : TextureWrap.CLAMP_TO_EDGE, diff --git a/Source/Scene/Sun.js b/Source/Scene/Sun.js index e04347d1ab2d..9ef176bd3cac 100644 --- a/Source/Scene/Sun.js +++ b/Source/Scene/Sun.js @@ -175,12 +175,13 @@ define([ // errors in the tests. size = Math.max(1.0, size); + var pixelDatatype = useHDR ? (context.halfFloatingPointTexture ? PixelDatatype.HALF_FLOAT : PixelDatatype.FLOAT) : PixelDatatype.UNSIGNED_BYTE; this._texture = new Texture({ context : context, width : size, height : size, pixelFormat : PixelFormat.RGBA, - pixelDatatype : useHDR ? PixelDatatype.HALF_FLOAT : PixelFormat.UNSIGNED_BYTE + pixelDatatype : pixelDatatype }); this._glowLengthTS = this._glowFactor * 5.0; From a6f2e72d0d55c405083fa6325814b9489101f7ad Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 30 Aug 2018 19:49:09 -0400 Subject: [PATCH 34/76] Add flag for HDR (need to modify shaders). Clean up phong lighting. --- Source/Scene/Scene.js | 20 +++++++++++++++++-- Source/Scene/Sun.js | 6 +++++- Source/Shaders/Builtin/Functions/fog.glsl | 2 -- .../Builtin/Functions/gammaCorrect.glsl | 13 ++++++++++-- .../Builtin/Functions/inverseGamma.glsl | 13 ++++++++++-- Source/Shaders/Builtin/Functions/phong.glsl | 19 +++--------------- 6 files changed, 48 insertions(+), 25 deletions(-) diff --git a/Source/Scene/Scene.js b/Source/Scene/Scene.js index 71fccef848cf..f84353bdbf3f 100644 --- a/Source/Scene/Scene.js +++ b/Source/Scene/Scene.js @@ -325,8 +325,6 @@ define([ this._oit = oit; this._sceneFramebuffer = new SceneFramebuffer(); - this._hdr = context.depthTexture && (context.colorBufferFloat || context.colorBufferHalfFloat); - this._clearColorCommand = new ClearCommand({ color : new Color(), stencil : 0, @@ -803,6 +801,8 @@ define([ this._removeTaskProcessorListenerCallback = TaskProcessor.taskCompletedEvent.addEventListener(requestRenderAfterFrame(this)); this._removeGlobeCallbacks = []; + this._hdr = undefined; + this.hdr = true; this.gamma = 2.4; this._sunColor = new Color(0.8, 0.85, 1.0, 1.0); @@ -1450,6 +1450,22 @@ define([ } }, + /** + * 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; + this._hdr = value && context.depthTexture && (context.colorBufferFloat || context.colorBufferHalfFloat); + } + }, + /** * Gets or sets the color of the light emitted by the sun. * diff --git a/Source/Scene/Sun.js b/Source/Scene/Sun.js index 9ef176bd3cac..a8d399d091d3 100644 --- a/Source/Scene/Sun.js +++ b/Source/Scene/Sun.js @@ -101,6 +101,8 @@ define([ this.glowFactor = 1.0; this._glowFactorDirty = false; + this._useHDR = undefined; + var that = this; this._uniformMap = { u_texture : function() { @@ -161,11 +163,13 @@ define([ if (!defined(this._texture) || drawingBufferWidth !== this._drawingBufferWidth || drawingBufferHeight !== this._drawingBufferHeight || - this._glowFactorDirty) { + this._glowFactorDirty || + useHDR !== this._useHDR) { this._texture = this._texture && this._texture.destroy(); this._drawingBufferWidth = drawingBufferWidth; this._drawingBufferHeight = drawingBufferHeight; this._glowFactorDirty = false; + this._useHDR = useHDR; var size = Math.max(drawingBufferWidth, drawingBufferHeight); size = Math.pow(2.0, Math.ceil(Math.log(size) / Math.log(2.0)) - 2.0); diff --git a/Source/Shaders/Builtin/Functions/fog.glsl b/Source/Shaders/Builtin/Functions/fog.glsl index f9dcf2f6643e..002237504979 100644 --- a/Source/Shaders/Builtin/Functions/fog.glsl +++ b/Source/Shaders/Builtin/Functions/fog.glsl @@ -14,7 +14,6 @@ vec3 czm_fog(float distanceToCamera, vec3 color, vec3 fogColor) { float scalar = distanceToCamera * czm_fogDensity; float fog = 1.0 - exp(-(scalar * scalar)); - return mix(color, fogColor, fog); } @@ -35,6 +34,5 @@ vec3 czm_fog(float distanceToCamera, vec3 color, vec3 fogColor, float fogModifie { float scalar = distanceToCamera * czm_fogDensity; float fog = 1.0 - exp(-((fogModifierConstant * scalar + fogModifierConstant) * (scalar * (1.0 + fogModifierConstant)))); - return mix(color, fogColor, fog); } diff --git a/Source/Shaders/Builtin/Functions/gammaCorrect.glsl b/Source/Shaders/Builtin/Functions/gammaCorrect.glsl index 595c6763b330..36a04889595a 100644 --- a/Source/Shaders/Builtin/Functions/gammaCorrect.glsl +++ b/Source/Shaders/Builtin/Functions/gammaCorrect.glsl @@ -1,3 +1,12 @@ -vec3 czm_gammaCorrect(vec3 rgb) { - return pow(rgb, vec3(czm_gamma)); +/** + * Converts a color from RGB space to linear space. + * + * @name czm_gammaCorrect + * @glslFunction + * + * @param {vec3} color The color in RGB space. + * @returns {vec3} The color in linear space. + */ +vec3 czm_gammaCorrect(vec3 color) { + return pow(color, vec3(czm_gamma)); } diff --git a/Source/Shaders/Builtin/Functions/inverseGamma.glsl b/Source/Shaders/Builtin/Functions/inverseGamma.glsl index 461113bc89fc..c12b8400b064 100644 --- a/Source/Shaders/Builtin/Functions/inverseGamma.glsl +++ b/Source/Shaders/Builtin/Functions/inverseGamma.glsl @@ -1,3 +1,12 @@ -vec3 czm_inverseGamma(vec3 rgb) { - return pow(rgb, vec3(1.0 / czm_gamma)); +/** + * Converts a color in linear space to RGB space. + * + * @name czm_inverseGamma + * @glslFunction + * + * @param {vec3} color The color in linear space. + * @returns {vec3} The color in RGB space. + */ +vec3 czm_inverseGamma(vec3 color) { + return pow(color, vec3(1.0 / czm_gamma)); } diff --git a/Source/Shaders/Builtin/Functions/phong.glsl b/Source/Shaders/Builtin/Functions/phong.glsl index 70999aba0c9b..2e223b489db5 100644 --- a/Source/Shaders/Builtin/Functions/phong.glsl +++ b/Source/Shaders/Builtin/Functions/phong.glsl @@ -28,7 +28,6 @@ float czm_private_getSpecularOfMaterial(vec3 lightDirectionEC, vec3 toEyeEC, czm */ vec4 czm_phong(vec3 toEye, czm_material material) { -/* // Diffuse from directional light sources at eye (for top-down) float diffuse = czm_private_getLambertDiffuseOfMaterial(vec3(0.0, 0.0, 1.0), material); if (czm_sceneMode == czm_sceneMode3D) { @@ -47,24 +46,12 @@ vec4 czm_phong(vec3 toEye, czm_material material) color += materialDiffuse * diffuse; color += material.specular * specular; - return vec4(color, material.alpha); - */ - - vec3 color = material.emission + material.diffuse * 0.25; +#define HDR +#ifdef HDR vec3 sunColor = czm_sunColor.rgb + czm_sunColor.a; - -#define USE_SUN_LIGHTING - -#ifdef USE_SUN_LIGHTING float sunDiffuse = czm_private_getLambertDiffuseOfMaterial(czm_sunDirectionEC, material); - float sunSpecular = czm_private_getSpecularOfMaterial(czm_sunDirectionEC, toEye, material); - - color += material.diffuse * sunDiffuse * sunColor; - color += material.specular * sunSpecular; -#else - float cameraDiffuse = czm_private_getLambertDiffuseOfMaterial(vec3(0.0, 0.0, 1.0), material); - color += material.diffuse * cameraDiffuse * sunColor; + color += materialDiffuse * sunDiffuse * sunColor; #endif return vec4(color, material.alpha); From 84ecd4ba7db621ee764f746fbb91b91e35aabf26 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Fri, 31 Aug 2018 18:02:18 -0400 Subject: [PATCH 35/76] Clean up shaders. --- Source/Shaders/Builtin/Functions/phong.glsl | 2 - Source/Shaders/GlobeFS.glsl | 56 ++++++++++--------- Source/Shaders/SkyAtmosphereFS.glsl | 5 +- .../processPbrMetallicRoughness.js | 6 +- 4 files changed, 35 insertions(+), 34 deletions(-) diff --git a/Source/Shaders/Builtin/Functions/phong.glsl b/Source/Shaders/Builtin/Functions/phong.glsl index 2e223b489db5..7f0374b26368 100644 --- a/Source/Shaders/Builtin/Functions/phong.glsl +++ b/Source/Shaders/Builtin/Functions/phong.glsl @@ -46,8 +46,6 @@ vec4 czm_phong(vec3 toEye, czm_material material) color += materialDiffuse * diffuse; color += material.specular * specular; -#define HDR - #ifdef HDR vec3 sunColor = czm_sunColor.rgb + czm_sunColor.a; float sunDiffuse = czm_private_getLambertDiffuseOfMaterial(czm_sunDirectionEC, material); diff --git a/Source/Shaders/GlobeFS.glsl b/Source/Shaders/GlobeFS.glsl index dc555a424c3d..19f1ef8da474 100644 --- a/Source/Shaders/GlobeFS.glsl +++ b/Source/Shaders/GlobeFS.glsl @@ -120,6 +120,10 @@ vec4 sampleAndBlend( vec3 color = value.rgb; float alpha = value.a; +#ifdef APPLY_GAMMA + color = pow(color, vec3(textureOneOverGamma)); +#endif + color = czm_gammaCorrect(color); #ifdef APPLY_SPLIT @@ -150,10 +154,6 @@ vec4 sampleAndBlend( color = czm_saturation(color, textureSaturation); #endif -//#ifdef APPLY_GAMMA -// color = pow(color, vec3(textureOneOverGamma)); -//#endif - float sourceAlpha = alpha * textureAlpha; float outAlpha = mix(previousColor.a, 1.0, sourceAlpha); vec3 outColor = mix(previousColor.rgb * previousColor.a, color, sourceAlpha) / outAlpha; @@ -183,10 +183,10 @@ void main() } #endif -//#if defined(SHOW_REFLECTIVE_OCEAN) || defined(ENABLE_DAYNIGHT_SHADING) +#if defined(SHOW_REFLECTIVE_OCEAN) || defined(ENABLE_DAYNIGHT_SHADING) || defined(HDR) vec3 normalMC = czm_geodeticSurfaceNormal(v_positionMC, vec3(0.0), vec3(1.0)); // normalized surface normal in model coordinates vec3 normalEC = czm_normal3D * normalMC; // normalized surface normal in eye coordiantes -//#endif +#endif #ifdef SHOW_REFLECTIVE_OCEAN vec2 waterMaskTranslation = u_waterMaskTranslationAndScale.xy; @@ -244,7 +244,13 @@ void main() float fade = clamp((cameraDist - fadeOutDist) / (fadeInDist - fadeOutDist), 0.0, 1.0); #endif -#if defined(ENABLE_VERTEX_LIGHTING) && !defined(GROUND_ATMOSPHERE) +#ifdef HDR + czm_material material; + material.diffuse = color.rgb; + material.alpha = color.a; + material.normal = normalEC; + vec4 finalColor = czm_phong(normalize(-v_positionEC), material); +#elif defined(ENABLE_VERTEX_LIGHTING) && !defined(GROUND_ATMOSPHERE) float diffuseIntensity = clamp(czm_getLambertDiffuse(czm_sunDirectionEC, normalize(v_normalEC)) * 0.9 + 0.3, 0.0, 1.0); vec4 finalColor = vec4(color.rgb * diffuseIntensity, color.a); #elif defined(ENABLE_DAYNIGHT_SHADING) && !defined(GROUND_ATMOSPHERE) @@ -255,19 +261,7 @@ void main() vec4 finalColor = color; #endif -//#ifdef ENABLE_VERTEX_LIGHTING - czm_material material; - material.diffuse = color.rgb; - material.alpha = color.a; - material.normal = normalEC; - //vec4 finalColor = czm_phong(normalize(-v_positionEC), material); - finalColor = czm_phong(normalize(-v_positionEC), material); -//#else -// vec4 finalColor = color; -//#endif - //gl_FragColor = finalColor; - //return; #ifdef ENABLE_CLIPPING_PLANES vec4 clippingPlanesEdgeColor = vec4(1.0); @@ -283,8 +277,9 @@ void main() #if defined(FOG) || defined(GROUND_ATMOSPHERE) const float fExposure = 1.3; vec3 fogColor = v_fogMieColor + finalColor.rgb * v_fogRayleighColor; - // TODO: disable exposure if using HDR - //fogColor = vec3(1.0) - exp(-fExposure * fogColor); +#ifndef HDR + fogColor = vec3(1.0) - exp(-fExposure * fogColor); +#endif #endif #ifdef FOG @@ -293,9 +288,12 @@ void main() fogColor *= darken; #endif - // TODO: Only use modified fog function if HDR +#ifdef HDR const float modifier = 0.15; finalColor = vec4(czm_fog(v_distance, finalColor.rgb, fogColor, modifier), finalColor.a); +#else + finalColor = vec4(czm_fog(v_distance, finalColor.rgb, fogColor), finalColor.a); +#endif #endif #ifdef GROUND_ATMOSPHERE @@ -423,15 +421,21 @@ vec4 computeWaterColor(vec3 positionEyeCoordinates, vec2 textureCoordinates, mat // Add specular highlights in 3D, and in all modes when zoomed in. float specularIntensity = czm_getSpecular(czm_sunDirectionEC, normalizedpositionToEyeEC, normalEC, 10.0) + 0.25 * czm_getSpecular(czm_moonDirectionEC, normalizedpositionToEyeEC, normalEC, 10.0); float surfaceReflectance = mix(0.0, mix(u_zoomedOutOceanSpecularIntensity, oceanSpecularIntensity, waveIntensity), maskValue); - float specular = specularIntensity * surfaceReflectance * 1.4; + float specular = specularIntensity * surfaceReflectance; + +#ifdef HDR + specular *= 1.4; float e = 0.2; float d = 3.3; float c = 1.7; - return vec4(imageryColor.rgb + (c * (vec3(e) + imageryColor.rgb * d) * (diffuseHighlight + nonDiffuseHighlight + specular)), imageryColor.a); - //return vec4(0.0, 0.0, 1.0, 1.0); - //return vec4(imageryColor.rgb + diffuseHighlight + nonDiffuseHighlight + specular, imageryColor.a); + vec3 color = imageryColor.rgb + (c * (vec3(e) + imageryColor.rgb * d) * (diffuseHighlight + nonDiffuseHighlight + specular)); +#else + vec3 color = imageryColor.rgb + diffuseHighlight + nonDiffuseHighlight + specular; +#endif + + return vec4(color, imageryColor.a); } #endif // #ifdef SHOW_REFLECTIVE_OCEAN diff --git a/Source/Shaders/SkyAtmosphereFS.glsl b/Source/Shaders/SkyAtmosphereFS.glsl index 5f6ffb2864c0..b90fbec67933 100644 --- a/Source/Shaders/SkyAtmosphereFS.glsl +++ b/Source/Shaders/SkyAtmosphereFS.glsl @@ -47,9 +47,6 @@ varying vec3 v_mieColor; varying vec3 v_toCamera; varying vec3 v_positionEC; -// TODO HDR -#define HDR - void main (void) { // Extra normalize added for Android @@ -61,7 +58,7 @@ void main (void) #ifndef HDR const float exposure = 1.1; - //rgb = vec3(1.0) - exp(-exposure * rgb); + rgb = vec3(1.0) - exp(-exposure * rgb); #endif #ifdef COLOR_CORRECT diff --git a/Source/ThirdParty/GltfPipeline/processPbrMetallicRoughness.js b/Source/ThirdParty/GltfPipeline/processPbrMetallicRoughness.js index bc949b8ac30e..28fe28dea4e0 100644 --- a/Source/ThirdParty/GltfPipeline/processPbrMetallicRoughness.js +++ b/Source/ThirdParty/GltfPipeline/processPbrMetallicRoughness.js @@ -460,11 +460,13 @@ define([ ' return vec4(linearOut, srgbIn.a);\n' + '}\n\n'; - // TODO HDR fragmentShader += 'vec3 LINEARtoSRGB(vec3 linearIn) \n' + '{\n' + - //' return pow(linearIn, vec3(1.0/2.2));\n' + + '#ifndef HDR \n' + + ' return pow(linearIn, vec3(1.0/2.2));\n' + + '#else \n' + ' return linearIn;\n' + + '#endif \n' + '}\n\n'; fragmentShader += 'void main(void) \n{\n'; From 1dc42bcb51ec843ec7457b2faee16425f97ff442 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Fri, 31 Aug 2018 18:41:45 -0400 Subject: [PATCH 36/76] Add HDR derived commands to add an HDR define when supported. Otherwise, gamma correct the color. --- Source/Scene/DerivedCommand.js | 80 ++++++++++++++++++++++++++++++++++ Source/Scene/Scene.js | 17 ++++++-- 2 files changed, 94 insertions(+), 3 deletions(-) diff --git a/Source/Scene/DerivedCommand.js b/Source/Scene/DerivedCommand.js index a4f969c41ba7..b424eae4f9dc 100644 --- a/Source/Scene/DerivedCommand.js +++ b/Source/Scene/DerivedCommand.js @@ -323,5 +323,85 @@ define([ return result; }; + function getHDRShaderProgram(context, useHDR, shaderProgram) { + var shader; + var attributeLocations; + var vs; + var fs; + + if (useHDR) { + shader = context.shaderCache.getDerivedShaderProgram(shaderProgram, 'HDR'); + if (!defined(shader)) { + attributeLocations = shaderProgram._attributeLocations; + vs = shaderProgram.vertexShaderSource.clone(); + fs = shaderProgram.fragmentShaderSource.clone(); + + vs.defines = defined(vs.defines) ? vs.defines.slice(0) : []; + vs.defines.push('HDR'); + fs.defines = defined(fs.defines) ? fs.defines.slice(0) : []; + fs.defines.push('HDR'); + + shader = context.shaderCache.createDerivedShaderProgram(shaderProgram, 'HDR', { + vertexShaderSource : vs, + fragmentShaderSource : fs, + attributeLocations : attributeLocations + }); + } + + return shader; + } + + shader = context.shaderCache.getDerivedShaderProgram(shaderProgram, 'gammaCorrect'); + if (!defined(shader)) { + attributeLocations = shaderProgram._attributeLocations; + vs = shaderProgram.vertexShaderSource.clone(); + fs = shaderProgram.fragmentShaderSource.clone(); + + var sources = fs.sources; + var length = sources.length; + for (var i = 0; i < length; ++i) { + sources[i] = ShaderSource.replaceMain(sources[i], 'czm_non_gamma_main'); + } + + var main = + '\n\n' + + 'void main() \n' + + '{ \n' + + ' czm_non_gamma_main(); \n' + + ' gl_FragColor.rgb = czm_inverseGamma(gl_FragColor.rgb); \n' + + '} \n'; + sources.push(main); + + shader = context.shaderCache.createDerivedShaderProgram(shaderProgram, 'HDR', { + vertexShaderSource : vs, + fragmentShaderSource : fs, + attributeLocations : attributeLocations + }); + } + return shader; + } + + DerivedCommand.createHDRCommand = function(command, context, useHDR, result) { + if (!defined(result)) { + result = {}; + } + + var shader; + if (defined(result.command)) { + shader = result.command.shaderProgram; + } + + result.command = DrawCommand.shallowClone(command, result.command); + + if (!defined(shader) || result.shaderProgramId !== command.shaderProgram.id) { + result.command.shaderProgram = getHDRShaderProgram(context, useHDR, command.shaderProgram); + result.shaderProgramId = command.shaderProgram.id; + } else { + result.command.shaderProgram = shader; + } + + return result; + }; + return DerivedCommand; }); diff --git a/Source/Scene/Scene.js b/Source/Scene/Scene.js index f84353bdbf3f..6b57e23301ce 100644 --- a/Source/Scene/Scene.js +++ b/Source/Scene/Scene.js @@ -802,7 +802,8 @@ define([ this._removeGlobeCallbacks = []; this._hdr = undefined; - this.hdr = true; + this._hdrDirty = undefined; + this.highDynamicRange = true; this.gamma = 2.4; this._sunColor = new Color(0.8, 0.85, 1.0, 1.0); @@ -1462,7 +1463,9 @@ define([ }, set : function(value) { var context = this._context; - this._hdr = value && context.depthTexture && (context.colorBufferFloat || context.colorBufferHalfFloat); + var hdr = value && context.depthTexture && (context.colorBufferFloat || context.colorBufferHalfFloat); + this._hdrDirty = hdr !== this._hdr; + this._hdr = hdr; } }, @@ -1543,7 +1546,7 @@ define([ } var derivedCommands = command.derivedCommands; - if ((scene._logDepthBufferDirty || scene._frustumChanged || command.dirty) && defined(derivedCommands)) { + if ((scene._hdrDirty || scene._logDepthBufferDirty || scene._frustumChanged || command.dirty) && defined(derivedCommands)) { command.dirty = false; var frustum = scene.camera.frustum; @@ -1574,6 +1577,9 @@ define([ derivedCommands.picking = DerivedCommand.createPickDerivedCommand(scene, command, context, derivedCommands.picking); } + derivedCommands.hdr = DerivedCommand.createHDRCommand(command, context, scene._hdr, derivedCommands.hdr); + command = derivedCommands.hdr.command; + var oit = scene._oit; if (command.pass === Pass.TRANSLUCENT && defined(oit) && oit.isSupported()) { if (lightShadowsEnabled && command.receiveShadows) { @@ -2098,6 +2104,10 @@ define([ command = command.derivedCommands.logDepth.command; } + if (defined(command.derivedCommands) && defined(command.derivedCommands.hdr)) { + command = command.derivedCommands.hdr.command; + } + var passes = frameState.passes; if (passes.pick || passes.depth) { if (passes.pick && !passes.depth && defined(command.derivedCommands.picking)) { @@ -3360,6 +3370,7 @@ define([ this._lastRenderTime = JulianDate.clone(time, this._lastRenderTime); this._renderRequested = false; this._logDepthBufferDirty = false; + this._hdrDirty = false; // Render this._preRender.raiseEvent(this, time); From 9e39ad84b504c041534b6d3970cabf8811f317fe Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 5 Sep 2018 16:06:49 -0400 Subject: [PATCH 37/76] Fix gamma correction when HDR is disabled. --- Source/Scene/DerivedCommand.js | 60 ++++--------------- Source/Scene/Scene.js | 10 ++-- Source/Scene/SkyBox.js | 28 ++++++--- .../Builtin/Functions/gammaCorrect.glsl | 5 +- Source/Shaders/GlobeFS.glsl | 4 +- 5 files changed, 45 insertions(+), 62 deletions(-) diff --git a/Source/Scene/DerivedCommand.js b/Source/Scene/DerivedCommand.js index b424eae4f9dc..21d29eeb15bf 100644 --- a/Source/Scene/DerivedCommand.js +++ b/Source/Scene/DerivedCommand.js @@ -323,54 +323,17 @@ define([ return result; }; - function getHDRShaderProgram(context, useHDR, shaderProgram) { - var shader; - var attributeLocations; - var vs; - var fs; - - if (useHDR) { - shader = context.shaderCache.getDerivedShaderProgram(shaderProgram, 'HDR'); - if (!defined(shader)) { - attributeLocations = shaderProgram._attributeLocations; - vs = shaderProgram.vertexShaderSource.clone(); - fs = shaderProgram.fragmentShaderSource.clone(); - - vs.defines = defined(vs.defines) ? vs.defines.slice(0) : []; - vs.defines.push('HDR'); - fs.defines = defined(fs.defines) ? fs.defines.slice(0) : []; - fs.defines.push('HDR'); - - shader = context.shaderCache.createDerivedShaderProgram(shaderProgram, 'HDR', { - vertexShaderSource : vs, - fragmentShaderSource : fs, - attributeLocations : attributeLocations - }); - } - - return shader; - } - - shader = context.shaderCache.getDerivedShaderProgram(shaderProgram, 'gammaCorrect'); + function getHDRShaderProgram(context, shaderProgram) { + var shader = context.shaderCache.getDerivedShaderProgram(shaderProgram, 'HDR'); if (!defined(shader)) { - attributeLocations = shaderProgram._attributeLocations; - vs = shaderProgram.vertexShaderSource.clone(); - fs = shaderProgram.fragmentShaderSource.clone(); - - var sources = fs.sources; - var length = sources.length; - for (var i = 0; i < length; ++i) { - sources[i] = ShaderSource.replaceMain(sources[i], 'czm_non_gamma_main'); - } + var attributeLocations = shaderProgram._attributeLocations; + var vs = shaderProgram.vertexShaderSource.clone(); + var fs = shaderProgram.fragmentShaderSource.clone(); - var main = - '\n\n' + - 'void main() \n' + - '{ \n' + - ' czm_non_gamma_main(); \n' + - ' gl_FragColor.rgb = czm_inverseGamma(gl_FragColor.rgb); \n' + - '} \n'; - sources.push(main); + vs.defines = defined(vs.defines) ? vs.defines.slice(0) : []; + vs.defines.push('HDR'); + fs.defines = defined(fs.defines) ? fs.defines.slice(0) : []; + fs.defines.push('HDR'); shader = context.shaderCache.createDerivedShaderProgram(shaderProgram, 'HDR', { vertexShaderSource : vs, @@ -378,10 +341,11 @@ define([ attributeLocations : attributeLocations }); } + return shader; } - DerivedCommand.createHDRCommand = function(command, context, useHDR, result) { + DerivedCommand.createHDRCommand = function(command, context, result) { if (!defined(result)) { result = {}; } @@ -394,7 +358,7 @@ define([ result.command = DrawCommand.shallowClone(command, result.command); if (!defined(shader) || result.shaderProgramId !== command.shaderProgram.id) { - result.command.shaderProgram = getHDRShaderProgram(context, useHDR, command.shaderProgram); + result.command.shaderProgram = getHDRShaderProgram(context, command.shaderProgram); result.shaderProgramId = command.shaderProgram.id; } else { result.command.shaderProgram = shader; diff --git a/Source/Scene/Scene.js b/Source/Scene/Scene.js index 6b57e23301ce..60c4499fcc07 100644 --- a/Source/Scene/Scene.js +++ b/Source/Scene/Scene.js @@ -804,7 +804,7 @@ define([ this._hdr = undefined; this._hdrDirty = undefined; this.highDynamicRange = true; - this.gamma = 2.4; + this.gamma = 2.2; this._sunColor = new Color(0.8, 0.85, 1.0, 1.0); // initial guess at frustums. @@ -1577,8 +1577,10 @@ define([ derivedCommands.picking = DerivedCommand.createPickDerivedCommand(scene, command, context, derivedCommands.picking); } - derivedCommands.hdr = DerivedCommand.createHDRCommand(command, context, scene._hdr, derivedCommands.hdr); - command = derivedCommands.hdr.command; + if (scene._hdr) { + derivedCommands.hdr = DerivedCommand.createHDRCommand(command, context, derivedCommands.hdr); + command = derivedCommands.hdr.command; + } var oit = scene._oit; if (command.pass === Pass.TRANSLUCENT && defined(oit) && oit.isSupported()) { @@ -2916,7 +2918,7 @@ define([ environmentState.isReadyForAtmosphere = environmentState.isReadyForAtmosphere || globe._surface._tilesToRender.length > 0; } environmentState.skyAtmosphereCommand = defined(skyAtmosphere) ? skyAtmosphere.update(frameState) : undefined; - environmentState.skyBoxCommand = defined(scene.skyBox) ? scene.skyBox.update(frameState) : undefined; + environmentState.skyBoxCommand = defined(scene.skyBox) ? scene.skyBox.update(frameState, scene._hdr) : undefined; var sunCommands = defined(scene.sun) ? scene.sun.update(frameState, passState, scene._hdr) : undefined; environmentState.sunDrawCommand = defined(sunCommands) ? sunCommands.drawCommand : undefined; environmentState.sunComputeCommand = defined(sunCommands) ? sunCommands.computeCommand : undefined; diff --git a/Source/Scene/SkyBox.js b/Source/Scene/SkyBox.js index c2c9ed8b26ef..ab23ae38fa97 100644 --- a/Source/Scene/SkyBox.js +++ b/Source/Scene/SkyBox.js @@ -14,6 +14,7 @@ define([ '../Renderer/loadCubeMap', '../Renderer/RenderState', '../Renderer/ShaderProgram', + '../Renderer/ShaderSource', '../Renderer/VertexArray', '../Shaders/SkyBoxFS', '../Shaders/SkyBoxVS', @@ -35,6 +36,7 @@ define([ loadCubeMap, RenderState, ShaderProgram, + ShaderSource, VertexArray, SkyBoxFS, SkyBoxVS, @@ -98,6 +100,9 @@ define([ owner : this }); this._cubeMap = undefined; + + this._attributeLocations = undefined; + this._useHDR = undefined; } /** @@ -111,7 +116,7 @@ define([ * @exception {DeveloperError} this.sources is required and must have positiveX, negativeX, positiveY, negativeY, positiveZ, and negativeZ properties. * @exception {DeveloperError} this.sources properties must all be the same type. */ - SkyBox.prototype.update = function(frameState) { + SkyBox.prototype.update = function(frameState, useHDR) { var that = this; if (!this.show) { @@ -181,7 +186,7 @@ define([ dimensions : new Cartesian3(2.0, 2.0, 2.0), vertexFormat : VertexFormat.POSITION_ONLY })); - var attributeLocations = GeometryPipeline.createAttributeLocations(geometry); + var attributeLocations = this._attributeLocations = GeometryPipeline.createAttributeLocations(geometry); command.vertexArray = VertexArray.fromGeometry({ context : context, @@ -190,16 +195,23 @@ define([ bufferUsage : BufferUsage.STATIC_DRAW }); + command.renderState = RenderState.fromCache({ + blending : BlendingState.ALPHA_BLEND + }); + } + + if (!defined(command.shaderProgram) || this._useHDR !== useHDR) { + var fs = new ShaderSource({ + defines : [useHDR ? 'HDR' : ''], + sources : [SkyBoxFS] + }); command.shaderProgram = ShaderProgram.fromCache({ context : context, vertexShaderSource : SkyBoxVS, - fragmentShaderSource : SkyBoxFS, - attributeLocations : attributeLocations - }); - - command.renderState = RenderState.fromCache({ - blending : BlendingState.ALPHA_BLEND + fragmentShaderSource : fs, + attributeLocations : this._attributeLocations }); + this._useHDR = useHDR; } if (!defined(this._cubeMap)) { diff --git a/Source/Shaders/Builtin/Functions/gammaCorrect.glsl b/Source/Shaders/Builtin/Functions/gammaCorrect.glsl index 36a04889595a..0dc6f2eb4b32 100644 --- a/Source/Shaders/Builtin/Functions/gammaCorrect.glsl +++ b/Source/Shaders/Builtin/Functions/gammaCorrect.glsl @@ -8,5 +8,8 @@ * @returns {vec3} The color in linear space. */ vec3 czm_gammaCorrect(vec3 color) { - return pow(color, vec3(czm_gamma)); +#ifdef HDR + color = pow(color, vec3(czm_gamma)); +#endif + return color; } diff --git a/Source/Shaders/GlobeFS.glsl b/Source/Shaders/GlobeFS.glsl index 19f1ef8da474..82743c603e69 100644 --- a/Source/Shaders/GlobeFS.glsl +++ b/Source/Shaders/GlobeFS.glsl @@ -275,9 +275,9 @@ void main() #endif #if defined(FOG) || defined(GROUND_ATMOSPHERE) - const float fExposure = 1.3; vec3 fogColor = v_fogMieColor + finalColor.rgb * v_fogRayleighColor; #ifndef HDR + const float fExposure = 2.0; fogColor = vec3(1.0) - exp(-fExposure * fogColor); #endif #endif @@ -320,7 +320,9 @@ void main() AtmosphereColor atmosColor = computeGroundAtmosphereFromSpace(ellipsoidPosition, true); vec3 groundAtmosphereColor = atmosColor.mie + finalColor.rgb * atmosColor.rayleigh; +#ifndef HDR groundAtmosphereColor = vec3(1.0) - exp(-fExposure * groundAtmosphereColor); +#endif fadeInDist = u_nightFadeDistance.x; fadeOutDist = u_nightFadeDistance.y; From b9c9073e852793c6b01bdf76d3b98ece70961060 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 5 Sep 2018 16:19:31 -0400 Subject: [PATCH 38/76] Pass globe eye position when HDR enabled. --- Source/Shaders/GlobeFS.glsl | 2 +- Source/Shaders/GlobeVS.glsl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Shaders/GlobeFS.glsl b/Source/Shaders/GlobeFS.glsl index 82743c603e69..d5e04472f558 100644 --- a/Source/Shaders/GlobeFS.glsl +++ b/Source/Shaders/GlobeFS.glsl @@ -183,7 +183,7 @@ void main() } #endif -#if defined(SHOW_REFLECTIVE_OCEAN) || defined(ENABLE_DAYNIGHT_SHADING) || defined(HDR) +#if defined(SHOW_REFLECTIVE_OCEAN) || defined(ENABLE_DAYNIGHT_SHADING) vec3 normalMC = czm_geodeticSurfaceNormal(v_positionMC, vec3(0.0), vec3(1.0)); // normalized surface normal in model coordinates vec3 normalEC = czm_normal3D * normalMC; // normalized surface normal in eye coordiantes #endif diff --git a/Source/Shaders/GlobeVS.glsl b/Source/Shaders/GlobeVS.glsl index f7c1bb25263e..5e27d963bc30 100644 --- a/Source/Shaders/GlobeVS.glsl +++ b/Source/Shaders/GlobeVS.glsl @@ -162,7 +162,7 @@ void main() vec3 normalMC = czm_octDecode(encodedNormal); v_normalMC = normalMC; v_normalEC = czm_normal3D * v_normalMC; -#elif defined(SHOW_REFLECTIVE_OCEAN) || defined(ENABLE_DAYNIGHT_SHADING) || defined(GENERATE_POSITION) +#elif defined(SHOW_REFLECTIVE_OCEAN) || defined(ENABLE_DAYNIGHT_SHADING) || defined(GENERATE_POSITION) || defined(HDR) v_positionEC = (u_modifiedModelView * vec4(position, 1.0)).xyz; v_positionMC = position3DWC; // position in model coordinates #endif From 6a6ca8a7a6bd515ed9d7085c6beb3d2f0e3168d5 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 5 Sep 2018 16:24:32 -0400 Subject: [PATCH 39/76] Update CHANGES.md after merge. --- CHANGES.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index d1fb853b1431..90ba41dcf2ac 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,6 +1,11 @@ Change Log ========== +### 1.50 - 2018-10-01 + +##### Additions :tada: +* Added ground atmosphere lighting in 3D. This can be toggled with `Globe.showGroundAtmosphere`. [6877](https://github.com/AnalyticalGraphicsInc/cesium/pull/6877) + ### 1.49 - 2018-09-04 ##### Breaking Changes :mega: From 132b9337b190e0afc22c18695c0456f528fbcb10 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 5 Sep 2018 17:10:28 -0400 Subject: [PATCH 40/76] Fix some tests and a copy-paste error. --- Source/Scene/Model.js | 2 +- Specs/createScene.js | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Source/Scene/Model.js b/Source/Scene/Model.js index 248f644f4af0..319b6358110d 100644 --- a/Source/Scene/Model.js +++ b/Source/Scene/Model.js @@ -2103,7 +2103,7 @@ define([ '\n' + 'void main() { \n' + ' non_gamma_corrected_main(); \n' + - ' gl_FragColor.rgb = gl_FragColor.rgb(gl_FragColor.rgb); \n' + + ' gl_FragColor.rgb = czm_gammaCorrect(gl_FragColor.rgb); \n' + '} \n'; } diff --git a/Specs/createScene.js b/Specs/createScene.js index 277548492693..ef117fcbe48e 100644 --- a/Specs/createScene.js +++ b/Specs/createScene.js @@ -37,6 +37,7 @@ define([ } var scene = new Scene(options); + scene.highDynamicRange = false; if (!!window.webglValidation) { var context = scene.context; From bbde12b5f6d392e975eda29ae0cf1b416bbe69e5 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 6 Sep 2018 16:16:44 -0400 Subject: [PATCH 41/76] Fix after merge. --- Source/Scene/Scene.js | 6 +++--- Source/Scene/SceneFramebuffer.js | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Source/Scene/Scene.js b/Source/Scene/Scene.js index 01f8c6641fe6..292cf6319aad 100644 --- a/Source/Scene/Scene.js +++ b/Source/Scene/Scene.js @@ -1499,6 +1499,7 @@ define([ derivedCommands.picking = DerivedCommand.createPickDerivedCommand(scene, command, context, derivedCommands.picking); } + // TODO HDR if (scene._hdr) { derivedCommands.hdr = DerivedCommand.createHDRCommand(command, context, derivedCommands.hdr); command = derivedCommands.hdr.command; @@ -1547,7 +1548,7 @@ define([ var hasDerivedCommands = defined(derivedCommands.originalCommand); var needsLogDepthDerivedCommands = useLogDepth && !hasLogDepthDerivedCommands; var needsDerivedCommands = !useLogDepth && !hasDerivedCommands; - command.dirty = command.dirty || needsLogDepthDerivedCommands || needsDerivedCommands || scene._hdrDirty; // HDR_TODO + command.dirty = command.dirty || needsLogDepthDerivedCommands || needsDerivedCommands || this._hdrDirty; // TODO HDR if (command.dirty) { command.dirty = false; @@ -2102,7 +2103,6 @@ define([ } if (defined(globeDepth) && environmentState.useGlobeDepthFramebuffer) { - globeDepth.update(context, passState, view.viewport); globeDepth.executeCopyDepth(context, passState); } @@ -2860,7 +2860,7 @@ define([ 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); + view.sceneFramebuffer.update(context, view.viewport, scene._hdr); view.sceneFramebuffer.clear(context, passState, clearColor); postProcess.update(context, frameState.useLogDepth, scene._hdr); diff --git a/Source/Scene/SceneFramebuffer.js b/Source/Scene/SceneFramebuffer.js index f5fd8f6713a3..d677617be0bb 100644 --- a/Source/Scene/SceneFramebuffer.js +++ b/Source/Scene/SceneFramebuffer.js @@ -83,6 +83,7 @@ define([ } destroyResources(this); + this._useHDR = hdr; var pixelDatatype = hdr ? (context.halfFloatingPointTexture ? PixelDatatype.HALF_FLOAT : PixelDatatype.FLOAT) : PixelDatatype.UNSIGNED_BYTE; this._colorTexture = new Texture({ From 2dbfe37859066a1c1c327077060f9269ff6b384c Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 6 Sep 2018 16:24:30 -0400 Subject: [PATCH 42/76] More fixes after merge. --- Source/Scene/Scene.js | 21 ++++++++++----------- Source/Shaders/GlobeFS.glsl | 2 +- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/Source/Scene/Scene.js b/Source/Scene/Scene.js index 292cf6319aad..d7e93a9ecef8 100644 --- a/Source/Scene/Scene.js +++ b/Source/Scene/Scene.js @@ -1491,20 +1491,25 @@ define([ var derivedCommands = command.derivedCommands; - if (lightShadowsEnabled && command.receiveShadows) { - derivedCommands.shadows = ShadowMap.createReceiveDerivedCommand(lightShadowMaps, command, shadowsDirty, context, derivedCommands.shadows); - } - if (defined(command.pickId)) { derivedCommands.picking = DerivedCommand.createPickDerivedCommand(scene, command, context, derivedCommands.picking); } - // TODO HDR + 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; } + 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 : {}; @@ -1513,12 +1518,6 @@ define([ derivedCommands.oit = oit.createDerivedCommands(command, context, derivedCommands.oit); } } - - if (!command.pickOnly) { - derivedCommands.depth = DerivedCommand.createDepthOnlyDerivedCommand(scene, command, context, derivedCommands.depth); - } - - derivedCommands.originalCommand = command; } /** diff --git a/Source/Shaders/GlobeFS.glsl b/Source/Shaders/GlobeFS.glsl index d5e04472f558..82743c603e69 100644 --- a/Source/Shaders/GlobeFS.glsl +++ b/Source/Shaders/GlobeFS.glsl @@ -183,7 +183,7 @@ void main() } #endif -#if defined(SHOW_REFLECTIVE_OCEAN) || defined(ENABLE_DAYNIGHT_SHADING) +#if defined(SHOW_REFLECTIVE_OCEAN) || defined(ENABLE_DAYNIGHT_SHADING) || defined(HDR) vec3 normalMC = czm_geodeticSurfaceNormal(v_positionMC, vec3(0.0), vec3(1.0)); // normalized surface normal in model coordinates vec3 normalEC = czm_normal3D * normalMC; // normalized surface normal in eye coordiantes #endif From 42ad8d99aedb7bfbaaa16a4d6f02a29b3b36823c Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 6 Sep 2018 16:54:16 -0400 Subject: [PATCH 43/76] Updates for derived command from scene re-work. --- Source/Scene/Scene.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Source/Scene/Scene.js b/Source/Scene/Scene.js index d7e93a9ecef8..969ca8398a55 100644 --- a/Source/Scene/Scene.js +++ b/Source/Scene/Scene.js @@ -1542,12 +1542,15 @@ define([ } 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 needsDerivedCommands = !useLogDepth && !hasDerivedCommands; - command.dirty = command.dirty || needsLogDepthDerivedCommands || needsDerivedCommands || this._hdrDirty; // TODO HDR + var needsHDRCommands = useHDR && !hasHDRCommands; + var needsDerivedCommands = (!useLogDepth || !useHDR) && !hasDerivedCommands; + command.dirty = command.dirty || needsLogDepthDerivedCommands || needsHDRCommands || needsDerivedCommands; if (command.dirty) { command.dirty = false; @@ -3122,7 +3125,7 @@ define([ this._postUpdate.raiseEvent(this, time); var cameraChanged = this._view.checkForCameraUpdates(this); - var shouldRender = !this.requestRenderMode || this._renderRequested || cameraChanged || this._logDepthBufferDirty || (this.mode === SceneMode.MORPHING); + 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; From 5a0802fad2bf7eb3c1e08d2885281a813c61288a Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 4 Oct 2018 15:49:03 -0400 Subject: [PATCH 44/76] Fixes after merge. --- Source/Scene/processPbrMaterials.js | 31 ++++++++++++++++++++--------- Source/Shaders/GlobeFS.glsl | 25 ----------------------- 2 files changed, 22 insertions(+), 34 deletions(-) diff --git a/Source/Scene/processPbrMaterials.js b/Source/Scene/processPbrMaterials.js index 931a944c3cb9..a11fce8bb229 100644 --- a/Source/Scene/processPbrMaterials.js +++ b/Source/Scene/processPbrMaterials.js @@ -425,33 +425,39 @@ define([ if (hasNormals) { fragmentShader += 'const float M_PI = 3.141592653589793;\n'; - fragmentShader += 'vec3 lambertianDiffuse(vec3 diffuseColor) \n' + + fragmentShader += + 'vec3 lambertianDiffuse(vec3 diffuseColor) \n' + '{\n' + ' return diffuseColor / M_PI;\n' + '}\n\n'; - fragmentShader += 'vec3 fresnelSchlick2(vec3 f0, vec3 f90, float VdotH) \n' + + fragmentShader += + 'vec3 fresnelSchlick2(vec3 f0, vec3 f90, float VdotH) \n' + '{\n' + ' return f0 + (f90 - f0) * pow(clamp(1.0 - VdotH, 0.0, 1.0), 5.0);\n' + '}\n\n'; - fragmentShader += 'vec3 fresnelSchlick(float metalness, float VdotH) \n' + + fragmentShader += + 'vec3 fresnelSchlick(float metalness, float VdotH) \n' + '{\n' + ' return metalness + (vec3(1.0) - metalness) * pow(1.0 - VdotH, 5.0);\n' + '}\n\n'; - fragmentShader += 'float smithVisibilityG1(float NdotV, float roughness) \n' + + fragmentShader += + 'float smithVisibilityG1(float NdotV, float roughness) \n' + '{\n' + ' float k = (roughness + 1.0) * (roughness + 1.0) / 8.0;\n' + ' return NdotV / (NdotV * (1.0 - k) + k);\n' + '}\n\n'; - fragmentShader += 'float smithVisibilityGGX(float roughness, float NdotL, float NdotV) \n' + + fragmentShader += + 'float smithVisibilityGGX(float roughness, float NdotL, float NdotV) \n' + '{\n' + ' return smithVisibilityG1(NdotL, roughness) * smithVisibilityG1(NdotV, roughness);\n' + '}\n\n'; - fragmentShader += 'float GGX(float roughness, float NdotH) \n' + + fragmentShader += + 'float GGX(float roughness, float NdotH) \n' + '{\n' + ' float roughnessSquared = roughness * roughness;\n' + ' float f = (NdotH * roughnessSquared - NdotH) * NdotH + 1.0;\n' + @@ -459,20 +465,27 @@ define([ '}\n\n'; } - fragmentShader += 'vec3 SRGBtoLINEAR3(vec3 srgbIn) \n' + + fragmentShader += + 'vec3 SRGBtoLINEAR3(vec3 srgbIn) \n' + '{\n' + ' return pow(srgbIn, vec3(2.2));\n' + '}\n\n'; - fragmentShader += 'vec4 SRGBtoLINEAR4(vec4 srgbIn) \n' + + fragmentShader += + 'vec4 SRGBtoLINEAR4(vec4 srgbIn) \n' + '{\n' + ' vec3 linearOut = pow(srgbIn.rgb, vec3(2.2));\n' + ' return vec4(linearOut, srgbIn.a);\n' + '}\n\n'; - fragmentShader += 'vec3 LINEARtoSRGB(vec3 linearIn) \n' + + fragmentShader += + 'vec3 LINEARtoSRGB(vec3 linearIn) \n' + '{\n' + + '#ifndef HDR \n' + ' return pow(linearIn, vec3(1.0/2.2));\n' + + '#else \n' + + ' return linearIn;\n' + + '#endif \n' + '}\n\n'; fragmentShader += 'void main(void) \n{\n'; diff --git a/Source/Shaders/GlobeFS.glsl b/Source/Shaders/GlobeFS.glsl index eeb1f2a70933..1c1914ee7719 100644 --- a/Source/Shaders/GlobeFS.glsl +++ b/Source/Shaders/GlobeFS.glsl @@ -259,31 +259,6 @@ void main() color.xyz = mix(color.xyz, material.diffuse, material.alpha); #endif -#if defined(ENABLE_DAYNIGHT_SHADING) || defined(GROUND_ATMOSPHERE) - float cameraDist; - if (czm_sceneMode == czm_sceneMode2D) - { - cameraDist = max(czm_frustumPlanes.x - czm_frustumPlanes.y, czm_frustumPlanes.w - czm_frustumPlanes.z) * 0.5; - } - else if (czm_sceneMode == czm_sceneModeColumbusView) - { - cameraDist = -czm_view[3].z; - } - else - { - cameraDist = length(czm_view[3]); - } - float fadeOutDist = u_lightingFadeDistance.x; - float fadeInDist = u_lightingFadeDistance.y; - if (czm_sceneMode != czm_sceneMode3D) { - vec3 radii = czm_getWgs84EllipsoidEC().radii; - float maxRadii = max(radii.x, max(radii.y, radii.z)); - fadeOutDist -= maxRadii; - fadeInDist -= maxRadii; - } - float fade = clamp((cameraDist - fadeOutDist) / (fadeInDist - fadeOutDist), 0.0, 1.0); -#endif - #ifdef HDR czm_material material; material.diffuse = color.rgb; From fb950f863dd5121f63dfdca3b236af0a42f8db03 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 4 Oct 2018 16:11:32 -0400 Subject: [PATCH 45/76] Updates from review. --- Source/Renderer/AutomaticUniforms.js | 2 +- Source/Scene/AutoExposure.js | 40 +++++++++++++------ Source/Scene/DerivedCommand.js | 6 +-- Source/Scene/GlobeDepth.js | 6 +-- Source/Scene/PostProcessStageCollection.js | 6 +-- Source/Scene/PostProcessStageLibrary.js | 8 ++-- Source/Scene/Scene.js | 16 ++++---- Source/Scene/SceneFramebuffer.js | 6 +-- Source/Scene/SkyBox.js | 10 ++--- Source/Scene/Sun.js | 10 ++--- Source/Shaders/GlobeFS.glsl | 1 - ...STonemapping.glsl => AcesTonemapping.glsl} | 0 .../PostProcessStages/FilmicTonemapping.glsl | 2 +- 13 files changed, 64 insertions(+), 49 deletions(-) rename Source/Shaders/PostProcessStages/{ACESTonemapping.glsl => AcesTonemapping.glsl} (100%) diff --git a/Source/Renderer/AutomaticUniforms.js b/Source/Renderer/AutomaticUniforms.js index a93da0ad36a0..72a223d4bb81 100644 --- a/Source/Renderer/AutomaticUniforms.js +++ b/Source/Renderer/AutomaticUniforms.js @@ -1689,7 +1689,7 @@ define([ }), /** - * An automatic GLSL uniform that will be used for gamma correction. + * An automatic GLSL uniform that is used for gamma correction. * * @alias czm_gamma * @glslUniform diff --git a/Source/Scene/AutoExposure.js b/Source/Scene/AutoExposure.js index 7ae2b0d01d11..98ea6ad1481c 100644 --- a/Source/Scene/AutoExposure.js +++ b/Source/Scene/AutoExposure.js @@ -1,4 +1,5 @@ define([ + '../Core/Cartesian2', '../Core/Color', '../Core/defaultValue', '../Core/defined', @@ -14,6 +15,7 @@ define([ '../Renderer/TextureMinificationFilter', '../Renderer/TextureWrap' ], function( + Cartesian2, Color, defaultValue, defined, @@ -32,7 +34,7 @@ define([ /** * A post process stage that will get the luminance value at each pixel and - * uses parallel reduction to get the average luminance in a 1x1 texture. + * uses parallel reduction to compute the average luminance in a 1x1 texture. * This texture can be used as input for tone mapping. * * @constructor @@ -58,6 +60,8 @@ define([ this._commands = undefined; this._clearCommand = undefined; + this._minMaxLuminance = new Cartesian2(); + /** * Whether or not to execute this post-process stage when ready. * @@ -66,7 +70,20 @@ define([ this.enabled = true; this._enabled = true; + /** + * The minimum value used to clamp the luminance. + * + * @type {Number} + * @default 0.1 + */ this.minimumLuminance = 0.1; + + /** + * The maximum value used to clamp the luminance. + * + * @type {Number} + * @default 10.0 + */ this.maximumLuminance = 10.0; } @@ -218,11 +235,8 @@ define([ }; } - uniforms.minimumLuminance = function() { - return autoexposure.minimumLuminance; - }; - uniforms.maximumLuminance = function() { - return autoexposure.maximumLuminance; + uniforms.minMaxLuminance = function() { + return autoexposure._minMaxLuminance; }; uniforms.previousLuminance = function() { return autoexposure._previousLuminance.getColorTexture(0); @@ -250,13 +264,12 @@ define([ source += 'uniform vec2 colorTextureDimensions; \n' + - 'uniform float minimumLuminance; \n' + - 'uniform float maximumLuminance; \n' + + 'uniform vec2 minMaxLuminance; \n' + 'uniform sampler2D previousLuminance; \n' + 'void main() { \n' + ' float color = 0.0; \n' + - ' float xStep = 1.0 /colorTextureDimensions.x; \n' + - ' float yStep = 1.0 /colorTextureDimensions.y; \n' + + ' float xStep = 1.0 / colorTextureDimensions.x; \n' + + ' float yStep = 1.0 / colorTextureDimensions.y; \n' + ' int count = 0; \n' + ' for (int i = 0; i < 3; ++i) { \n' + ' for (int j = 0; j < 3; ++j) { \n' + @@ -277,9 +290,9 @@ define([ if (index === length - 1) { source += ' float previous = texture2D(previousLuminance, vec2(0.5)).r; \n' + - ' color = clamp(color, minimumLuminance, maximumLuminance); \n' + + ' color = clamp(color, minMaxLuminance.x, minMaxLuminance.y); \n' + ' color = previous + (color - previous) / (60.0 * 1.5); \n' + - ' color = clamp(color, minimumLuminance, maximumLuminance); \n'; + ' color = clamp(color, minMaxLuminance.x, minMaxLuminance.y); \n'; } source += @@ -351,6 +364,9 @@ define([ } } + this._minMaxLuminance.x = this.minimumLuminance; + this._minMaxLuminance.y = this.maximumLuminance; + var framebuffers = this._framebuffers; var temp = framebuffers[framebuffers.length - 1]; framebuffers[framebuffers.length - 1] = this._previousLuminance; diff --git a/Source/Scene/DerivedCommand.js b/Source/Scene/DerivedCommand.js index 83a8320877f7..3a9cbcc916d9 100644 --- a/Source/Scene/DerivedCommand.js +++ b/Source/Scene/DerivedCommand.js @@ -330,7 +330,7 @@ define([ return result; }; - function getHDRShaderProgram(context, shaderProgram) { + function getHdrShaderProgram(context, shaderProgram) { var shader = context.shaderCache.getDerivedShaderProgram(shaderProgram, 'HDR'); if (!defined(shader)) { var attributeLocations = shaderProgram._attributeLocations; @@ -352,7 +352,7 @@ define([ return shader; } - DerivedCommand.createHDRCommand = function(command, context, result) { + DerivedCommand.createHdrCommand = function(command, context, result) { if (!defined(result)) { result = {}; } @@ -365,7 +365,7 @@ define([ result.command = DrawCommand.shallowClone(command, result.command); if (!defined(shader) || result.shaderProgramId !== command.shaderProgram.id) { - result.command.shaderProgram = getHDRShaderProgram(context, command.shaderProgram); + result.command.shaderProgram = getHdrShaderProgram(context, command.shaderProgram); result.shaderProgramId = command.shaderProgram.id; } else { result.command.shaderProgram = shader; diff --git a/Source/Scene/GlobeDepth.js b/Source/Scene/GlobeDepth.js index a0d96702df6c..7076b8ae5f2d 100644 --- a/Source/Scene/GlobeDepth.js +++ b/Source/Scene/GlobeDepth.js @@ -60,7 +60,7 @@ define([ this._scissorRectangle = undefined; this._useLogDepth = undefined; - this._useHDR = undefined; + this._useHdr = undefined; this._debugGlobeDepthViewportCommand = undefined; } @@ -167,7 +167,7 @@ define([ function updateFramebuffers(globeDepth, context, width, height, hdr) { var colorTexture = globeDepth._colorTexture; - var textureChanged = !defined(colorTexture) || colorTexture.width !== width || colorTexture.height !== height || hdr !== globeDepth._useHDR; + var textureChanged = !defined(colorTexture) || colorTexture.width !== width || colorTexture.height !== height || hdr !== globeDepth._useHdr; if (!defined(globeDepth.framebuffer) || textureChanged) { destroyTextures(globeDepth); destroyFramebuffers(globeDepth); @@ -249,7 +249,7 @@ define([ updateCopyCommands(this, context, width, height, passState); context.uniformState.globeDepthTexture = undefined; - this._useHDR = hdr; + this._useHdr = hdr; }; GlobeDepth.prototype.executeCopyDepth = function(context, passState) { diff --git a/Source/Scene/PostProcessStageCollection.js b/Source/Scene/PostProcessStageCollection.js index 6cb90f8aa425..61d406d23169 100644 --- a/Source/Scene/PostProcessStageCollection.js +++ b/Source/Scene/PostProcessStageCollection.js @@ -365,7 +365,7 @@ define([ tonemapper = PostProcessStageLibrary.createFilmicTonemappingStage(useAutoExposure); break; default: - tonemapper = PostProcessStageLibrary.createACESTonemappingStage(useAutoExposure); + tonemapper = PostProcessStageLibrary.createAcesTonemappingStage(useAutoExposure); break; } @@ -541,7 +541,7 @@ define([ * * @private */ - PostProcessStageCollection.prototype.update = function(context, useLogDepth, useHDR) { + PostProcessStageCollection.prototype.update = function(context, useLogDepth, useHdr) { removeStages(this); var previousActiveStages = this._activeStages; @@ -578,7 +578,7 @@ define([ var tonemapping = this._tonemapping; var fxaa = this._fxaa; - tonemapping.enabled = useHDR; + tonemapping.enabled = useHdr; var aoEnabled = ao.enabled && ao._isSupported(context); var bloomEnabled = bloom.enabled && bloom._isSupported(context); diff --git a/Source/Scene/PostProcessStageLibrary.js b/Source/Scene/PostProcessStageLibrary.js index 172616ba1387..cb817d647f9c 100644 --- a/Source/Scene/PostProcessStageLibrary.js +++ b/Source/Scene/PostProcessStageLibrary.js @@ -7,7 +7,7 @@ define([ '../Core/deprecationWarning', '../Core/destroyObject', '../Core/Ellipsoid', - '../Shaders/PostProcessStages/ACESTonemapping', + '../Shaders/PostProcessStages/AcesTonemapping', '../Shaders/PostProcessStages/AmbientOcclusionGenerate', '../Shaders/PostProcessStages/AmbientOcclusionModulate', '../Shaders/PostProcessStages/BlackAndWhite', @@ -39,7 +39,7 @@ define([ deprecationWarning, destroyObject, Ellipsoid, - ACESTonemapping, + AcesTonemapping, AmbientOcclusionGenerate, AmbientOcclusionModulate, BlackAndWhite, @@ -701,9 +701,9 @@ define([ * @return {PostProcessStage} A post-process stage that applies ACES tonemapping operator. * @private */ - PostProcessStageLibrary.createACESTonemappingStage = function(useAutoExposure) { + PostProcessStageLibrary.createAcesTonemappingStage = function(useAutoExposure) { var fs = useAutoExposure ? '#define AUTO_EXPOSURE\n' : ''; - fs += ACESTonemapping; + fs += AcesTonemapping; return new PostProcessStage({ name : 'czm_aces', fragmentShader : fs, diff --git a/Source/Scene/Scene.js b/Source/Scene/Scene.js index bed538690eca..a6b93cbbedf9 100644 --- a/Source/Scene/Scene.js +++ b/Source/Scene/Scene.js @@ -1454,7 +1454,7 @@ define([ * The value used for gamma correction. * @memberof Scene.prototype * @type {Number} - * @default 2.4 + * @default 2.2 */ gamma : { get : function() { @@ -1488,7 +1488,7 @@ define([ * * @memberof Scene.prototype * @type {Color} - * @default Color(0.8,0.8,0.8) + * @default Color(0.8, 0.8, 0.8) */ sunColor: { get: function() { @@ -1541,7 +1541,7 @@ define([ derivedCommands.originalCommand = command; if (scene._hdr) { - derivedCommands.hdr = DerivedCommand.createHDRCommand(command, context, derivedCommands.hdr); + derivedCommands.hdr = DerivedCommand.createHdrCommand(command, context, derivedCommands.hdr); command = derivedCommands.hdr.command; } @@ -1581,15 +1581,15 @@ define([ } var useLogDepth = frameState.useLogDepth; - var useHDR = this._hdr; + var useHdr = this._hdr; var derivedCommands = command.derivedCommands; var hasLogDepthDerivedCommands = defined(derivedCommands.logDepth); - var hasHDRCommands = defined(derivedCommands.hdr); + 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; + var needsHdrCommands = useHdr && !hasHdrCommands; + var needsDerivedCommands = (!useLogDepth || !useHdr) && !hasDerivedCommands; + command.dirty = command.dirty || needsLogDepthDerivedCommands || needsHdrCommands || needsDerivedCommands; if (command.dirty) { command.dirty = false; diff --git a/Source/Scene/SceneFramebuffer.js b/Source/Scene/SceneFramebuffer.js index d677617be0bb..7b448a06113d 100644 --- a/Source/Scene/SceneFramebuffer.js +++ b/Source/Scene/SceneFramebuffer.js @@ -45,7 +45,7 @@ define([ this._idClearColor = new Color(0.0, 0.0, 0.0, 0.0); - this._useHDR = undefined; + this._useHdr = undefined; this._clearCommand = new ClearCommand({ color : new Color(0.0, 0.0, 0.0, 0.0), @@ -78,12 +78,12 @@ define([ var width = viewport.width; var height = viewport.height; var colorTexture = this._colorTexture; - if (defined(colorTexture) && colorTexture.width === width && colorTexture.height === height && hdr === this._useHDR) { + if (defined(colorTexture) && colorTexture.width === width && colorTexture.height === height && hdr === this._useHdr) { return; } destroyResources(this); - this._useHDR = hdr; + this._useHdr = hdr; var pixelDatatype = hdr ? (context.halfFloatingPointTexture ? PixelDatatype.HALF_FLOAT : PixelDatatype.FLOAT) : PixelDatatype.UNSIGNED_BYTE; this._colorTexture = new Texture({ diff --git a/Source/Scene/SkyBox.js b/Source/Scene/SkyBox.js index ab23ae38fa97..15a1f360072f 100644 --- a/Source/Scene/SkyBox.js +++ b/Source/Scene/SkyBox.js @@ -102,7 +102,7 @@ define([ this._cubeMap = undefined; this._attributeLocations = undefined; - this._useHDR = undefined; + this._useHdr = undefined; } /** @@ -116,7 +116,7 @@ define([ * @exception {DeveloperError} this.sources is required and must have positiveX, negativeX, positiveY, negativeY, positiveZ, and negativeZ properties. * @exception {DeveloperError} this.sources properties must all be the same type. */ - SkyBox.prototype.update = function(frameState, useHDR) { + SkyBox.prototype.update = function(frameState, useHdr) { var that = this; if (!this.show) { @@ -200,9 +200,9 @@ define([ }); } - if (!defined(command.shaderProgram) || this._useHDR !== useHDR) { + if (!defined(command.shaderProgram) || this._useHdr !== useHdr) { var fs = new ShaderSource({ - defines : [useHDR ? 'HDR' : ''], + defines : [useHdr ? 'HDR' : ''], sources : [SkyBoxFS] }); command.shaderProgram = ShaderProgram.fromCache({ @@ -211,7 +211,7 @@ define([ fragmentShaderSource : fs, attributeLocations : this._attributeLocations }); - this._useHDR = useHDR; + this._useHdr = useHdr; } if (!defined(this._cubeMap)) { diff --git a/Source/Scene/Sun.js b/Source/Scene/Sun.js index a8d399d091d3..3009a8112058 100644 --- a/Source/Scene/Sun.js +++ b/Source/Scene/Sun.js @@ -101,7 +101,7 @@ define([ this.glowFactor = 1.0; this._glowFactorDirty = false; - this._useHDR = undefined; + this._useHdr = undefined; var that = this; this._uniformMap = { @@ -142,7 +142,7 @@ define([ /** * @private */ - Sun.prototype.update = function(frameState, passState, useHDR) { + Sun.prototype.update = function(frameState, passState, useHdr) { if (!this.show) { return undefined; } @@ -164,12 +164,12 @@ define([ drawingBufferWidth !== this._drawingBufferWidth || drawingBufferHeight !== this._drawingBufferHeight || this._glowFactorDirty || - useHDR !== this._useHDR) { + useHdr !== this._useHdr) { this._texture = this._texture && this._texture.destroy(); this._drawingBufferWidth = drawingBufferWidth; this._drawingBufferHeight = drawingBufferHeight; this._glowFactorDirty = false; - this._useHDR = useHDR; + this._useHdr = useHdr; var size = Math.max(drawingBufferWidth, drawingBufferHeight); size = Math.pow(2.0, Math.ceil(Math.log(size) / Math.log(2.0)) - 2.0); @@ -179,7 +179,7 @@ define([ // errors in the tests. size = Math.max(1.0, size); - var pixelDatatype = useHDR ? (context.halfFloatingPointTexture ? PixelDatatype.HALF_FLOAT : PixelDatatype.FLOAT) : PixelDatatype.UNSIGNED_BYTE; + var pixelDatatype = useHdr ? (context.halfFloatingPointTexture ? PixelDatatype.HALF_FLOAT : PixelDatatype.FLOAT) : PixelDatatype.UNSIGNED_BYTE; this._texture = new Texture({ context : context, width : size, diff --git a/Source/Shaders/GlobeFS.glsl b/Source/Shaders/GlobeFS.glsl index 1c1914ee7719..7e6ddcfa5907 100644 --- a/Source/Shaders/GlobeFS.glsl +++ b/Source/Shaders/GlobeFS.glsl @@ -276,7 +276,6 @@ void main() vec4 finalColor = color; #endif - #ifdef ENABLE_CLIPPING_PLANES vec4 clippingPlanesEdgeColor = vec4(1.0); clippingPlanesEdgeColor.rgb = u_clippingPlanesEdgeStyle.rgb; diff --git a/Source/Shaders/PostProcessStages/ACESTonemapping.glsl b/Source/Shaders/PostProcessStages/AcesTonemapping.glsl similarity index 100% rename from Source/Shaders/PostProcessStages/ACESTonemapping.glsl rename to Source/Shaders/PostProcessStages/AcesTonemapping.glsl diff --git a/Source/Shaders/PostProcessStages/FilmicTonemapping.glsl b/Source/Shaders/PostProcessStages/FilmicTonemapping.glsl index 4f839848454b..425166663a2e 100644 --- a/Source/Shaders/PostProcessStages/FilmicTonemapping.glsl +++ b/Source/Shaders/PostProcessStages/FilmicTonemapping.glsl @@ -30,6 +30,6 @@ void main() vec3 c = ((color * (A * color + C * B) + D * E) / (color * ( A * color + B) + D * F)) - E / F; float w = ((white * (A * white + C * B) + D * E) / (white * ( A * white + B) + D * F)) - E / F; - c = czm_inverseGamma(c / w); + c = czm_inverseGamma(c / w); gl_FragColor = vec4(c, 1.0); } From 0fcf8c53fcc48dd1c081b7d9a211770322aa84e2 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 17 Oct 2018 17:04:21 -0400 Subject: [PATCH 46/76] Fix gamma correction for PerInstanceColorAppearance. --- Source/Shaders/Appearances/PerInstanceColorAppearanceFS.glsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Shaders/Appearances/PerInstanceColorAppearanceFS.glsl b/Source/Shaders/Appearances/PerInstanceColorAppearanceFS.glsl index c2709e847ea9..9001f89b7ebb 100644 --- a/Source/Shaders/Appearances/PerInstanceColorAppearanceFS.glsl +++ b/Source/Shaders/Appearances/PerInstanceColorAppearanceFS.glsl @@ -15,7 +15,7 @@ void main() materialInput.normalEC = normalEC; materialInput.positionToEyeEC = positionToEyeEC; czm_material material = czm_getDefaultMaterial(materialInput); - material.diffuse = v_color.rgb; + material.diffuse = czm_gammaCorrect(v_color.rgb); material.alpha = v_color.a; gl_FragColor = czm_phong(normalize(positionToEyeEC), material); From 594a9b4e4fc8cba68ca96923a1b20e5b9dd9422d Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 17 Oct 2018 18:46:32 -0400 Subject: [PATCH 47/76] Fix some issues with gamma correction. --- Source/Scene/Material.js | 2 ++ Source/Scene/Model.js | 4 ++-- .../Appearances/PerInstanceColorAppearanceFS.glsl | 6 ++++-- Source/Shaders/BillboardCollectionFS.glsl | 2 +- .../Shaders/Builtin/Functions/gammaCorrect.glsl | 15 +++++++++++++++ Source/Shaders/GlobeFS.glsl | 6 ++++-- .../Shaders/Materials/CheckerboardMaterial.glsl | 3 ++- Source/Shaders/Materials/DotMaterial.glsl | 3 ++- .../Materials/ElevationContourMaterial.glsl | 8 +++++--- .../Shaders/Materials/ElevationRampMaterial.glsl | 3 ++- Source/Shaders/Materials/FadeMaterial.glsl | 3 ++- Source/Shaders/Materials/GridMaterial.glsl | 11 +++++++---- .../Shaders/Materials/PolylineArrowMaterial.glsl | 3 ++- .../Shaders/Materials/PolylineDashMaterial.glsl | 3 ++- .../Shaders/Materials/PolylineGlowMaterial.glsl | 9 +++++++-- .../Materials/PolylineOutlineMaterial.glsl | 3 ++- Source/Shaders/Materials/RimLightingMaterial.glsl | 9 ++++++--- Source/Shaders/Materials/SlopeRampMaterial.glsl | 3 ++- Source/Shaders/Materials/StripeMaterial.glsl | 3 ++- Source/Shaders/Materials/Water.glsl | 2 +- Source/Shaders/PointPrimitiveCollectionFS.glsl | 2 +- Source/Shaders/ShadowVolumeAppearanceFS.glsl | 2 +- Source/Shaders/SkyBoxFS.glsl | 5 ++--- Source/Shaders/SunFS.glsl | 2 +- 24 files changed, 77 insertions(+), 35 deletions(-) diff --git a/Source/Scene/Material.js b/Source/Scene/Material.js index 01cf65f09ec6..b25bcb2388e0 100644 --- a/Source/Scene/Material.js +++ b/Source/Scene/Material.js @@ -697,6 +697,8 @@ define([ if (components.hasOwnProperty(component)) { if (component === 'diffuse' || component === 'emission') { material.shaderSource += 'material.' + component + ' = czm_gammaCorrect(' + components[component] + '); \n'; + } else if (component === 'alpha') { + material.shaderSource += 'material.alpha = czm_gammaCorrectAlpha(' + components.alpha + '); \n'; } else { material.shaderSource += 'material.' + component + ' = ' + components[component] + ';\n'; } diff --git a/Source/Scene/Model.js b/Source/Scene/Model.js index 302373d22a9b..bb84224addb1 100644 --- a/Source/Scene/Model.js +++ b/Source/Scene/Model.js @@ -1945,7 +1945,7 @@ define([ '\n' + 'void main() { \n' + ' non_gamma_corrected_main(); \n' + - ' gl_FragColor.rgb = czm_gammaCorrect(gl_FragColor.rgb); \n' + + ' gl_FragColor = czm_gammaCorrect(gl_FragColor); \n' + '} \n'; } @@ -1998,7 +1998,7 @@ define([ '\n' + 'void main() { \n' + ' non_gamma_corrected_main(); \n' + - ' gl_FragColor.rgb = czm_gammaCorrect(gl_FragColor.rgb); \n' + + ' gl_FragColor = czm_gammaCorrect(gl_FragColor); \n' + '} \n'; } diff --git a/Source/Shaders/Appearances/PerInstanceColorAppearanceFS.glsl b/Source/Shaders/Appearances/PerInstanceColorAppearanceFS.glsl index 9001f89b7ebb..e13322e51d94 100644 --- a/Source/Shaders/Appearances/PerInstanceColorAppearanceFS.glsl +++ b/Source/Shaders/Appearances/PerInstanceColorAppearanceFS.glsl @@ -11,12 +11,14 @@ void main() normalEC = faceforward(normalEC, vec3(0.0, 0.0, 1.0), -normalEC); #endif + vec4 color = czm_gammaCorrect(v_color); + czm_materialInput materialInput; materialInput.normalEC = normalEC; materialInput.positionToEyeEC = positionToEyeEC; czm_material material = czm_getDefaultMaterial(materialInput); - material.diffuse = czm_gammaCorrect(v_color.rgb); - material.alpha = v_color.a; + material.diffuse = _color.rgb; + material.alpha = color.a; gl_FragColor = czm_phong(normalize(positionToEyeEC), material); } diff --git a/Source/Shaders/BillboardCollectionFS.glsl b/Source/Shaders/BillboardCollectionFS.glsl index 66ccfaf17e04..11b2c9b0946b 100644 --- a/Source/Shaders/BillboardCollectionFS.glsl +++ b/Source/Shaders/BillboardCollectionFS.glsl @@ -51,7 +51,7 @@ float getGlobeDepth(vec2 adjustedST, vec2 depthLookupST, bool applyTranslate, ve void main() { vec4 color = texture2D(u_atlas, v_textureCoordinates); - color.rgb = czm_gammaCorrect(color.rgb); + color = czm_gammaCorrect(color); color *= v_color; // Fully transparent parts of the billboard are not pickable. diff --git a/Source/Shaders/Builtin/Functions/gammaCorrect.glsl b/Source/Shaders/Builtin/Functions/gammaCorrect.glsl index 0dc6f2eb4b32..5815a265966e 100644 --- a/Source/Shaders/Builtin/Functions/gammaCorrect.glsl +++ b/Source/Shaders/Builtin/Functions/gammaCorrect.glsl @@ -13,3 +13,18 @@ vec3 czm_gammaCorrect(vec3 color) { #endif return color; } + +float czm_gammaCorrectAlpha(float alpha) { +#ifdef HDR + alpha = pow(alpha, 1.0 / czm_gamma); +#endif + return alpha; +} + +vec4 czm_gammaCorrect(vec4 color) { +#ifdef HDR + color.rgb = pow(color.rgb, vec3(czm_gamma)); + color.a = czm_gammaCorrectAlpha(color.a); +#endif + return color; +} diff --git a/Source/Shaders/GlobeFS.glsl b/Source/Shaders/GlobeFS.glsl index 46d6321023c9..b66e27ceb44d 100644 --- a/Source/Shaders/GlobeFS.glsl +++ b/Source/Shaders/GlobeFS.glsl @@ -132,7 +132,9 @@ vec4 sampleAndBlend( color = pow(color, vec3(textureOneOverGamma)); #endif - color = czm_gammaCorrect(color); + vec4 tempColor = czm_gammaCorrect(vec4(color, alpha)); + color = tempColor.rgb; + alpha = tempColor.a; #ifdef APPLY_SPLIT float splitPosition = czm_imagerySplitPosition; @@ -263,7 +265,7 @@ void main() color.xyz = mix(color.xyz, material.diffuse, material.alpha); #endif -#ifdef HDR +#if defined(HDR) && !defined(APPLY_MATERIAL) czm_material material; material.diffuse = color.rgb; material.alpha = color.a; diff --git a/Source/Shaders/Materials/CheckerboardMaterial.glsl b/Source/Shaders/Materials/CheckerboardMaterial.glsl index ea4af75e6fd1..7ef18fc45ebf 100644 --- a/Source/Shaders/Materials/CheckerboardMaterial.glsl +++ b/Source/Shaders/Materials/CheckerboardMaterial.glsl @@ -21,7 +21,8 @@ czm_material czm_getMaterial(czm_materialInput materialInput) vec4 currentColor = mix(lightColor, darkColor, b); vec4 color = czm_antialias(lightColor, darkColor, currentColor, value, 0.03); - material.diffuse = czm_gammaCorrect(color.rgb); + color = czm_gammaCorrect(color); + material.diffuse = color.rgb; material.alpha = color.a; return material; diff --git a/Source/Shaders/Materials/DotMaterial.glsl b/Source/Shaders/Materials/DotMaterial.glsl index 7ad2067b8b8e..84df550e1faf 100644 --- a/Source/Shaders/Materials/DotMaterial.glsl +++ b/Source/Shaders/Materials/DotMaterial.glsl @@ -10,7 +10,8 @@ czm_material czm_getMaterial(czm_materialInput materialInput) float b = smoothstep(0.3, 0.32, length(fract(repeat * materialInput.st) - 0.5)); // 0.0 or 1.0 vec4 color = mix(lightColor, darkColor, b); - material.diffuse = czm_gammaCorrect(color.rgb); + color = czm_gammaCorrect(color); + material.diffuse = color.rgb; material.alpha = color.a; return material; diff --git a/Source/Shaders/Materials/ElevationContourMaterial.glsl b/Source/Shaders/Materials/ElevationContourMaterial.glsl index 17c2dd63ed58..a42a62543761 100644 --- a/Source/Shaders/Materials/ElevationContourMaterial.glsl +++ b/Source/Shaders/Materials/ElevationContourMaterial.glsl @@ -16,12 +16,14 @@ czm_material czm_getMaterial(czm_materialInput materialInput) float dxc = abs(dFdx(materialInput.height)); float dyc = abs(dFdy(materialInput.height)); float dF = max(dxc, dyc) * width; - material.alpha = (distanceToContour < dF) ? 1.0 : 0.0; + float alpha = (distanceToContour < dF) ? 1.0 : 0.0; #else - material.alpha = (distanceToContour < (czm_resolutionScale * width)) ? 1.0 : 0.0; + float alpha = (distanceToContour < (czm_resolutionScale * width)) ? 1.0 : 0.0; #endif - material.diffuse = czm_gammaCorrect(color.rgb); + vec4 outColor = czm_gammaCorrect(vec4(color.rgb, alpha)); + material.diffuse = outColor.rgb; + material.alpha = outColor.a; return material; } diff --git a/Source/Shaders/Materials/ElevationRampMaterial.glsl b/Source/Shaders/Materials/ElevationRampMaterial.glsl index d9d62fe9418f..a9680c003f63 100644 --- a/Source/Shaders/Materials/ElevationRampMaterial.glsl +++ b/Source/Shaders/Materials/ElevationRampMaterial.glsl @@ -7,7 +7,8 @@ czm_material czm_getMaterial(czm_materialInput materialInput) czm_material material = czm_getDefaultMaterial(materialInput); float scaledHeight = clamp((materialInput.height - minimumHeight) / (maximumHeight - minimumHeight), 0.0, 1.0); vec4 rampColor = texture2D(image, vec2(scaledHeight, 0.5)); - material.diffuse = czm_gammaCorrect(rampColor.rgb); + rampColor = czm_gammaCorrect(rampColor); + material.diffuse = rampColor.rgb; material.alpha = rampColor.a; return material; } diff --git a/Source/Shaders/Materials/FadeMaterial.glsl b/Source/Shaders/Materials/FadeMaterial.glsl index fd0f182f5c79..961d21fc707e 100644 --- a/Source/Shaders/Materials/FadeMaterial.glsl +++ b/Source/Shaders/Materials/FadeMaterial.glsl @@ -29,7 +29,8 @@ czm_material czm_getMaterial(czm_materialInput materialInput) float u = length(vec2(s, t)); vec4 color = mix(fadeInColor, fadeOutColor, u); - material.emission = czm_gammaCorrect(color.rgb); + color = czm_gammaCorrect(color); + material.emission = color.rgb; material.alpha = color.a; return material; diff --git a/Source/Shaders/Materials/GridMaterial.glsl b/Source/Shaders/Materials/GridMaterial.glsl index 4977db3d77da..536cfb1aba5d 100644 --- a/Source/Shaders/Materials/GridMaterial.glsl +++ b/Source/Shaders/Materials/GridMaterial.glsl @@ -48,10 +48,13 @@ czm_material czm_getMaterial(czm_materialInput materialInput) float sRim = smoothstep(0.8, 1.0, dRim); value *= (1.0 - sRim); - vec3 halfColor = color.rgb * 0.5; - material.diffuse = czm_gammaCorrect(halfColor); - material.emission = czm_gammaCorrect(halfColor); - material.alpha = color.a * (1.0 - ((1.0 - cellAlpha) * value)); + vec4 halfColor; + halfColor.rgb = color.rgb * 0.5; + halfColor.a = color.a * (1.0 - ((1.0 - cellAlpha) * value)); + halfColor = czm_gammaCorrect(halfColor); + material.diffuse = halfColor.rgb; + material.emission = halfColor.rgb; + material.alpha = halfColor.a; return material; } diff --git a/Source/Shaders/Materials/PolylineArrowMaterial.glsl b/Source/Shaders/Materials/PolylineArrowMaterial.glsl index e6706c646320..0de3d651bbda 100644 --- a/Source/Shaders/Materials/PolylineArrowMaterial.glsl +++ b/Source/Shaders/Materials/PolylineArrowMaterial.glsl @@ -61,7 +61,8 @@ czm_material czm_getMaterial(czm_materialInput materialInput) vec4 currentColor = mix(outsideColor, color, clamp(s + t, 0.0, 1.0)); vec4 outColor = czm_antialias(outsideColor, color, currentColor, dist); - material.diffuse = czm_gammaCorrect(outColor.rgb); + outColor = czm_gammaCorrect(outColor); + material.diffuse = outColor.rgb; material.alpha = outColor.a; return material; } diff --git a/Source/Shaders/Materials/PolylineDashMaterial.glsl b/Source/Shaders/Materials/PolylineDashMaterial.glsl index 933013ae4080..35055cf80030 100644 --- a/Source/Shaders/Materials/PolylineDashMaterial.glsl +++ b/Source/Shaders/Materials/PolylineDashMaterial.glsl @@ -32,7 +32,8 @@ czm_material czm_getMaterial(czm_materialInput materialInput) discard; } - material.emission = czm_gammaCorrect(fragColor.rgb); + fragColor = czm_gammaCorrect(fragColor); + material.emission = fragColor.rgb; material.alpha = fragColor.a; return material; } diff --git a/Source/Shaders/Materials/PolylineGlowMaterial.glsl b/Source/Shaders/Materials/PolylineGlowMaterial.glsl index a2a04c0e0fc0..66ae9deb8660 100644 --- a/Source/Shaders/Materials/PolylineGlowMaterial.glsl +++ b/Source/Shaders/Materials/PolylineGlowMaterial.glsl @@ -10,8 +10,13 @@ czm_material czm_getMaterial(czm_materialInput materialInput) vec2 st = materialInput.st; float glow = glowPower / abs(st.t - 0.5) - (glowPower / 0.5); - material.emission = czm_gammaCorrect(max(vec3(glow - 1.0 + color.rgb), color.rgb)); - material.alpha = clamp(0.0, 1.0, glow) * color.a; + vec4 fragColor; + fragColor.rgb = max(vec3(glow - 1.0 + color.rgb), color.rgb); + fragColor.a = clamp(0.0, 1.0, glow) * color.a; + fragColor = czm_gammaCorrect(fragColor); + + material.emission = fragColor.rgb; + material.alpha = fragColor.a; return material; } diff --git a/Source/Shaders/Materials/PolylineOutlineMaterial.glsl b/Source/Shaders/Materials/PolylineOutlineMaterial.glsl index 41a8764b4528..196505bc5891 100644 --- a/Source/Shaders/Materials/PolylineOutlineMaterial.glsl +++ b/Source/Shaders/Materials/PolylineOutlineMaterial.glsl @@ -20,8 +20,9 @@ czm_material czm_getMaterial(czm_materialInput materialInput) vec4 currentColor = mix(outlineColor, color, b); vec4 outColor = czm_antialias(outlineColor, color, currentColor, dist); + outColor = czm_gammaCorrect(outColor); - material.diffuse = czm_gammaCorrect(outColor.rgb); + material.diffuse = outColor.rgb; material.alpha = outColor.a; return material; diff --git a/Source/Shaders/Materials/RimLightingMaterial.glsl b/Source/Shaders/Materials/RimLightingMaterial.glsl index 34b79bce9c56..6e3267eadd8b 100644 --- a/Source/Shaders/Materials/RimLightingMaterial.glsl +++ b/Source/Shaders/Materials/RimLightingMaterial.glsl @@ -10,9 +10,12 @@ czm_material czm_getMaterial(czm_materialInput materialInput) float d = 1.0 - dot(materialInput.normalEC, normalize(materialInput.positionToEyeEC)); float s = smoothstep(1.0 - width, 1.0, d); - material.diffuse = czm_gammaCorrect(color.rgb); - material.emission = czm_gammaCorrect(rimColor.rgb * s); - material.alpha = mix(color.a, rimColor.a, s); + vec4 outColor = czm_gammaCorrect(color); + vec4 outRimColor = czm_gammaCorrect(rimColor); + + material.diffuse = outColor.rgb; + material.emission = outRimColor.rgb * s; + material.alpha = mix(outColor.a, outRimColor.a, s); return material; } diff --git a/Source/Shaders/Materials/SlopeRampMaterial.glsl b/Source/Shaders/Materials/SlopeRampMaterial.glsl index 7471965bfc9b..15b27ae9e37b 100644 --- a/Source/Shaders/Materials/SlopeRampMaterial.glsl +++ b/Source/Shaders/Materials/SlopeRampMaterial.glsl @@ -4,7 +4,8 @@ czm_material czm_getMaterial(czm_materialInput materialInput) { czm_material material = czm_getDefaultMaterial(materialInput); vec4 rampColor = texture2D(image, vec2(materialInput.slope, 0.5)); - material.diffuse = czm_gammaCorrect(rampColor.rgb); + rampColor = czm_gammaCorrect(rampColor); + material.diffuse = rampColor.rgb; material.alpha = rampColor.a; return material; } diff --git a/Source/Shaders/Materials/StripeMaterial.glsl b/Source/Shaders/Materials/StripeMaterial.glsl index 4ff3a70803a3..9df8c95999ae 100644 --- a/Source/Shaders/Materials/StripeMaterial.glsl +++ b/Source/Shaders/Materials/StripeMaterial.glsl @@ -15,8 +15,9 @@ czm_material czm_getMaterial(czm_materialInput materialInput) vec4 currentColor = mix(evenColor, oddColor, step(0.5, value)); vec4 color = czm_antialias(evenColor, oddColor, currentColor, dist); + color = czm_gammaCorrect(color); - material.diffuse = czm_gammaCorrect(color.rgb); + material.diffuse = color.rgb; material.alpha = color.a; return material; diff --git a/Source/Shaders/Materials/Water.glsl b/Source/Shaders/Materials/Water.glsl index 0ac0f1bc8e44..7c529b5e8230 100644 --- a/Source/Shaders/Materials/Water.glsl +++ b/Source/Shaders/Materials/Water.glsl @@ -47,7 +47,7 @@ czm_material czm_getMaterial(czm_materialInput materialInput) // diffuse highlights are based on how perturbed the normal is material.diffuse += (0.1 * tsPerturbationRatio); - material.diffuse = czm_gammaCorrect(material.diffuse); + material.diffuse = material.diffuse; material.normal = normalize(materialInput.tangentToEyeMatrix * normalTangentSpace); diff --git a/Source/Shaders/PointPrimitiveCollectionFS.glsl b/Source/Shaders/PointPrimitiveCollectionFS.glsl index 45cead4d3f27..b7586705435e 100644 --- a/Source/Shaders/PointPrimitiveCollectionFS.glsl +++ b/Source/Shaders/PointPrimitiveCollectionFS.glsl @@ -38,6 +38,6 @@ void main() #endif #endif - gl_FragColor = vec4(czm_gammaCorrect(color.rgb), color.a); + gl_FragColor = czm_gammaCorrect(color); czm_writeLogDepth(); } diff --git a/Source/Shaders/ShadowVolumeAppearanceFS.glsl b/Source/Shaders/ShadowVolumeAppearanceFS.glsl index 0911f255552f..ab8903295863 100644 --- a/Source/Shaders/ShadowVolumeAppearanceFS.glsl +++ b/Source/Shaders/ShadowVolumeAppearanceFS.glsl @@ -96,7 +96,7 @@ void main(void) #ifdef PER_INSTANCE_COLOR - vec4 color = vec4(czm_gammaCorrect(v_color.rgb), v_color.a); + vec4 color = czm_gammaCorrect(v_color); #ifdef FLAT gl_FragColor = color; #else // FLAT diff --git a/Source/Shaders/SkyBoxFS.glsl b/Source/Shaders/SkyBoxFS.glsl index afc60f4e206b..d40f8a4e59c7 100644 --- a/Source/Shaders/SkyBoxFS.glsl +++ b/Source/Shaders/SkyBoxFS.glsl @@ -4,7 +4,6 @@ varying vec3 v_texCoord; void main() { - vec3 rgb = textureCube(u_cubeMap, normalize(v_texCoord)).rgb; - rgb = czm_gammaCorrect(rgb); - gl_FragColor = vec4(rgb, czm_morphTime); + vec4 color = textureCube(u_cubeMap, normalize(v_texCoord)); + gl_FragColor = vec4(czm_gammaCorrect(color).rgb, czm_morphTime); } diff --git a/Source/Shaders/SunFS.glsl b/Source/Shaders/SunFS.glsl index 99b973790e54..68abd170627f 100644 --- a/Source/Shaders/SunFS.glsl +++ b/Source/Shaders/SunFS.glsl @@ -5,5 +5,5 @@ varying vec2 v_textureCoordinates; void main() { vec4 color = texture2D(u_texture, v_textureCoordinates); - gl_FragColor = vec4(czm_gammaCorrect(color.rgb), color.a); + gl_FragColor = czm_gammaCorrect(color); } From 998f3e243ebf294430ceb3926fa514164a5da53a Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 18 Oct 2018 15:24:05 -0400 Subject: [PATCH 48/76] Fix glTF 1.0 model gamma correction. --- Source/Scene/Model.js | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/Source/Scene/Model.js b/Source/Scene/Model.js index bb84224addb1..2ca5e6e23407 100644 --- a/Source/Scene/Model.js +++ b/Source/Scene/Model.js @@ -646,8 +646,6 @@ define([ this._sourcePrograms = {}; this._quantizedVertexShaders = {}; - this._upgrade10To20 = undefined; - this._nodeCommands = []; this._pickIds = []; @@ -1938,7 +1936,7 @@ define([ drawFS = 'uniform vec4 czm_pickColor;\n' + drawFS; } - if (model._upgrade10To20) { + if (model.gltf.extras.sourceVersion !== '2.0') { drawFS = ShaderSource.replaceMain(drawFS, 'non_gamma_corrected_main'); drawFS = drawFS + @@ -1991,7 +1989,7 @@ define([ drawFS = 'uniform vec4 czm_pickColor;\n' + drawFS; } - if (model._upgrade10To20) { + if (model.gltf.extras.sourceVersion !== '2.0') { drawFS = ShaderSource.replaceMain(drawFS, 'non_gamma_corrected_main'); drawFS = drawFS + @@ -4019,10 +4017,6 @@ define([ this._defaultTexture = context.defaultTexture; if ((this._state === ModelState.NEEDS_LOAD) && defined(this.gltf)) { - if (!defined(this._upgrade10To20)) { - this._upgrade10To20 = defined(this.gltf.asset) && defined(this.gltf.asset.extras) && this.gltf.asset.extras.gltf_pipeline_upgrade_10to20; - } - // Use renderer resources from cache instead of loading/creating them? var cachedRendererResources; var cacheKey = this.cacheKey; From 209ec90204d59b113e302b7566e6b2977c7cc5f1 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 18 Oct 2018 15:28:02 -0400 Subject: [PATCH 49/76] Fix globe day/night shading. --- Source/Shaders/GlobeFS.glsl | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/Source/Shaders/GlobeFS.glsl b/Source/Shaders/GlobeFS.glsl index b66e27ceb44d..537f4851ebea 100644 --- a/Source/Shaders/GlobeFS.glsl +++ b/Source/Shaders/GlobeFS.glsl @@ -265,13 +265,7 @@ void main() color.xyz = mix(color.xyz, material.diffuse, material.alpha); #endif -#if defined(HDR) && !defined(APPLY_MATERIAL) - czm_material material; - material.diffuse = color.rgb; - material.alpha = color.a; - material.normal = normalEC; - vec4 finalColor = czm_phong(normalize(-v_positionEC), material); -#elif defined(ENABLE_VERTEX_LIGHTING) +#ifdef ENABLE_VERTEX_LIGHTING float diffuseIntensity = clamp(czm_getLambertDiffuse(czm_sunDirectionEC, normalize(v_normalEC)) * 0.9 + 0.3, 0.0, 1.0); vec4 finalColor = vec4(color.rgb * diffuseIntensity, color.a); #elif defined(ENABLE_DAYNIGHT_SHADING) From 260c0e610839aa570bda2b31dbb8bbdfc9e2088e Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 18 Oct 2018 15:34:06 -0400 Subject: [PATCH 50/76] Fix point cloud gamma correction. --- Source/Scene/PointCloud.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Scene/PointCloud.js b/Source/Scene/PointCloud.js index 2edd8c05735d..c2718f4e6ab5 100644 --- a/Source/Scene/PointCloud.js +++ b/Source/Scene/PointCloud.js @@ -1189,7 +1189,7 @@ define([ fs += 'void main() \n' + '{ \n' + - ' gl_FragColor = v_color; \n'; + ' gl_FragColor = czm_gammaCorrect(v_color); \n'; if (hasClippedContent) { fs += getClipAndStyleCode('u_clippingPlanes', 'u_clippingPlanesMatrix', 'u_clippingPlanesEdgeStyle'); From f72afd3f72a5676578d22179ffb915519d698209 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 18 Oct 2018 15:37:33 -0400 Subject: [PATCH 51/76] Update imagery contrast. --- Source/Shaders/GlobeFS.glsl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Source/Shaders/GlobeFS.glsl b/Source/Shaders/GlobeFS.glsl index 537f4851ebea..8a844ec012ec 100644 --- a/Source/Shaders/GlobeFS.glsl +++ b/Source/Shaders/GlobeFS.glsl @@ -132,10 +132,6 @@ vec4 sampleAndBlend( color = pow(color, vec3(textureOneOverGamma)); #endif - vec4 tempColor = czm_gammaCorrect(vec4(color, alpha)); - color = tempColor.rgb; - alpha = tempColor.a; - #ifdef APPLY_SPLIT float splitPosition = czm_imagerySplitPosition; // Split to the left @@ -164,6 +160,10 @@ vec4 sampleAndBlend( color = czm_saturation(color, textureSaturation); #endif + vec4 tempColor = czm_gammaCorrect(vec4(color, alpha)); + color = tempColor.rgb; + alpha = tempColor.a; + float sourceAlpha = alpha * textureAlpha; float outAlpha = mix(previousColor.a, 1.0, sourceAlpha); vec3 outColor = mix(previousColor.rgb * previousColor.a, color, sourceAlpha) / outAlpha; From 4d911f81910e0cfc0a209b498213aa3ca7b45f9a Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 18 Oct 2018 15:51:51 -0400 Subject: [PATCH 52/76] Fix background color gamma correction. --- Source/Scene/Scene.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Source/Scene/Scene.js b/Source/Scene/Scene.js index f2a5324defa3..1b3d7233a8e6 100644 --- a/Source/Scene/Scene.js +++ b/Source/Scene/Scene.js @@ -3069,6 +3069,8 @@ define([ frameState.creditDisplay.update(); } + var scratchBackgroundColor = new Color(); + function render(scene, time) { scene._pickPositionCacheDirty = true; @@ -3085,6 +3087,12 @@ define([ frameState.passes.postProcess = scene.postProcessStages.hasSelected; 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; frameState.creditDisplay.beginFrame(); From 7cada271c19a7298e6b352b7fd6bb3d52ce0e63a Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 18 Oct 2018 16:07:42 -0400 Subject: [PATCH 53/76] Fix shadows and a typo. --- Source/Scene/OIT.js | 5 +++++ Source/Scene/Scene.js | 1 + Source/Shaders/Appearances/PerInstanceColorAppearanceFS.glsl | 2 +- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/Source/Scene/OIT.js b/Source/Scene/OIT.js index 549d90c1c85d..025c8b042607 100644 --- a/Source/Scene/OIT.js +++ b/Source/Scene/OIT.js @@ -538,6 +538,7 @@ define([ var context = scene.context; var useLogDepth = scene.frameState.useLogDepth; + var useHdr = scene._hdr; var framebuffer = passState.framebuffer; var length = commands.length; @@ -554,6 +555,7 @@ define([ for (j = 0; j < length; ++j) { command = commands[j]; command = useLogDepth ? command.derivedCommands.logDepth.command : command; + command = useHdr ? command.derivedCommands.hdr.command : command; derivedCommand = (lightShadowsEnabled && command.receiveShadows) ? command.derivedCommands.oit.shadows.translucentCommand : command.derivedCommands.oit.translucentCommand; executeFunction(derivedCommand, scene, context, passState, debugFramebuffer); } @@ -569,6 +571,7 @@ define([ for (j = 0; j < length; ++j) { command = commands[j]; command = useLogDepth ? command.derivedCommands.logDepth.command : command; + command = useHdr ? command.derivedCommands.hdr.command : command; derivedCommand = (lightShadowsEnabled && command.receiveShadows) ? command.derivedCommands.oit.shadows.alphaCommand : command.derivedCommands.oit.alphaCommand; executeFunction(derivedCommand, scene, context, passState, debugFramebuffer); } @@ -585,6 +588,7 @@ define([ function executeTranslucentCommandsSortedMRT(oit, scene, executeFunction, passState, commands, invertClassification) { var context = scene.context; var useLogDepth = scene.frameState.useLogDepth; + var useHdr = scene._hdr; var framebuffer = passState.framebuffer; var length = commands.length; @@ -602,6 +606,7 @@ define([ for (var j = 0; j < length; ++j) { command = commands[j]; command = useLogDepth ? command.derivedCommands.logDepth.command : command; + command = useHdr ? command.derivedCommands.hdr.command : command; 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 1b3d7233a8e6..47d032762a61 100644 --- a/Source/Scene/Scene.js +++ b/Source/Scene/Scene.js @@ -1543,6 +1543,7 @@ define([ if (scene._hdr) { derivedCommands.hdr = DerivedCommand.createHdrCommand(command, context, derivedCommands.hdr); command = derivedCommands.hdr.command; + derivedCommands = command.derivedCommands; } if (lightShadowsEnabled && command.receiveShadows) { diff --git a/Source/Shaders/Appearances/PerInstanceColorAppearanceFS.glsl b/Source/Shaders/Appearances/PerInstanceColorAppearanceFS.glsl index e13322e51d94..b031af4e8aa7 100644 --- a/Source/Shaders/Appearances/PerInstanceColorAppearanceFS.glsl +++ b/Source/Shaders/Appearances/PerInstanceColorAppearanceFS.glsl @@ -17,7 +17,7 @@ void main() materialInput.normalEC = normalEC; materialInput.positionToEyeEC = positionToEyeEC; czm_material material = czm_getDefaultMaterial(materialInput); - material.diffuse = _color.rgb; + material.diffuse = color.rgb; material.alpha = color.a; gl_FragColor = czm_phong(normalize(positionToEyeEC), material); From b0541b0c836731c88c4be801656ca97771f69231 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 18 Oct 2018 16:28:04 -0400 Subject: [PATCH 54/76] Fix picking and another typo. --- Source/Scene/PostProcessStageLibrary.js | 2 +- Source/Scene/Scene.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Source/Scene/PostProcessStageLibrary.js b/Source/Scene/PostProcessStageLibrary.js index cb817d647f9c..8400b18078aa 100644 --- a/Source/Scene/PostProcessStageLibrary.js +++ b/Source/Scene/PostProcessStageLibrary.js @@ -23,7 +23,7 @@ define([ '../Shaders/PostProcessStages/LensFlare', '../Shaders/PostProcessStages/ModifiedReinhardTonemapping', '../Shaders/PostProcessStages/NightVision', - '../shaders/PostProcessStages/ReinhardTonemapping', + '../Shaders/PostProcessStages/ReinhardTonemapping', '../Shaders/PostProcessStages/Silhouette', '../ThirdParty/Shaders/FXAA3_11', './AutoExposure', diff --git a/Source/Scene/Scene.js b/Source/Scene/Scene.js index 47d032762a61..03b451fc7364 100644 --- a/Source/Scene/Scene.js +++ b/Source/Scene/Scene.js @@ -1893,11 +1893,11 @@ define([ command = command.derivedCommands.logDepth.command; } - if (defined(command.derivedCommands) && defined(command.derivedCommands.hdr)) { + var passes = frameState.passes; + if (!passes.pick && defined(command.derivedCommands) && defined(command.derivedCommands.hdr)) { command = command.derivedCommands.hdr.command; } - var passes = frameState.passes; if (passes.pick || passes.depth) { if (passes.pick && !passes.depth && defined(command.derivedCommands.picking)) { command = command.derivedCommands.picking.pickCommand; From b8144a9b050a1e00c80d9cbf8f8ac1765f4754b1 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 18 Oct 2018 17:25:39 -0400 Subject: [PATCH 55/76] Fix tests. --- Source/Scene/Material.js | 2 +- Source/Scene/Model.js | 6 ++++-- Source/Scene/PostProcessStageCollection.js | 2 +- Source/Shaders/Builtin/Functions/gammaCorrect.glsl | 9 +-------- Specs/Scene/ModelSpec.js | 6 +++++- Specs/Scene/ShadowMapSpec.js | 4 +--- 6 files changed, 13 insertions(+), 16 deletions(-) diff --git a/Source/Scene/Material.js b/Source/Scene/Material.js index b25bcb2388e0..14cd62335aa6 100644 --- a/Source/Scene/Material.js +++ b/Source/Scene/Material.js @@ -698,7 +698,7 @@ define([ if (component === 'diffuse' || component === 'emission') { material.shaderSource += 'material.' + component + ' = czm_gammaCorrect(' + components[component] + '); \n'; } else if (component === 'alpha') { - material.shaderSource += 'material.alpha = czm_gammaCorrectAlpha(' + components.alpha + '); \n'; + material.shaderSource += 'material.alpha = czm_gammaCorrect(vec4(vec3(0.0), ' + components.alpha + ')).a; \n'; } else { material.shaderSource += 'material.' + component + ' = ' + components[component] + ';\n'; } diff --git a/Source/Scene/Model.js b/Source/Scene/Model.js index 2ca5e6e23407..76c57d7e5741 100644 --- a/Source/Scene/Model.js +++ b/Source/Scene/Model.js @@ -656,6 +656,7 @@ define([ this._rtcCenter2D = undefined; // in projected world coordinates this._keepPipelineExtras = options.keepPipelineExtras; // keep the buffers in memory for use in other applications + this._sourceVersion = undefined; } defineProperties(Model.prototype, { @@ -1936,7 +1937,7 @@ define([ drawFS = 'uniform vec4 czm_pickColor;\n' + drawFS; } - if (model.gltf.extras.sourceVersion !== '2.0') { + if (model._sourceVersion !== '2.0') { drawFS = ShaderSource.replaceMain(drawFS, 'non_gamma_corrected_main'); drawFS = drawFS + @@ -1989,7 +1990,7 @@ define([ drawFS = 'uniform vec4 czm_pickColor;\n' + drawFS; } - if (model.gltf.extras.sourceVersion !== '2.0') { + if (model._sourceVersion !== '2.0') { drawFS = ShaderSource.replaceMain(drawFS, 'non_gamma_corrected_main'); drawFS = drawFS + @@ -4095,6 +4096,7 @@ define([ var gltf = this.gltf; // Add the original version so it remains cached gltf.extras.sourceVersion = ModelUtility.getAssetVersion(gltf); + this._sourceVersion = gltf.extras.sourceVersion; updateVersion(gltf); addDefaults(gltf); diff --git a/Source/Scene/PostProcessStageCollection.js b/Source/Scene/PostProcessStageCollection.js index 61d406d23169..a365fcff9db0 100644 --- a/Source/Scene/PostProcessStageCollection.js +++ b/Source/Scene/PostProcessStageCollection.js @@ -748,7 +748,7 @@ define([ execute(autoexposure, context, initialTexture, depthTexture, idTexture); } if (tonemappingEnabled && tonemapping.ready) { - execute(tonemapping, context, initialTexture, depthTexture); + execute(tonemapping, context, initialTexture, depthTexture, idTexture); initialTexture = getOutputTexture(tonemapping); } diff --git a/Source/Shaders/Builtin/Functions/gammaCorrect.glsl b/Source/Shaders/Builtin/Functions/gammaCorrect.glsl index 5815a265966e..39a1c162a452 100644 --- a/Source/Shaders/Builtin/Functions/gammaCorrect.glsl +++ b/Source/Shaders/Builtin/Functions/gammaCorrect.glsl @@ -14,17 +14,10 @@ vec3 czm_gammaCorrect(vec3 color) { return color; } -float czm_gammaCorrectAlpha(float alpha) { -#ifdef HDR - alpha = pow(alpha, 1.0 / czm_gamma); -#endif - return alpha; -} - vec4 czm_gammaCorrect(vec4 color) { #ifdef HDR color.rgb = pow(color.rgb, vec3(czm_gamma)); - color.a = czm_gammaCorrectAlpha(color.a); + color.a = pow(color.a, 1.0 / czm_gamma); #endif return color; } diff --git a/Specs/Scene/ModelSpec.js b/Specs/Scene/ModelSpec.js index c4d67c41b25a..eb1993e246cb 100644 --- a/Specs/Scene/ModelSpec.js +++ b/Specs/Scene/ModelSpec.js @@ -947,7 +947,11 @@ defineSuite([ m.show = true; expect(scene).toRenderAndCall(function(rgba) { - expect(rgba).toEqualEpsilon([169, 3, 3, 255], 10); // Red + // Red + expect(rgba[0]).toBeGreaterThan(160); + expect(rgba[1]).toBeLessThan(15); + expect(rgba[2]).toBeLessThan(15); + expect(rgba[3]).toEqual(255); }); primitives.remove(m); diff --git a/Specs/Scene/ShadowMapSpec.js b/Specs/Scene/ShadowMapSpec.js index d8609a591018..ec3739d8ba4a 100644 --- a/Specs/Scene/ShadowMapSpec.js +++ b/Specs/Scene/ShadowMapSpec.js @@ -1118,9 +1118,7 @@ defineSuite([ scene.render(); } - // Expect derived commands to be updated twice for both the floor and box, - // once on the first frame and again when the shadow map is dirty - expect(spy1.calls.count()).toEqual(4); + expect(spy1.calls.count()).toEqual(8); expect(spy2.calls.count()).toEqual(4); box.show = false; From 7b011f14c58486e2039d77061936b7010259ff76 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Fri, 19 Oct 2018 15:31:51 -0400 Subject: [PATCH 56/76] Fix DOF. --- Source/Scene/PostProcessStageTextureCache.js | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/Source/Scene/PostProcessStageTextureCache.js b/Source/Scene/PostProcessStageTextureCache.js index 1d6f2c5e80db..c3a57eafa7e4 100644 --- a/Source/Scene/PostProcessStageTextureCache.js +++ b/Source/Scene/PostProcessStageTextureCache.js @@ -77,6 +77,8 @@ define([ return previousName; } + var originalDependency = previousName; + var inSeries = !defined(composite.inputPreviousStageTexture) || composite.inputPreviousStageTexture; var currentName = previousName; var length = composite.length; @@ -96,14 +98,21 @@ define([ // Stages not in a series depend on every stage executed before it since it could reference it as a uniform. // This prevents looking at the dependencies of each stage in the composite, but might create more framebuffers than necessary. // In practice, there are only 2-3 stages in these composites. + var j; + var name; if (!inSeries) { - for (var j = 1; j < length; ++j) { - var name = getLastStageName(composite.get(j)); + for (j = 1; j < length; ++j) { + name = getLastStageName(composite.get(j)); var currentDependencies = dependencies[name]; for (var k = 0; k < j; ++k) { currentDependencies[getLastStageName(composite.get(k))] = true; } } + } else { + for (j = 1; j < length; ++j) { + name = getLastStageName(composite.get(j)); + dependencies[name][originalDependency] = true; + } } return currentName; From faf1904db3e2e4ddc30b4d84f593d2d080027f29 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Fri, 19 Oct 2018 15:58:08 -0400 Subject: [PATCH 57/76] Update doc. --- Source/Scene/Scene.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Scene/Scene.js b/Source/Scene/Scene.js index 03b451fc7364..20b99dff5301 100644 --- a/Source/Scene/Scene.js +++ b/Source/Scene/Scene.js @@ -1451,7 +1451,7 @@ define([ }, /** - * The value used for gamma correction. + * The value used for gamma correction. This is only used when rendering with high dynamic range. * @memberof Scene.prototype * @type {Number} * @default 2.2 @@ -1488,7 +1488,7 @@ define([ * * @memberof Scene.prototype * @type {Color} - * @default Color(0.8, 0.8, 0.8) + * @default Color(0.8, 0.85, 1.0) */ sunColor: { get: function() { From 15dbe1e379acfbf16b32cfd9534eee46ceb9dbd6 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Fri, 19 Oct 2018 17:21:53 -0400 Subject: [PATCH 58/76] Fix typo after merge. --- Source/Scene/Model.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Source/Scene/Model.js b/Source/Scene/Model.js index eefb0d77a7b1..a34eb91d1016 100644 --- a/Source/Scene/Model.js +++ b/Source/Scene/Model.js @@ -2079,7 +2079,8 @@ define([ ' non_gamma_corrected_main(); \n' + ' gl_FragColor = czm_gammaCorrect(gl_FragColor); \n' + '} \n'; - }? + } + createAttributesAndProgram(programId, techniqueId, drawFS, drawVS, model, context); } From 0019163d8620e4873e482ca6b79fd535100e5072 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Mon, 22 Oct 2018 16:41:12 -0400 Subject: [PATCH 59/76] Make czm_sunColor a Cartesian3. --- Source/Renderer/AutomaticUniforms.js | 2 +- Source/Renderer/UniformState.js | 4 ++-- Source/Scene/Scene.js | 6 +++--- Source/Shaders/Builtin/Functions/phong.glsl | 3 +-- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/Source/Renderer/AutomaticUniforms.js b/Source/Renderer/AutomaticUniforms.js index 72a223d4bb81..988f6dbe5c9e 100644 --- a/Source/Renderer/AutomaticUniforms.js +++ b/Source/Renderer/AutomaticUniforms.js @@ -1710,7 +1710,7 @@ define([ */ czm_sunColor: new AutomaticUniform({ size: 1, - datatype: WebGLConstants.FLOAT_VEC4, + datatype: WebGLConstants.FLOAT_VEC3, getValue: function(uniformState) { return uniformState.sunColor; } diff --git a/Source/Renderer/UniformState.js b/Source/Renderer/UniformState.js index 0ec0e682a292..998c409602f4 100644 --- a/Source/Renderer/UniformState.js +++ b/Source/Renderer/UniformState.js @@ -147,7 +147,7 @@ define([ this._sunPositionColumbusView = new Cartesian3(); this._sunDirectionWC = new Cartesian3(); this._sunDirectionEC = new Cartesian3(); - this._sunColor = new Color(); + this._sunColor = new Cartesian3(); this._moonDirectionEC = new Cartesian3(); this._pass = undefined; @@ -1085,7 +1085,7 @@ define([ } setSunAndMoonDirections(this, frameState); - this._sunColor = Color.clone(frameState.sunColor, this._sunColor); + this._sunColor = Cartesian3.clone(frameState.sunColor, this._sunColor); var brdfLutGenerator = frameState.brdfLutGenerator; var brdfLut = defined(brdfLutGenerator) ? brdfLutGenerator.colorTexture : undefined; diff --git a/Source/Scene/Scene.js b/Source/Scene/Scene.js index 20b99dff5301..4dac146c1262 100644 --- a/Source/Scene/Scene.js +++ b/Source/Scene/Scene.js @@ -779,7 +779,7 @@ define([ this._hdrDirty = undefined; this.highDynamicRange = true; this.gamma = 2.2; - this._sunColor = new Color(0.8, 0.85, 1.0, 1.0); + this._sunColor = new Cartesian3(1.8, 1.85, 2.0); // Give frameState, camera, and screen space camera controller initial state before rendering updateFrameState(this, 0.0, JulianDate.now()); @@ -1487,8 +1487,8 @@ define([ * Gets or sets the color of the light emitted by the sun. * * @memberof Scene.prototype - * @type {Color} - * @default Color(0.8, 0.85, 1.0) + * @type {Cartesian3} + * @default Cartesian3(1.8, 1.85, 2.0) */ sunColor: { get: function() { diff --git a/Source/Shaders/Builtin/Functions/phong.glsl b/Source/Shaders/Builtin/Functions/phong.glsl index 7f0374b26368..540f33b9c2c6 100644 --- a/Source/Shaders/Builtin/Functions/phong.glsl +++ b/Source/Shaders/Builtin/Functions/phong.glsl @@ -47,9 +47,8 @@ vec4 czm_phong(vec3 toEye, czm_material material) color += material.specular * specular; #ifdef HDR - vec3 sunColor = czm_sunColor.rgb + czm_sunColor.a; float sunDiffuse = czm_private_getLambertDiffuseOfMaterial(czm_sunDirectionEC, material); - color += materialDiffuse * sunDiffuse * sunColor; + color += materialDiffuse * sunDiffuse * czm_sunColor; #endif return vec4(color, material.alpha); From bd5cb7f08f16274ad08f6d310bbe7f9a16b4682a Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Mon, 22 Oct 2018 16:55:20 -0400 Subject: [PATCH 60/76] Add automatic uniforms tests. --- Specs/Renderer/AutomaticUniformSpec.js | 30 ++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/Specs/Renderer/AutomaticUniformSpec.js b/Specs/Renderer/AutomaticUniformSpec.js index 25778ed564f9..af277d2447db 100644 --- a/Specs/Renderer/AutomaticUniformSpec.js +++ b/Specs/Renderer/AutomaticUniformSpec.js @@ -1340,4 +1340,34 @@ defineSuite([ }).contextToRender(); }); + it('has czm_gamma', function() { + context.uniformState.gamma = 1.0; + var fs = + 'void main() {' + + ' gl_FragColor = vec4(czm_gamma == 1.0);' + + '}'; + expect({ + context : context, + fragmentShader : fs + }).contextToRender(); + }); + + it('has czm_sunColor', function() { + var us = context.uniformState; + var frameState = createFrameState(context, createMockCamera()); + frameState.sunColor = new Cartesian3(1.0, 2.0, 3.0); + us.update(frameState); + var fs = + 'void main() {' + + ' bool b0 = czm_sunColor.x == 1.0;' + + ' bool b1 = czm_sunColor.y == 2.0;' + + ' bool b2 = czm_sunColor.z == 3.0;' + + ' gl_FragColor = vec4(b0 && b1 && b2);' + + '}'; + expect({ + context : context, + fragmentShader : fs + }).contextToRender(); + }); + }, 'WebGL'); From aeb9abd0334e7e7bc5a314a2b66d2149604c6bc4 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Mon, 22 Oct 2018 17:02:13 -0400 Subject: [PATCH 61/76] Fix toggling HDR. --- Source/Scene/Scene.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Scene/Scene.js b/Source/Scene/Scene.js index 4dac146c1262..888f595245a8 100644 --- a/Source/Scene/Scene.js +++ b/Source/Scene/Scene.js @@ -1894,7 +1894,7 @@ define([ } var passes = frameState.passes; - if (!passes.pick && defined(command.derivedCommands) && defined(command.derivedCommands.hdr)) { + if (!passes.pick && scene._hdr && defined(command.derivedCommands) && defined(command.derivedCommands.hdr)) { command = command.derivedCommands.hdr.command; } From 8d0f552ec28921d63bfb4ebfe0e2614464e90176 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Mon, 22 Oct 2018 17:13:42 -0400 Subject: [PATCH 62/76] Fix crash when toggling HDR because globe tile resources were destroyed. --- Source/Scene/GlobeSurfaceTileProvider.js | 1 + 1 file changed, 1 insertion(+) diff --git a/Source/Scene/GlobeSurfaceTileProvider.js b/Source/Scene/GlobeSurfaceTileProvider.js index aab4ab685cd2..0117fdf3b1ad 100644 --- a/Source/Scene/GlobeSurfaceTileProvider.js +++ b/Source/Scene/GlobeSurfaceTileProvider.js @@ -1564,6 +1564,7 @@ define([ command.orientedBoundingBox = OrientedBoundingBox.clone(surfaceTile.orientedBoundingBox, orientedBoundingBox); } + command.dirty = true; frameState.commandList.push(command); renderState = otherPassesRenderState; From 6dac90e8c9e8b187b238ab5f8a2f3e2943a52f5e Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Tue, 23 Oct 2018 14:56:24 -0400 Subject: [PATCH 63/76] Add tonemapping tests and an HDR test. --- Source/Scene/PostProcessStageCollection.js | 12 ++ Source/Scene/Scene.js | 13 ++ Specs/Scene/PostProcessStageCollectionSpec.js | 112 +++++++++++++++++- Specs/Scene/PostProcessStageLibrarySpec.js | 32 +---- Specs/Scene/SceneSpec.js | 28 +++++ Specs/ViewportPrimitive.js | 40 +++++++ 6 files changed, 207 insertions(+), 30 deletions(-) create mode 100644 Specs/ViewportPrimitive.js diff --git a/Source/Scene/PostProcessStageCollection.js b/Source/Scene/PostProcessStageCollection.js index a365fcff9db0..1b0d8481f226 100644 --- a/Source/Scene/PostProcessStageCollection.js +++ b/Source/Scene/PostProcessStageCollection.js @@ -351,6 +351,11 @@ define([ } //>>includeEnd('debug'); + if (defined(this._tonemapping)) { + delete this._stageNames[this._tonemapping.name]; + this._tonemapping.destroy(); + } + var useAutoExposure = this._autoExposureEnabled; var tonemapper; @@ -378,6 +383,13 @@ define([ this._tonemapper = value; this._tonemapping = tonemapper; + + if (defined(this._stageNames)) { + this._stageNames[tonemapper.name] = tonemapper; + tonemapper._textureCache = this._textureCache; + } + + this._textureCacheDirty = true; } } }); diff --git a/Source/Scene/Scene.js b/Source/Scene/Scene.js index 888f595245a8..37b29f719721 100644 --- a/Source/Scene/Scene.js +++ b/Source/Scene/Scene.js @@ -1483,6 +1483,19 @@ define([ } }, + /** + * Whether or not high dynamic range rendering is supported. + * @memberof Scene.prototype + * @type {Boolean} + * @default true + */ + highDynamicRangeSupported : { + get : function() { + var context = this._context; + return context.depthTexture && (context.colorBufferFloat || context.colorBufferHalfFloat); + } + }, + /** * Gets or sets the color of the light emitted by the sun. * diff --git a/Specs/Scene/PostProcessStageCollectionSpec.js b/Specs/Scene/PostProcessStageCollectionSpec.js index 5c62af66569d..87c401f5caf8 100644 --- a/Specs/Scene/PostProcessStageCollectionSpec.js +++ b/Specs/Scene/PostProcessStageCollectionSpec.js @@ -2,12 +2,16 @@ defineSuite([ 'Scene/PostProcessStageCollection', 'Core/Color', 'Scene/PostProcessStage', - 'Specs/createScene' + 'Scene/Tonemapper', + 'Specs/createScene', + 'Specs/ViewportPrimitive' ], function( PostProcessStageCollection, Color, PostProcessStage, - createScene) { + Tonemapper, + createScene, + ViewportPrimitive) { 'use strict'; var scene; @@ -223,6 +227,110 @@ defineSuite([ expect(scene.postProcessStages.getOutputTexture(stage1.name)).not.toBeDefined(); }); + it('uses Reinhard tonemapping', function() { + if (!scene.highDynamicRangeSupported) { + return; + } + + var fs = + 'void main() { \n' + + ' gl_FragColor = vec4(4.0, 0.0, 0.0, 1.0); \n' + + '} \n'; + scene.primitives.add(new ViewportPrimitive(fs)); + + scene.postProcessStages.tonemapper = Tonemapper.REINHARD; + + expect(scene).toRender([255, 0, 0, 255]); + scene.highDynamicRange = true; + expect(scene).toRenderAndCall(function(rgba) { + expect(rgba).not.toEqual([0, 0, 0, 255]); + expect(rgba).not.toEqual([255, 0, 0, 255]); + expect(rgba[0]).toBeGreaterThan(0); + expect(rgba[1]).toEqual(0); + expect(rgba[2]).toEqual(0); + expect(rgba[3]).toEqual(255); + }); + scene.highDynamicRange = false; + }); + + it('uses modified Reinhard tonemapping', function() { + if (!scene.highDynamicRangeSupported) { + return; + } + + var fs = + 'void main() { \n' + + ' gl_FragColor = vec4(0.5, 0.0, 0.0, 1.0); \n' + + '} \n'; + scene.primitives.add(new ViewportPrimitive(fs)); + + scene.postProcessStages.tonemapper = Tonemapper.MODIFIED_REINHARD; + + expect(scene).toRender([127, 0, 0, 255]); + scene.highDynamicRange = true; + expect(scene).toRenderAndCall(function(rgba) { + expect(rgba).not.toEqual([0, 0, 0, 255]); + expect(rgba).not.toEqual([127, 0, 0, 255]); + expect(rgba[0]).toBeGreaterThan(0); + expect(rgba[1]).toEqual(0); + expect(rgba[2]).toEqual(0); + expect(rgba[3]).toEqual(255); + }); + scene.highDynamicRange = false; + }); + + it('uses filmic tonemapping', function() { + if (!scene.highDynamicRangeSupported) { + return; + } + + var fs = + 'void main() { \n' + + ' gl_FragColor = vec4(4.0, 0.0, 0.0, 1.0); \n' + + '} \n'; + scene.primitives.add(new ViewportPrimitive(fs)); + + scene.postProcessStages.tonemapper = Tonemapper.FILMIC; + + expect(scene).toRender([255, 0, 0, 255]); + scene.highDynamicRange = true; + expect(scene).toRenderAndCall(function(rgba) { + expect(rgba).not.toEqual([0, 0, 0, 255]); + expect(rgba).not.toEqual([255, 0, 0, 255]); + expect(rgba[0]).toBeGreaterThan(0); + expect(rgba[1]).toEqual(0); + expect(rgba[2]).toEqual(0); + expect(rgba[3]).toEqual(255); + }); + scene.highDynamicRange = false; + }); + + it('uses ACES tonemapping', function() { + if (!scene.highDynamicRangeSupported) { + return; + } + + var fs = + 'void main() { \n' + + ' gl_FragColor = vec4(4.0, 0.0, 0.0, 1.0); \n' + + '} \n'; + scene.primitives.add(new ViewportPrimitive(fs)); + + scene.postProcessStages.tonemapper = Tonemapper.ACES; + + expect(scene).toRender([255, 0, 0, 255]); + scene.highDynamicRange = true; + expect(scene).toRenderAndCall(function(rgba) { + expect(rgba).not.toEqual([0, 0, 0, 255]); + expect(rgba).not.toEqual([255, 0, 0, 255]); + expect(rgba[0]).toBeGreaterThan(0); + expect(rgba[1]).toEqual(0); + expect(rgba[2]).toEqual(0); + expect(rgba[3]).toEqual(255); + }); + scene.highDynamicRange = false; + }); + it('destroys', function() { var stages = new PostProcessStageCollection(); var stage = stages.add(new PostProcessStage({ diff --git a/Specs/Scene/PostProcessStageLibrarySpec.js b/Specs/Scene/PostProcessStageLibrarySpec.js index 64b9281a2648..1d73cd5cd5b9 100644 --- a/Specs/Scene/PostProcessStageLibrarySpec.js +++ b/Specs/Scene/PostProcessStageLibrarySpec.js @@ -13,7 +13,8 @@ defineSuite([ 'ThirdParty/when', 'Specs/createCanvas', 'Specs/createScene', - 'Specs/pollToPromise' + 'Specs/pollToPromise', + 'Specs/ViewportPrimitive' ], function( PostProcessStageLibrary, Cartesian3, @@ -29,7 +30,8 @@ defineSuite([ when, createCanvas, createScene, - pollToPromise) { + pollToPromise, + ViewportPrimitive) { 'use strict'; var scene; @@ -53,32 +55,6 @@ defineSuite([ scene.postProcessStages.ambientOcclusion.enabled = false; }); - var ViewportPrimitive = function(fragmentShader) { - this._fs = fragmentShader; - this._command = undefined; - }; - - ViewportPrimitive.prototype.update = function(frameState) { - if (!defined(this._command)) { - this._command = frameState.context.createViewportQuadCommand(this._fs, { - renderState : RenderState.fromCache(), - pass : Pass.OPAQUE - }); - } - frameState.commandList.push(this._command); - }; - - ViewportPrimitive.prototype.isDestroyed = function() { - return false; - }; - - ViewportPrimitive.prototype.destroy = function() { - if (defined(this._command)) { - this._command.shaderProgram = this._command.shaderProgram && this._command.shaderProgram.destroy(); - } - return destroyObject(this); - }; - var model; function loadModel(url) { diff --git a/Specs/Scene/SceneSpec.js b/Specs/Scene/SceneSpec.js index 4d299e9285bc..04c7b96b2790 100644 --- a/Specs/Scene/SceneSpec.js +++ b/Specs/Scene/SceneSpec.js @@ -700,6 +700,34 @@ defineSuite([ s.destroyForSpecs(); }); + it('renders with HDR when available', function() { + if (!scene.highDynamicRangeSupported) { + return; + } + + var s = createScene(); + s.highDynamicRange = true; + + var rectangle = Rectangle.fromDegrees(-100.0, 30.0, -90.0, 40.0); + + var rectanglePrimitive = createRectangle(rectangle, 1000.0); + rectanglePrimitive.appearance.material.uniforms.color = new Color(10.0, 0.0, 0.0, 1.0); + + var primitives = s.primitives; + primitives.add(rectanglePrimitive); + + s.camera.setView({ destination : rectangle }); + + expect(s).toRenderAndCall(function(rgba) { + expect(rgba[0]).toBeGreaterThan(0); + expect(rgba[0]).toBeLessThanOrEqualTo(255); + expect(rgba[1]).toEqual(0); + expect(rgba[2]).toEqual(0); + }); + + s.destroyForSpecs(); + }); + it('copies the globe depth', function() { var scene = createScene(); if (scene.context.depthTexture) { diff --git a/Specs/ViewportPrimitive.js b/Specs/ViewportPrimitive.js new file mode 100644 index 000000000000..e52d9dd0e704 --- /dev/null +++ b/Specs/ViewportPrimitive.js @@ -0,0 +1,40 @@ +define([ + 'Core/defined', + 'Core/destroyObject', + 'Renderer/Pass', + 'Renderer/RenderState' + ], function( + defined, + destroyObject, + Pass, + RenderState) { + 'use strict'; + + var ViewportPrimitive = function(fragmentShader) { + this._fs = fragmentShader; + this._command = undefined; + }; + + ViewportPrimitive.prototype.update = function(frameState) { + if (!defined(this._command)) { + this._command = frameState.context.createViewportQuadCommand(this._fs, { + renderState : RenderState.fromCache(), + pass : Pass.OPAQUE + }); + } + frameState.commandList.push(this._command); + }; + + ViewportPrimitive.prototype.isDestroyed = function() { + return false; + }; + + ViewportPrimitive.prototype.destroy = function() { + if (defined(this._command)) { + this._command.shaderProgram = this._command.shaderProgram && this._command.shaderProgram.destroy(); + } + return destroyObject(this); + }; + + return ViewportPrimitive; +}); From 55bfbe30c596ac0a8edf7bd60b7638c1d6fb7e0f Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 24 Oct 2018 15:45:51 -0400 Subject: [PATCH 64/76] Fix test. --- Specs/Scene/ModelSpec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Specs/Scene/ModelSpec.js b/Specs/Scene/ModelSpec.js index 150accc2e06f..800b026c9fd2 100644 --- a/Specs/Scene/ModelSpec.js +++ b/Specs/Scene/ModelSpec.js @@ -2080,7 +2080,7 @@ defineSuite([ expect(scene).toRender([0, 0, 0, 255]); m.show = true; m.zoomTo(); - expect(scene).toRender([51, 51, 51, 255]); // Cesium has minimum lighting + expect(scene).toRender([53, 53, 53, 255]); // Cesium has minimum lighting m.show = false; primitives.remove(m); From 44d53e53eb60bcd03b8d217a119c9541f093e413 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 24 Oct 2018 15:56:54 -0400 Subject: [PATCH 65/76] Fix failing WebGL stub test. --- Specs/Scene/ShadowMapSpec.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Specs/Scene/ShadowMapSpec.js b/Specs/Scene/ShadowMapSpec.js index ec3739d8ba4a..ae6d8e266d0e 100644 --- a/Specs/Scene/ShadowMapSpec.js +++ b/Specs/Scene/ShadowMapSpec.js @@ -1118,7 +1118,8 @@ defineSuite([ scene.render(); } - expect(spy1.calls.count()).toEqual(8); + // When using WebGL, this value is 8. When using the stub, this value is 4. + expect(spy1.calls.count()).toBeLessThanOrEqualTo(8); expect(spy2.calls.count()).toEqual(4); box.show = false; From fba732446531ea7034d9a598c937a395fd70bb59 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Tue, 30 Oct 2018 16:03:55 -0400 Subject: [PATCH 66/76] Fix gamma correct for billboard color. --- Source/Shaders/BillboardCollectionFS.glsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Shaders/BillboardCollectionFS.glsl b/Source/Shaders/BillboardCollectionFS.glsl index 11b2c9b0946b..0fd32b8a1ceb 100644 --- a/Source/Shaders/BillboardCollectionFS.glsl +++ b/Source/Shaders/BillboardCollectionFS.glsl @@ -52,7 +52,7 @@ void main() { vec4 color = texture2D(u_atlas, v_textureCoordinates); color = czm_gammaCorrect(color); - color *= v_color; + color *= czm_gammaCorrect(v_color); // Fully transparent parts of the billboard are not pickable. #if !defined(OPAQUE) && !defined(TRANSLUCENT) From 6184f61f84bd43a7bf642545f077f2823ec25da3 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Tue, 30 Oct 2018 16:23:27 -0400 Subject: [PATCH 67/76] Gamma correct 3D Tiles styling color. --- Source/Scene/Cesium3DTileBatchTable.js | 4 +++- Source/Shaders/ShadowVolumeFS.glsl | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Source/Scene/Cesium3DTileBatchTable.js b/Source/Scene/Cesium3DTileBatchTable.js index 50af0168750a..c3ec0f36d8b8 100644 --- a/Source/Scene/Cesium3DTileBatchTable.js +++ b/Source/Scene/Cesium3DTileBatchTable.js @@ -963,6 +963,7 @@ define([ 'void tile_color(vec4 tile_featureColor) \n' + '{ \n' + ' tile_main(); \n' + + ' tile_featureColor = czm_gammaCorrect(tile_featureColor);; \n' + ' gl_FragColor.a *= tile_featureColor.a; \n' + ' float highlight = ceil(tile_colorBlend); \n' + ' gl_FragColor.rgb *= mix(tile_featureColor.rgb, vec3(1.0), highlight); \n' + @@ -1044,6 +1045,7 @@ define([ // The color blend mode is intended for the RGB channels so alpha is always just multiplied. // gl_FragColor is multiplied by the tile color only when tile_colorBlend is 0.0 (highlight) var highlight = + ' tile_featureColor = czm_gammaCorrect(tile_featureColor); \n' + ' gl_FragColor.a *= tile_featureColor.a; \n' + ' float highlight = ceil(tile_colorBlend); \n' + ' gl_FragColor.rgb *= mix(tile_featureColor.rgb, vec3(1.0), highlight); \n'; @@ -1055,7 +1057,7 @@ define([ regex = new RegExp(diffuseAttributeOrUniformName, 'g'); source = source.replace(regex, replaceDiffuse); setColor = - ' vec4 source = ' + sourceDiffuse + '; \n' + + ' vec4 source = czm_gammaCorrect(' + sourceDiffuse + '); \n' + ' tile_diffuse = tile_diffuse_final(source, tile_featureColor); \n' + ' tile_main(); \n'; } else if (type === 'sampler2D') { diff --git a/Source/Shaders/ShadowVolumeFS.glsl b/Source/Shaders/ShadowVolumeFS.glsl index 981c6f56fddf..b1af3c3ff493 100644 --- a/Source/Shaders/ShadowVolumeFS.glsl +++ b/Source/Shaders/ShadowVolumeFS.glsl @@ -9,7 +9,7 @@ uniform vec4 u_highlightColor; void main(void) { #ifdef VECTOR_TILE - gl_FragColor = u_highlightColor; + gl_FragColor = czm_gammaCorrect(u_highlightColor); #else gl_FragColor = vec4(1.0); #endif From 25efa798307dc610f6921e3d48d964e887f422ed Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Tue, 30 Oct 2018 16:29:30 -0400 Subject: [PATCH 68/76] Fix composite material example. --- Apps/Sandcastle/gallery/Materials.html | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/Apps/Sandcastle/gallery/Materials.html b/Apps/Sandcastle/gallery/Materials.html index b19aacc0068f..d9fea96fdfa0 100644 --- a/Apps/Sandcastle/gallery/Materials.html +++ b/Apps/Sandcastle/gallery/Materials.html @@ -107,16 +107,20 @@ } }, source : - 'czm_material czm_getMaterial(czm_materialInput materialInput) {' + - 'czm_material material = czm_getDefaultMaterial(materialInput);' + - 'float heightValue = texture2D(heightField, materialInput.st).r;' + - 'material.diffuse = mix(vec3(0.2, 0.6, 0.2), vec3(1.0, 0.5, 0.2), heightValue);' + - 'material.alpha = (1.0 - texture2D(image, materialInput.st).r) * 0.7;' + - 'material.normal = bumpMap.normal;' + - 'material.specular = step(0.1, heightValue);' + // Specular mountain tops - 'material.shininess = 8.0;' + // Sharpen highlight - 'return material;' + - '}' + 'czm_material czm_getMaterial(czm_materialInput materialInput) { \n' + + ' czm_material material = czm_getDefaultMaterial(materialInput); \n' + + ' vec4 color; \n' + + ' float heightValue = texture2D(heightField, materialInput.st).r; \n' + + ' color.rgb = mix(vec3(0.2, 0.6, 0.2), vec3(1.0, 0.5, 0.2), heightValue); \n' + + ' color.a = (1.0 - texture2D(image, materialInput.st).r) * 0.7; \n' + + ' color = czm_gammaCorrect(color); \n' + + ' material.diffuse = color.rgb; \n' + + ' material.alpha = color.a; \n' + + ' material.normal = bumpMap.normal; \n' + + ' material.specular = step(0.1, heightValue); \n' + // Specular mountain tops + ' material.shininess = 8.0; \n' + // Sharpen highlight + ' return material; \n' + + '} \n' } }); } From f82229a8acd3932f4477782a41df11c1b2e57f01 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Fri, 2 Nov 2018 14:13:35 -0400 Subject: [PATCH 69/76] Update CHANGES.md. --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index 8a0a833427dd..f45b91fd3d38 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -4,6 +4,7 @@ Change Log ### 1.52 - 2018-12-03 ##### Additions :tada: +* Added support for high dynamic range rendering. It is enabled by default when supported, but can be disabled with `Scene.highDynamicRange`. [#7017](https://github.com/AnalyticalGraphicsInc/cesium/pull/7017) * Added `Scene.invertClassificationSupported` for checking if invert classification is supported. ##### Fixes :wrench: From 308801992994b6ce4243094a8046b80f72f4e7b0 Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Wed, 7 Nov 2018 17:41:17 -0500 Subject: [PATCH 70/76] Globe HDR visual tweaks --- Source/Shaders/GlobeFS.glsl | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Source/Shaders/GlobeFS.glsl b/Source/Shaders/GlobeFS.glsl index a6d015ab4f9e..fd937528bd1e 100644 --- a/Source/Shaders/GlobeFS.glsl +++ b/Source/Shaders/GlobeFS.glsl @@ -359,11 +359,22 @@ void main() fadeOutDist = u_nightFadeDistance.y; float sunlitAtmosphereIntensity = clamp((cameraDist - fadeOutDist) / (fadeInDist - fadeOutDist), 0.0, 1.0); + +#ifdef HDR + // Some tweaking to make HDR look better + sunlitAtmosphereIntensity = max(sunlitAtmosphereIntensity * sunlitAtmosphereIntensity, 0.03); +#endif + groundAtmosphereColor = mix(groundAtmosphereColor, fogColor, sunlitAtmosphereIntensity); #else vec3 groundAtmosphereColor = fogColor; #endif +#ifdef HDR + // Some tweaking to make HDR look better + groundAtmosphereColor = czm_saturation(groundAtmosphereColor, 1.6); +#endif + finalColor = vec4(mix(finalColor.rgb, groundAtmosphereColor, fade), finalColor.a); #endif From 4c33a68d12e034603eb209d5d4f8c989f7e29e83 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 8 Nov 2018 16:22:04 -0500 Subject: [PATCH 71/76] Fix gamma correction on some 3D Tiles. --- Source/Scene/Cesium3DTileBatchTable.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Source/Scene/Cesium3DTileBatchTable.js b/Source/Scene/Cesium3DTileBatchTable.js index c3ec0f36d8b8..5efa05d19f2f 100644 --- a/Source/Scene/Cesium3DTileBatchTable.js +++ b/Source/Scene/Cesium3DTileBatchTable.js @@ -963,7 +963,8 @@ define([ 'void tile_color(vec4 tile_featureColor) \n' + '{ \n' + ' tile_main(); \n' + - ' tile_featureColor = czm_gammaCorrect(tile_featureColor);; \n' + + ' tile_featureColor = czm_gammaCorrect(tile_featureColor); \n' + + ' gl_FragColor = czm_gammaCorrect(gl_FragColor); \n' + ' gl_FragColor.a *= tile_featureColor.a; \n' + ' float highlight = ceil(tile_colorBlend); \n' + ' gl_FragColor.rgb *= mix(tile_featureColor.rgb, vec3(1.0), highlight); \n' + From 6f27325c72677edbc8c19612082d043358e3d047 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 8 Nov 2018 16:36:21 -0500 Subject: [PATCH 72/76] Fix IE crash by removing const expression. --- Source/Shaders/SunTextureFS.glsl | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/Source/Shaders/SunTextureFS.glsl b/Source/Shaders/SunTextureFS.glsl index fb286f6dee3c..d211be042ef5 100644 --- a/Source/Shaders/SunTextureFS.glsl +++ b/Source/Shaders/SunTextureFS.glsl @@ -7,19 +7,17 @@ vec2 rotate(vec2 p, vec2 direction) return vec2(p.x * direction.x - p.y * direction.y, p.x * direction.y + p.y * direction.x); } -const float lengthScalar = 2.0 / sqrt(2.0); - -vec4 addBurst(vec2 position, vec2 direction) +vec4 addBurst(vec2 position, vec2 direction, float lengthScalar) { vec2 rotatedPosition = rotate(position, direction) * vec2(25.0, 0.75); float radius = length(rotatedPosition) * lengthScalar; float burst = 1.0 - smoothstep(0.0, 0.55, radius); - return vec4(burst); } void main() { + float lengthScalar = 2.0 / sqrt(2.0); vec2 position = v_textureCoordinates - vec2(0.5); float radius = length(position) * lengthScalar; float surface = step(radius, u_radiusTS); @@ -35,19 +33,19 @@ void main() // //for (float i = 0.4; i < 3.2; i += 1.047) { // vec2 direction = vec2(sin(i), cos(i)); - // burst += 0.4 * addBurst(position, direction); + // burst += 0.4 * addBurst(position, direction, lengthScalar); // // direction = vec2(sin(i - 0.08), cos(i - 0.08)); - // burst += 0.3 * addBurst(position, direction); + // burst += 0.3 * addBurst(position, direction, lengthScalar); //} - burst += 0.4 * addBurst(position, vec2(0.38942, 0.92106)); // angle == 0.4 - burst += 0.4 * addBurst(position, vec2(0.99235, 0.12348)); // angle == 0.4 + 1.047 - burst += 0.4 * addBurst(position, vec2(0.60327, -0.79754)); // angle == 0.4 + 1.047 * 2.0 + burst += 0.4 * addBurst(position, vec2(0.38942, 0.92106), lengthScalar); // angle == 0.4 + burst += 0.4 * addBurst(position, vec2(0.99235, 0.12348), lengthScalar); // angle == 0.4 + 1.047 + burst += 0.4 * addBurst(position, vec2(0.60327, -0.79754), lengthScalar); // angle == 0.4 + 1.047 * 2.0 - burst += 0.3 * addBurst(position, vec2(0.31457, 0.94924)); // angle == 0.4 - 0.08 - burst += 0.3 * addBurst(position, vec2(0.97931, 0.20239)); // angle == 0.4 + 1.047 - 0.08 - burst += 0.3 * addBurst(position, vec2(0.66507, -0.74678)); // angle == 0.4 + 1.047 * 2.0 - 0.08 + burst += 0.3 * addBurst(position, vec2(0.31457, 0.94924), lengthScalar); // angle == 0.4 - 0.08 + burst += 0.3 * addBurst(position, vec2(0.97931, 0.20239), lengthScalar); // angle == 0.4 + 1.047 - 0.08 + burst += 0.3 * addBurst(position, vec2(0.66507, -0.74678), lengthScalar); // angle == 0.4 + 1.047 * 2.0 - 0.08 // End of manual loop unrolling. From 8492d351126d28f0200051579a9c8965762aaeb9 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Mon, 12 Nov 2018 15:44:54 -0500 Subject: [PATCH 73/76] Update for models with KHR_techniques_webgl from review. --- Source/Scene/Cesium3DTileBatchTable.js | 1 - Source/Scene/Model.js | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Source/Scene/Cesium3DTileBatchTable.js b/Source/Scene/Cesium3DTileBatchTable.js index 5efa05d19f2f..7499470a9b2f 100644 --- a/Source/Scene/Cesium3DTileBatchTable.js +++ b/Source/Scene/Cesium3DTileBatchTable.js @@ -964,7 +964,6 @@ define([ '{ \n' + ' tile_main(); \n' + ' tile_featureColor = czm_gammaCorrect(tile_featureColor); \n' + - ' gl_FragColor = czm_gammaCorrect(gl_FragColor); \n' + ' gl_FragColor.a *= tile_featureColor.a; \n' + ' float highlight = ceil(tile_colorBlend); \n' + ' gl_FragColor.rgb *= mix(tile_featureColor.rgb, vec3(1.0), highlight); \n' + diff --git a/Source/Scene/Model.js b/Source/Scene/Model.js index 810411ac0a63..b2df1d5709a7 100644 --- a/Source/Scene/Model.js +++ b/Source/Scene/Model.js @@ -2009,7 +2009,7 @@ define([ drawFS = '#define USE_CUSTOM_LIGHT_COLOR \n\n' + drawFS; } - if (model._sourceVersion !== '2.0') { + if (model._sourceVersion !== '2.0' || model.extensionsUsed.KHR_techniques_webgl) { drawFS = ShaderSource.replaceMain(drawFS, 'non_gamma_corrected_main'); drawFS = drawFS + @@ -2070,7 +2070,7 @@ define([ drawFS = '#define USE_CUSTOM_LIGHT_COLOR \n\n' + drawFS; } - if (model._sourceVersion !== '2.0') { + if (model._sourceVersion !== '2.0' || model.extensionsUsed.KHR_techniques_webgl) { drawFS = ShaderSource.replaceMain(drawFS, 'non_gamma_corrected_main'); drawFS = drawFS + From 171ccb2a988cb99460d24635656c60bbd47515fd Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Tue, 13 Nov 2018 15:27:42 -0500 Subject: [PATCH 74/76] Update from review. --- Source/Scene/Model.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Source/Scene/Model.js b/Source/Scene/Model.js index b2df1d5709a7..6a7c2db6e61c 100644 --- a/Source/Scene/Model.js +++ b/Source/Scene/Model.js @@ -663,6 +663,7 @@ define([ this._keepPipelineExtras = options.keepPipelineExtras; // keep the buffers in memory for use in other applications this._sourceVersion = undefined; + this._sourceKHRTechniquesWebGL = undefined; this._imageBasedLightingFactor = new Cartesian2(1.0, 1.0); Cartesian2.clone(options.imageBasedLightingFactor, this._imageBasedLightingFactor); @@ -2009,7 +2010,7 @@ define([ drawFS = '#define USE_CUSTOM_LIGHT_COLOR \n\n' + drawFS; } - if (model._sourceVersion !== '2.0' || model.extensionsUsed.KHR_techniques_webgl) { + if (model._sourceVersion !== '2.0' || model._sourceKHRTechniquesWebGL) { drawFS = ShaderSource.replaceMain(drawFS, 'non_gamma_corrected_main'); drawFS = drawFS + @@ -2070,7 +2071,7 @@ define([ drawFS = '#define USE_CUSTOM_LIGHT_COLOR \n\n' + drawFS; } - if (model._sourceVersion !== '2.0' || model.extensionsUsed.KHR_techniques_webgl) { + if (model._sourceVersion !== '2.0' || model._sourceKHRTechniquesWebGL) { drawFS = ShaderSource.replaceMain(drawFS, 'non_gamma_corrected_main'); drawFS = drawFS + @@ -4191,6 +4192,7 @@ define([ // Add the original version so it remains cached gltf.extras.sourceVersion = ModelUtility.getAssetVersion(gltf); this._sourceVersion = gltf.extras.sourceVersion; + this._sourceKHRTechniquesWebGL = defined(ModelUtility.getUsedExtensions(gltf).KHR_techniques_webgl); updateVersion(gltf); addDefaults(gltf); From 7a062bc11aacd5baf5aeebc2435632dca60cc80c Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 14 Nov 2018 15:19:37 -0500 Subject: [PATCH 75/76] Fix issue with cached glTFs. --- Source/Scene/Model.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Source/Scene/Model.js b/Source/Scene/Model.js index 6a7c2db6e61c..041179f01256 100644 --- a/Source/Scene/Model.js +++ b/Source/Scene/Model.js @@ -4191,8 +4191,10 @@ define([ var gltf = this.gltf; // Add the original version so it remains cached gltf.extras.sourceVersion = ModelUtility.getAssetVersion(gltf); + gltf.extras.sourceKHRTechniquesWebGL = defined(ModelUtility.getUsedExtensions(gltf).KHR_techniques_webgl); + this._sourceVersion = gltf.extras.sourceVersion; - this._sourceKHRTechniquesWebGL = defined(ModelUtility.getUsedExtensions(gltf).KHR_techniques_webgl); + this._sourceKHRTechniquesWebGL = gltf.extras.sourceKHRTechniquesWebGL; updateVersion(gltf); addDefaults(gltf); @@ -4205,6 +4207,9 @@ define([ processPbrMaterials(gltf, options); } + this._sourceVersion = this.gltf.extras.sourceVersion; + this._sourceKHRTechniquesWebGL = this.gltf.extras.sourceKHRTechniquesWebGL; + // Skip dequantizing in the shader if not encoded this._dequantizeInShader = this._dequantizeInShader && DracoLoader.hasExtension(this); From ac63b9520df3c852e3a971b2f99c13d1b2ba08d6 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 14 Nov 2018 15:55:56 -0500 Subject: [PATCH 76/76] Fix extra gamma correct. --- Source/Scene/Cesium3DTileBatchTable.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Scene/Cesium3DTileBatchTable.js b/Source/Scene/Cesium3DTileBatchTable.js index 7499470a9b2f..3e09fa4188ea 100644 --- a/Source/Scene/Cesium3DTileBatchTable.js +++ b/Source/Scene/Cesium3DTileBatchTable.js @@ -1057,7 +1057,7 @@ define([ regex = new RegExp(diffuseAttributeOrUniformName, 'g'); source = source.replace(regex, replaceDiffuse); setColor = - ' vec4 source = czm_gammaCorrect(' + sourceDiffuse + '); \n' + + ' vec4 source = ' + sourceDiffuse + '; \n' + ' tile_diffuse = tile_diffuse_final(source, tile_featureColor); \n' + ' tile_main(); \n'; } else if (type === 'sampler2D') {