What’s on our mind?

Collection of articles, design, site, and resources made by designers and publisher @Menu View

index92
createApp({
    params: {
        roughness: 0.1
    },
    async init() {
        // OrbitControls
        this.controls = new OrbitControls(this.camera, this.renderer.domElement)
        this.controls.enableDamping = true
        this.controls.autoRotate = true

        // Environment
        const envMap = await loadHDRI(hdriURL, this.renderer)
        this.scene.environment = envMap

        // Mesh
        const geometry = new THREE.SphereGeometry(1, 64, 32)
        const material = new THREE.MeshStandardMaterial(this.params)

        material.onBeforeCompile = shader => {
            shader.fragmentShader = shader.fragmentShader.replace(/vec4 diffuseColor.*;/, `
                vec3 rgb = vNormal * 0.5 + 0.5;
                        vec4 diffuseColor = vec4(rgb, 1.);      
            `)
        }

        this.mesh = new THREE.Mesh(geometry, material)
        this.scene.add(this.mesh)
    },
    tick(time) {
        this.controls.update()
    }
})

function createApp(app) {
    const scene = new THREE.Scene()
    const renderer = createRenderer()
    const camera = createCamera()
    Object.assign(renderer.domElement.style, {
        position: 'absolute',
        top: 0,
        left: 0,
        width: '100vw',
        height: '100vh',
        background: 'radial-gradient(pink, #aaaaaa)'
    })
    document.body.appendChild(renderer.domElement)
    window.addEventListener('resize', () => {
        camera.aspect = window.innerWidth / window.innerHeight
        camera.updateProjectionMatrix()
        renderer.setSize(window.innerWidth, window.innerHeight)
    }, false)
    const clock = new THREE.Clock()
    const loop = () => {
        requestAnimationFrame(loop)
        const delta = clock.getDelta()
        app.tick(clock.elapsedTime, delta)
        renderer.render(scene, camera)
    }
    Object.assign(app, {
        scene,
        camera,
        renderer,
        clock
    })
    app.init().then(loop)
}

function createRenderer() {
    const renderer = new THREE.WebGLRenderer({
        antialias: true,
        alpha: true
    })
    renderer.toneMapping = THREE.ACESFilmicToneMapping
    renderer.outputEncoding = THREE.sRGBEncoding
    renderer.setSize(window.innerWidth, window.innerHeight)
    return renderer
}

function createCamera() {
    const camera = new THREE.PerspectiveCamera(
        75,
        window.innerWidth / window.innerHeight,
        0.1,
        1000
    )
    camera.position.set(0, 0, 2)
    return camera
}

function loadHDRI(url, renderer) {
    return new Promise(resolve => {
        const loader = new RGBELoader()
        const pmremGenerator = new THREE.PMREMGenerator(renderer)
        loader.load(url, (texture) => {
            const envMap = pmremGenerator.fromEquirectangular(texture).texture
            texture.dispose()
            pmremGenerator.dispose()
            resolve(envMap)
        })
    })
}