1+ /* eslint-disable @typescript-eslint/no-explicit-any */
12"use client" ;
23import {
34 Box ,
45 Camera ,
6+ GLTFLoader ,
57 Mesh ,
68 Plane ,
79 Program ,
@@ -16,14 +18,15 @@ import { Overlay } from "../overlay";
1618const DESKTOP_HEIGHT = 256 ;
1719const MOBILE_HEIGHT = 260 ;
1820
19- const DESKTOP_CAMERA_POSITION = 2.3 ;
20- const MOBILE_CAMERA_POSITION = 2.7 ;
21+ const DESKTOP_CAMERA_POSITION = new Vec3 ( 5 , - 5 , 10 ) ;
22+
23+ const MOBILE_CAMERA_POSITION = new Vec3 ( 2 , - 2 , 1 ) ;
2124
2225export const HeroASCII = ( ) => {
2326 const containerRef = useRef < HTMLDivElement > ( null ) ;
2427 useEffect ( ( ) => {
2528 const container = containerRef . current ;
26- const vertex = `#version 300 es
29+ const vertex = /*glsl*/ `#version 300 es
2730in vec3 position;
2831in vec3 normal;
2932in vec2 uv;
@@ -37,7 +40,7 @@ void main() {
3740 vNormal = normalize(normalMatrix * normal);
3841 gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
3942}` ;
40- const fragment = `#version 300 es
43+ const fragment = /*glsl*/ `#version 300 es
4144precision mediump float;
4245uniform float uTime;
4346in vec2 vUv;
@@ -50,24 +53,24 @@ void main() {
5053 // Basic white color with light intensity
5154 fragColor = vec4(light, light, light, 1.0);
5255}` ;
53- const asciiVertex = `#version 300 es
56+ const asciiVertex = /*glsl*/ `#version 300 es
5457in vec2 uv;
5558in vec2 position;
5659out vec2 vUv;
5760void main() {
5861 vUv = uv;
5962 gl_Position = vec4(position, 0., 1.);
6063}` ;
61- const asciiFragment = `#version 300 es
64+ const asciiFragment = /*glsl*/ `#version 300 es
6265precision highp float;
6366uniform vec2 uResolution;
6467uniform sampler2D uTexture;
6568out vec4 fragColor;
6669float character(int n, vec2 p) {
6770 // character grid scale
68- float scale = uResolution.x < 768.0 ? 6.0 : 4 .0;
71+ float scale = uResolution.x < 768.0 ? 6.0 : 6 .0;
6972 p = floor(p * vec2(-scale, scale) + 2.5);
70- if(clamp(p.x, 0.0, 4 .0) == p.x && clamp(p.y, 0.0, 4 .0) == p.y) {
73+ if(clamp(p.x, 0.0, 6 .0) == p.x && clamp(p.y, 0.0, 6 .0) == p.y) {
7174 int a = int(round(p.x) + 5.0 * round(p.y));
7275 if(((n >> a) & 1) == 1) return 0.8;
7376 }
@@ -76,7 +79,7 @@ float character(int n, vec2 p) {
7679void main() {
7780 vec2 pix = gl_FragCoord.xy;
7881 // pixel size
79- float pixelSize = uResolution.x < 768.0 ? 12.0 : 16 .0;
82+ float pixelSize = uResolution.x < 768.0 ? 12.0 : 14 .0;
8083 vec3 col = texture(uTexture, floor(pix / pixelSize) * pixelSize / uResolution.xy).rgb;
8184 float gray = 0.3 * col.r + 0.59 * col.g + 0.11 * col.b;
8285 int n = 2048;
@@ -88,7 +91,7 @@ void main() {
8891 if(gray > 0.7) n = 13195790;
8992 if(gray > 0.8) n = 11512810;
9093 // char size
91- float charSize = uResolution.x < 768.0 ? 6.0 : 8 .0;
94+ float charSize = uResolution.x < 768.0 ? 6.0 : 4 .0;
9295 vec2 p = mod(pix / charSize, 2.0) - vec2(1.0);
9396 col = vec3(character(n, p));
9497 if (gray < 0.2) {
@@ -102,14 +105,38 @@ void main() {
102105 const renderer = new Renderer ( { antialias : true } ) ;
103106 const gl = renderer . gl ;
104107 containerRef . current ?. appendChild ( gl . canvas ) ;
105- const camera = new Camera ( gl , { near : 0.1 , far : 100 } ) ;
108+ const camera = new Camera ( gl , { near : 0.1 , far : 100 , fov : 10 } ) ;
106109 camera . position . set (
107- isMobile ( )
108- ? new Vec3 ( MOBILE_CAMERA_POSITION )
109- : new Vec3 ( DESKTOP_CAMERA_POSITION )
110+ isMobile ( ) ? MOBILE_CAMERA_POSITION : DESKTOP_CAMERA_POSITION
110111 ) ;
111112 camera . lookAt ( new Vec3 ( 0 , 0 , 0 ) ) ;
112113
114+ const scene = new Transform ( ) ;
115+
116+ let gltf : any ;
117+ async function loadModel ( ) {
118+ gltf = await GLTFLoader . load ( gl , "/logo.glb" ) ;
119+
120+ const s = gltf . scene || gltf . scenes [ 0 ] ;
121+ s . forEach ( ( root : any ) => {
122+ root . setParent ( scene ) ;
123+ root . traverse ( ( node : any ) => {
124+ if ( node . program ) {
125+ node . program = createProgram ( ) ;
126+ }
127+ } ) ;
128+ } ) ;
129+ }
130+
131+ function createProgram ( ) {
132+ return new Program ( gl , {
133+ vertex,
134+ fragment
135+ } ) ;
136+ }
137+
138+ loadModel ( ) ;
139+
113140 const updateSize = ( ) => {
114141 const height = isMobile ( ) ? MOBILE_HEIGHT : DESKTOP_HEIGHT ;
115142 renderer . setSize ( window . innerWidth - 32 , window . innerHeight - height ) ;
@@ -150,10 +177,9 @@ void main() {
150177 const asciiScene = new Transform ( ) ;
151178 asciiMesh . setParent ( asciiScene ) ;
152179
153- const MAX_TILT = 0.2 ;
180+ const MAX_TILT = 0.4 ;
154181 const LERP_FACTOR = 0.05 ;
155182
156- // Add hover and touch animation
157183 let targetRotationX = 0 ;
158184 let targetRotationY = 0 ;
159185 let targetRotationZ = 0 ;
@@ -173,7 +199,6 @@ void main() {
173199
174200 function onTouchStart ( e : TouchEvent ) {
175201 isDragging = true ;
176- // Prevent default touch behavior
177202 e . preventDefault ( ) ;
178203 }
179204
@@ -204,20 +229,25 @@ void main() {
204229 window . addEventListener ( "touchend" , onTouchEnd ) ;
205230
206231 function update ( time : number ) {
232+ // Animate model if it has animations
233+ if ( gltf ?. animations ?. length ) {
234+ const { animation } = gltf . animations [ 0 ] ;
235+ animation . elapsed += 0.01 ;
236+ animation . update ( ) ;
237+ }
238+
207239 const elapsedTime = time * 0.001 ;
208240 boxProgram . uniforms . uTime . value = elapsedTime ;
209241
210- // Smoothly interpolate current rotation towards target rotation
211242 currentRotationX += ( targetRotationX - currentRotationX ) * LERP_FACTOR ;
212243 currentRotationY += ( targetRotationY - currentRotationY ) * LERP_FACTOR ;
213244 currentRotationZ += ( targetRotationZ - currentRotationZ ) * LERP_FACTOR ;
214245
215- // Apply rotation to the box
216- boxMesh . rotation . x = currentRotationX ;
217- boxMesh . rotation . y = currentRotationY ;
218- boxMesh . rotation . z = currentRotationZ ;
246+ scene . rotation . x = currentRotationX ;
247+ scene . rotation . y = currentRotationY ;
248+ scene . rotation . z = currentRotationZ ;
219249
220- renderer . render ( { scene : boxScene , camera, target : renderTarget } ) ;
250+ renderer . render ( { scene, camera, target : renderTarget } ) ;
221251 asciiProgram . uniforms . uResolution . value = [
222252 gl . canvas . width ,
223253 gl . canvas . height
0 commit comments