Snapshot: fog implementation + fidelity tooling baseline (pre bilinear-clamp fix)
Per-vertex GS fog end-to-end (gs_stub emit incl. persp_emit5, gs_prim_list_feeder XYZ2->XYZF2 on PRIM.FGE, gs_make_sh3_scheduler_fixture.py F/FGE packing), new fog TBs, fidelity attribution tooling. Functional baseline before removing the dead bilinear lerp8 clamps (Codex: 161-node comb loop -> -0.042ns setup fail). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -53,6 +53,10 @@ def main(argv):
|
||||
def opt(n, dv=None): return argv[argv.index(n)+1] if n in argv else dv
|
||||
frame = int(opt("--frame","1")); maxd = int(opt("--max-draws","100000"))
|
||||
min_area = float(opt("--min-area","0"))
|
||||
no_z = ("--no-z" in argv) # diagnostic: paint in submission order, last draw wins (bypass z-buffer)
|
||||
dofog = ("--fog" in argv) # apply authentic GS per-vertex fog (FOGCOL=0 black => color*F/256) on FGE draws
|
||||
only_tbp = int(opt("--only-tbp","-1")) # diagnostic: render only draws bound to this texture base
|
||||
only_idx = int(opt("--only-idx","-1")) # diagnostic: render only the draw with this first_idx
|
||||
outdir = opt("--out", os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
|
||||
"captures","gs","silenthill3","extracted","recon"))
|
||||
os.makedirs(outdir, exist_ok=True)
|
||||
@@ -62,7 +66,9 @@ def main(argv):
|
||||
d, h, events, uploads, runs, vram = collected
|
||||
draws, _, _ = C.census(dump, frame_filter=frame, min_prims=1, collected=collected)
|
||||
draws = [dr for dr in draws if dr["prim"]["tme"] and dr["tex0"]["psm"] in (0x13,0x00)
|
||||
and dr["onscreen_area"] >= min_area]
|
||||
and dr["onscreen_area"] >= min_area
|
||||
and (only_tbp < 0 or dr["tex0"]["tbp"] == only_tbp)
|
||||
and (only_idx < 0 or dr["first_idx"] == only_idx)]
|
||||
draws.sort(key=lambda x: x["first_idx"])
|
||||
print(f"[frameref] frame {frame}: {len(draws)} textured (PSMT8/CT32) draws, min_area={min_area}; "
|
||||
f"replaying uploads incrementally")
|
||||
@@ -97,6 +103,7 @@ def main(argv):
|
||||
if kind is None: continue
|
||||
tw, th = t0["tw"], t0["th"]
|
||||
verts = dr["verts"]; pt = dr["prim"]["type"]
|
||||
draw_fge = dofog and bool(dr["prim"].get("fge",0))
|
||||
def tri(i0,i1,i2):
|
||||
nonlocal painted_total
|
||||
v0,v1,v2 = verts[i0],verts[i1],verts[i2]
|
||||
@@ -120,8 +127,14 @@ def main(argv):
|
||||
u=(S/Q)*tw; vv=(T/Q)*th
|
||||
z=int(b0*v0["z"]+b1*v1["z"]+b2*v2["z"])
|
||||
o=base+px
|
||||
if z>=zb[o]:
|
||||
zb[o]=z; fb[o]=sample(tex,pal,kind,tw,th,u,vv)+(255,); painted_total+=1
|
||||
if no_z or z>=zb[o]:
|
||||
rgb=sample(tex,pal,kind,tw,th,u,vv)
|
||||
if draw_fge:
|
||||
F=int(b0*v0["fog"]+b1*v1["fog"]+b2*v2["fog"]) # affine per-vertex fog; FOGCOL=0
|
||||
if F<0: F=0
|
||||
elif F>255: F=255
|
||||
rgb=((rgb[0]*F)>>8, (rgb[1]*F)>>8, (rgb[2]*F)>>8)
|
||||
zb[o]=z; fb[o]=rgb+(255,); painted_total+=1
|
||||
if pt==4:
|
||||
for i in range(2,len(verts)): tri(i-2,i-1,i)
|
||||
elif pt==5:
|
||||
|
||||
Reference in New Issue
Block a user