-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Haze Pass #41
base: master
Are you sure you want to change the base?
Add Haze Pass #41
Changes from 6 commits
01707b4
6c5297e
be63718
86c1ff2
4043280
3fbe5ca
c56c3da
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,10 +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 "./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 "./shaders/haze_shader.js"; | ||
import {Settings} from "./settings.js"; | ||
import {SkyBox} from "./skybox.js"; | ||
import {Util} from "./util.js"; | ||
|
@@ -85,6 +87,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 +697,67 @@ class App { | |
|
||
this.scene.add(this.camera); | ||
|
||
this.composer = new THREE.EffectComposer(this.renderer); | ||
// Set up render target for holding depth information. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It'd be great to make all the new composers/passes conditional on a url param, so if it's not enabled, the behavior/rendering is unchanged from before. This will make it easier to deploy this new feature while we experiment with and tweak it, without changing the current user experience. (At the moment it looks to me like there is a bit of a haze effect, or maybe it's just the antialising, I'm not sure, even if the new haze & depth params aren't present in the url. Also, eventually we might want different haze settings for birds-eye vs street-level views. In any case, if we can make it so that none of this is enabled, and the user sees the same result as before, unless they add special url params, then we can go ahead and deploy it and start experimenting with it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good note, I'll work on that. I think the current "haze" when the haze feature is disabled actually comes from the softening of the edges with the antialising from a previous merge, but I'll double check that. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
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; | ||
|
||
// 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.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) | ||
|
||
// 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); | ||
|
||
// 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') { | ||
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); | ||
} | ||
|
||
// 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({ | ||
|
@@ -977,7 +1026,10 @@ class App { | |
requestAnimationFrame(() => { | ||
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]); | ||
}); | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 <common>', | ||
|
||
'#include <packing>', | ||
|
||
'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}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 <common>', | ||
|
||
'#include <packing>', | ||
|
||
'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}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would you mind moving the new url params into main.js so they're handled the same as the current url params (the pattern is that the url params are parsed in main.js and loaded into an "options" object which is passed to the App construtor).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Much cleaner, done.