尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证AT-LP120XUSB turntable rendered with vgpu (WebGPU) in Next.js
翻译准备中
取自仓库 README
正在加载完整 README。 以下为已保存的摘录。
Visor 3D en tiempo real de una bandeja giradisco profesional (Audio-Technica AT-LP120XUSB, acabado negro) construido con Next.js 16 y vgpu, la librería WebGPU de Vercel Labs. Todo el render corre en WebGPU a través de la API de vgpu (draw, effect, target, frameLoop, uniforms, módulos WGSL con import/export), sin three.js.查看完整 README ↗
Visor 3D en tiempo real de una bandeja giradisco profesional (Audio-Technica
AT-LP120XUSB, acabado negro) construido con Next.js 16 y vgpu,
la librería WebGPU de Vercel Labs. Todo el render corre en WebGPU a través de la API
de vgpu (draw, effect, target, frameLoop, uniforms, módulos WGSL con
import/export), sin three.js.
lib/gltf/glb.ts, sin dependencias).orbitControls) con auto‑rotación, plato girando a 33⅓ rpm,
y un acabado "Negro" que recolorea el dorado del modelo original a negro satinado.pnpm install
pnpm dev
# http://localhost:3000 -> bandeja giradisco
# http://localhost:3000/?model=helmet -> Damaged Helmet (Khronos), prueba de pipeline
Requiere un navegador con WebGPU (Chrome/Edge 113+, Safari 26+).
Los .glb viven en public/models/ y están fuera de git por tamaño.
| id | archivo | fuente |
|---|---|---|
turntable | public/models/turntable.glb | Pioneer PLX‑1000 Turntable Ltd. (Remastered) · Mateusz Kołakowski · CC BY 4.0 |
helmet | public/models/DamagedHelmet.glb | Khronos glTF Sample Assets · CC BY‑NC 4.0 |
No existe un modelo libre del AT‑LP120XUSB; el PLX‑1000 comparte la misma
arquitectura (clon del Technics SL‑1200: brazo en S, plato con puntos de estrobo,
pitch fader) y el acabado "Negro" lo acerca al AT‑LP120X negro. Para usar otro GLB,
añade una entrada en lib/models.ts.
app/ layout + página (Server Component) que monta el visor
components/ TurntableViewer.tsx (client) + HUD
lib/gltf/glb.ts parser GLB -> buffers intercalados, materiales, instancias
lib/render/engine.ts ciclo de render vgpu: sombra -> PBR HDR -> bloom -> post
lib/render/environment.ts horneado IBL (entorno, prefiltro GGX, irradiancia, LUT)
lib/render/textures.ts subida de imágenes + mipmaps, blit, samplers glTF
lib/render/shaders/*.wgsl módulos WGSL (common, pbr, shadow, env, prefilter, ...)
Atajos: arrastrar orbita, rueda acerca, R reinicia la cámara, H oculta la UI.
lib/models.ts describe la escena además del GLB principal:
attachments: el disco (public/models/vinyl.glb) se recoloca sobre el plato
detectado geométricamente (mallas finas de huella casi cuadrada), se escala a su
diámetro real (fitDiameter: 0.3 m) y gira con él a 33⅓ rpm. Los GLB de Sketchfab
traen una inclinación de presentación en el nodo raíz; ignoreNodeTransforms usa el
espacio de malla en bruto y upAxis lo endereza.tonearm: lista de mallas que forman el brazo (tubo, headshell, cápsula, cables,
contrapeso). El visor lo gira sobre su eje hasta que la púa queda a playRadius
(146 mm, surco de entrada) y lo inclina hasta apoyarla en la superficie del disco.
La geometría de la púa es la original del modelo, sin simplificar.Los console.info [viewer] resumen tiempos de carga y el ángulo aplicado al brazo.
playbackRate del audio; el HUD muestra % y rpm.public/audio/track.m4a + public/audio/cover.jpg (carátula pintada en la
etiqueta del disco). Ambos están fuera de git y del deploy público: son material con
derechos, descargado para uso local con yt-dlp desde el enlace indicado en
lib/models.ts. Sin ellos el visor funciona igual (sin sonido y con la etiqueta original). El sonido se
activa con el botón "Activar sonido" (política de autoplay) y solo suena con la púa
apoyada; el espectro del HUD sale de un AnalyserNode.El picking usa las cajas envolventes de cada malla (rayo desde la cámara) con prioridad para las piezas interactivas; el arrastre del pitch captura el puntero y no orbita la cámara.
La página usa siempre la vista "mesa" (añade ?layout=studio para el set oscuro con
cámara orbital y panel de controles): fondo blanco, cámara fija
picada (~54°) ajustada al ancho, sombra suave (PCF ancho) compuesta en post sobre el blanco,
y debajo solo la carátula y el título. No hay botones: el primer toque activa el audio y los
gestos sobre la escena (brazo, START/STOP, pitch) siguen activos. La cámara se mueve con un
dedo sobre la mesa (fuera de la bandeja) o con dos dedos (pinza = zoom, giro = yaw).
El reposabrazos se oculta mientras el brazo está sobre el disco, y los LED azules solo se
encienden con el motor en marcha.
START/STOP, 33, 45 y QUARTZ son cajas en el espacio de la escena (controls.buttons en
lib/models.ts). Al tocarlas su LED parpadea un instante (feedback de pulsación, sin deformar
geometría) y luego sigue el estado: 33/45 seleccionan la velocidad
nominal del plato (el audio sube a 45 rpm como en un disco real), QUARTZ bloquea el pitch
a 0 % (LED encendido) hasta volver a pulsarlo. El brazo avanza hacia el centro al ritmo del
plato como en una cara real (~20 min de surco).
En teléfonos (puntero táctil) el visor carga turntable.mobile.glb y vinyl.mobile.glb:
piezas pequeñas decimadas (≤10k triángulos por malla, scripts/build-mobile-assets.mjs),
placas intactas, texturas a 1k (WebP en la bandeja, PNG en el disco) y vértices cuantizados
(KHR_mesh_quantization). Además baja el DPR a 1.25, usa shadow map 1024 con 8 taps, omite el
bloom y limita a 60 fps. Fuerza un modo con ?quality=mobile o ?quality=high.
node scripts/build-mobile-assets.mjs public/models/turntable.glb /tmp/t3.glb 10000
npx @gltf-transform/cli@4 resize /tmp/t3.glb /tmp/t4.glb --width 1024 --height 1024
npx @gltf-transform/cli@4 webp /tmp/t4.glb /tmp/t5.glb --quality 90
npx @gltf-transform/cli@4 quantize /tmp/t5.glb public/models/turntable.mobile.glb --quantize-position 14 --quantize-normal 8 --quantize-texcoord 12
El motor mide los fps reales y sube o baja por una escalera de calidad (escala de render del
target HDR 0.5→1.0 con reescalado en post, taps de sombra 4/8/16, bloom on/off). Baja un
escalón si cae de 30 fps y sube si supera 54 fps con margen; un nivel que falló no se
reintenta durante 20 s. El escritorio arranca arriba del todo; el móvil en el nivel medio y
sube hasta 2× de DPR si el teléfono lo aguanta. La consola registra cada cambio ([viewer] quality level).
La web pública no incluye el audio ni la carátula (material con derechos). Para uso personal
existe un segundo proyecto de Vercel, saturday-night-private, desplegado directamente desde
la carpeta local (incluye public/audio/, ver .vercelignore) y protegido con contraseña
mediante proxy.ts (HTTP Basic, variable SITE_PASSWORD). Para actualizarlo:
vercel link --yes --project saturday-night-private && vercel --prod && vercel link --yes --project saturday-night