Smooth look on WebGPU: WGSL port fed by GPU inputs and CPU overrides (t88 phase 2c)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
// Field mip levels preserve the legacy trilinear AO sample at level 2.2.
|
||||
const GPU_FIELD_MIP = `
|
||||
@group(0) @binding(0) var source: texture_2d<f32>;
|
||||
@group(0) @binding(1) var linear: sampler;
|
||||
@vertex fn vs(@builtin(vertex_index) i: u32) -> @builtin(position) vec4f {
|
||||
let pos=array<vec2f,3>(vec2f(-1,-1),vec2f(3,-1),vec2f(-1,3)); return vec4f(pos[i],0,1);
|
||||
}
|
||||
@fragment fn fs(@builtin(position) p: vec4f) -> @location(0) vec4f {
|
||||
let size=max(vec2u(1),textureDimensions(source)/2u);
|
||||
return textureSampleLevel(source,linear,p.xy/vec2f(size),0);
|
||||
}`;
|
||||
function gpuSmoothInit() {
|
||||
const d=GPU.device;
|
||||
const pipeline=(code,vertex,format)=>d.createRenderPipeline({layout:'auto',vertex:{module:d.createShaderModule({code:vertex}),entryPoint:'vs'},fragment:{module:d.createShaderModule({code}),entryPoint:'fs',targets:[{format}]},primitive:{topology:'triangle-list'}});
|
||||
GPU.smooth=pipeline(GPU_SMOOTH,GPU_DRAW,GPU.format);
|
||||
GPU.fieldMip=pipeline(GPU_FIELD_MIP,GPU_FIELD_MIP,'rgba8unorm');
|
||||
GPU.smoothUniform=d.createBuffer({size:16,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST});
|
||||
}
|
||||
function gpuSmoothTextures() {
|
||||
const w=R.bw,h=R.bh;
|
||||
GPU.smoothOver=Array.from({length:3},()=>gpuTexture(w,h));
|
||||
GPU.smoothMask=gpuTexture(w,h,'r8uint');
|
||||
GPU.backTex=gpuTexture(w,h,'rgba8unorm',true);
|
||||
GPU.treeTex=gpuTexture(w,h,'rgba8unorm',true);
|
||||
GPU.fieldTex=GPU.device.createTexture({size:[w,h],format:'rgba8unorm',mipLevelCount:Math.min(4,1+Math.floor(Math.log2(Math.max(w,h)))),usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.STORAGE_BINDING|GPUTextureUsage.RENDER_ATTACHMENT});
|
||||
GPU.viewTextures.push(...GPU.smoothOver,GPU.smoothMask,GPU.backTex,GPU.treeTex,GPU.fieldTex);
|
||||
}
|
||||
function gpuSmoothBindings(group,view,buffer) {
|
||||
GPU.bindColourSmooth=group(GPU.colourSmooth,[buffer(GPU.uniform),buffer(GPU.lut),buffer(GPU.land),...GPU.worldTextures.slice(0,9).map(view),view(GPU.override),view(GPU.overrideGlow),view(GPU.colourTex),view(GPU.glowTex),view(GPU.backTex),view(GPU.treeTex),GPU.fieldTex.createView({baseMipLevel:0,mipLevelCount:1}),...GPU.smoothOver.map(view),view(GPU.smoothMask)]);
|
||||
GPU.bindSmooth=group(GPU.smooth,[buffer(GPU.uniform),view(GPU.colourTex),view(GPU.backTex),view(GPU.treeTex),view(GPU.fieldTex),view(GPU.lightTex),view(GPU.glowTex),GPU.sampler,buffer(GPU.smoothUniform)]);
|
||||
GPU.fieldMips=[];
|
||||
for(let i=1;i<GPU.fieldTex.mipLevelCount;i++) GPU.fieldMips.push({
|
||||
bind:group(GPU.fieldMip,[GPU.fieldTex.createView({baseMipLevel:i-1,mipLevelCount:1}),GPU.sampler]),
|
||||
view:GPU.fieldTex.createView({baseMipLevel:i,mipLevelCount:1})
|
||||
});
|
||||
}
|
||||
function gpuSmoothUpload() {
|
||||
for(const [i,a] of [R.backPx,R.treePx,R.fieldPx].entries()) gpuWrite(GPU.smoothOver[i],a,R.bw,0,0,R.bw,R.bh);
|
||||
gpuWrite(GPU.smoothMask,GPU.overrideMask,R.bw,0,0,R.bw,R.bh);
|
||||
GPU.device.queue.writeBuffer(GPU.smoothUniform,0,new Float32Array([(performance.now()-SM.t0)/1000,smoothSurface(),SET.glow==='off'?0:SET.glow==='high'?0.9:0.55,0]));
|
||||
}
|
||||
function gpuSmoothMips(encoder) {
|
||||
for(const m of GPU.fieldMips) {
|
||||
const pass=encoder.beginRenderPass({colorAttachments:[{view:m.view,loadOp:'clear',storeOp:'store'}]});
|
||||
pass.setPipeline(GPU.fieldMip);pass.setBindGroup(0,m.bind);pass.draw(3);pass.end();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user