Mark a pixel the lens correction pushed off the sensor with alpha 0 in the camera-space tap
The fused shader stored black with alpha 1 for a pixel whose source coordinate left the frame, and the merge's warp averaged it in like any other: a dark, badly interpolated fringe along every frame's edge, visible as a seam wherever a frame ended and, later, as the edge the border fill continued. The display keeps its opaque black; CameraLinear stores alpha 0 and the warp weights each sample by the alpha it interpolated, dropping a sample that has none.
This commit is contained in:
@@ -68,8 +68,8 @@ fn to_direction(u: f32, v: f32) -> vec3<f32> {
|
||||
return vec3<f32>(sin(theta) * cos(phi), sin(phi), cos(theta) * cos(phi));
|
||||
}
|
||||
|
||||
fn load(x: i32, y: i32) -> vec3<f32> {
|
||||
return textureLoad(tile, vec2<i32>(x, y), 0).rgb;
|
||||
fn load(x: i32, y: i32) -> vec4<f32> {
|
||||
return textureLoad(tile, vec2<i32>(x, y), 0);
|
||||
}
|
||||
|
||||
@compute @workgroup_size(8, 8, 1)
|
||||
@@ -110,11 +110,25 @@ fn warp(@builtin(global_invocation_id) gid: vec3<u32>) {
|
||||
let y1 = min(y0 + 1, i32(p.tile_size.y) - 1);
|
||||
let fx = tx - f32(x0);
|
||||
let fy = ty - f32(y0);
|
||||
let top = mix(load(x0, y0), load(x1, y0), fx);
|
||||
let bot = mix(load(x0, y1), load(x1, y1), fx);
|
||||
let rgb = mix(top, bot, fy) * p.gain;
|
||||
// The four texels, with their alpha: the tap writes alpha 0 where the
|
||||
// lens correction found no source pixel, and a sample that touches one
|
||||
// of those is a partial pixel — down-weighted by exactly how much of
|
||||
// it is missing, and dropped when all of it is.
|
||||
let s00 = load(x0, y0);
|
||||
let s10 = load(x1, y0);
|
||||
let s01 = load(x0, y1);
|
||||
let s11 = load(x1, y1);
|
||||
let top = mix(s00, s10, fx);
|
||||
let bot = mix(s01, s11, fx);
|
||||
let s = mix(top, bot, fy);
|
||||
if (s.a <= 0.001) {
|
||||
return;
|
||||
}
|
||||
// Colour is the alpha-weighted mean of the texels that exist.
|
||||
let rgb = s.rgb / s.a * p.gain;
|
||||
let wa = w * s.a;
|
||||
let i = gid.y * p.chunk_size.x + gid.x;
|
||||
acc[i] = acc[i] + vec4<f32>(rgb * w, w);
|
||||
acc[i] = acc[i] + vec4<f32>(rgb * wa, wa);
|
||||
}
|
||||
|
||||
// Resolve: the accumulated chunk to sixteen-bit samples.
|
||||
|
||||
Reference in New Issue
Block a user