Skip to content

Commit 5516431

Browse files
committed
Add logo model and enhance Hero component rendering
- Introduced a new 3D logo model (`logo.glb`) for the Hero component. - Updated camera positions for desktop and mobile views to improve scene rendering. - Refactored shader code to use GLSL template literals for better readability. - Enhanced animation handling for the logo model within the Hero component. - Adjusted character grid scale and pixel size for improved visual fidelity.
1 parent 1d45a81 commit 5516431

File tree

2 files changed

+53
-23
lines changed

2 files changed

+53
-23
lines changed

public/logo.glb

14.1 KB
Binary file not shown.

src/components/hero/index.tsx

Lines changed: 53 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
/* eslint-disable @typescript-eslint/no-explicit-any */
12
"use client";
23
import {
34
Box,
45
Camera,
6+
GLTFLoader,
57
Mesh,
68
Plane,
79
Program,
@@ -16,14 +18,15 @@ import { Overlay } from "../overlay";
1618
const DESKTOP_HEIGHT = 256;
1719
const 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

2225
export 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
2730
in vec3 position;
2831
in vec3 normal;
2932
in 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
4144
precision mediump float;
4245
uniform float uTime;
4346
in 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
5457
in vec2 uv;
5558
in vec2 position;
5659
out vec2 vUv;
5760
void 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
6265
precision highp float;
6366
uniform vec2 uResolution;
6467
uniform sampler2D uTexture;
6568
out vec4 fragColor;
6669
float 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) {
7679
void 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

Comments
 (0)