From ff81ee24ad85c8a578e841ef4215e1d6e7c7c0ab Mon Sep 17 00:00:00 2001 From: Stelios Vitalis Date: Tue, 18 Jun 2024 10:46:54 +0200 Subject: [PATCH] Add AO and fix lighting --- package-lock.json | 69 +++++++++++++++++++++- package.json | 4 ++ src/lib-components/ThreeJsViewer.vue | 88 +++++++++++++++++++++++----- 3 files changed, 144 insertions(+), 17 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0db1078..ce48d23 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "ninja", - "version": "0.7.0", + "version": "0.8.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "ninja", - "version": "0.7.0", + "version": "0.8.0", "dependencies": { "@fortawesome/fontawesome-free": "^5.15.4", "bootstrap": "^4.6.1", @@ -24,6 +24,7 @@ "@vue/component-compiler-utils": "^3.3.0", "autoprefixer": "^10.4.4", "babel-eslint": "^10.1.0", + "buffer": "^6.0.3", "concurrently": "^6.5.1", "eslint": "^7.24.0", "eslint-config-mdcs": "^5.0.0", @@ -2880,6 +2881,26 @@ "safe-buffer": "^5.0.1" } }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", @@ -2965,6 +2986,30 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -4268,6 +4313,26 @@ "entities": "^3.0.1" } }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/ignore": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", diff --git a/package.json b/package.json index 5089285..2da758f 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "@vue/component-compiler-utils": "^3.3.0", "autoprefixer": "^10.4.4", "babel-eslint": "^10.1.0", + "buffer": "^6.0.3", "concurrently": "^6.5.1", "eslint": "^7.24.0", "eslint-config-mdcs": "^5.0.0", @@ -34,5 +35,8 @@ "static-server": "^2.2.1", "vue-hot-reload-api": "^2.3.4", "vue-template-compiler": "^2.6.11" + }, + "@parcel/resolver-default": { + "packageExports": true } } diff --git a/src/lib-components/ThreeJsViewer.vue b/src/lib-components/ThreeJsViewer.vue index bf335d7..ae2bd8c 100644 --- a/src/lib-components/ThreeJsViewer.vue +++ b/src/lib-components/ThreeJsViewer.vue @@ -10,6 +10,9 @@ import * as THREE from 'three'; import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'; import { AttributeEvaluator, CityJSONLoader, CityJSONWorkerParser, CityObjectsMaterial, TextureManager } from 'cityjson-threejs-loader'; import { SRGBColorSpace } from 'three'; +import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; +import { GTAOPass, OutputPass, RenderPass } from 'three/examples/jsm/Addons.js'; +import GUI from 'three/examples/jsm/libs/lil-gui.module.min.js'; export default { name: 'ThreeJsViewer', @@ -360,6 +363,7 @@ export default { this.raycaster = null; this.mouse = null; this.spotLight = null; + this.composer = null; }, mounted() { @@ -507,7 +511,8 @@ export default { } ); - this.renderer.render( this.scene, this.camera ); + // this.renderer.render( this.scene, this.camera ); + this.composer.render(); }, refreshColors() { @@ -628,6 +633,22 @@ export default { } + }, + getParams() { + + const hash = window.location.hash; + + if ( hash ) { + + const params = new URLSearchParams( hash.substring( 1 ) ); + return Object.fromEntries( params ); + + } else { + + return {}; + + } + }, initScene() { @@ -648,30 +669,67 @@ export default { this.renderer.setSize( viewer.clientWidth, viewer.clientHeight ); this.renderer.setClearColor( this.backgroundColor ); this.renderer.setPixelRatio( window.devicePixelRatio ); - // this.renderer.shadowMap.enabled = true; - // this.renderer.shadowMap.type = THREE.PCFSoftShadowMap; + + const composer = new EffectComposer( this.renderer ); + this.composer = composer; + + const renderPass = new RenderPass( this.scene, this.camera ); + composer.addPass( renderPass ); + + const gtaoPass = new GTAOPass( this.scene, this.camera, viewer.clientWidth, viewer.clientHeight ); + + const aoParameters = { + radius: 2.4, + distanceExponent: 1., + thickness: 10., + scale: 1.3, + samples: 16, + distanceFallOff: 1., + screenSpaceRadius: false, + }; + + gtaoPass.updateGtaoMaterial( aoParameters ); + + composer.addPass( gtaoPass ); + + const outputPass = new OutputPass(); + composer.addPass( outputPass ); + + const updateGtaoMaterial = () => { + + gtaoPass.updateGtaoMaterial( aoParameters ); + this.updateScene(); + + }; + + if ( "debug" in this.getParams() ) { + + const gui = new GUI(); + + gui.add( gtaoPass, 'blendIntensity' ).min( 0 ).max( 1 ).step( 0.01 ); + gui.add( aoParameters, 'radius' ).min( 0.01 ).max( 10 ).step( 0.1 ).onChange( updateGtaoMaterial ); + gui.add( aoParameters, 'distanceExponent' ).min( 1 ).max( 4 ).step( 0.01 ).onChange( updateGtaoMaterial ); + gui.add( aoParameters, 'thickness' ).min( 0.01 ).max( 10 ).step( 0.1 ).onChange( updateGtaoMaterial ); + gui.add( aoParameters, 'distanceFallOff' ).min( 0 ).max( 1 ).step( 0.01 ).onChange( updateGtaoMaterial ); + gui.add( aoParameters, 'scale' ).min( 0.01 ).max( 2.0 ).step( 0.1 ).onChange( updateGtaoMaterial ); + gui.add( aoParameters, 'samples' ).min( 2 ).max( 32 ).step( 1 ).onChange( updateGtaoMaterial ); + gui.add( aoParameters, 'screenSpaceRadius' ).onChange( updateGtaoMaterial ); + + } let self = this; - // add raycaster and mouse (for clickable objects) this.raycaster = new THREE.Raycaster(); this.mouse = new THREE.Vector2(); - //add AmbientLight (light that is only there that there's a minimum of light and you can see color) - //kind of the natural daylight - var am_light = new THREE.AmbientLight( 0xffffff, 0.7 ); // soft white light - this.scene.add( am_light ); + const ambientLight = new THREE.AmbientLight( 0x999999, 0.7 * Math.PI ); // soft white light + this.scene.add( ambientLight ); - // Add directional light - this.spotLight = new THREE.DirectionalLight( 0xDDDDDD ); + this.spotLight = new THREE.DirectionalLight( 0xDDDDDD, Math.PI ); this.spotLight.position.set( 1, 2, 3 ); - this.spotLight.target = this.scene; - // this.spotLight.castShadow = true; - // spot_light.intensity = 0.4; - // spot_light.position.normalize(); + this.scene.add( this.spotLight ); - //render & orbit controls this.controls = new OrbitControls( this.camera, this.renderer.domElement ); this.controls.addEventListener( 'change', function () {