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




Examples : Shiny Refraction

Description

This example demonstrates,

  • Using the EffectComposer to add a Depth of Field (DOF) effect.
  • Dynamically changing the DOF depending on camera and ball distance.
  • Changing MeshPhysicalMaterial properties using the GUI.

Code

./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
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'
import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer'
import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass'
import { BokehPass } from 'three/examples/jsm/postprocessing/BokehPass'
const scene = new THREE.Scene()
const envTexture = new THREE.CubeTextureLoader().load([
    'img/px_25.jpg',
    'img/nx_25.jpg',
    'img/py_25.jpg',
    'img/ny_25.jpg',
    'img/pz_25.jpg',
    'img/nz_25.jpg',
])
scene.background = envTexture
const ambientLight = new THREE.AmbientLight(0x444444)
scene.add(ambientLight)
const light1 = new THREE.PointLight()
light1.position.set(-6, 10, -6)
light1.castShadow = true
light1.shadow.mapSize.height = 1024
light1.shadow.mapSize.width = 1024
scene.add(light1)
const camera = new THREE.PerspectiveCamera(
    75,
    window.innerWidth / window.innerHeight,
    0.01,
    100
)
camera.position.set(3, 1.5, 3)
const renderer = new THREE.WebGLRenderer()
renderer.setSize(window.innerWidth, window.innerHeight)
renderer.shadowMap.enabled = true
document.body.appendChild(renderer.domElement)
const renderPass = new RenderPass(scene, camera)
const bokehPass = new BokehPass(scene, camera, {
    focus: 1.0,
    aperture: 0.0001,
    maxblur: 1.0,
    width: window.innerWidth,
    height: window.innerHeight,
})
const composer = new EffectComposer(renderer)
composer.addPass(renderPass)
composer.addPass(bokehPass)
const orbitControls = new OrbitControls(camera, renderer.domElement)
orbitControls.enableDamping = true
orbitControls.target.set(1, 0, 0)
const planeGeometry = new THREE.PlaneGeometry(25, 25)
const texture = new THREE.TextureLoader().load('img/grid.png')
const plane = new THREE.Mesh(
    planeGeometry,
    new THREE.MeshPhongMaterial({ map: texture })
)
plane.rotateX(-Math.PI / 2)
plane.position.y = -1
plane.receiveShadow = true
scene.add(plane)
window.addEventListener('resize', onWindowResize, false)
function onWindowResize() {
    camera.aspect = window.innerWidth / window.innerHeight
    camera.updateProjectionMatrix()
    renderer.setSize(window.innerWidth, window.innerHeight)
    composer.setSize(window.innerWidth, window.innerHeight)
}
const pivot = new THREE.Object3D()
scene.add(pivot)
const cubeRenderTarget = new THREE.WebGLCubeRenderTarget(2048)
const cubeCamera = new THREE.CubeCamera(0.1, 100, cubeRenderTarget)
scene.add(cubeCamera)
const material = new THREE.MeshPhysicalMaterial({
    reflectivity: 1.0,
    transmission: 1.0,
    roughness: 0,
    metalness: 0,
    clearcoat: 0.3,
    clearcoatRoughness: 0.25,
    color: new THREE.Color(0xffffff),
    ior: 1.5,
})
material.thickness = 50.0

//cubeRenderTarget.texture.mapping = THREE.CubeRefractionMapping;
const ball = new THREE.Mesh(new THREE.SphereGeometry(1, 32, 32), material)
ball.position.set(1.5, 0, 0)
ball.castShadow = true
pivot.add(ball)
const gui = new GUI()
const ballFolder = gui.addFolder('Ball1')
ballFolder.add(ball, 'visible').name('Visible')
ballFolder.add(material, 'metalness', 0, 1.0, 0.01).name('Metalness')
ballFolder.add(material, 'roughness', 0, 1.0, 0.01).name('Roughness')
ballFolder.add(material, 'transmission', 0, 1.0, 0.01).name('Transmission')
ballFolder.add(material, 'clearcoat', 0, 1.0, 0.01).name('Clearcoat')
ballFolder
    .add(material, 'clearcoatRoughness', 0, 1.0, 0.01)
    .name('ClearcoatRoughness')
ballFolder.add(material, 'reflectivity', 0, 1.0, 0.01).name('Reflectivity')
ballFolder.add(material, 'ior', 1.0, 2.333, 0.01).name('IOR')
ballFolder.add(material, 'thickness', 0, 50.0, 0.1).name('thickness')
ballFolder.open()
const stats = new Stats()
document.body.appendChild(stats.dom)
const clock = new THREE.Clock()
var animate = function () {
    requestAnimationFrame(animate)
    orbitControls.update()
    const ballWorldPosition = new THREE.Vector3()
    ball.getWorldPosition(ballWorldPosition)
    ;(bokehPass.uniforms as any).focus.value =
        camera.position.distanceTo(ballWorldPosition)
    const delta = clock.getDelta()
    ball.rotateY(-0.5 * delta)
    pivot.rotateY(0.5 * delta)
    render()
    stats.update()
}
function render() {
    cubeCamera.position.copy(camera.position)
    cubeCamera.update(renderer, scene)
    //renderer.render(scene, camera)
    composer.render(0.1)
}
animate()