Fix V-face deformation with lower-jaw landmark pins; pass regression
这个提交包含在:
1 父节点
58f09e5756
当前提交
7fa3298e02
19 个文件已更改
+566
-36
没有与搜索条件相匹配的文件
@@ -0,0 +1,42 @@
|
||||
# V 脸下颌区域修复
|
||||
|
||||
2026-10-22,针对用户报告「V 脸作用到眼睛,应作用于下颌」。目标为本机 MSE18V2 2.4.0(20260724150000),产品修复版本为 1.3.1(16)。
|
||||
|
||||
## 原因与修改
|
||||
|
||||
1.3.0 仍使用脸框上的宽范围高斯带及纵向位移近似 V 脸。它不依赖真实下颌轮廓,在真实人像上能测到眼区变化。不是面板标签或参数 ID 接错;本次只替换 V 脸几何场。
|
||||
|
||||
新版目标的 AIR 按 `69→39、65→35、70→26、64→34` 顺序执行四组局部逆向采样。起点都是下颌轮廓,锚点都是外唇。每步使用前一步更新后的 q:
|
||||
|
||||
```text
|
||||
r = length(anchor − origin)
|
||||
if r > 0.0001:
|
||||
weight = clamp(1 − length(q − origin) / r, 0, 1)
|
||||
q = clamp(q − (anchor − origin) × ratio × weight, 0, 1)
|
||||
```
|
||||
|
||||
CPU 函数 `0x10002fb74` 从参数 `+0x90` 读取 V 值,乘位于 `0x100085ea0` 的 double `0.065` 和公共强度,再转 float 写入 shape 结构的 `+8`。新版三个 shader helper 都没有旧版的 `280/尺寸` 增益;本项目 V 使用 `clamp(faceV,0,1)×0.065`,整体混合沿用现有产品链。公共强度各调用方的完整来源尚未追踪,不将整体混合宣称为原版该参数的等价重建。
|
||||
|
||||
生产实现复用局部 pin 核心,四步严格顺序更新,与图像/四张支持蒙版共享同一坐标场;完整 76 点缺失或不合法时安全直通。Core Image 坐标和关键点一起转换到 Y 向下的全图 UV,结束后一起转回,支持非零图像原点、横竖画幅和歪头。
|
||||
|
||||
## 静态证据与复现
|
||||
|
||||
原始 APP、metallib、完整 AIR 与用户帧仅留本机 build,不是构建依赖。源码没有嵌入目标二进制、私有模型或授权逻辑。
|
||||
|
||||
- 原 APP 嵌套 Mach-O(fat)SHA-256:`577303e0de72e07feb576c882e82382b3f056b023a7e987d990ffb37f6b16109`。
|
||||
- arm64 切片 SHA-256:`afc71d0d21fd3c1ca95ca745ddafcd729e36ad95f17d8638009f2e45d9b7e8df`。
|
||||
- metallib SHA-256:`856849c45cea2c8f083eeba06a9e318c450f4a56694b438d1a5ba8ef752a0ee0`。
|
||||
- `xcrun metal-objdump --metallib --disassemble` 输出 SHA-256:`1d5bd8d5a3917afbb3b4fe1c40b44480760614102685ac826e84ad2e30a450f9`;V 分支 3364–3431 行,四组点索引在 3374、3376、3378、3380 行。
|
||||
- 精简 AIR 摘录:[vface-air.txt](vface-air.txt);CPU 字段/系数与分析条件:[vface-findings.json](vface-findings.json);REA CPU 汇编和常量证据:[rea-vface-evidence.json](rea-vface-evidence.json)。REA 操作为只读,未运行原 APP 或原 shader。
|
||||
|
||||
## 验证
|
||||
|
||||
修改前隔离 V 测试复现:NASA 人像瞳孔 6 的位移约 0.031493 像素;宿主物理行序测试四种原点组合的 V 输出与独立 upright 参考均不符。原宿主输出两眼区像素变化量分别为 12824、19304,下颌为 195206。
|
||||
|
||||
修改后瞳孔检查通过;宿主四种原点组合的 V 眼区像素变化量均为 0,下颌为 39246,独立 upright 对照最大差 1/255、均差 0.000124/255。数值场覆盖 4 种画幅、正侧脸和歪头、半强度、小脸不带旧增益、顺序组合、缺点/坏点以及四张蒙版同步。独立的真实解剖位置检查要求下颌有位移且两瞳孔位移小于 0.002 像素,避免只用复制实现的数值公式验收。
|
||||
|
||||
完整自动回归:1901 项通过(57 Beauty、116 Face、1033 几何、370 Host ASan、98 OSC ASan、227 Inspector ASan)。真实用户帧专项另记交付验证;与基础用例重叠,不相加。正式安装和原生宿主 V 脸视觉验收状态见 [验证记录](../验证记录.md)。
|
||||
|
||||
## 范围
|
||||
|
||||
V 脸现在加入已恢复的五项局部控制。瘦脸、下巴、短脸、下颌骨沿用此前版本的尺寸增益;未将新版目标的其他差异混入本次修复。大眼、窄脸、颧骨和小头仍为近似,整条混合控制链的数学、顺序和最终像素尚未全部对齐。静态重建、离屏/接口检查不等于原版 shader 的运行时逐像素比较,也不等于 Motion/FCP 原生视觉验收。
|
||||
@@ -0,0 +1 @@
|
||||
{"artifacts":[{"architecture":"arm64","digest":{"sha256":"afc71d0d21fd3c1ca95ca745ddafcd729e36ad95f17d8638009f2e45d9b7e8df"},"format":"mach-o"}],"captures":[],"environments":[],"providers":[{"id":"ghidra","name":"Ghidra","version":"12.1.4"}],"records":[{"analysis_profile":{"digest":"20565088524a2d0359b9b96f46ac48e679d774c7b0092c56abc06de8fdbec11c","parameters":{"analyzer_preset":"ghidra-default","annotation_policy":"atomic-function-entry-metadata-v1","architecture":"arm64","available_architectures":["arm64"],"compiler_spec_id":"auto-default","decompiler_jump_loads":true,"function_body_evidence":"complete-inclusive-ranges-v1","function_boundary_observations":"ghidra-terminal-call-limitations-v1","function_references":"complete-body-and-entry-reference-manager-v2","import_mode":"ephemeral-source-immutable","instruction_flow_evidence":"decoded-return-pcode-v1","jump_table_evidence":"typed-case-default-blocks-v1","language_id":"auto-from-header","load_image_observations":"source-mappings-entry-context-v2","loader":"auto-from-header","location_resolution":"explicit-address-exact-entry-symbol-first-v3","no_return_repair":"returning-imports-decoded-return-v2","process_launch":"inspected-jvm-launch-support-v1","string_inventory_evidence":"defined-data-coverage-v1","target_format":"mach-o","target_kind":"executable"},"provider":{"id":"ghidra","name":"Ghidra","version":"12.1.4"}},"authority":"shipped-artifact","confidence":"observed","environment":null,"evidence_id":"ev_32b6ee46d4fb5eab563883ba73e35a458d5da21229b8977fddcb4df656517152","evidence_links":[],"limitations":["The session serves operations only after Ghidra reports default auto-analysis complete; incomplete analysis does not expose partial results.","The imported Program and temporary project are ephemeral and deleted on close. Annotation operations edit session database metadata; original executable bytes are never written.","Cancelling an active Ghidra request terminates its ephemeral database and discards session annotations. The selected target remains open; the next provider query imports the original artifact again.","Default-space addresses use lowercase 0x-prefixed hexadecimal; other address spaces use <percent-encoded-space>:0x<hex>.","Bytes reflect Ghidra's initialized memory, including loader fixups. Reads stop at an unmapped or uninitialized byte and report completeness explicitly.","macOS sessions require a matching executable Ghidra native decompiler; REA checks for it but does not build native components or change Gatekeeper quarantine state."],"locations":[],"normalized_result":{"address":"0x100085ea0","bytes_hex":"a4703d0ad7a3b03f9a9999999999a93f","complete":true,"requested_bytes":16,"returned_bytes":16},"operation":"read_bytes","parameters":{"address":"0x100085ea0","length":16},"predicate_type":"rea.analysis","provider":{"id":"ghidra","name":"Ghidra","version":"12.1.4"},"raw_result":{"address":"0x100085ea0","bytes_hex":"a4703d0ad7a3b03f9a9999999999a93f","complete":true,"requested_bytes":16,"returned_bytes":16},"subject":{"architecture":"arm64","digest":{"sha256":"afc71d0d21fd3c1ca95ca745ddafcd729e36ad95f17d8638009f2e45d9b7e8df"},"format":"mach-o","local_path":"/Users/dayu/Documents/PaintFCP/build/body-analysis/MSE18V2-arm64","name":"MSE18V2-arm64"}},{"analysis_profile":{"digest":"20565088524a2d0359b9b96f46ac48e679d774c7b0092c56abc06de8fdbec11c","parameters":{"analyzer_preset":"ghidra-default","annotation_policy":"atomic-function-entry-metadata-v1","architecture":"arm64","available_architectures":["arm64"],"compiler_spec_id":"auto-default","decompiler_jump_loads":true,"function_body_evidence":"complete-inclusive-ranges-v1","function_boundary_observations":"ghidra-terminal-call-limitations-v1","function_references":"complete-body-and-entry-reference-manager-v2","import_mode":"ephemeral-source-immutable","instruction_flow_evidence":"decoded-return-pcode-v1","jump_table_evidence":"typed-case-default-blocks-v1","language_id":"auto-from-header","load_image_observations":"source-mappings-entry-context-v2","loader":"auto-from-header","location_resolution":"explicit-address-exact-entry-symbol-first-v3","no_return_repair":"returning-imports-decoded-return-v2","process_launch":"inspected-jvm-launch-support-v1","string_inventory_evidence":"defined-data-coverage-v1","target_format":"mach-o","target_kind":"executable"},"provider":{"id":"ghidra","name":"Ghidra","version":"12.1.4"}},"authority":"shipped-artifact","confidence":"observed","environment":null,"evidence_id":"ev_6a88310573f4dfd2f23feef7d12c3f58eba366db1717861770656d55375e07a1","evidence_links":[],"limitations":["The session serves operations only after Ghidra reports default auto-analysis complete; incomplete analysis does not expose partial results.","The imported Program and temporary project are ephemeral and deleted on close. Annotation operations edit session database metadata; original executable bytes are never written.","Cancelling an active Ghidra request terminates its ephemeral dataLine truncated
|
||||
@@ -0,0 +1,71 @@
|
||||
MSE18V2 2.4.0 AIR excerpt; original complete-text line numbers.
|
||||
SHA256: 1d5bd8d5a3917afbb3b4fe1c40b44480760614102685ac826e84ad2e30a450f9
|
||||
|
||||
3364: 158: ; preds = %109, %85
|
||||
3365: %159 = phi <2 x float> [ %155, %109 ], [ %86, %85 ]
|
||||
3366: %160 = tail call fast float @air.fast_fabs.f32(float %5) #2
|
||||
3367: %161 = fcmp fast ogt float %160, 0x3EB0C6F7A0000000
|
||||
3368: br i1 %161, label %162, label %209
|
||||
3369:
|
||||
3370: 162: ; preds = %158
|
||||
3371: %163 = bitcast [4 x <2 x i32>]* %17 to i8*
|
||||
3372: call void @llvm.lifetime.start.p0i8(i64 32, i8* nonnull %163) #10
|
||||
3373: %164 = getelementptr inbounds [4 x <2 x i32>], [4 x <2 x i32>]* %17, i64 0, i64 0
|
||||
3374: store <2 x i32> <i32 69, i32 39>, <2 x i32>* %164, align 8
|
||||
3375: %165 = getelementptr inbounds [4 x <2 x i32>], [4 x <2 x i32>]* %17, i64 0, i64 1
|
||||
3376: store <2 x i32> <i32 65, i32 35>, <2 x i32>* %165, align 8
|
||||
3377: %166 = getelementptr inbounds [4 x <2 x i32>], [4 x <2 x i32>]* %17, i64 0, i64 2
|
||||
3378: store <2 x i32> <i32 70, i32 26>, <2 x i32>* %166, align 8
|
||||
3379: %167 = getelementptr inbounds [4 x <2 x i32>], [4 x <2 x i32>]* %17, i64 0, i64 3
|
||||
3380: store <2 x i32> <i32 64, i32 34>, <2 x i32>* %167, align 8
|
||||
3381: %168 = insertelement <2 x float> undef, float %5, i64 0
|
||||
3382: %169 = shufflevector <2 x float> %168, <2 x float> undef, <2 x i32> zeroinitializer
|
||||
3383: br label %171
|
||||
3384:
|
||||
3385: 170: ; preds = %205
|
||||
3386: call void @llvm.lifetime.end.p0i8(i64 32, i8* nonnull %163) #10
|
||||
3387: br label %209
|
||||
3388:
|
||||
3389: 171: ; preds = %205, %162
|
||||
3390: %172 = phi <2 x float> [ %159, %162 ], [ %206, %205 ]
|
||||
3391: %173 = phi i32 [ 0, %162 ], [ %207, %205 ]
|
||||
3392: %174 = zext i32 %173 to i64
|
||||
3393: %175 = getelementptr inbounds [4 x <2 x i32>], [4 x <2 x i32>]* %17, i64 0, i64 %174
|
||||
3394: %176 = load <2 x i32>, <2 x i32>* %175, align 8
|
||||
3395: %177 = extractelement <2 x i32> %176, i64 0
|
||||
3396: %178 = add nsw i32 %177, %2
|
||||
3397: %179 = sext i32 %178 to i64
|
||||
3398: %180 = getelementptr inbounds %struct.MSSFaceThinPoint, %struct.MSSFaceThinPoint addrspace(2)* %1, i64 %179, i32 0
|
||||
3399: %181 = load <2 x float>, <2 x float> addrspace(2)* %180, align 8, !tbaa !74
|
||||
3400: %182 = extractelement <2 x i32> %176, i64 1
|
||||
3401: %183 = add nsw i32 %182, %2
|
||||
3402: %184 = sext i32 %183 to i64
|
||||
3403: %185 = getelementptr inbounds %struct.MSSFaceThinPoint, %struct.MSSFaceThinPoint addrspace(2)* %1, i64 %184, i32 0
|
||||
3404: %186 = load <2 x float>, <2 x float> addrspace(2)* %185, align 8, !tbaa !74
|
||||
3405: %187 = fsub fast <2 x float> %181, %186
|
||||
3406: %188 = tail call fast float @air.dot.v2f32(<2 x float> %187, <2 x float> %187) #2
|
||||
3407: %189 = tail call fast float @air.fast_sqrt.f32(float %188) #2
|
||||
3408: %190 = fcmp fast ugt float %189, 0x3F1A36E2E0000000
|
||||
3409: br i1 %190, label %191, label %205
|
||||
3410:
|
||||
3411: 191: ; preds = %171
|
||||
3412: %192 = fsub fast <2 x float> %186, %181
|
||||
3413: %193 = fsub fast <2 x float> %172, %181
|
||||
3414: %194 = tail call fast float @air.dot.v2f32(<2 x float> %193, <2 x float> %193) #2
|
||||
3415: %195 = tail call fast float @air.fast_sqrt.f32(float %194) #2
|
||||
3416: %196 = fdiv fast float %195, %189
|
||||
3417: %197 = fsub fast float 1.000000e+00, %196
|
||||
3418: %198 = tail call fast float @air.fast_clamp.f32(float %197, float 0.000000e+00, float 1.000000e+00) #2
|
||||
3419: %199 = insertelement <2 x float> undef, float %198, i64 0
|
||||
3420: %200 = shufflevector <2 x float> %199, <2 x float> undef, <2 x i32> zeroinitializer
|
||||
3421: %201 = fmul fast <2 x float> %192, %169
|
||||
3422: %202 = fmul fast <2 x float> %201, %200
|
||||
3423: %203 = fsub fast <2 x float> %172, %202
|
||||
3424: %204 = tail call fast <2 x float> @air.fast_clamp.v2f32(<2 x float> %203, <2 x float> zeroinitializer, <2 x float> <float 1.000000e+00, float 1.000000e+00>) #2
|
||||
3425: br label %205
|
||||
3426:
|
||||
3427: 205: ; preds = %191, %171
|
||||
3428: %206 = phi <2 x float> [ %204, %191 ], [ %172, %171 ]
|
||||
3429: %207 = add nuw nsw i32 %173, 1
|
||||
3430: %208 = icmp eq i32 %207, 4
|
||||
3431: br i1 %208, label %170, label %171, !llvm.loop !89
|
||||
@@ -0,0 +1,258 @@
|
||||
{
|
||||
"authority": "Static shipped Apple AIR and Mach-O byte/assembly inspection; target app and shaders not executed",
|
||||
"sources": {
|
||||
"metallib": "/Users/dayu/Downloads/MSE18V2.app/Contents/PlugIns/MSE18V2.pluginkit/Contents/Resources/default.metallib",
|
||||
"metallib_sha256": "856849c45cea2c8f083eeba06a9e318c450f4a56694b438d1a5ba8ef752a0ee0",
|
||||
"command": [
|
||||
"xcrun",
|
||||
"metal-objdump",
|
||||
"--metallib",
|
||||
"--disassemble",
|
||||
"/Users/dayu/Downloads/MSE18V2.app/Contents/PlugIns/MSE18V2.pluginkit/Contents/Resources/default.metallib"
|
||||
],
|
||||
"air_sha256": "1d5bd8d5a3917afbb3b4fe1c40b44480760614102685ac826e84ad2e30a450f9",
|
||||
"binary": "/Users/dayu/Downloads/MSE18V2.app/Contents/PlugIns/MSE18V2.pluginkit/Contents/MacOS/MSE18V2",
|
||||
"binary_arm64_sha256": "afc71d0d21fd3c1ca95ca745ddafcd729e36ad95f17d8638009f2e45d9b7e8df",
|
||||
"double065_file_offsets_in_arm64_slice": [
|
||||
548512
|
||||
]
|
||||
},
|
||||
"new_version_vface": {
|
||||
"struct_field": "MSSFaceShapeParams.vlian offset8; helper parameter5",
|
||||
"render_params_field": "faceV double offset0x90",
|
||||
"cpu_function": "0x10002fb74",
|
||||
"cpu_coefficient_address": "0x100085ea0",
|
||||
"cpu_coefficient": 0.065,
|
||||
"cpu_ratio": "float(clamp(faceV,0,1)*0.065*double(float(clamp(commonStrength,0,1))))",
|
||||
"pin_order": [
|
||||
[
|
||||
69,
|
||||
39
|
||||
],
|
||||
[
|
||||
65,
|
||||
35
|
||||
],
|
||||
[
|
||||
70,
|
||||
26
|
||||
],
|
||||
[
|
||||
64,
|
||||
34
|
||||
]
|
||||
],
|
||||
"pin_fields": [
|
||||
"origin",
|
||||
"direction/radius anchor"
|
||||
],
|
||||
"coordinate_system": "full-image normalized UV; q and points must share the same vertical axis",
|
||||
"radius": "length(Panchor-Porigin), unscaled UV metric; skip radius<=0.0001",
|
||||
"weight": "clamp(1-length(q-Porigin)/radius,0,1)",
|
||||
"step": "q=clamp(q-(Panchor-Porigin)*ratio*weight,0,1)",
|
||||
"sequential": true,
|
||||
"ratio_threshold": 1e-06,
|
||||
"shader_lines": {
|
||||
"helper": 3159,
|
||||
"vface_gate": 3364,
|
||||
"pins": [
|
||||
3374,
|
||||
3376,
|
||||
3378,
|
||||
3380
|
||||
],
|
||||
"loop": 3389,
|
||||
"radius": 3405,
|
||||
"offset": 3412,
|
||||
"clamp": 3424,
|
||||
"count": 3430,
|
||||
"metadata": 4132
|
||||
},
|
||||
"order": "thin17 -> narrow16 -> V4 -> jaw6 -> cheek6 -> chin3 -> short -> smallHead -> bigEye",
|
||||
"helper_copies": [
|
||||
{
|
||||
"start_line": 3159,
|
||||
"v_pins": [
|
||||
[
|
||||
69,
|
||||
39
|
||||
],
|
||||
[
|
||||
65,
|
||||
35
|
||||
],
|
||||
[
|
||||
70,
|
||||
26
|
||||
],
|
||||
[
|
||||
64,
|
||||
34
|
||||
]
|
||||
],
|
||||
"has_old_pixel_gain_constant": false
|
||||
},
|
||||
{
|
||||
"start_line": 6840,
|
||||
"v_pins": [
|
||||
[
|
||||
69,
|
||||
39
|
||||
],
|
||||
[
|
||||
65,
|
||||
35
|
||||
],
|
||||
[
|
||||
70,
|
||||
26
|
||||
],
|
||||
[
|
||||
64,
|
||||
34
|
||||
]
|
||||
],
|
||||
"has_old_pixel_gain_constant": false
|
||||
},
|
||||
{
|
||||
"start_line": 8682,
|
||||
"v_pins": [
|
||||
[
|
||||
69,
|
||||
39
|
||||
],
|
||||
[
|
||||
65,
|
||||
35
|
||||
],
|
||||
[
|
||||
70,
|
||||
26
|
||||
],
|
||||
[
|
||||
64,
|
||||
34
|
||||
]
|
||||
],
|
||||
"has_old_pixel_gain_constant": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"version_difference": {
|
||||
"old_air": "build/pose-analysis/face-thin.air.txt",
|
||||
"old_gain_lines": [
|
||||
592,
|
||||
633
|
||||
],
|
||||
"old_vface_lines": [
|
||||
830,
|
||||
897
|
||||
],
|
||||
"old_cpu_coefficient_address": "0x10005f9a0",
|
||||
"coefficient_unchanged": true,
|
||||
"old_extra_gain": "clamp(280/max(length((P75-P59)*pixelSize),2*length((P67-(P74+P60)/2)*pixelSize),1),1,2.25)",
|
||||
"new_extra_gain": "Absent from all3 new shader helper copies and the complete new AIR text; CPU helper is plain clamped-control*.065*commonStrength",
|
||||
"anatomy": "Origin indices64,65,69,70 are lower contour; anchor indices26,34,35,39 are outer lips; eyes0..13 are not controls."
|
||||
},
|
||||
"eye_support_probe": {
|
||||
"authority": "Derived from existing local public-API Vision probe; no new image coordinates or original plug-in execution",
|
||||
"settings": {
|
||||
"vface": 1,
|
||||
"common_strength": 1,
|
||||
"coefficient": 0.065,
|
||||
"pins": [
|
||||
[
|
||||
69,
|
||||
39
|
||||
],
|
||||
[
|
||||
65,
|
||||
35
|
||||
],
|
||||
[
|
||||
70,
|
||||
26
|
||||
],
|
||||
[
|
||||
64,
|
||||
34
|
||||
]
|
||||
]
|
||||
},
|
||||
"samples": [
|
||||
{
|
||||
"seconds": 0,
|
||||
"minimum_eye_distance_over_pin_radius": 2.86112178668839,
|
||||
"max_eye_weight": 0,
|
||||
"max_sequential_eye_displacement_pixels": 0
|
||||
},
|
||||
{
|
||||
"seconds": 2,
|
||||
"minimum_eye_distance_over_pin_radius": 2.7386373955689196,
|
||||
"max_eye_weight": 0,
|
||||
"max_sequential_eye_displacement_pixels": 0
|
||||
},
|
||||
{
|
||||
"seconds": 4,
|
||||
"minimum_eye_distance_over_pin_radius": 2.0723834235969316,
|
||||
"max_eye_weight": 0,
|
||||
"max_sequential_eye_displacement_pixels": 0
|
||||
},
|
||||
{
|
||||
"seconds": 6,
|
||||
"minimum_eye_distance_over_pin_radius": 2.7994186406360964,
|
||||
"max_eye_weight": 0,
|
||||
"max_sequential_eye_displacement_pixels": 0
|
||||
},
|
||||
{
|
||||
"seconds": 8,
|
||||
"minimum_eye_distance_over_pin_radius": 2.720538093620307,
|
||||
"max_eye_weight": 0,
|
||||
"max_sequential_eye_displacement_pixels": 0
|
||||
},
|
||||
{
|
||||
"seconds": 10,
|
||||
"minimum_eye_distance_over_pin_radius": 2.7459899006401245,
|
||||
"max_eye_weight": 0,
|
||||
"max_sequential_eye_displacement_pixels": 0
|
||||
},
|
||||
{
|
||||
"seconds": 12,
|
||||
"minimum_eye_distance_over_pin_radius": 2.8522571566241655,
|
||||
"max_eye_weight": 0,
|
||||
"max_sequential_eye_displacement_pixels": 0
|
||||
},
|
||||
{
|
||||
"seconds": 14,
|
||||
"minimum_eye_distance_over_pin_radius": 2.7849986024852744,
|
||||
"max_eye_weight": 0,
|
||||
"max_sequential_eye_displacement_pixels": 0
|
||||
},
|
||||
{
|
||||
"seconds": 16,
|
||||
"minimum_eye_distance_over_pin_radius": 2.86097776991491,
|
||||
"max_eye_weight": 0,
|
||||
"max_sequential_eye_displacement_pixels": 0
|
||||
},
|
||||
{
|
||||
"seconds": 18,
|
||||
"minimum_eye_distance_over_pin_radius": 2.4994391012873294,
|
||||
"max_eye_weight": 0,
|
||||
"max_sequential_eye_displacement_pixels": 0
|
||||
},
|
||||
{
|
||||
"seconds": 20,
|
||||
"minimum_eye_distance_over_pin_radius": 2.3076941598447127,
|
||||
"max_eye_weight": 0,
|
||||
"max_sequential_eye_displacement_pixels": 0
|
||||
}
|
||||
]
|
||||
},
|
||||
"limits": [
|
||||
"No reference shader runtime or pixel comparison performed.",
|
||||
"The commonStrength caller-source semantics are not fully traced; formula reports the helper input.",
|
||||
"CPU prechecks/license/module gates are observed but are outside the independently authored geometry reconstruction.",
|
||||
"Eye support results apply to the11 existing saved Vision samples, not every possible pose.",
|
||||
"No product sources, app build, host session or Git were changed."
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
Beauty renderer: 57 checks, 0 failures (Metal).
|
||||
2026-10-22 16:24:20.836 face-tests[22582:8025448] FBBA: creating VNFaceBBoxAligner from VNFaceDetectorRevision2: VNFaceDetectorRevision2
|
||||
Face processing: 116 checks passed
|
||||
2026-10-22 16:24:34.977 slim-tests[22589:8025534] FBBA: creating VNFaceBBoxAligner from VNFaceDetectorRevision2: VNFaceDetectorRevision2
|
||||
PASS: 1033 slim alignment checks; maximum UV oracle error 1.09828022e-05
|
||||
@@ -0,0 +1,37 @@
|
||||
2026-10-22 16:21:55.726 host-tests[22385:8017721] FBBA: creating VNFaceBBoxAligner from VNFaceDetectorRevision2: VNFaceDetectorRevision2
|
||||
Default IOSurface maximum byte difference: 0
|
||||
Alternate destination tag maximum byte difference: 0
|
||||
Anatomy default 0/0 max=0 mean=0.0000000 eye=0/0 chin=0 inverted=0
|
||||
Anatomy default 0/1 max=0 mean=0.0000000 eye=0/0 chin=0 inverted=0
|
||||
Anatomy default 1/0 max=0 mean=0.0000000 eye=0/0 chin=0 inverted=0
|
||||
Anatomy default 1/1 max=0 mean=0.0000000 eye=0/0 chin=0 inverted=0
|
||||
Anatomy big-eye 0/0 max=2 mean=0.0008917 eye=33510/33880 chin=0 inverted=0
|
||||
Anatomy big-eye 0/1 max=2 mean=0.0008917 eye=33510/33880 chin=0 inverted=0
|
||||
Anatomy big-eye 1/0 max=2 mean=0.0008917 eye=33510/33880 chin=0 inverted=0
|
||||
Anatomy big-eye 1/1 max=2 mean=0.0008917 eye=33510/33880 chin=0 inverted=0
|
||||
Anatomy chin-positive 0/0 max=1 mean=0.0001459 eye=0/0 chin=116812 inverted=0
|
||||
Anatomy chin-positive 0/1 max=1 mean=0.0001459 eye=0/0 chin=116812 inverted=0
|
||||
Anatomy chin-positive 1/0 max=1 mean=0.0001459 eye=0/0 chin=116812 inverted=0
|
||||
Anatomy chin-positive 1/1 max=1 mean=0.0001459 eye=0/0 chin=116812 inverted=0
|
||||
Anatomy chin-negative 0/0 max=1 mean=0.0000849 eye=0/0 chin=60426 inverted=0
|
||||
Anatomy chin-negative 0/1 max=1 mean=0.0000849 eye=0/0 chin=60426 inverted=0
|
||||
Anatomy chin-negative 1/0 max=1 mean=0.0000849 eye=0/0 chin=60426 inverted=0
|
||||
Anatomy chin-negative 1/1 max=1 mean=0.0000849 eye=0/0 chin=60426 inverted=0
|
||||
Anatomy short-positive 0/0 max=2 mean=0.0011072 eye=0/0 chin=285953 inverted=0
|
||||
Anatomy short-positive 0/1 max=2 mean=0.0011072 eye=0/0 chin=285953 inverted=0
|
||||
Anatomy short-positive 1/0 max=2 mean=0.0011072 eye=0/0 chin=285953 inverted=0
|
||||
Anatomy short-positive 1/1 max=2 mean=0.0011072 eye=0/0 chin=285953 inverted=0
|
||||
Anatomy short-negative 0/0 max=2 mean=0.0008583 eye=0/0 chin=225648 inverted=0
|
||||
Anatomy short-negative 0/1 max=2 mean=0.0008583 eye=0/0 chin=225648 inverted=0
|
||||
Anatomy short-negative 1/0 max=2 mean=0.0008583 eye=0/0 chin=225648 inverted=0
|
||||
Anatomy short-negative 1/1 max=2 mean=0.0008583 eye=0/0 chin=225648 inverted=0
|
||||
Anatomy jaw 0/0 max=1 mean=0.0001974 eye=0/0 chin=12951 inverted=0
|
||||
Anatomy jaw 0/1 max=1 mean=0.0001974 eye=0/0 chin=12951 inverted=0
|
||||
Anatomy jaw 1/0 max=1 mean=0.0001974 eye=0/0 chin=12951 inverted=0
|
||||
Anatomy jaw 1/1 max=1 mean=0.0001974 eye=0/0 chin=12951 inverted=0
|
||||
Anatomy v-face 0/0 max=1 mean=0.0001240 eye=0/0 chin=39246 inverted=0
|
||||
Anatomy v-face 0/1 max=1 mean=0.0001240 eye=0/0 chin=39246 inverted=0
|
||||
Anatomy v-face 1/0 max=1 mean=0.0001240 eye=0/0 chin=39246 inverted=0
|
||||
Anatomy v-face 1/1 max=1 mean=0.0001240 eye=0/0 chin=39246 inverted=0
|
||||
Legacy fallback upright comparison: max=2 mean=0.0010357
|
||||
Host adapter: 370 checks, 0 failures
|
||||
@@ -0,0 +1 @@
|
||||
Inspector: 227 checks, 0 failures
|
||||
@@ -0,0 +1,21 @@
|
||||
2026-10-22 16:24:26.444 osc-tests[22624:8025751] PGFaceOSC point-write desired=(0.25,0.75) setter=(0.25,0.75) readback=(0.25,0.75) mode=normalized verified=1
|
||||
2026-10-22 16:24:26.452 osc-tests[22624:8025751] PGFaceOSC coordinates selection=(0.25,0.75) objectBounds=(-100,-50,200,100) canvas=(80,180) surface=320x240 origin=0
|
||||
2026-10-22 16:24:26.887 osc-tests[22624:8025751] PGFaceOSC point-write desired=(0.8,0.3) setter=(1152,-432) readback=(0.8,0.3) mode=centered-pixels verified=1
|
||||
2026-10-22 16:24:26.887 osc-tests[22624:8025751] PGFaceOSC coordinates selection=(0.7,0.4) objectBounds=(-1920,-1080,3840,2160) canvas=(152,78) surface=320x240 origin=0
|
||||
2026-10-22 16:24:26.944 osc-tests[22624:8025751] PGFaceOSC point-write desired=(0.8,0.3) setter=(0.8,0.3) readback=(0.12345,0.87654) mode=normalized verified=0
|
||||
2026-10-22 16:24:26.944 osc-tests[22624:8025751] PGFaceOSC point-write desired=(0.75,0.25) setter=(0.75,0.25) readback=(0.75,0.25) mode=normalized verified=1
|
||||
2026-10-22 16:24:26.944 osc-tests[22624:8025751] PGFaceOSC coordinates selection=(0.75,0.25) objectBounds=(-100,-50,200,100) canvas=(160,60) surface=320x240 origin=0
|
||||
2026-10-22 16:24:26.994 osc-tests[22624:8025751] PGFaceOSC point-write desired=(0.625,0.375) setter=(0.625,0.375) readback=(0.625,0.375) mode=normalized verified=1
|
||||
2026-10-22 16:24:26.994 osc-tests[22624:8025751] PGFaceOSC coordinates selection=(0.625,0.375) objectBounds=(-100,-50,200,100) canvas=(240,60) surface=320x240 origin=0
|
||||
2026-10-22 16:24:27.043 osc-tests[22624:8025751] PGFaceOSC point-write desired=(0.25,0.75) setter=(0.25,0.75) readback=(0.25,0.75) mode=normalized verified=1
|
||||
2026-10-22 16:24:27.043 osc-tests[22624:8025751] PGFaceOSC coordinates selection=(0.25,0.75) objectBounds=(-100,-50,200,100) canvas=(144,180) surface=320x240 origin=0
|
||||
2026-10-22 16:24:27.094 osc-tests[22624:8025751] PGFaceOSC point-write desired=(0.5,0.5) setter=(0.5,0.5) readback=(0.5,0.5) mode=normalized verified=1
|
||||
2026-10-22 16:24:27.094 osc-tests[22624:8025751] PGFaceOSC coordinates selection=(0,1) objectBounds=(-100,-50,200,100) canvas=(100,140) surface=320x240 origin=0
|
||||
2026-10-22 16:24:27.144 osc-tests[22624:8025751] PGFaceOSC coordinates selection=(0.25,0.75) objectBounds=(-100,-50,200,100) canvas=(nan,nan) surface=320x240 origin=0
|
||||
2026-10-22 16:24:27.194 osc-tests[22624:8025751] PGFaceOSC point-write desired=(0.5,0.5) setter=(0.5,0.5) readback=(0.5,0.5) mode=normalized verified=1
|
||||
2026-10-22 16:24:27.194 osc-tests[22624:8025751] PGFaceOSC coordinates selection=(0.25,0.75) objectBounds=(-100,-50,200,100) canvas=(inf,nan) surface=320x240 origin=0
|
||||
2026-10-22 16:24:27.242 osc-tests[22624:8025751] PGFaceOSC point-write desired=(0.5,0.5) setter=(0.5,0.5) readback=(0.5,0.5) mode=normalized verified=1
|
||||
2026-10-22 16:24:27.242 osc-tests[22624:8025751] PGFaceOSC coordinates selection=(0.25,0.75) objectBounds=(-100,-50,200,100) canvas=(80,nan) surface=320x240 origin=0
|
||||
2026-10-22 16:24:27.304 osc-tests[22624:8025751] PGFaceOSC point-write desired=(0.5,0.5) setter=(0.5,0.5) readback=(0.5,0.5) mode=normalized verified=1
|
||||
2026-10-22 16:24:27.304 osc-tests[22624:8025751] PGFaceOSC point-write desired=(0.5,0.5) setter=(0.5,0.5) readback=(0.5,0.5) mode=normalized verified=1
|
||||
OSC adapter: 98 checks, 0 failures
|
||||
@@ -0,0 +1,2 @@
|
||||
2026-10-22 16:25:35.195 slim-tests[22704:8027100] FBBA: creating VNFaceBBoxAligner from VNFaceDetectorRevision2: VNFaceDetectorRevision2
|
||||
PASS: 1561 slim alignment checks; maximum UV oracle error 1.09828022e-05
|
||||
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"status": "passed",
|
||||
"version": "1.3.1",
|
||||
"build": "16",
|
||||
"checks": {
|
||||
"beauty": 57,
|
||||
"face": 116,
|
||||
"geometry": 1033,
|
||||
"hostASan": 370,
|
||||
"oscASan": 98,
|
||||
"inspectorASan": 227
|
||||
},
|
||||
"total": 1901,
|
||||
"extraRealPoseASan": {
|
||||
"checks": 1561,
|
||||
"inputs": "NASA astronaut plus 11 local user frames; frame images and full Vision points not uploaded",
|
||||
"overlapsBaseline": true
|
||||
},
|
||||
"maximumUVOracleError": 1.09828022e-05,
|
||||
"isolatedV": {
|
||||
"eyeChange": [
|
||||
0,
|
||||
0
|
||||
],
|
||||
"lowerFaceChange": 39246,
|
||||
"originsCompared": 4,
|
||||
"uprightMax255": 1,
|
||||
"uprightMean255": 0.000124
|
||||
},
|
||||
"nativeVisualQA": "pending user"
|
||||
}
|
||||
+6
-3
@@ -2,6 +2,8 @@
|
||||
|
||||
更新时间:2026-10-22,Asia/Shanghai。项目根目录:`/Users/dayu/Documents/PaintFCP`。
|
||||
|
||||
正在准备 **1.3.1(16)** 的 V 脸下颌修复;1901 项自动检查通过,正式安装尚未替换。
|
||||
|
||||
当前正式安装的 APP 为 **1.3.0(构建 15)**,已完成通用 Release 编译、正式签名、Apple 公证、票据验证及唯一正式路径安装。新增磨皮参数迁移与 1636 项自动检查已完成,原生效果视觉仍待用户实测。公开文章、PKG 与 GitHub Release 继续对应 **1.2.0**;本次未更新这些发行资料,也未覆盖模板或宣传图。
|
||||
|
||||
代码由 **OpenAI + Codex 全程编写,站长仅参与调试和测试**。文章和仓库须保留这个表述,不使用“站长原创代码”等说法。免费版本无需账号、激活码或付费授权;“自动注册”指系统插件注册。
|
||||
@@ -84,18 +86,19 @@ Xcode 工程:`beatygril/beatygril.xcodeproj`。外层 scheme 为 `Wrapper Appl
|
||||
|
||||
本项目几何历史只取当前请求之前的近时记录,原版还存在近未来历史分支;冷启动、热缓存、乱序渲染、同尺寸换源和多人交叉仍有差异边界。旧离线分析字段保留兼容,但当前新面板的渲染统一使用实时自动跟随。
|
||||
|
||||
### 已完成的四项局部算法
|
||||
### 已完成的五项局部算法
|
||||
|
||||
| 控制项 | 当前实现 | 防止回归的要点 |
|
||||
| --- | --- | --- |
|
||||
| 瘦脸 | 76 点、17 组轮廓到鼻部或瞳孔锚点的局部逆向采样 | 不恢复整脸框水平挤压;保留尺寸增益、组顺序和逐步 clamp |
|
||||
| V 脸 | `69→39`、`65→35`、`70→26`、`64→34` 四组下颌到外唇局部位移 | 新版 2.4.0 使用 0.065 系数、无旧尺寸增益;两瞳孔保持不动 |
|
||||
| 下巴 | `68→38`、`67→37`、`66→36` 三组局部位移 | 正值上收、负值延伸,保留正负不同系数 |
|
||||
| 下颌骨 | 六组相邻轮廓半径的顺序局部位移 | 半径来自相邻轮廓点,方向锚点为 P29;不能同时求和替代逐步更新 |
|
||||
| 短脸 | P62 至 P72 的下半脸闭合区域,沿 P46−P48 鼻梁轴位移 | 正值收短、负值延长;不是太阳穴区域或脸框纵向压缩 |
|
||||
|
||||
这四项共享由实际图像像素尺寸计算的增益。完整合法 76 点缺失时,四项安全直通,不退回猜测的脸框场。图像与磨皮、肤色、牙齿、眼睛蒙版共用几何变形路径,避免效果与蒙版错位。
|
||||
此前四项沿用由实际图像像素尺寸计算的增益;V 脸对齐新版目标,不带该额外增益。完整合法 76 点缺失时,五项安全直通,不退回猜测的脸框场。图像与磨皮、肤色、牙齿、眼睛蒙版共用几何变形路径,避免效果与蒙版错位。
|
||||
|
||||
**仍为近似实现的五项:大眼、窄脸、V 脸、颧骨、小头。** 原版完整链为 `thin → narrow → V → jaw → cheek → chin → short → small-head → eyes`,本项目尚未完全恢复整条组合链的数学及顺序。用户单项验收不代表所有参数组合逐像素等价。详细索引、系数和独立数值场验证见[下巴与坐标分析](analysis/下巴与坐标分析.md)、[短脸与下颌骨分析](analysis/短脸与下颌骨分析.md)。
|
||||
**仍为近似实现的四项:大眼、窄脸、颧骨、小头。** 原版完整链为 `thin → narrow → V → jaw → cheek → chin → short → small-head → eyes`,本项目尚未完全恢复整条组合链的数学及顺序。用户单项验收不代表所有参数组合逐像素等价。V 脸修复见 [下颌区域分析](analysis/V脸下颌区域修复.md)。详细索引、系数和独立数值场验证见[下巴与坐标分析](analysis/下巴与坐标分析.md)、[短脸与下颌骨分析](analysis/短脸与下颌骨分析.md)。
|
||||
|
||||
### 坐标约定
|
||||
|
||||
|
||||
+5
@@ -138,3 +138,8 @@ Motion:独立普通视频项目,源PTS0、1920×1080/25fps/10秒,媒体通
|
||||
按用户纠正后的截图需求,迁移连续五官保护、非肤色区保护和局部微细锐化;保留旧 bool、全局磨皮/锐化 ID 与旧工程行为。正式签名源码 `2f2c081980dc610ac810f8daf92da8966f310802`。1636 项通过:57 Beauty、116 Face、796 几何、341 宿主适配 ASan、98 OSC ASan、228 Inspector ASan(含 1 项可选 PNG 输出)。保护 0/50/100 像素响应、色彩覆盖隔离、透明度、v1 状态迁移、新控件归档/插值/输入/重置/旁路/松手前发布均有检查;离屏面板已查看。
|
||||
|
||||
通用 Release 正式签名、公证 Accepted(`ca96837f-bf33-44fa-8d58-799026ce5c7d`)、票据、双架构严格签名、安装身份、Gatekeeper、PluginKit 正式路径与临时副本清理通过。独立从 origin 克隆签名源码节点,205 个受跟踪文件逐字节匹配且 strict/full fsck 通过。本次没有原生新滑杆/效果视觉验收,也没有生成新 PKG 或更新文章;用户已保存并退出宿主后才执行安装。详见 `verification/v1.3.0/` 与 `analysis/新版磨皮参数迁移.md`。
|
||||
|
||||
|
||||
## 1.3.1(16)V 脸下颌区域修复(构建前)
|
||||
|
||||
移除 V 脸的脸框近似宽带,改为新版目标的四组下颌到外唇 pin,单项映射为 clamp(V,0,1)×0.065,不叠加旧尺寸增益。无合法76点时直通,图像与四张蒙版同场变形。1901项自动检查通过:57 Beauty、116 Face、1033几何、370 Host ASan、98 OSC ASan、227 Inspector ASan。原失败复现、点位/CPU/AIR证据和未对齐范围见 analysis/V脸下颌区域修复.md。另对 NASA 人像和本机用户视频11帧运行1561项几何ASan专项(含重复基础用例,不相加),通过;用户帧和完整点坐标未上传。安装及用户视觉待完成,当前正式APP仍为1.3.0。
|
||||
在新工单中引用
屏蔽一个用户