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:
@@ -193,8 +193,8 @@ function VrmModel({ url, audioLevel, emotion, status, cursor, pat, dance, onErro
|
|||||||
const cur = cursor?.current
|
const cur = cursor?.current
|
||||||
if (cur) {
|
if (cur) {
|
||||||
const hx = Math.max(-1, Math.min(1, cur.x)), hy = Math.max(-1, Math.min(1, cur.y))
|
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, "neck", -hy * 0.06, hx * 0.10, 0)
|
||||||
addBone(vrm, "head", hy * 0.08, hx * 0.14, 0)
|
addBone(vrm, "head", -hy * 0.08, hx * 0.14, 0)
|
||||||
}
|
}
|
||||||
// Antippen/Streicheln: kurze freudige Reaktion (Kopf-Wackeln; Laecheln in der Mimik unten)
|
// 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 }
|
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()
|
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))
|
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(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
|
// dezente Blick-Mikrobewegung (Sakkaden) -> das Gesicht wirkt nicht eingefroren
|
||||||
const s = sac.current
|
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
|
const statusRef = useRef(status); statusRef.current = status
|
||||||
return (
|
return (
|
||||||
<div className="avatarCanvas" style={{ position: "relative", height: "100%", width: "100%" }}>
|
<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} />
|
<ambientLight intensity={0.85} />
|
||||||
<directionalLight position={[1, 2, 2]} intensity={1.1} />
|
<directionalLight position={[1, 2, 2]} intensity={1.1} />
|
||||||
<directionalLight position={[-1, 1, -1]} intensity={0.4} />
|
<directionalLight position={[-1, 1, -1]} intensity={0.4} />
|
||||||
|
|||||||
@@ -57,12 +57,12 @@ body {
|
|||||||
linear-gradient(180deg, #0b0b15 0%, #07070d 100%);
|
linear-gradient(180deg, #0b0b15 0%, #07070d 100%);
|
||||||
box-shadow: inset 0 0 130px 36px rgba(0,0,0,0.55); /* Vignette -> Tiefe */
|
box-shadow: inset 0 0 130px 36px rgba(0,0,0,0.55); /* Vignette -> Tiefe */
|
||||||
}
|
}
|
||||||
.digitalRoom::before { /* sanft driftendes Aurora-Licht */
|
.digitalRoom::before { /* sanft driftendes Aurora-Licht (KEIN filter:blur -> Verlaeufe sind weich genug, spart GPU) */
|
||||||
content: ""; position: absolute; inset: -20%; z-index: 0;
|
content: ""; position: absolute; inset: -20%; z-index: 0; will-change: transform;
|
||||||
background:
|
background:
|
||||||
radial-gradient(40% 40% at 30% 32%, rgba(125,211,252,0.12), transparent 70%),
|
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%);
|
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 */
|
.digitalRoom::after { /* perspektivisches Neon-Gitter am Boden */
|
||||||
content: ""; position: absolute; left: -25%; right: -25%; bottom: -12%; height: 58%;
|
content: ""; position: absolute; left: -25%; right: -25%; bottom: -12%; height: 58%;
|
||||||
@@ -73,21 +73,15 @@ body {
|
|||||||
-webkit-mask-image: linear-gradient(transparent, #000 65%);
|
-webkit-mask-image: linear-gradient(transparent, #000 65%);
|
||||||
animation: gridDrift 14s linear infinite;
|
animation: gridDrift 14s linear infinite;
|
||||||
}
|
}
|
||||||
/* schwebende Partikel (zwei Ebenen -> Parallax-Tiefe), nahtlos gekachelt */
|
/* schwebende Partikel (eine Ebene, nahtlos gekachelt) -> dezente Tiefe, guenstig */
|
||||||
.dust {
|
.dust {
|
||||||
position: absolute; inset: 0; z-index: 0; pointer-events: none; opacity: 0.7;
|
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.55), transparent 60%);
|
background-image: radial-gradient(1.6px 1.6px at 50% 50%, rgba(125,211,252,0.5), transparent 60%);
|
||||||
background-size: 96px 96px; animation: dustRise 24s linear infinite;
|
background-size: 110px 110px; animation: dustRise 30s 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;
|
|
||||||
}
|
}
|
||||||
@keyframes gridDrift { to { background-position: 0 46px, 46px 0; } }
|
@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 auroraDrift { from { transform: translate(-3%, -2%) scale(1); } to { transform: translate(4%, 3%) scale(1.08); } }
|
||||||
@keyframes dustRise { to { background-position: 0 -96px; } }
|
@keyframes dustRise { to { background-position: 0 -110px; } }
|
||||||
@keyframes dustRise2 { to { background-position: 0 -140px; } }
|
|
||||||
.app.overlay .digitalRoom { display: none; } /* Overlay floatet -> nur Avatar + Aura */
|
.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; }
|
.aura { position: absolute; inset: 0; z-index: 1; pointer-events: none; will-change: transform, opacity; }
|
||||||
|
|||||||
Reference in New Issue
Block a user