음성 재생과 운영 배포 정리
This commit is contained in:
parent
8ed185ce6c
commit
ac7db95542
1020 changed files with 46863 additions and 2175 deletions
|
|
@ -35,7 +35,14 @@ const VARIANT_FOR_EXPRESSION: Record<AvatarExpression, RasterVariant> = {
|
|||
};
|
||||
|
||||
const LIVE2D_PARTS_ART_SETS = new Set(["seoyeon-live2d-v3"]);
|
||||
const PSB_GROUP_ART_SETS = new Set(["seoyeon-live2d-psb"]);
|
||||
const PERSONA_GENERATED_ART_SETS = [
|
||||
"p4-live2d-generated",
|
||||
"p5-live2d-generated",
|
||||
"p6-live2d-generated",
|
||||
"p7-live2d-generated",
|
||||
];
|
||||
const PSB_GROUP_ART_SETS = new Set(["seoyeon-live2d-psb", "seoyeon-live2d-psd-v2", ...PERSONA_GENERATED_ART_SETS]);
|
||||
const PSB_CRYING_ART_SETS = new Set(["seoyeon-live2d-psd-v2", ...PERSONA_GENERATED_ART_SETS]);
|
||||
|
||||
export function rasterVariantFor(expression: AvatarExpression): RasterVariant {
|
||||
return VARIANT_FOR_EXPRESSION[expression];
|
||||
|
|
@ -100,6 +107,13 @@ function mouthForVariant(variant: RasterVariant): string {
|
|||
return "mouth-neutral";
|
||||
}
|
||||
|
||||
function blushOpacity(artSet: string, variant: RasterVariant): number {
|
||||
if (artSet === "seoyeon-live2d-psd-v2") {
|
||||
return variant === "warm" ? 0.62 : 0.34;
|
||||
}
|
||||
return variant === "warm" ? 1 : 0.72;
|
||||
}
|
||||
|
||||
function browPoseForVariant(variant: RasterVariant): { y: number; leftRotate: number; rightRotate: number } {
|
||||
switch (variant) {
|
||||
case "sad":
|
||||
|
|
@ -255,6 +269,7 @@ export function RasterBust({
|
|||
|
||||
if (PSB_GROUP_ART_SETS.has(artSet)) {
|
||||
const part = (name: string) => `${import.meta.env.BASE_URL}avatar/${artSet}/parts/${name}.png`;
|
||||
const cryingArtSet = PSB_CRYING_ART_SETS.has(artSet);
|
||||
const speakingOpen = speaking ? clamp01(Math.max(mouth, 0.1)) : 0;
|
||||
const wideOpen = clamp01((speakingOpen - 0.34) / 0.5);
|
||||
const smallOpen = speakingOpen > 0 ? 1 - wideOpen : 0;
|
||||
|
|
@ -275,6 +290,10 @@ export function RasterBust({
|
|||
const lowerLidY = eyePose.lowerY - closedEyes * 2.4;
|
||||
const lashY = eyePose.lashY + closedEyes * 2.1;
|
||||
const expressionMouth = psbMouthForVariant(variant);
|
||||
const useSadCryingParts = cryingArtSet && variant === "sad";
|
||||
const browLeftPart = useSadCryingParts ? "brow-sad-left" : "brow-left";
|
||||
const browRightPart = useSadCryingParts ? "brow-sad-right" : "brow-right";
|
||||
const tearOpacity = useSadCryingParts ? clamp01(0.82 + openEyes * 0.18 - closedEyes * 0.35) : 0;
|
||||
const eyeDetailLayers: Array<{ name: string; mask: string; zIndex: number }> = [
|
||||
{ name: "iris-left", mask: "eye-white-left", zIndex: 9 },
|
||||
{ name: "iris-right", mask: "eye-white-right", zIndex: 9 },
|
||||
|
|
@ -329,8 +348,8 @@ export function RasterBust({
|
|||
{renderLayer("ear-left", "vg-raster__layer--ear", 5)}
|
||||
{renderLayer("ear-right", "vg-raster__layer--ear", 5)}
|
||||
{renderLayer("face-base", "vg-raster__layer--face", 6)}
|
||||
{renderLayer("blush-left", "vg-raster__layer--face", 7, { opacity: variant === "warm" ? 1 : 0.72 })}
|
||||
{renderLayer("blush-right", "vg-raster__layer--face", 7, { opacity: variant === "warm" ? 1 : 0.72 })}
|
||||
{renderLayer("blush-left", "vg-raster__layer--face", 7, { opacity: blushOpacity(artSet, variant) })}
|
||||
{renderLayer("blush-right", "vg-raster__layer--face", 7, { opacity: blushOpacity(artSet, variant) })}
|
||||
{generatedEyeVariant ? (
|
||||
<>
|
||||
{renderLayer(`eyegen-${generatedEyeVariant}-eye-left`, "vg-raster__layer--eyes", 8, {
|
||||
|
|
@ -419,13 +438,13 @@ export function RasterBust({
|
|||
transform: layerTransform(`translateY(${lowerLidY.toFixed(2)}px)`),
|
||||
transformOrigin: "60.8% 32.4%",
|
||||
})}
|
||||
{renderLayer("brow-left", "vg-raster__layer--brow", 14, {
|
||||
{renderLayer(browLeftPart, "vg-raster__layer--brow", 14, {
|
||||
transform: layerTransform(
|
||||
`translateY(${(brow.y + browFloat - talkBounce * 0.28).toFixed(2)}px) rotate(${(brow.leftRotate - speakingOpen * 0.35 - browFloat * 0.08).toFixed(2)}deg)`,
|
||||
),
|
||||
transformOrigin: "40% 27%",
|
||||
})}
|
||||
{renderLayer("brow-right", "vg-raster__layer--brow", 14, {
|
||||
{renderLayer(browRightPart, "vg-raster__layer--brow", 14, {
|
||||
transform: layerTransform(
|
||||
`translateY(${(brow.y + browFloat - talkBounce * 0.28).toFixed(2)}px) rotate(${(brow.rightRotate + speakingOpen * 0.35 + browFloat * 0.08).toFixed(2)}deg)`,
|
||||
),
|
||||
|
|
@ -433,6 +452,20 @@ export function RasterBust({
|
|||
})}
|
||||
</>
|
||||
)}
|
||||
{cryingArtSet ? (
|
||||
<>
|
||||
{renderLayer("tear-left", "vg-raster__layer--tear", 15, {
|
||||
opacity: tearOpacity,
|
||||
filter: "drop-shadow(0 0 1.5px rgba(112, 166, 218, 0.72)) brightness(1.18) saturate(1.18)",
|
||||
transform: layerTransform(`translateY(${(closedEyes * 1.4 + breath * 0.08).toFixed(2)}px)`),
|
||||
})}
|
||||
{renderLayer("tear-right", "vg-raster__layer--tear", 15, {
|
||||
opacity: tearOpacity,
|
||||
filter: "drop-shadow(0 0 1.5px rgba(112, 166, 218, 0.72)) brightness(1.18) saturate(1.18)",
|
||||
transform: layerTransform(`translateY(${(closedEyes * 1.4 + breath * 0.08).toFixed(2)}px)`),
|
||||
})}
|
||||
</>
|
||||
) : null}
|
||||
{renderLayer("nose", "vg-raster__layer--nose", 15)}
|
||||
{renderLayer("hair-side-left-1", "vg-raster__layer--hair", 16, {
|
||||
transform: layerTransform(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue