DisplacementMap
Video Lecture
Description
A displacement map, is an image that can be used to alter the geometry of a mesh. The value of each pixel is used to change the position of the vertices of the mesh.
Start Script
./src/client/client.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | // If using Relative Import References import * as THREE from '/build/three.module.js' import { OrbitControls } from '/jsm/controls/OrbitControls' import Stats from '/jsm/libs/stats.module' import { GUI } from '/jsm/libs/dat.gui.module' // If using Module Specifiers //import * as THREE from 'three' //import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls' //import Stats from 'three/examples/jsm/libs/stats.module' //import { GUI } from 'three/examples/jsm/libs/dat.gui.module' const scene: THREE.Scene = new THREE.Scene() //scene.background = new THREE.Color(0xff0000) const axesHelper = new THREE.AxesHelper(5) scene.add(axesHelper) const light = new THREE.PointLight(0xffffff, 2); light.position.set(0, 5, 10); scene.add(light); const camera: THREE.PerspectiveCamera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000) const renderer: THREE.WebGLRenderer = new THREE.WebGLRenderer() renderer.setSize(window.innerWidth, window.innerHeight) document.body.appendChild(renderer.domElement) const controls = new OrbitControls(camera, renderer.domElement) controls.screenSpacePanning = true //so that panning up and down doesn't zoom in/out //controls.addEventListener('change', render) const planeGeometry: THREE.PlaneGeometry = new THREE.PlaneGeometry(3.6, 1.8)//, 360, 180) const material: THREE.MeshPhongMaterial = new THREE.MeshPhongMaterial() //const texture = new THREE.TextureLoader().load("img/grid.png") const texture = new THREE.TextureLoader().load("img/worldColour.5400x2700.jpg") material.map = texture // const envTexture = new THREE.CubeTextureLoader().load(["img/px_eso0932a.jpg", "img/nx_eso0932a.jpg", "img/py_eso0932a.jpg", "img/ny_eso0932a.jpg", "img/pz_eso0932a.jpg", "img/nz_eso0932a.jpg"]) // envTexture.mapping = THREE.CubeReflectionMapping // material.envMap = envTexture //const specularTexture = new THREE.TextureLoader().load("img/earthSpecular.jpg") // material.specularMap = specularTexture const displacementMap = new THREE.TextureLoader().load("img/gebco_bathy.5400x2700_8bit.jpg") material.displacementMap = displacementMap const plane: THREE.Mesh = new THREE.Mesh(planeGeometry, material) scene.add(plane) camera.position.z = 3 window.addEventListener('resize', onWindowResize, false) function onWindowResize() { camera.aspect = window.innerWidth / window.innerHeight camera.updateProjectionMatrix() renderer.setSize(window.innerWidth, window.innerHeight) render() } const stats = Stats() document.body.appendChild(stats.dom) var options = { side: { "FrontSide": THREE.FrontSide, "BackSide": THREE.BackSide, "DoubleSide": THREE.DoubleSide, } } const gui = new GUI() const materialFolder = gui.addFolder('THREE.Material') materialFolder.add(material, 'transparent') materialFolder.add(material, 'opacity', 0, 1, 0.01) materialFolder.add(material, 'depthTest') materialFolder.add(material, 'depthWrite') materialFolder.add(material, 'alphaTest', 0, 1, 0.01).onChange(() => updateMaterial()) materialFolder.add(material, 'visible') materialFolder.add(material, 'side', options.side).onChange(() => updateMaterial()) //materialFolder.open() var data = { color: material.color.getHex(), emissive: material.emissive.getHex(), specular: material.specular.getHex() }; var meshPhongMaterialFolder = gui.addFolder('THREE.meshPhongMaterialFolder'); meshPhongMaterialFolder.addColor(data, 'color').onChange(() => { material.color.setHex(Number(data.color.toString().replace('#', '0x'))) }) meshPhongMaterialFolder.addColor(data, 'emissive').onChange(() => { material.emissive.setHex(Number(data.emissive.toString().replace('#', '0x'))) }) meshPhongMaterialFolder.addColor(data, 'specular').onChange(() => { material.specular.setHex(Number(data.specular.toString().replace('#', '0x'))) }); meshPhongMaterialFolder.add(material, 'shininess', 0, 1024); meshPhongMaterialFolder.add(material, 'wireframe') meshPhongMaterialFolder.add(material, 'flatShading').onChange(() => updateMaterial()) meshPhongMaterialFolder.add(material, 'reflectivity', 0, 1) meshPhongMaterialFolder.add(material, 'refractionRatio', 0, 1) meshPhongMaterialFolder.add(material, 'displacementScale', 0, 1, 0.01) meshPhongMaterialFolder.add(material, 'displacementBias', -1, 1, 0.01) meshPhongMaterialFolder.open() // var planeData = { // width: 3.6, // height: 1.8, // widthSegments: 1, // heightSegments: 1 // }; // const planePropertiesFolder = gui.addFolder("PlaneGeometry") // //planePropertiesFolder.add(planeData, 'width', 1, 30).onChange(regeneratePlaneGeometry) // //planePropertiesFolder.add(planeData, 'height', 1, 30).onChange(regeneratePlaneGeometry) // planePropertiesFolder.add(planeData, 'widthSegments', 1, 360).onChange(regeneratePlaneGeometry) // planePropertiesFolder.add(planeData, 'heightSegments', 1, 180).onChange(regeneratePlaneGeometry) // planePropertiesFolder.open() // function regeneratePlaneGeometry() { // let newGeometry = new THREE.PlaneGeometry( // planeData.width, planeData.height, planeData.widthSegments, planeData.heightSegments // ) // plane.geometry.dispose() // plane.geometry = newGeometry // } function updateMaterial() { material.side = Number(material.side) material.needsUpdate = true } var animate = function () { requestAnimationFrame(animate) render() stats.update() }; function render() { renderer.render(scene, camera) } animate(); |
Final Script
./src/client/client.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | // If using Relative Import References import * as THREE from '/build/three.module.js' import { OrbitControls } from '/jsm/controls/OrbitControls' import Stats from '/jsm/libs/stats.module' import { GUI } from '/jsm/libs/dat.gui.module' // If using Module Specifiers //import * as THREE from 'three' //import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls' //import Stats from 'three/examples/jsm/libs/stats.module' //import { GUI } from 'three/examples/jsm/libs/dat.gui.module' const scene: THREE.Scene = new THREE.Scene() //scene.background = new THREE.Color(0xff0000) const axesHelper = new THREE.AxesHelper(5) scene.add(axesHelper) const light = new THREE.PointLight(0xffffff, 2); light.position.set(0, 5, 10); scene.add(light); const camera: THREE.PerspectiveCamera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000) const renderer: THREE.WebGLRenderer = new THREE.WebGLRenderer() renderer.setSize(window.innerWidth, window.innerHeight) document.body.appendChild(renderer.domElement) const controls = new OrbitControls(camera, renderer.domElement) controls.screenSpacePanning = true //so that panning up and down doesn't zoom in/out //controls.addEventListener('change', render) const planeGeometry: THREE.PlaneGeometry = new THREE.PlaneGeometry(3.6, 1.8, 360, 180) const material: THREE.MeshPhongMaterial = new THREE.MeshPhongMaterial() //const texture = new THREE.TextureLoader().load("img/grid.png") const texture = new THREE.TextureLoader().load("img/worldColour.5400x2700.jpg") material.map = texture // const envTexture = new THREE.CubeTextureLoader().load(["img/px_eso0932a.jpg", "img/nx_eso0932a.jpg", "img/py_eso0932a.jpg", "img/ny_eso0932a.jpg", "img/pz_eso0932a.jpg", "img/nz_eso0932a.jpg"]) // envTexture.mapping = THREE.CubeReflectionMapping // material.envMap = envTexture //const specularTexture = new THREE.TextureLoader().load("img/earthSpecular.jpg") // material.specularMap = specularTexture const displacementMap = new THREE.TextureLoader().load("img/gebco_bathy.5400x2700_8bit.jpg") material.displacementMap = displacementMap const plane: THREE.Mesh = new THREE.Mesh(planeGeometry, material) scene.add(plane) camera.position.z = 3 window.addEventListener('resize', onWindowResize, false) function onWindowResize() { camera.aspect = window.innerWidth / window.innerHeight camera.updateProjectionMatrix() renderer.setSize(window.innerWidth, window.innerHeight) render() } const stats = Stats() document.body.appendChild(stats.dom) var options = { side: { "FrontSide": THREE.FrontSide, "BackSide": THREE.BackSide, "DoubleSide": THREE.DoubleSide, } } const gui = new GUI() const materialFolder = gui.addFolder('THREE.Material') materialFolder.add(material, 'transparent') materialFolder.add(material, 'opacity', 0, 1, 0.01) materialFolder.add(material, 'depthTest') materialFolder.add(material, 'depthWrite') materialFolder.add(material, 'alphaTest', 0, 1, 0.01).onChange(() => updateMaterial()) materialFolder.add(material, 'visible') materialFolder.add(material, 'side', options.side).onChange(() => updateMaterial()) //materialFolder.open() var data = { color: material.color.getHex(), emissive: material.emissive.getHex(), specular: material.specular.getHex() }; var meshPhongMaterialFolder = gui.addFolder('THREE.meshPhongMaterialFolder'); meshPhongMaterialFolder.addColor(data, 'color').onChange(() => { material.color.setHex(Number(data.color.toString().replace('#', '0x'))) }) meshPhongMaterialFolder.addColor(data, 'emissive').onChange(() => { material.emissive.setHex(Number(data.emissive.toString().replace('#', '0x'))) }) meshPhongMaterialFolder.addColor(data, 'specular').onChange(() => { material.specular.setHex(Number(data.specular.toString().replace('#', '0x'))) }); meshPhongMaterialFolder.add(material, 'shininess', 0, 1024); meshPhongMaterialFolder.add(material, 'wireframe') meshPhongMaterialFolder.add(material, 'flatShading').onChange(() => updateMaterial()) meshPhongMaterialFolder.add(material, 'reflectivity', 0, 1) meshPhongMaterialFolder.add(material, 'refractionRatio', 0, 1) meshPhongMaterialFolder.add(material, 'displacementScale', -1, 1, 0.01) meshPhongMaterialFolder.add(material, 'displacementBias', -1, 1, 0.01) meshPhongMaterialFolder.open() var planeData = { width: 3.6, height: 1.8, widthSegments: 360, heightSegments: 180 }; const planePropertiesFolder = gui.addFolder("PlaneGeometry") //planePropertiesFolder.add(planeData, 'width', 1, 30).onChange(regeneratePlaneGeometry) //planePropertiesFolder.add(planeData, 'height', 1, 30).onChange(regeneratePlaneGeometry) planePropertiesFolder.add(planeData, 'widthSegments', 1, 360).onChange(regeneratePlaneGeometry) planePropertiesFolder.add(planeData, 'heightSegments', 1, 180).onChange(regeneratePlaneGeometry) planePropertiesFolder.open() function regeneratePlaneGeometry() { let newGeometry = new THREE.PlaneGeometry( planeData.width, planeData.height, planeData.widthSegments, planeData.heightSegments ) plane.geometry.dispose() plane.geometry = newGeometry } function updateMaterial() { material.side = Number(material.side) material.needsUpdate = true } var animate = function () { requestAnimationFrame(animate) render() stats.update() }; function render() { renderer.render(scene, camera) } animate(); |