WebGPU pixel look: GPU colours the world, CPU only rare cells (t88 phase 2a)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+10
-9
@@ -21,7 +21,7 @@ with launch(viewport={'width': 1024, 'height': 640}) as (b, pg, url):
|
||||
ev = pg.evaluate
|
||||
check('the smooth look is the default and is drawing', ev("SET.look === 'smooth' && SM.ok && R.smoothOn"), ev('[SET.look, SM.ok, SM.why, R.smoothOn]'))
|
||||
# the canvas shows the GPU image: sample a sky pixel and a ground pixel, they must differ and not be black
|
||||
px = ev("""(() => { const c = R.ctx.getImageData(R.canvas.width >> 1, 4, 1, 1).data, g = worldToScreenPx(bot.x + 2, surfY[Math.floor(bot.x)] + 6), d = R.ctx.getImageData(Math.round(g.x), Math.round(g.y), 1, 1).data; return [Array.from(c), Array.from(d)]; })()""")
|
||||
px = ev("""(() => { const c = worldPixelContext().getImageData(R.canvas.width >> 1, 4, 1, 1).data, g = worldToScreenPx(bot.x + 2, surfY[Math.floor(bot.x)] + 6), d = worldPixelContext().getImageData(Math.round(g.x), Math.round(g.y), 1, 1).data; return [Array.from(c), Array.from(d)]; })()""")
|
||||
check('it draws sky and ground', sum(px[0][:3]) > 200 and px[0][:3] != px[1][:3], px)
|
||||
pg.screenshot(path=str(out / 'smooth.png'))
|
||||
ev("player.lens = true"); pg.keyboard.press('h'); pg.wait_for_timeout(1500)
|
||||
@@ -43,8 +43,9 @@ with launch(viewport={'width': 1024, 'height': 640}) as (b, pg, url):
|
||||
const i = y * W + x;
|
||||
setCell(i, STONE, 22, F_NAT); bgm[i] = 0; noiseB[i] = 128;
|
||||
}
|
||||
GPU.world = null; // The fixture changed static noise in place.
|
||||
const fill = m => { for (let y = 100; y < 140; y++) for (let x = 100; x < 180; x++) setCell(y * W + x, m, 22); };
|
||||
const at = (x, y) => { const c = R.px[(y - R.vy0) * R.bw + x - R.vx0]; return (c & 255) + (c >>> 8 & 255) + (c >>> 16 & 255); };
|
||||
const at = (x, y) => { const p=worldToScreenPx(x+0.5,y+0.5), c=worldPixelContext().getImageData(p.x,p.y,1,1).data; return c[0]+c[1]+c[2]; };
|
||||
const out = {};
|
||||
for (const lens of [false, true]) {
|
||||
R.lens = lens; SET.look = 'pixel'; fill(RSTONE); drawWorld();
|
||||
@@ -59,7 +60,7 @@ with launch(viewport={'width': 1024, 'height': 640}) as (b, pg, url):
|
||||
fill(RSTONE); SET.look = 'smooth'; SM.scale = 1; drawWorld();
|
||||
const sample = (x, y) => {
|
||||
const p = worldToScreenPx(x, y);
|
||||
const c = R.ctx.getImageData(Math.floor(p.x), Math.floor(p.y), 1, 1).data;
|
||||
const c = worldPixelContext().getImageData(Math.floor(p.x), Math.floor(p.y), 1, 1).data;
|
||||
return c[0] + c[1] + c[2];
|
||||
};
|
||||
out.smooth = [sample(140.5, 140.08), sample(140.5, 142.5)];
|
||||
@@ -140,8 +141,8 @@ with launch(viewport={'width': 1024, 'height': 640}) as (b, pg, url):
|
||||
const x=cell%W,y=(cell/W)|0,control=80*W+180;
|
||||
bot.x=118;bot.y=78;snapCamera();
|
||||
setCell(cell,SAND,22,0);setCell(control,SAND,22,0);
|
||||
noiseB[cell]=noiseB[control]=128;
|
||||
const at=i=>R.px[(((i/W)|0)-R.vy0)*R.bw+i%W-R.vx0];
|
||||
noiseB[cell]=noiseB[control]=128; GPU.world=null;
|
||||
const at=i=>{ if(R.smoothOn) return R.px[(((i/W)|0)-R.vy0)*R.bw+i%W-R.vx0]; const p=worldToScreenPx(i%W+0.5,((i/W)|0)+0.5), c=worldPixelContext().getImageData(p.x,p.y,1,1).data; return c[0]|c[1]<<8|c[2]<<16; };
|
||||
SET.look='pixel';drawWorld();const colors=[at(cell)&0xffffff,at(control)&0xffffff];
|
||||
SET.look='smooth';drawWorld();const grainClass=at(cell)>>>24;
|
||||
return {colors,grainClass};
|
||||
@@ -162,7 +163,7 @@ with launch(viewport={'width': 1024, 'height': 640}) as (b, pg, url):
|
||||
for(const look of ["pixel","smooth"]) {
|
||||
SET.look=look;SM.scale=1;drawWorld();
|
||||
const bad=[], copper=c=>c[0]>c[1]*1.15 && c[1]>c[2]*1.1;
|
||||
const sample=(x,y)=>{const p=worldToScreenPx(x,y);return Array.from(R.ctx.getImageData(Math.floor(p.x),Math.floor(p.y),1,1).data);};
|
||||
const sample=(x,y)=>{const p=worldToScreenPx(x,y);return Array.from(worldPixelContext().getImageData(Math.floor(p.x),Math.floor(p.y),1,1).data);};
|
||||
for(const j of JOIN_CASES.filter(j=>j.code===BP_SCREW)) {
|
||||
const slope=j.v===4 || j.v===6?-1:1, side=j.end?1:-1;
|
||||
const joins=diagonalScrewJoins(j.bx,j.by,j.v);
|
||||
@@ -211,7 +212,7 @@ with launch(viewport={'width': 1024, 'height': 640}) as (b, pg, url):
|
||||
const b=j.by*BW+j.bx,nb=j.ny*BW+j.nx;
|
||||
const plan=new Map([[b,[BP_SCREW,j.v]],[nb,[BP_SCREW,j.straight]]]);
|
||||
removeBlock(j.bx,j.by);removeBlock(j.nx,j.ny);
|
||||
const sample=(x,y)=>{const p=worldToScreenPx(j.nx*4+x,j.ny*4+y);return Array.from(R.ctx.getImageData(Math.floor(p.x),Math.floor(p.y),1,1).data).join(',');};
|
||||
const sample=(x,y)=>{const p=worldToScreenPx(j.nx*4+x,j.ny*4+y);return Array.from(worldPixelContext().getImageData(Math.floor(p.x),Math.floor(p.y),1,1).data).join(',');};
|
||||
SM.scale=1;drawWorld();const bg=sample(ux,uy),empty=sample(2,2);
|
||||
for(const [n,piece] of plan)ghostBlocks.set(n,piece);
|
||||
drawWorld();
|
||||
@@ -236,7 +237,7 @@ with launch(viewport={'width': 1024, 'height': 640}) as (b, pg, url):
|
||||
try {
|
||||
const j=JOIN_CASES.find(j=>j.v===5 && j.end===1 && !j.vertical && j.spot===2 && j.code===BP_SCREW);
|
||||
const bx=j.nx+1,by=j.ny;
|
||||
const sample=()=>{const p=worldToScreenPx(bx*4,by*4);return Array.from(R.ctx.getImageData(Math.floor(p.x),Math.floor(p.y),4*R.zp,4*R.zp).data).join(',');};
|
||||
const sample=()=>{const p=worldToScreenPx(bx*4,by*4);return Array.from(worldPixelContext().getImageData(Math.floor(p.x),Math.floor(p.y),4*R.zp,4*R.zp).data).join(',');};
|
||||
drawWorld();const plain=sample(),bad=[];
|
||||
for(const m of [WOOD,LEAVES]) {
|
||||
for(let y=by*4;y<by*4+4;y++)for(let x=bx*4;x<bx*4+4;x++)bgm[y*W+x]=m;
|
||||
@@ -252,7 +253,7 @@ with launch(viewport={'width': 1024, 'height': 640}) as (b, pg, url):
|
||||
const j=JOIN_CASES.find(j=>j.v===4&&j.end===0&&j.code===BP_BELT&&j.spot===0);
|
||||
try {
|
||||
slopeDetailAt=()=>0;performance.now=()=>frozen;
|
||||
const sample=()=>{const p=worldToScreenPx(j.bx*BS+0.4,j.by*BS+2.5);return Array.from(R.ctx.getImageData(Math.floor(p.x),Math.floor(p.y),1,1).data);};
|
||||
const sample=()=>{const p=worldToScreenPx(j.bx*BS+0.4,j.by*BS+2.5);return Array.from(worldPixelContext().getImageData(Math.floor(p.x),Math.floor(p.y),1,1).data);};
|
||||
for(const look of ['pixel','smooth']) {
|
||||
SET.look=look;SM.scale=1;drawWorld();const joined=sample();
|
||||
removeBlock(j.nx,j.ny);drawWorld();const free=sample();
|
||||
|
||||
Reference in New Issue
Block a user