AUREOLE-R-v3 / scripts /demo.py
PureOne's picture
AUREOLE-R 3.0.0-hf.1: standalone public research release
9d6c005 verified
Raw
History Blame Contribute Delete
3.39 kB
"""Run a small physical rendering demo with bundled weights; CPU, no account."""
from pathlib import Path
import argparse,json,sys
ROOT=Path(__file__).resolve().parents[1]
sys.path.insert(0,str(ROOT))
import numpy as np
from aureole import WorldMemory,freeze,draw,correct
from aureole.core import proposal_from_bound
from aureole.renderer import Scene,VisibilityPrior,receiver_grid,light_grid,unoccluded,physical_table
def run(output,frames=24,side=48):
if frames<1 or side<2:raise ValueError("Need frames>=1, side>=2")
output=Path(output);output.mkdir(parents=True,exist_ok=True)
points=receiver_grid(side,side);lights=light_grid();scene=Scene.create(300)
prior=VisibilityPrior(ROOT/"models/visibility_prior.npz")
p=prior(scene.features(points[:,None,:],lights[None,:,:]))
memory=WorldMemory(len(points),len(lights),"demo-scene-300")
rng=np.random.default_rng(3101);ids=np.arange(len(points));b=unoccluded(points,lights)
images={};events=[]
for frame in range(frames):
if frame==frames//2:
scene=scene.changed() # no notification to memory: deliberate surprise
v=memory.predict(ids,p)
s=freeze(b*v[...,None],proposal_from_bound(b,v,memory.trusted(ids),active=True))
j=draw(s,2,rng);vis=scene.visibility(points[:,None,:],lights[j])
values=b[np.arange(len(ids))[:,None],j]*vis[...,None]
result=correct(s,j,values)
conflicts=memory.commit(ids,j,vis,revise_on_conflict=True)
events.append({"frame":frame,"conflicting_ray_entries":conflicts,"epoch_after":memory.epoch})
if frame in {0,max(0,frames//2-1),frames//2,frames-1}:
images[f"frame_{frame:03d}"]=result.reshape(side,side,3)
# Reference is generated after online rendering and never supplied to it.
images["reference_final"]=physical_table(scene,points,lights,b).sum(1).reshape(side,side,3)
np.savez_compressed(output/"linear_frames.npz",**images)
memory.save(output/"world_memory.npz")
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
fig,axes=plt.subplots(1,len(images),figsize=(3*len(images),3.6))
for ax,(label,im) in zip(np.atleast_1d(axes),images.items()):
ax.imshow(np.clip(im,0,1)**(1/2.2),origin="lower")
ax.set_title(label.replace("_"," "),fontsize=10);ax.axis("off")
fig.suptitle("AUREOLE-R CPU demo: two fresh shadow rays per receiver / frame",fontsize=13)
fig.text(.5,.035,"Preview clips negative estimates and applies gamma. Statistical outputs remain linear in the NPZ.",ha="center",fontsize=9)
fig.tight_layout(rect=(0,.08,1,.92));fig.savefig(output/"demo.png",dpi=160);plt.close(fig)
report={"frames":frames,"receiver_count":len(points),"emitters":len(lights),"rays":frames*len(points)*2,
"events":events,"final_mse":float(np.mean((images[f"frame_{frames-1:03d}"]-images["reference_final"])**2)),
"scope":"small CPU direct-light demo; no SR/FG/game/GPU implementation"}
(output/"demo.json").write_text(json.dumps(report,indent=2)+"\n")
print(json.dumps(report,indent=2))
if __name__=="__main__":
parser=argparse.ArgumentParser();parser.add_argument("--output",default="demo_output")
parser.add_argument("--frames",type=int,default=24);parser.add_argument("--side",type=int,default=48)
args=parser.parse_args();run(args.output,args.frames,args.side)