Lucy v2: Blick-Vertikale korrigiert + Performance entschaerft

- Mauszeiger-Verfolgung: Hoch/Runter war invertiert -> Vorzeichen fuer Augen + Kopf/Nacken gedreht
- Performance: animierten filter:blur (Aurora) entfernt, dpr auf [1,1.5] gedeckelt,
  Partikel auf eine Ebene reduziert (Ruckeln gemeldet)
- (visuelle Abnahme durch User steht noch aus)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Hitonabi
2026-06-30 21:34:37 +02:00
parent 38f8c96b66
commit 3c0a24feb7
2 changed files with 13 additions and 18 deletions
@@ -193,8 +193,8 @@ function VrmModel({ url, audioLevel, emotion, status, cursor, pat, dance, onErro
const cur = cursor?.current
if (cur) {
const hx = Math.max(-1, Math.min(1, cur.x)), hy = Math.max(-1, Math.min(1, cur.y))
addBone(vrm, "neck", hy * 0.06, hx * 0.10, 0)
addBone(vrm, "head", hy * 0.08, hx * 0.14, 0)
addBone(vrm, "neck", -hy * 0.06, hx * 0.10, 0)
addBone(vrm, "head", -hy * 0.08, hx * 0.14, 0)
}
// Antippen/Streicheln: kurze freudige Reaktion (Kopf-Wackeln; Laecheln in der Mimik unten)
if (pat && pat.current !== lastPat.current) { lastPat.current = pat.current; patReact.current = 1 }
@@ -229,7 +229,7 @@ function VrmModel({ url, audioLevel, emotion, status, cursor, pat, dance, onErro
camUp.current.set(e[4], e[5], e[6]).normalize()
const cx = Math.max(-1.5, Math.min(1.5, cur.x)), cy = Math.max(-1.5, Math.min(1.5, cur.y))
gaze.current.position.addScaledVector(camRight.current, cx * 1.8)
gaze.current.position.addScaledVector(camUp.current, -cy * 1.8)
gaze.current.position.addScaledVector(camUp.current, cy * 1.8)
}
// dezente Blick-Mikrobewegung (Sakkaden) -> das Gesicht wirkt nicht eingefroren
const s = sac.current
@@ -289,7 +289,8 @@ export function Avatar3D({ url, audioLevel, emotion, status = "idle", cursor, pa
const statusRef = useRef(status); statusRef.current = status
return (
<div className="avatarCanvas" style={{ position: "relative", height: "100%", width: "100%" }}>
<Canvas camera={{ position: [0, 1.35, 1.25], fov: 30 }} gl={{ alpha: true, antialias: true }} style={{ background: "transparent" }}>
<Canvas camera={{ position: [0, 1.35, 1.25], fov: 30 }} dpr={[1, 1.5]}
gl={{ alpha: true, antialias: true, powerPreference: "high-performance" }} style={{ background: "transparent" }}>
<ambientLight intensity={0.85} />
<directionalLight position={[1, 2, 2]} intensity={1.1} />
<directionalLight position={[-1, 1, -1]} intensity={0.4} />
@@ -57,12 +57,12 @@ body {
linear-gradient(180deg, #0b0b15 0%, #07070d 100%);
box-shadow: inset 0 0 130px 36px rgba(0,0,0,0.55); /* Vignette -> Tiefe */
}
.digitalRoom::before { /* sanft driftendes Aurora-Licht */
content: ""; position: absolute; inset: -20%; z-index: 0;
.digitalRoom::before { /* sanft driftendes Aurora-Licht (KEIN filter:blur -> Verlaeufe sind weich genug, spart GPU) */
content: ""; position: absolute; inset: -20%; z-index: 0; will-change: transform;
background:
radial-gradient(40% 40% at 30% 32%, rgba(125,211,252,0.12), transparent 70%),
radial-gradient(45% 45% at 74% 42%, rgba(167,139,250,0.12), transparent 70%);
filter: blur(22px); animation: auroraDrift 22s ease-in-out infinite alternate;
animation: auroraDrift 26s ease-in-out infinite alternate;
}
.digitalRoom::after { /* perspektivisches Neon-Gitter am Boden */
content: ""; position: absolute; left: -25%; right: -25%; bottom: -12%; height: 58%;
@@ -73,21 +73,15 @@ body {
-webkit-mask-image: linear-gradient(transparent, #000 65%);
animation: gridDrift 14s linear infinite;
}
/* schwebende Partikel (zwei Ebenen -> Parallax-Tiefe), nahtlos gekachelt */
/* schwebende Partikel (eine Ebene, nahtlos gekachelt) -> dezente Tiefe, guenstig */
.dust {
position: absolute; inset: 0; z-index: 0; pointer-events: none; opacity: 0.7;
background-image: radial-gradient(1.6px 1.6px at 50% 50%, rgba(125,211,252,0.55), transparent 60%);
background-size: 96px 96px; animation: dustRise 24s linear infinite;
}
.dust::after {
content: ""; position: absolute; inset: 0;
background-image: radial-gradient(1.3px 1.3px at 30% 70%, rgba(167,139,250,0.5), transparent 60%);
background-size: 140px 140px; animation: dustRise2 38s linear infinite;
position: absolute; inset: 0; z-index: 0; pointer-events: none; opacity: 0.6;
background-image: radial-gradient(1.6px 1.6px at 50% 50%, rgba(125,211,252,0.5), transparent 60%);
background-size: 110px 110px; animation: dustRise 30s linear infinite;
}
@keyframes gridDrift { to { background-position: 0 46px, 46px 0; } }
@keyframes auroraDrift { from { transform: translate(-3%, -2%) scale(1); } to { transform: translate(4%, 3%) scale(1.08); } }
@keyframes dustRise { to { background-position: 0 -96px; } }
@keyframes dustRise2 { to { background-position: 0 -140px; } }
@keyframes dustRise { to { background-position: 0 -110px; } }
.app.overlay .digitalRoom { display: none; } /* Overlay floatet -> nur Avatar + Aura */
.aura { position: absolute; inset: 0; z-index: 1; pointer-events: none; will-change: transform, opacity; }