Skip to content


 Zabbix
 Grafana
 Prometheus
 React Three Fiber
 Threejs and TypeScript
 SocketIO and TypeScript
 Blender Topological Earth
 Sweet Home 3D
 Design Patterns Python
 Design Patterns TypeScript
   
 Course Coupon Codes
Three.js and TypeScript
Kindle Edition
$6.99 $9.99 Paperback 
$22.99 $29.99




Design Patterns in TypeScript
Kindle Edition
$6.99 $9.99 Paperback
$11.99 $19.99




Design Patterns in Python
Kindle Edition
$6.99 $9.99 Paperback
$11.99 $19.99




Globe

Description

Using a displacement map on a sphere.

./dist/client/index.html

 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
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <title>
            Three.js TypeScript Tutorials by Sean Bradley :
            https://sbcode.net/threejs
        </title>
        <style>
            body {
                overflow: hidden;
                margin: 0px;
            }

            #locationData {
                position: absolute;
                left: 50%;
                top: 50%;
                font-size: 14px;
                font-family: monospace;
                color: white;
                pointer-events: none;
                user-select: none;
            }
        </style>
    </head>

    <body>
        <div id="locationData"></div>
        <script type="module" src="bundle.js"></script>
    </body>
</html>

./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
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 'dat.gui'

const scene = new THREE.Scene()

const axesHelper = new THREE.AxesHelper(5)
scene.add(axesHelper)

const ambientLight = new THREE.AmbientLight(0x444444)
scene.add(ambientLight)

const light = new THREE.DirectionalLight(0xffffff, 2)
light.position.set(0, 0, 3)
light.castShadow = true
light.shadow.bias = -0.003
light.shadow.mapSize.width = 2048
light.shadow.mapSize.height = 2048
light.shadow.camera.left = -2
light.shadow.camera.right = 2
light.shadow.camera.top = -2
light.shadow.camera.bottom = 2
light.shadow.camera.near = 1
light.shadow.camera.far = 5

const helper = new THREE.CameraHelper(light.shadow.camera)
scene.add(helper)

const lightPivot = new THREE.Object3D()
lightPivot.add(light)
scene.add(lightPivot)

scene.background = 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',
])

const camera = new THREE.PerspectiveCamera(
    75,
    window.innerWidth / window.innerHeight,
    0.1,
    100
)

const renderer = new THREE.WebGLRenderer()
renderer.shadowMap.enabled = true
renderer.shadowMap.type = THREE.PCFShadowMap
renderer.setSize(window.innerWidth, window.innerHeight)
document.body.appendChild(renderer.domElement)

const locationDataElem = document.getElementById(
    'locationData'
) as HTMLDivElement
let locationDataText = ''

const controls = new OrbitControls(camera, renderer.domElement)
controls.addEventListener('change', () => {
    locationDataText =
        ((controls.getPolarAngle() / -Math.PI) * 180 + 90).toFixed(6) +
        ' ' +
        ((controls.getAzimuthalAngle() / Math.PI) * 180).toFixed(6)
    locationDataElem.innerText = locationDataText
})
controls.screenSpacePanning = true

const sphereGeometry = new THREE.SphereGeometry(1, 720, 360)
const material = new THREE.MeshStandardMaterial()
const texture = new THREE.TextureLoader().load('img/worldColour.5400x2700.jpg')
texture.anisotropy = renderer.capabilities.getMaxAnisotropy()
material.map = texture

const displacementMap = new THREE.TextureLoader().load(
    'img/srtm_ramp2.world.5400x2700.jpg'
)
material.displacementMap = displacementMap
material.displacementScale = 0.1

const sphere = new THREE.Mesh(sphereGeometry, material)
sphere.rotation.y = -Math.PI / 2
sphere.castShadow = true
sphere.receiveShadow = true
scene.add(sphere)

camera.position.z = 2

window.addEventListener('resize', onWindowResize, false)
function onWindowResize() {
    camera.aspect = window.innerWidth / window.innerHeight
    camera.updateProjectionMatrix()
    renderer.setSize(window.innerWidth, window.innerHeight)
    render()
}

const gui = new GUI()
gui.add(material, 'displacementScale', 0, 1, 0.01)

const stats = Stats()
document.body.appendChild(stats.dom)

function animate() {
    requestAnimationFrame(animate)

    controls.update()
    helper.update()
    lightPivot.rotation.y += 0.01

    render()

    stats.update()
}

function render() {
    renderer.render(scene, camera)
}

animate()