From 97074e5c968de24a6a1cce57ef010c2188d34af4 Mon Sep 17 00:00:00 2001 From: Kangning Li Date: Fri, 13 Jul 2018 13:12:45 -0400 Subject: [PATCH] remove float texture requirement for eye dome lighting --- CHANGES.md | 1 + Source/Scene/PointCloudEyeDomeLighting.js | 71 ++++++++----------- .../PointCloudEyeDomeLighting.glsl | 41 ++++++----- 3 files changed, 51 insertions(+), 62 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 46c4f9d69092..047b6e04709b 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -17,6 +17,7 @@ Change Log * Fixed a bug that was preventing 3D Tilesets on the opposite side of the globe from being occluded [#6714](https://github.com/AnalyticalGraphicsInc/cesium/issues/6714) * Fixed a bug where 3D Tilesets using the `region` bounding volume don't get transformed when the tileset's `modelMatrix` changes. [6755](https://github.com/AnalyticalGraphicsInc/cesium/pull/6755) * Fixed `PolygonGeometry` and `EllipseGeometry` tangent and bitangent attributes when a texture rotation is used [#6788](https://github.com/AnalyticalGraphicsInc/cesium/pull/6788) +* Fixed a bug that caused eye dome lighting for point clouds to fail in Safari on macOS by removing the dependency on floating point color textures. [#6792](https://github.com/AnalyticalGraphicsInc/cesium/issues/6792) ### 1.47 - 2018-07-02 diff --git a/Source/Scene/PointCloudEyeDomeLighting.js b/Source/Scene/PointCloudEyeDomeLighting.js index 7eb8f33daa08..c1bd297d0a4a 100644 --- a/Source/Scene/PointCloudEyeDomeLighting.js +++ b/Source/Scene/PointCloudEyeDomeLighting.js @@ -46,14 +46,14 @@ define([ /** * Eye dome lighting. Does not support points with per-point translucency, but does allow translucent styling against the globe. - * Requires support for EXT_frag_depth, OES_texture_float, and WEBGL_draw_buffers extensions in WebGL 1.0. + * Requires support for EXT_frag_depth and WEBGL_draw_buffers extensions in WebGL 1.0. * * @private */ function PointCloudEyeDomeLighting() { this._framebuffer = undefined; - this._colorTexture = undefined; // color gbuffer - this._ecAndLogDepthTexture = undefined; // depth gbuffer + this._colorGBuffer = undefined; // color gbuffer + this._depthGBuffer = undefined; // depth gbuffer this._depthTexture = undefined; // needed to write depth so camera based on depth works this._drawCommand = undefined; this._clearCommand = undefined; @@ -77,14 +77,14 @@ define([ return; } - processor._colorTexture.destroy(); - processor._ecAndLogDepthTexture.destroy(); + processor._colorGBuffer.destroy(); + processor._depthGBuffer.destroy(); processor._depthTexture.destroy(); framebuffer.destroy(); processor._framebuffer = undefined; - processor._colorTexture = undefined; - processor._ecAndLogDepthTexture = undefined; + processor._colorGBuffer = undefined; + processor._depthGBuffer = undefined; processor._depthTexture = undefined; processor._drawCommand = undefined; processor._clearCommand = undefined; @@ -94,22 +94,21 @@ define([ var screenWidth = context.drawingBufferWidth; var screenHeight = context.drawingBufferHeight; - var colorTexture = new Texture({ + var colorGBuffer = new Texture({ context : context, width : screenWidth, height : screenHeight, pixelFormat : PixelFormat.RGBA, - // Firefox as of 57.02 throws FRAMEBUFFER_UNSUPPORTED 0x8CDD if this doesn't match what's in ecTexture - pixelDatatype : FeatureDetection.isFirefox() ? PixelDatatype.FLOAT : PixelDatatype.UNSIGNED_BYTE, + pixelDatatype : PixelDatatype.UNSIGNED_BYTE, sampler : createSampler() }); - var ecTexture = new Texture({ + var depthGBuffer = new Texture({ context : context, width : screenWidth, height : screenHeight, pixelFormat : PixelFormat.RGBA, - pixelDatatype : PixelDatatype.FLOAT, + pixelDatatype : PixelDatatype.UNSIGNED_BYTE, sampler : createSampler() }); @@ -125,14 +124,14 @@ define([ processor._framebuffer = new Framebuffer({ context : context, colorTextures : [ - colorTexture, - ecTexture + colorGBuffer, + depthGBuffer ], depthTexture : depthTexture, destroyAttachments : false }); - processor._colorTexture = colorTexture; - processor._ecAndLogDepthTexture = ecTexture; + processor._colorGBuffer = colorGBuffer; + processor._depthGBuffer = depthGBuffer; processor._depthTexture = depthTexture; } @@ -142,11 +141,11 @@ define([ var blendFS = PointCloudEyeDomeLightingShader; var blendUniformMap = { - u_pointCloud_colorTexture : function() { - return processor._colorTexture; + u_pointCloud_colorGBuffer : function() { + return processor._colorGBuffer; }, - u_pointCloud_ecAndLogDepthTexture : function() { - return processor._ecAndLogDepthTexture; + u_pointCloud_depthGBuffer : function() { + return processor._depthGBuffer; }, u_distancesAndEdlStrength : function() { distancesAndEdlStrengthScratch.x = processor._radius / context.drawingBufferWidth; @@ -184,13 +183,13 @@ define([ function createResources(processor, context) { var screenWidth = context.drawingBufferWidth; var screenHeight = context.drawingBufferHeight; - var colorTexture = processor._colorTexture; + var colorGBuffer = processor._colorGBuffer; var nowDirty = false; - var resized = defined(colorTexture) && - ((colorTexture.width !== screenWidth) || - (colorTexture.height !== screenHeight)); + var resized = defined(colorGBuffer) && + ((colorGBuffer.width !== screenWidth) || + (colorGBuffer.height !== screenHeight)); - if (!defined(colorTexture) || resized) { + if (!defined(colorGBuffer) || resized) { destroyFramebuffer(processor); createFramebuffer(processor, context); createCommands(processor, context); @@ -200,7 +199,7 @@ define([ } function isSupported(context) { - return context.floatingPointTexture && context.drawBuffers && context.fragmentDepth; + return context.drawBuffers && context.fragmentDepth; } PointCloudEyeDomeLighting.isSupported = isSupported; @@ -210,39 +209,25 @@ define([ if (!defined(shader)) { var attributeLocations = shaderProgram._attributeLocations; - var vs = shaderProgram.vertexShaderSource.clone(); var fs = shaderProgram.fragmentShaderSource.clone(); - vs.sources = vs.sources.map(function(source) { - source = ShaderSource.replaceMain(source, 'czm_point_cloud_post_process_main'); - return source; - }); - fs.sources = fs.sources.map(function(source) { source = ShaderSource.replaceMain(source, 'czm_point_cloud_post_process_main'); source = source.replace(/gl_FragColor/g, 'gl_FragData[0]'); return source; }); - vs.sources.push( - 'varying vec3 v_positionEC; \n' + - 'void main() \n' + - '{ \n' + - ' czm_point_cloud_post_process_main(); \n' + - ' v_positionEC = (czm_inverseProjection * gl_Position).xyz; \n' + - '}'); fs.sources.unshift('#extension GL_EXT_draw_buffers : enable \n'); fs.sources.push( - 'varying vec3 v_positionEC; \n' + + 'varying float v_depthOrLogDepth; \n' + 'void main() \n' + '{ \n' + ' czm_point_cloud_post_process_main(); \n' + - // Write log base 2 depth to alpha for EDL - ' gl_FragData[1] = vec4(v_positionEC, log2(-v_positionEC.z)); \n' + + ' gl_FragData[1] = czm_packDepth(gl_FragCoord.z); \n' + '}'); shader = context.shaderCache.createDerivedShaderProgram(shaderProgram, 'EC', { - vertexShaderSource : vs, + vertexShaderSource : shaderProgram.vertexShaderSource, fragmentShaderSource : fs, attributeLocations : attributeLocations }); diff --git a/Source/Shaders/PostProcessStages/PointCloudEyeDomeLighting.glsl b/Source/Shaders/PostProcessStages/PointCloudEyeDomeLighting.glsl index 3cdfc984b540..e78bc7943c3e 100644 --- a/Source/Shaders/PostProcessStages/PointCloudEyeDomeLighting.glsl +++ b/Source/Shaders/PostProcessStages/PointCloudEyeDomeLighting.glsl @@ -1,32 +1,35 @@ #extension GL_EXT_frag_depth : enable -uniform sampler2D u_pointCloud_colorTexture; -uniform sampler2D u_pointCloud_ecAndLogDepthTexture; +uniform sampler2D u_pointCloud_colorGBuffer; +uniform sampler2D u_pointCloud_depthGBuffer; uniform vec3 u_distancesAndEdlStrength; varying vec2 v_textureCoordinates; vec2 neighborContribution(float log2Depth, vec2 padding) { - vec2 depthAndLog2Depth = texture2D(u_pointCloud_ecAndLogDepthTexture, v_textureCoordinates + padding).zw; - if (depthAndLog2Depth.x == 0.0) // 0.0 is the clear value for the gbuffer - { - return vec2(0.0); // throw out this sample - } - else - { - return vec2(max(0.0, log2Depth - depthAndLog2Depth.y), 1.0); + float depthOrLogDepth = czm_unpackDepth(texture2D(u_pointCloud_depthGBuffer, v_textureCoordinates + padding)); + if (depthOrLogDepth == 0.0) { // 0.0 is the clear value for the gbuffer + return vec2(0.0); } + vec4 eyeCoordinate = czm_windowToEyeCoordinates(v_textureCoordinates + padding, depthOrLogDepth); + return vec2(max(0.0, log2Depth - log2(-eyeCoordinate.z / eyeCoordinate.w)), 1.0); } void main() { - vec4 ecAlphaDepth = texture2D(u_pointCloud_ecAndLogDepthTexture, v_textureCoordinates); - if (length(ecAlphaDepth.xyz) < czm_epsilon7) + float depthOrLogDepth = czm_unpackDepth(texture2D(u_pointCloud_depthGBuffer, v_textureCoordinates)); + + vec4 eyeCoordinate = czm_windowToEyeCoordinates(gl_FragCoord.xy, depthOrLogDepth); + eyeCoordinate /= eyeCoordinate.w; + + float log2Depth = log2(-eyeCoordinate.z); + + if (length(eyeCoordinate.xyz) < czm_epsilon7) { discard; } - vec4 color = texture2D(u_pointCloud_colorTexture, v_textureCoordinates); + vec4 color = texture2D(u_pointCloud_colorGBuffer, v_textureCoordinates); // sample from neighbors up, down, left, right float distX = u_distancesAndEdlStrength.x; @@ -34,10 +37,10 @@ void main() vec2 responseAndCount = vec2(0.0); - responseAndCount += neighborContribution(ecAlphaDepth.a, vec2(0, distY)); - responseAndCount += neighborContribution(ecAlphaDepth.a, vec2(distX, 0)); - responseAndCount += neighborContribution(ecAlphaDepth.a, vec2(0, -distY)); - responseAndCount += neighborContribution(ecAlphaDepth.a, vec2(-distX, 0)); + responseAndCount += neighborContribution(log2Depth, vec2(0, distY)); + responseAndCount += neighborContribution(log2Depth, vec2(distX, 0)); + responseAndCount += neighborContribution(log2Depth, vec2(0, -distY)); + responseAndCount += neighborContribution(log2Depth, vec2(-distX, 0)); float response = responseAndCount.x / responseAndCount.y; float shade = exp(-response * 300.0 * u_distancesAndEdlStrength.z); @@ -45,8 +48,8 @@ void main() gl_FragColor = vec4(color); #ifdef LOG_DEPTH - czm_writeLogDepth(1.0 + (czm_projection * vec4(ecAlphaDepth.xyz, 1.0)).w); + czm_writeLogDepth(1.0 + (czm_projection * vec4(eyeCoordinate.xyz, 1.0)).w); #else - gl_FragDepthEXT = czm_eyeToWindowCoordinates(vec4(ecAlphaDepth.xyz, 1.0)).z; + gl_FragDepthEXT = czm_eyeToWindowCoordinates(vec4(eyeCoordinate.xyz, 1.0)).z; #endif }