From 01707b43652ec13cf5f9674d0bfe657796e3b693 Mon Sep 17 00:00:00 2001 From: Eimear Crotty Date: Fri, 12 Mar 2021 14:32:10 +0000 Subject: [PATCH 1/7] Add depth pass with URL toggle. --- app.js | 61 +++++++++++++++++++++++++++++++++++++++++++++---- depth_shader.js | 59 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 115 insertions(+), 5 deletions(-) create mode 100644 depth_shader.js diff --git a/app.js b/app.js index 858d067..b1addbc 100644 --- a/app.js +++ b/app.js @@ -16,6 +16,7 @@ import {Axes} from "./axes.js"; import {Rect} from "./rect.js"; import {Colors} from "./colors.js"; import {Coords} from "./coords.js"; +import {DepthShader} from "./depth_shader.js"; import {EventTracker} from "./event_tracker.js"; import {Extruder} from "./extruder.js"; import {FetchQueue} from "./fetch_queue.js"; @@ -85,6 +86,8 @@ class App { this.infoDetailsClose = document.getElementById("info-details-close"); this.infoDetailsDisplayed = false; + this.urlParams = new URLSearchParams(window.location.search); + // map whose keys are bbox strings, value is an object giving details about the corresponding data tile this.bBoxStringToSceneTileDetails = { // "-74.002,40.742,-74.001,40.743": { @@ -693,22 +696,53 @@ class App { this.scene.add(this.camera); - this.composer = new THREE.EffectComposer(this.renderer); + // Set up render target for holding depth information. + this.depthRenderTarget = new THREE.WebGLRenderTarget( this.container.offsetWidth, this.container.offsetHeight ); + this.depthRenderTarget.texture.format = THREE.RGBFormat; + this.depthRenderTarget.texture.minFilter = THREE.NearestFilter; + this.depthRenderTarget.texture.magFilter = THREE.NearestFilter; + this.depthRenderTarget.texture.generateMipmaps = false; + this.depthRenderTarget.stencilBuffer = false; + this.depthRenderTarget.depthBuffer = true; + this.depthRenderTarget.depthTexture = new THREE.DepthTexture(); + this.depthRenderTarget.depthTexture.type = THREE.UnsignedShortType; + + this.composer = new THREE.EffectComposer(this.renderer, this.depthRenderTarget); this.renderPass = new THREE.RenderPass(this.scene, this.camera); this.composer.addPass(this.renderPass); + // Set up copy pass. Copies into write buffer, which can be used in calculating depth in this.depthPass. + this.copyPass = new THREE.ShaderPass(THREE.CopyShader); + this.composer.addPass(this.copyPass); + + // Render to screen. + var renderTargetParameters = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBFormat, stencilBuffer: false }; + this.screenRenderTarget = new THREE.WebGLRenderTarget( this.container.offsetWidth, this.container.offsetHeight, renderTargetParameters ); + this.composerFinal = new THREE.EffectComposer(this.renderer, this.screenRenderTarget); + const renderPass = new THREE.RenderPass(this.scene, this.camera ); + this.composerFinal.addPass(renderPass) + + // Set up outline pass. this.outlinePass = new THREE.OutlinePass(new THREE.Vector2(this.container.offsetWidth, this.container.offsetHeight), this.scene, this.camera); this.outlinePass.edgeStrength = 5.0; this.outlinePass.edgeGlow = 0.5; this.outlinePass.edgeThickness = 2.0; - this.composer.addPass(this.outlinePass); + this.composerFinal.addPass(this.outlinePass); - // Set up antialiasing. + // Set up antialiasing pass. this.fxaaPass = new THREE.ShaderPass(THREE.FXAAShader); const pixelRatio = this.renderer.getPixelRatio(); this.fxaaPass.material.uniforms['resolution'].value.x = 1 / (this.container.offsetWidth * pixelRatio); this.fxaaPass.material.uniforms['resolution'].value.y = 1 / (this.container.offsetHeight * pixelRatio); - this.composer.addPass(this.fxaaPass); + this.composerFinal.addPass(this.fxaaPass); + + if (this.urlParams.get('depth')=='true') { + this.depthPass = new THREE.ShaderPass( DepthShader ); + this.depthPass.uniforms['tDepth'].value = this.depthRenderTarget.depthTexture; + this.depthPass.needsSwap = true; + this.depthPass.renderToScreen = true; + this.composerFinal.addPass(this.depthPass); + } if (this.debug) { this.axes = Axes.axes3D({ @@ -977,7 +1011,24 @@ class App { requestAnimationFrame(() => { this.renderRequested = false; // this.renderer.render( this.scene, this.camera ); -this.composer.render(); + + // this.renderer.setRenderTarget( this.depthRenderTarget ); // For some reason, need this line. + // this.renderer.render( this.scene, this.camera ); // For some reason, need this line. + + // this.renderer.clearDepth(1); + this.composer.render(); + // this.renderer.clear(); + // this.renderer.clearDepth(1); + this.composerFinal.render(); + // this.renderer.clear(); + + // Below works. + // this.renderer.setRenderTarget( this.target ); + // this.renderer.render( this.scene, this.camera ); + // postMaterial.uniforms.tDepth.value = this.target.depthTexture; + // this.renderer.setRenderTarget( null ); + // this.renderer.render( postScene, postCamera ); + //console.log([window.performance.memory.totalJSHeapSize, window.performance.memory.usedJSHeapSize]); }); } diff --git a/depth_shader.js b/depth_shader.js new file mode 100644 index 0000000..9d941aa --- /dev/null +++ b/depth_shader.js @@ -0,0 +1,59 @@ +var DepthShader = { + + uniforms: { + + 'tDepth': { value: null } + + }, + + vertexShader: [ + + 'varying vec2 vUv;', + + 'void main() {', + + ' vUv = uv;', + + ' gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', + + '}' + + ].join( '\n' ), + + fragmentShader: [ + + '#include ', + + '#include ', + + 'uniform sampler2D tDepth;', + + 'varying vec2 vUv;', + + 'float readDepth( sampler2D depthSampler, vec2 coord ) {', + + ' float cameraFar = 100.0;', + + ' float fragCoordZ = texture2D( depthSampler, coord ).x;', + + ' float viewZ = perspectiveDepthToViewZ( fragCoordZ, 1.0, cameraFar );', + + ' return viewZToOrthographicDepth( viewZ, 1.0, cameraFar );', + + '}', + + 'void main() {', + + ' float depth = readDepth( tDepth, vUv );', + + ' gl_FragColor.rgb = 1.0 - vec3( depth );', + + ' gl_FragColor.a = 1.0;', + + '}' + + ].join( '\n' ) + +}; + +export {DepthShader}; \ No newline at end of file From 6c5297e2d263e33ad9d10df862bd8510aae3a2f2 Mon Sep 17 00:00:00 2001 From: Eimear Crotty Date: Fri, 12 Mar 2021 14:35:47 +0000 Subject: [PATCH 2/7] Tidy render loop. --- app.js | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/app.js b/app.js index b1addbc..cd83e1a 100644 --- a/app.js +++ b/app.js @@ -1012,22 +1012,8 @@ class App { this.renderRequested = false; // this.renderer.render( this.scene, this.camera ); - // this.renderer.setRenderTarget( this.depthRenderTarget ); // For some reason, need this line. - // this.renderer.render( this.scene, this.camera ); // For some reason, need this line. - - // this.renderer.clearDepth(1); - this.composer.render(); - // this.renderer.clear(); - // this.renderer.clearDepth(1); - this.composerFinal.render(); - // this.renderer.clear(); - - // Below works. - // this.renderer.setRenderTarget( this.target ); - // this.renderer.render( this.scene, this.camera ); - // postMaterial.uniforms.tDepth.value = this.target.depthTexture; - // this.renderer.setRenderTarget( null ); - // this.renderer.render( postScene, postCamera ); + this.composer.render(); + this.composerFinal.render(); //console.log([window.performance.memory.totalJSHeapSize, window.performance.memory.usedJSHeapSize]); }); From be6371848fdc1fa25d1d1dce1aa7295cc9c52643 Mon Sep 17 00:00:00 2001 From: Eimear Crotty Date: Fri, 12 Mar 2021 16:12:58 +0000 Subject: [PATCH 3/7] Add haze shader with URL toggle. --- app.js | 11 +++++++++ haze_shader.js | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+) create mode 100644 haze_shader.js diff --git a/app.js b/app.js index cd83e1a..724623c 100644 --- a/app.js +++ b/app.js @@ -21,6 +21,7 @@ import {EventTracker} from "./event_tracker.js"; import {Extruder} from "./extruder.js"; import {FetchQueue} from "./fetch_queue.js"; import {Ground} from "./ground.js"; +import {HazeShader} from "./haze_shader.js"; import {Settings} from "./settings.js"; import {SkyBox} from "./skybox.js"; import {Util} from "./util.js"; @@ -736,6 +737,7 @@ class App { this.fxaaPass.material.uniforms['resolution'].value.y = 1 / (this.container.offsetHeight * pixelRatio); this.composerFinal.addPass(this.fxaaPass); + // Render depth pass if `depth=true` is in the URL parameters. if (this.urlParams.get('depth')=='true') { this.depthPass = new THREE.ShaderPass( DepthShader ); this.depthPass.uniforms['tDepth'].value = this.depthRenderTarget.depthTexture; @@ -744,6 +746,15 @@ class App { this.composerFinal.addPass(this.depthPass); } + // Render haze pass if `haze=true` is in the URL parameters. + if (this.urlParams.get('haze')=='true') { + this.hazePass = new THREE.ShaderPass( HazeShader ); + this.hazePass.uniforms['tDepth'].value = this.depthRenderTarget.depthTexture; + this.hazePass.needsSwap = true; + this.hazePass.renderToScreen = true; + this.composerFinal.addPass(this.hazePass); + } + if (this.debug) { this.axes = Axes.axes3D({ length: 50, diff --git a/haze_shader.js b/haze_shader.js new file mode 100644 index 0000000..e33158b --- /dev/null +++ b/haze_shader.js @@ -0,0 +1,67 @@ +var HazeShader = { + + uniforms: { + + 'tDepth': { value: null }, + + 'tDiffuse': { value: null }, + + }, + + vertexShader: [ + + 'varying vec2 vUv;', + + 'void main() {', + + ' vUv = uv;', + + ' gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', + + '}' + + ].join( '\n' ), + + fragmentShader: [ + + '#include ', + + '#include ', + + 'uniform sampler2D tDepth;', + + 'uniform sampler2D tDiffuse;', + + 'varying vec2 vUv;', + + 'float readDepth( sampler2D depthSampler, vec2 coord ) {', + + ' float cameraFar = 200.0;', + + ' float fragCoordZ = texture2D( depthSampler, coord ).x;', + + ' float viewZ = perspectiveDepthToViewZ( fragCoordZ, 1.0, cameraFar );', + + ' return viewZToOrthographicDepth( viewZ, 1.0, cameraFar );', + + '}', + + 'void main() {', + + ' float depth = readDepth( tDepth, vUv );', + + ' vec4 color = texture2D( tDiffuse, vUv );', + + ' vec4 haze = vec4( 0.9, 0.8, 0.8, 1.0);', + + ' float intensity = depth * 0.6;', + + ' gl_FragColor = mix(color, haze, intensity);', + + '}' + + ].join( '\n' ) + +}; + +export {HazeShader}; \ No newline at end of file From 86c1ff2622e0548da274489b40cbb9b92c051bfa Mon Sep 17 00:00:00 2001 From: Eimear Crotty Date: Fri, 12 Mar 2021 16:33:46 +0000 Subject: [PATCH 4/7] Put depth view behind a setting. --- app.js | 5 +++-- settings.js | 5 +++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/app.js b/app.js index 724623c..ddac531 100644 --- a/app.js +++ b/app.js @@ -737,8 +737,9 @@ class App { this.fxaaPass.material.uniforms['resolution'].value.y = 1 / (this.container.offsetHeight * pixelRatio); this.composerFinal.addPass(this.fxaaPass); - // Render depth pass if `depth=true` is in the URL parameters. - if (this.urlParams.get('depth')=='true') { + // Render depth pass if the user has enabled debug in the settings + // and `depth=true` is in the URL parameters. + if (Settings.enableDepthDebug && this.urlParams.get('depth')=='true') { this.depthPass = new THREE.ShaderPass( DepthShader ); this.depthPass.uniforms['tDepth'].value = this.depthRenderTarget.depthTexture; this.depthPass.needsSwap = true; diff --git a/settings.js b/settings.js index 0528739..5ac088c 100644 --- a/settings.js +++ b/settings.js @@ -115,6 +115,11 @@ let Settings = { // pixel height and width of the in-memory canvas used as the // texture for the ground square; should be a power of 2: 'groundTextureSize': 4096, + + // Enables ability to view depth buffer in the browser by adding + // depth=true + // in the URL parameters. + 'enableDepthDebug': true, }; export {Settings}; From 4043280a746b7e20c1ddaacdb2ce54ec4b30cf6f Mon Sep 17 00:00:00 2001 From: Eimear Crotty Date: Fri, 12 Mar 2021 16:38:59 +0000 Subject: [PATCH 5/7] Use debug parameter instead of enableDepthDebug. --- app.js | 15 +++++++++------ settings.js | 5 ----- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/app.js b/app.js index ddac531..7514cbd 100644 --- a/app.js +++ b/app.js @@ -708,17 +708,20 @@ class App { this.depthRenderTarget.depthTexture = new THREE.DepthTexture(); this.depthRenderTarget.depthTexture.type = THREE.UnsignedShortType; - this.composer = new THREE.EffectComposer(this.renderer, this.depthRenderTarget); + // Composer for preprocessing. + this.composerPreprocess = new THREE.EffectComposer(this.renderer, this.depthRenderTarget); this.renderPass = new THREE.RenderPass(this.scene, this.camera); - this.composer.addPass(this.renderPass); + this.composerPreprocess.addPass(this.renderPass); // Set up copy pass. Copies into write buffer, which can be used in calculating depth in this.depthPass. this.copyPass = new THREE.ShaderPass(THREE.CopyShader); - this.composer.addPass(this.copyPass); + this.composerPreprocess.addPass(this.copyPass); // Render to screen. var renderTargetParameters = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBFormat, stencilBuffer: false }; this.screenRenderTarget = new THREE.WebGLRenderTarget( this.container.offsetWidth, this.container.offsetHeight, renderTargetParameters ); + + // Composer for rendering to the screen. this.composerFinal = new THREE.EffectComposer(this.renderer, this.screenRenderTarget); const renderPass = new THREE.RenderPass(this.scene, this.camera ); this.composerFinal.addPass(renderPass) @@ -737,9 +740,9 @@ class App { this.fxaaPass.material.uniforms['resolution'].value.y = 1 / (this.container.offsetHeight * pixelRatio); this.composerFinal.addPass(this.fxaaPass); - // Render depth pass if the user has enabled debug in the settings + // Render depth pass if the user has enabled debug // and `depth=true` is in the URL parameters. - if (Settings.enableDepthDebug && this.urlParams.get('depth')=='true') { + if (this.debug && this.urlParams.get('depth')=='true') { this.depthPass = new THREE.ShaderPass( DepthShader ); this.depthPass.uniforms['tDepth'].value = this.depthRenderTarget.depthTexture; this.depthPass.needsSwap = true; @@ -1024,7 +1027,7 @@ class App { this.renderRequested = false; // this.renderer.render( this.scene, this.camera ); - this.composer.render(); + this.composerPreprocess.render(); this.composerFinal.render(); //console.log([window.performance.memory.totalJSHeapSize, window.performance.memory.usedJSHeapSize]); diff --git a/settings.js b/settings.js index 5ac088c..0528739 100644 --- a/settings.js +++ b/settings.js @@ -115,11 +115,6 @@ let Settings = { // pixel height and width of the in-memory canvas used as the // texture for the ground square; should be a power of 2: 'groundTextureSize': 4096, - - // Enables ability to view depth buffer in the browser by adding - // depth=true - // in the URL parameters. - 'enableDepthDebug': true, }; export {Settings}; From 3fbe5ca43475f0f6859d156f6117f4e1980193e6 Mon Sep 17 00:00:00 2001 From: Eimear Crotty Date: Fri, 12 Mar 2021 16:46:17 +0000 Subject: [PATCH 6/7] Move custom shaders to shaders subdirectory. --- app.js | 4 ++-- depth_shader.js => shaders/depth_shader.js | 0 haze_shader.js => shaders/haze_shader.js | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename depth_shader.js => shaders/depth_shader.js (100%) rename haze_shader.js => shaders/haze_shader.js (100%) diff --git a/app.js b/app.js index 7514cbd..e5cd619 100644 --- a/app.js +++ b/app.js @@ -16,12 +16,12 @@ import {Axes} from "./axes.js"; import {Rect} from "./rect.js"; import {Colors} from "./colors.js"; import {Coords} from "./coords.js"; -import {DepthShader} from "./depth_shader.js"; +import {DepthShader} from "./shaders/depth_shader.js"; import {EventTracker} from "./event_tracker.js"; import {Extruder} from "./extruder.js"; import {FetchQueue} from "./fetch_queue.js"; import {Ground} from "./ground.js"; -import {HazeShader} from "./haze_shader.js"; +import {HazeShader} from "./shaders/haze_shader.js"; import {Settings} from "./settings.js"; import {SkyBox} from "./skybox.js"; import {Util} from "./util.js"; diff --git a/depth_shader.js b/shaders/depth_shader.js similarity index 100% rename from depth_shader.js rename to shaders/depth_shader.js diff --git a/haze_shader.js b/shaders/haze_shader.js similarity index 100% rename from haze_shader.js rename to shaders/haze_shader.js From c56c3dae4e5793916886de1392df121082ad131c Mon Sep 17 00:00:00 2001 From: Eimear Crotty Date: Fri, 23 Apr 2021 13:02:52 +0000 Subject: [PATCH 7/7] remove custom urlParams for haze and depth --- app.js | 8 ++++---- main.js | 2 ++ 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/app.js b/app.js index e5cd619..c2e0646 100644 --- a/app.js +++ b/app.js @@ -39,6 +39,8 @@ class App { this.speed = ('speed' in options) ? options['speed'] : Settings.speed; this.debug = ('debug' in options) ? options['debug'] : Settings.debug; this.year = ('year' in options) ? options['year'] : Settings.year; + this.haze = ('haze' in options) ? options['haze'] : Settings.haze; + this.depth = ('depth' in options) ? options['depth'] : Settings.depth; const defaultCameraSceneX = ('eyex' in options) ? options['eyex'] : Settings.eyex; const defaultCameraSceneZ = ('eyez' in options) ? options['eyez'] : Settings.eyez; @@ -87,8 +89,6 @@ class App { this.infoDetailsClose = document.getElementById("info-details-close"); this.infoDetailsDisplayed = false; - this.urlParams = new URLSearchParams(window.location.search); - // map whose keys are bbox strings, value is an object giving details about the corresponding data tile this.bBoxStringToSceneTileDetails = { // "-74.002,40.742,-74.001,40.743": { @@ -742,7 +742,7 @@ class App { // Render depth pass if the user has enabled debug // and `depth=true` is in the URL parameters. - if (this.debug && this.urlParams.get('depth')=='true') { + if (this.debug && this.depth) { this.depthPass = new THREE.ShaderPass( DepthShader ); this.depthPass.uniforms['tDepth'].value = this.depthRenderTarget.depthTexture; this.depthPass.needsSwap = true; @@ -751,7 +751,7 @@ class App { } // Render haze pass if `haze=true` is in the URL parameters. - if (this.urlParams.get('haze')=='true') { + if (this.haze) { this.hazePass = new THREE.ShaderPass( HazeShader ); this.hazePass.uniforms['tDepth'].value = this.depthRenderTarget.depthTexture; this.hazePass.needsSwap = true; diff --git a/main.js b/main.js index ff8afe8..fc26262 100644 --- a/main.js +++ b/main.js @@ -35,6 +35,8 @@ Util.setOptionFromUrlParams(options, params, "lon", parseFloat); Util.setOptionFromUrlParams(options, params, "lat", parseFloat); Util.setOptionFromUrlParams(options, params, "pitch", parseFloat); Util.setOptionFromUrlParams(options, params, "yaw", parseFloat); +Util.setOptionFromUrlParams(options, params, "haze", Util.stringToBoolean); +Util.setOptionFromUrlParams(options, params, "depth", Util.stringToBoolean); const app = new App(document.getElementById('viewport'), options);