Files
Genarrative/server-rs/crates/api-server/src/prompt/character_visual.rs
2026-04-28 19:36:39 +08:00

97 lines
4.7 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/// 自定义世界角色主图提示词脚本。
pub(crate) fn build_character_visual_prompt(prompt_text: &str) -> String {
build_master_prompt(prompt_text.trim())
}
/// 角色主图被供应商内容审核拦截时使用的安全兜底提示词。
///
/// 这里刻意不继续携带角色姓名、作品名和长设定文本,避免把可疑专名原样送回上游导致连续失败。
pub(crate) fn build_fallback_moderation_safe_character_visual_prompt(prompt_text: &str) -> String {
let archetype = resolve_original_role_archetype(prompt_text);
build_master_prompt(
[
format!("角色定位:{}", archetype),
"原创奇幻冒险角色,成年类人骨架,站姿稳定,表情中性,服装为无品牌旅行装、轻甲或职业装备的原创组合。".to_string(),
"不参考任何现有动漫、游戏、影视、小说角色,不使用可识别 IP 元素、商标、队徽、作品名、角色名或知名角色标志性发型服装。".to_string(),
"所有图案、配色、武器、饰品都采用原创通用设计,只保留横版像素动作角色所需的清晰轮廓和可读职业特征。".to_string(),
]
.join("\n")
.as_str(),
)
}
fn resolve_original_role_archetype(source: &str) -> &'static str {
if source.contains("法师") || source.contains("魔法") || source.contains("术士") {
return "原创法术职业冒险者";
}
if source.contains("骑士") || source.contains("守卫") || source.contains("圣骑") {
return "原创重装守护者";
}
if source.contains("") || source.contains("猎人") || source.contains("游侠") {
return "原创远程游侠";
}
if source.contains("刺客") || source.contains("盗贼") || source.contains("潜行") {
return "原创敏捷潜行者";
}
if source.contains("") || source.contains("战士") || source.contains("武士") {
return "原创近战剑士";
}
if source.contains("祭司") || source.contains("牧师") || source.contains("治疗") {
return "原创支援祭司";
}
"原创冒险者"
}
/// 角色主图统一提示词骨架,迁移自旧共享 qwenSprite 主链。
fn build_master_prompt(character_brief: &str) -> String {
[
"单人2D像素角色形象头身比必须控制在1.5头身,主体完整可见,底部轮廓完整,身体比例稳定,轮廓清楚,适合后续制作 sprite sheet 动画。".to_string(),
"视角要求:角色采用横版动作素材常用的右向斜侧身站姿,身体整体朝右,但保留少量正面信息,能读到面部轮廓与胸肩结构,不是完全 90 度纯右视图,也不是正面立绘。".to_string(),
"主体要求:画面中只保留单个角色主体,不要额外人物、动物、召唤物、载具或陪体。".to_string(),
"画面要求1:1 正方形画布,画面中心构图,角色主体完整置于画面中央,不要裁切主体顶部和底部,不要镜头透视,不要特写。背景固定为纯绿色绿幕,只作为抠像底色,不出现建筑、室内布景、风景、地面道具、漂浮物、烟雾叙事元素、文字或其他角色以外的场景内容。".to_string(),
"风格要求:横版像素角色,细节精致,设计感足。使用深色清楚轮廓、稳定剪影、有限大色块和硬朗边缘,不要柔和厚涂插画感,发型、服装、配饰优先形成醒目可读的像素级识别点。".to_string(),
"如果角色形象设定没有明确要求非人身体结构,默认优先使用人类或类人动作角色骨架。\
默认将角色形象设定作用在角色自身的服装剪裁、材质、纹样、饰品、发光细节上。".to_string(),
"角色形象设定:".to_string(),
character_brief.trim().to_string(),
]
.into_iter()
.filter(|value| !value.trim().is_empty())
.collect::<Vec<_>>()
.join("\n")
}
/// 自定义世界角色主图负面提示词脚本。
pub(crate) fn build_character_visual_negative_prompt() -> String {
[
"正面视角",
"左朝向",
"完全 90 度纯右视图",
"镜头透视",
"半身像",
"脚被裁切",
"头顶被裁切",
"多角色",
"复杂背景",
"建筑场景",
"漂浮物",
"烟雾环境",
"武器消失",
"武器换手",
"额外手臂",
"额外腿",
"服装变化",
"脸部变化",
"模糊",
"运动模糊",
"文字",
"水印",
"UI 元素",
"厚涂插画感",
"低对比柔边",
]
.join("")
}