-
Notifications
You must be signed in to change notification settings - Fork 0
/
LiquidSphere.js
95 lines (80 loc) · 2.43 KB
/
LiquidSphere.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
import * as THREE from 'three'
import React, { useEffect, useMemo } from 'react'
import { useFrame, Canvas} from '@react-three/fiber'
import vertexShader from "./vertexShader";
import fragmentShader from "./fragmentShader";
import { ThinFilmFresnelMap } from './ThinFilmFresnelMap';
export const LiquidSphere = (props) => {
let mousePos = new THREE.Vector2(0, 0);
const getNormalizedMousePos = (e) => {
return {
x: (e.clientX / window.innerWidth) * 2 - 1,
y: -(e.clientY / window.innerHeight) * 2 + 1
};
};
function setMousePos(e) {
const { x, y } = getNormalizedMousePos(e);
mousePos.x = x;
mousePos.y = y;
}
function trackMousePos() {
window.addEventListener("mousemove", (e) => {
setMousePos(e);
});
window.addEventListener("touchstart", (e) => {
setMousePos(e.touches[0]);
}, { passive: false });
window.addEventListener("touchmove", (e) => {
setMousePos(e.touches[0]);
});
}
const map = new ThinFilmFresnelMap(1000, 1.2, 3.2, 128);
map.texture.needsUpdate = true;
const w_uniforms = useMemo(() => {
return {
uTime: { value: 0 },
uResolution: {value: new THREE.Vector2(window.innerWidth * 4, window.innerHeight * 4)},
uMouse: {value: new THREE.Vector2(0, 0)},
uIriMap: {value: map.texture},
uIriBoost: {value: 80}
};
});
const waterMaterial = new THREE.ShaderMaterial({
vertexShader: vertexShader,
fragmentShader: fragmentShader,
side: THREE.DoubleSide,
uniforms: w_uniforms
});
const geometry = new THREE.SphereGeometry(10, 64, 64);
useEffect(() => {
trackMousePos();
});
useFrame((state) => {
const { clock } = state;
const elapsedTime = clock.getElapsedTime();
const time = elapsedTime * 0.1;
if (waterMaterial) {
w_uniforms.uTime.value = time;
w_uniforms.uMouse.value = mousePos;
}
});
return(
<>
<mesh
scale={0.2}
position={[0, 0, 0]}
geometry={geometry}
material={waterMaterial}
/>
</>
);
}
export const LiquidSphereContainer = (props) => {
return(
<>
<Canvas>
{props.children}
</Canvas>
</>
);
}