-
Notifications
You must be signed in to change notification settings - Fork 0
/
Ocean.js
101 lines (86 loc) · 2.83 KB
/
Ocean.js
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
import * as THREE from 'three';
import { Water } from 'three/examples/jsm/objects/Water.js';
import { Sky } from 'three/examples/jsm/objects/Sky.js';
export class Ocean {
constructor(scene, renderer) {
this.scene = scene;
this.renderer = renderer;
this.objects = new Set();
this.params = {
waterColor: 0x001e0f,
distortionScale: 3.7
};
this.init();
}
init() {
// Water
const waterGeometry = new THREE.PlaneGeometry(10000, 10000);
const water = new Water(waterGeometry, {
textureWidth: 512,
textureHeight: 512,
waterNormals: new THREE.TextureLoader().load('/textures/waternormals.jpg', (texture) => {
texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
}),
sunDirection: new THREE.Vector3(),
sunColor: 0xffffff,
waterColor: this.params.waterColor,
distortionScale: this.params.distortionScale,
fog: false
});
water.rotation.x = -Math.PI / 2;
this.water = water;
this.objects.add(water);
// Sky
const sky = new Sky();
sky.scale.setScalar(10000);
this.sky = sky;
this.objects.add(sky);
// Sun position
const sun = new THREE.Vector3();
const parameters = {
elevation: 2,
azimuth: 180
};
const pmremGenerator = new THREE.PMREMGenerator(this.renderer);
function updateSun() {
const phi = THREE.MathUtils.degToRad(90 - parameters.elevation);
const theta = THREE.MathUtils.degToRad(parameters.azimuth);
sun.setFromSphericalCoords(1, phi, theta);
sky.material.uniforms['sunPosition'].value.copy(sun);
water.material.uniforms['sunDirection'].value.copy(sun).normalize();
const sceneEnv = new THREE.Scene();
sceneEnv.add(sky);
const renderTarget = pmremGenerator.fromScene(sceneEnv);
this.scene.environment = renderTarget.texture;
}
updateSun.call(this);
// Add a subtle directional light for shadows
const dirLight = new THREE.DirectionalLight(0xffffff, 1);
dirLight.position.set(5, 5, 5);
dirLight.castShadow = true;
dirLight.shadow.mapSize.width = 1024;
dirLight.shadow.mapSize.height = 1024;
this.objects.add(dirLight);
// Add everything to scene
this.objects.forEach(obj => this.scene.add(obj));
}
update(time) {
if (this.water) {
this.water.material.uniforms['time'].value += 1.0 / 60.0;
}
}
dispose() {
this.objects.forEach(obj => {
this.scene.remove(obj);
if (obj.material) obj.material.dispose();
if (obj.geometry) obj.geometry.dispose();
});
}
updateParams(newParams) {
Object.assign(this.params, newParams);
if (this.water) {
this.water.material.uniforms.waterColor.value.setHex(this.params.waterColor);
this.water.material.uniforms.distortionScale.value = this.params.distortionScale;
}
}
}