Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
154 changes: 144 additions & 10 deletions src/components/Brain/Annotation/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import {
useCallback,
useEffect,
useMemo,
useRef,
} from 'react'
import {
Expand All @@ -11,17 +12,15 @@ import {
RingGeometry,
type Mesh,
type MeshStandardMaterial,
type ShaderMaterial,
type Vector3Tuple,
} from 'three'
import {
useFrame,
useThree,
type ThreeEvent,
} from '@react-three/fiber'
import {
Text,
useTexture,
} from '@react-three/drei'
import { Text } from '@react-three/drei'
import {
animated,
useSpring,
Expand Down Expand Up @@ -56,6 +55,7 @@ export function Annotation({
}: AnnotationProps) {
const circleRef = useRef<Mesh>(null)
const outlineRef = useRef<Mesh>(null)
const annotationShaderMaterialRef = useRef<ShaderMaterial>(null)
const labelMaterialRef = useRef<MeshStandardMaterial>(null)
const contentMaterialRef = useRef<MeshStandardMaterial>(null)
const previousCameraPositionRef = useRef<Vector3Tuple>([ 0, 0, 2.5 ])
Expand Down Expand Up @@ -246,7 +246,140 @@ export function Annotation({
return () => clearTimeout(timeout)
})

const annotationTexture = useTexture('/3D/textures/annotationTexture.jpg')
const vertexShader = `
varying vec2 vUv;

void main() {
vUv = uv;

vec4 modelPosition = modelMatrix * vec4(position, 1.0);
vec4 viewPosition = viewMatrix * modelPosition;
vec4 projectedPosition = projectionMatrix * viewPosition;

gl_Position = projectedPosition;
}
`

const fragmentShader = `
uniform float u_time;
uniform vec3 u_bg;
uniform vec3 u_colorA;
uniform vec3 u_colorB;

varying vec2 vUv;

//
// Description : Array and textureless GLSL 2D simplex noise function.
// Author : Ian McEwan, Ashima Arts.
// Maintainer : ijm
// Lastmod : 20110822 (ijm)
// License : Copyright (C) 2011 Ashima Arts. All rights reserved.
// Distributed under the MIT License. See LICENSE file.
// https://github.com/ashima/webgl-noise
//

// https://github.com/hughsk/glsl-noise/blob/master/simplex/2d.glsl

vec3 mod289(vec3 x) {
return x - floor(x * (1.0 / 289.0)) * 289.0;
}

vec2 mod289(vec2 x) {
return x - floor(x * (1.0 / 289.0)) * 289.0;
}

vec3 permute(vec3 x) {
return mod289(((x*34.0)+1.0)*x);
}

float snoise(vec2 v)
{
const vec4 C = vec4(0.211324865405187, // (3.0-sqrt(3.0))/6.0
0.366025403784439, // 0.5*(sqrt(3.0)-1.0)
-0.577350269189626, // -1.0 + 2.0 * C.x
0.024390243902439); // 1.0 / 41.0
// First corner
vec2 i = floor(v + dot(v, C.yy) );
vec2 x0 = v - i + dot(i, C.xx);

// Other corners
vec2 i1;
//i1.x = step( x0.y, x0.x ); // x0.x > x0.y ? 1.0 : 0.0
//i1.y = 1.0 - i1.x;
i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);
// x0 = x0 - 0.0 + 0.0 * C.xx ;
// x1 = x0 - i1 + 1.0 * C.xx ;
// x2 = x0 - 1.0 + 2.0 * C.xx ;
vec4 x12 = x0.xyxy + C.xxzz;
x12.xy -= i1;

// Permutations
i = mod289(i); // Avoid truncation effects in permutation
vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 ))
+ i.x + vec3(0.0, i1.x, 1.0 ));

vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy), dot(x12.zw,x12.zw)), 0.0);
m = m*m ;
m = m*m ;

// Gradients: 41 points uniformly over a line, mapped onto a diamond.
// The ring size 17*17 = 289 is close to a multiple of 41 (41*7 = 287)

vec3 x = 2.0 * fract(p * C.www) - 1.0;
vec3 h = abs(x) - 0.5;
vec3 ox = floor(x + 0.5);
vec3 a0 = x - ox;

// Normalise gradients implicitly by scaling m
// Approximation of: m *= inversesqrt( a0*a0 + h*h );
m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h );

// Compute final noise value at P
vec3 g;
g.x = a0.x * x0.x + h.x * x0.y;
g.yz = a0.yz * x12.xz + h.yz * x12.yw;
return 130.0 * dot(m, g);
}
// End of Simplex Noise Code


void main() {
vec3 color = u_bg;

float noise1 = snoise(vUv + (u_time * 0.05));
float noise2 = snoise(vUv + (u_time * 0.05));

color = mix(color, u_colorA, noise1);
color = mix(color, u_colorB, noise2);

gl_FragColor = vec4(color ,1.0);
}
`

const uniforms = useMemo(() => ({
u_time: {
value: 0.0,
},
u_bg: {
value: new Color('#faf9f9'),
},
u_colorA: {
value: new Color('#efecec'),
},
u_colorB: {
value: new Color('#fffafa'),
},
}), [])

useFrame((state) => {
if (!annotationShaderMaterialRef.current) {
return
}

const { clock } = state;

annotationShaderMaterialRef.current.uniforms.u_time.value = clock.getElapsedTime();
})

if (!colors?.background || !colors?.foreground) {
return null
Expand Down Expand Up @@ -278,11 +411,12 @@ export function Annotation({
ref={circleRef}
scale={springs.scale}
>
<meshStandardMaterial
color={colors.white}
map={annotationTexture}
metalness={1.35}
// roughness={0} // Makes the surface completely mirror reflective, which reflects back the stage background producing a cool effect. Problem is that when you expand an annotation the user then sees the pixelated background enlarged
<shaderMaterial
ref={annotationShaderMaterialRef}
uniforms={uniforms}
wireframe={false}
vertexShader={vertexShader}
fragmentShader={fragmentShader}
/>

<AnimatedText
Expand Down