Doop
Doop: 오픈소스 멀티플레이어 디자인 캔버스 및 AI 에이전트용 MCP
Audio-Technica AT-LP120XUSB 프로페셔널 턴테이블을 WebGPU와 vgpu로 실시간 렌더링
Audio-Technica AT-LP120XUSB professional turntable rendered in real time with WebGPU via vgpu: PBR, studio lighting, soft shadows and bloom.
디자인TypeScript · WGSLGitHub @arvenz0210온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기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