code wiki / (root) / nx_render_target_match.nx

nx_render_target_match.nx source

↩ module page · 209 lines · 8498 B

1// nx_render_target_match.nx -- did the generated image match the target? 2// 3// Universal RENDERED-VS-TARGET verdict primitive. Given two 16-element 4// feature vectors (target image + rendered image), emits a sealed-enum 5// verdict + per-axis divergence + actionable next-axis pinpoint. 6// 7// USE CASES (all the same substrate, different target sources): 8// 9// 1. RETAIL VIRTUAL TRY-ON (Google Shopping AI Mode pattern): 10// target = product image (lingerie / dress / jacket / shoes) 11// render = model wearing the product (via gen-img) 12// verdict = did the rendered model faithfully wear the product? 13// action = which visual axis (color / texture / silhouette / etc.) 14// needs another iteration? 15// 16// 2. VIDEO-GAME ASSET RENDER: 17// target = concept art reference for a weapon / armor / character 18// render = in-engine model the procgen produced 19// verdict = does the asset match the brief? 20// 21// 3. STORY-DRIVEN SCENE RENDER (legal adult or all-ages): 22// target = reference image for the desired scene mood 23// render = generated scene image 24// verdict = does the render hit the mood? 25// 26// All three use the SAME primitive. Different in the prompt + concept- 27// embedding upstream; identical at the measure-the-output layer. 28// 29// COMPOSES: 30// nx_cosine_similarity -- overall vector alignment 31// per-axis delta math -- normalized |target - rendered| per axis 32// sealed verdict bands -- substrate-honest routing 33// worst-axis pinpoint -- which axis to refactor next render 34// 35// genealogy_id: salton_1971_smart + clip_score_hessel_2021 + 36// ip_adapter_ye_2023 + lpips_zhang_2018 + 37// fid_heusel_2017 38// lineage_id: render_target_match_q10 39 40// nx_safety_envelope: 41// intended_use: AUTO_APPLIED -- primitive-specific tuning queued 42// sil_target: SIL1 43// evidence: [bulk_applied_2026-05-16, see-file-comment-for-detail] 44// verdict: NOT_YET_EVALUATED 45 46import "nx_syscalls.nx" 47import "nx_tier.nx" 48import "nx_image_feature_extract.nx" 49import "nx_cosine_similarity.nx" 50 51const NX_RTM_Q: nx_int = 1024 52 53// Sealed-enum verdicts (HIGH = better match) 54const NX_RTM_MATCH_FAILED: nx_int = 0 // cos < 256 or fidelity below floor 55const NX_RTM_MATCH_POOR: nx_int = 1 // 256 <= cos < 512 56const NX_RTM_MATCH_PARTIAL: nx_int = 2 // 512 <= cos < 768 57const NX_RTM_MATCH_GOOD: nx_int = 3 // 768 <= cos < 921 58const NX_RTM_MATCH_EXCELLENT: nx_int = 4 // cos >= 921 AND worst-axis-delta tight 59const NX_RTM_N_VERDICTS: nx_int = 5 60 61// Recommended next-action sealed enum (operator chooses based on 62// worst-axis pinpoint). 63const NX_RTM_ACTION_SHIP: nx_int = 0 64const NX_RTM_ACTION_REFINE_COLOR: nx_int = 1 65const NX_RTM_ACTION_REFINE_LIGHTING: nx_int = 2 66const NX_RTM_ACTION_REFINE_COMPOSITION: nx_int = 3 67const NX_RTM_ACTION_REFINE_CLARITY: nx_int = 4 68const NX_RTM_ACTION_REFINE_SHARPNESS: nx_int = 5 69const NX_RTM_ACTION_REFINE_FRACTAL: nx_int = 6 70const NX_RTM_ACTION_REFINE_SYMMETRY: nx_int = 7 71const NX_RTM_ACTION_RESTART_FROM_SCRATCH: nx_int = 8 72const NX_RTM_N_ACTIONS: nx_int = 9 73 74// Tolerance: a per-axis delta below this counts as "aligned." 75const NX_RTM_AXIS_TOLERANCE_Q10: nx_int = 200 // 20% of full scale 76 77// Worst-axis-delta ceiling for the EXCELLENT band -- even with high 78// cosine, if ANY single axis diverges this much, demote to GOOD. 79const NX_RTM_EXCELLENT_MAX_AXIS_DELTA: nx_int = 100 80 81struct RenderTargetMatchReport { 82 overall_cosine_q10: nx_int, 83 n_aligned_axes: nx_int, // axes with delta <= tolerance 84 n_diverged_axes: nx_int, // axes above tolerance 85 worst_axis_delta_q10: nx_int, // max per-axis delta 86 worst_axis_index: nx_int, // which axis (0..15) 87 actionable_axis: nx_int, // same as worst_axis_index in v1 88 recommended_action: nx_int, // NX_RTM_ACTION_* 89 verdict: nx_int, // NX_RTM_MATCH_* 90 fidelity_q10: nx_int, 91} 92 93// Map a feature-axis index to its recommended next-action. 94// Feature axes 0..5 = aesthetics; 6..8 = fractal; 9..15 = symmetry. 95func _rtm_axis_to_action(axis: nx_int) -> nx_int { 96 if axis == NX_IMG_FEAT_COLOR_HARMONY { return NX_RTM_ACTION_REFINE_COLOR } 97 if axis == NX_IMG_FEAT_LIGHTING { return NX_RTM_ACTION_REFINE_LIGHTING } 98 if axis == NX_IMG_FEAT_COMPOSITION { return NX_RTM_ACTION_REFINE_COMPOSITION } 99 if axis == NX_IMG_FEAT_CLARITY { return NX_RTM_ACTION_REFINE_CLARITY } 100 if axis == NX_IMG_FEAT_SHARPNESS { return NX_RTM_ACTION_REFINE_SHARPNESS } 101 if axis == NX_IMG_FEAT_AESTHETIC_COMPOSITE { return NX_RTM_ACTION_REFINE_COMPOSITION } 102 if axis == NX_IMG_FEAT_FRACTAL_DIM { return NX_RTM_ACTION_REFINE_FRACTAL } 103 if axis == NX_IMG_FEAT_FRACTAL_AESTHETIC { return NX_RTM_ACTION_REFINE_FRACTAL } 104 if axis == NX_IMG_FEAT_EDGE_DENSITY { return NX_RTM_ACTION_REFINE_SHARPNESS } 105 if axis >= NX_IMG_FEAT_SYM_COMPOSITE { return NX_RTM_ACTION_REFINE_SYMMETRY } 106 return NX_RTM_ACTION_RESTART_FROM_SCRATCH 107} 108 109// Absolute value helper. 110func _rtm_abs(x: nx_int) -> nx_int { 111 if x < 0 { return -x } 112 return x 113} 114 115// ===== Public compute ================================================ 116 117func nx_render_target_match(target_features: *nx_int, 118 rendered_features: *nx_int, 119 report: *RenderTargetMatchReport) -> nx_int { 120 report.overall_cosine_q10 = 0 121 report.n_aligned_axes = 0 122 report.n_diverged_axes = 0 123 report.worst_axis_delta_q10 = 0 124 report.worst_axis_index = 0 125 report.actionable_axis = 0 126 report.recommended_action = NX_RTM_ACTION_SHIP 127 report.verdict = NX_RTM_MATCH_FAILED 128 report.fidelity_q10 = NX_RTM_Q 129 130 // Overall cosine over the two feature vectors. 131 let cos: nx_int = nx_cosine_similarity( 132 target_features, NX_IMAGE_FEATURE_LEN, 133 rendered_features, NX_IMAGE_FEATURE_LEN 134 ) 135 report.overall_cosine_q10 = cos 136 137 // Per-axis delta + aligned/diverged tally + worst-axis pinpoint. 138 var worst_delta: nx_int = 0 139 var worst_idx: nx_int = 0 140 var n_aligned: nx_int = 0 141 var n_diverged: nx_int = 0 142 var i: nx_int = 0 143 while i < NX_IMAGE_FEATURE_LEN { 144 let t: nx_int = target_features[i] 145 let r: nx_int = rendered_features[i] 146 let d: nx_int = _rtm_abs(t - r) 147 if d <= NX_RTM_AXIS_TOLERANCE_Q10 { 148 n_aligned = n_aligned + 1 149 } else { 150 n_diverged = n_diverged + 1 151 } 152 if d > worst_delta { 153 worst_delta = d 154 worst_idx = i 155 } 156 i = i + 1 157 } 158 report.n_aligned_axes = n_aligned 159 report.n_diverged_axes = n_diverged 160 report.worst_axis_delta_q10 = worst_delta 161 report.worst_axis_index = worst_idx 162 report.actionable_axis = worst_idx 163 report.recommended_action = _rtm_axis_to_action(worst_idx) 164 165 // Sealed-enum verdict routing. 166 // 167 // EXCELLENT requires both high cosine AND tight worst-axis (no 168 // single axis blew the budget). GOOD/PARTIAL/POOR route on 169 // cosine alone. FAILED catches negative-cosine + low-fidelity 170 // cases. 171 if cos < 256 { 172 report.verdict = NX_RTM_MATCH_FAILED 173 return 0 174 } 175 if cos < 512 { 176 report.verdict = NX_RTM_MATCH_POOR 177 return 0 178 } 179 if cos < 768 { 180 report.verdict = NX_RTM_MATCH_PARTIAL 181 return 0 182 } 183 if cos < 921 { 184 report.verdict = NX_RTM_MATCH_GOOD 185 return 0 186 } 187 // cos >= 921: candidate for EXCELLENT pending worst-axis check. 188 if worst_delta > NX_RTM_EXCELLENT_MAX_AXIS_DELTA { 189 report.verdict = NX_RTM_MATCH_GOOD // close but not perfect 190 return 0 191 } 192 report.verdict = NX_RTM_MATCH_EXCELLENT 193 report.recommended_action = NX_RTM_ACTION_SHIP // ship the render 194 return 0 195} 196 197// ===== Sealed-enum validity ========================================= 198 199func nx_render_target_match_verdict_is_valid(v: nx_int) -> nx_int { 200 if v < 0 { return 0 } 201 if v >= NX_RTM_N_VERDICTS { return 0 } 202 return 1 203} 204 205func nx_render_target_match_action_is_valid(a: nx_int) -> nx_int { 206 if a < 0 { return 0 } 207 if a >= NX_RTM_N_ACTIONS { return 0 } 208 return 1 209}