// 3x3 convolution (vec4-optimized) // Source layers: 7→4 channels (RGBD output) // Assumes 'tex' (the input) is *not* normalized to [-1,1], but is [0,1] // UV coordinates remain in [0,1] and are normalized internally // weights: array, 72> (9 pos × 4 ch × 2 vec4) fn cnn_conv3x3_7to4_src( tex: texture_2d, samp: sampler, uv: vec2, resolution: vec2, weights: array, 72> ) -> vec4 { let step = 1.0 / resolution; // Compute grayscale from original (converted in [-1,1]) let original = (textureSample(tex, samp, uv) - 0.5) * 2.0; let gray = dot(original.rgb, vec3(0.2126, 0.7152, 0.0722)); // Normalize UV to [-1,1] let uv_norm = (uv - 0.5) * 2.0; let in1 = vec4(uv_norm, gray, 1.0); var sum = vec4(0.0); var pos = 0; for (var dy = -1; dy <= 1; dy++) { for (var dx = -1; dx <= 1; dx++) { let offset = vec2(f32(dx), f32(dy)) * step; let rgbd = (textureSample(tex, samp, uv + offset) - .5) * 2.0; sum.r += dot(weights[pos+0], rgbd) + dot(weights[pos+1], in1); sum.g += dot(weights[pos+2], rgbd) + dot(weights[pos+3], in1); sum.b += dot(weights[pos+4], rgbd) + dot(weights[pos+5], in1); sum.a += dot(weights[pos+6], rgbd) + dot(weights[pos+7], in1); pos += 8; } } return sum; } // Inner layers: 7→4 channels (vec4-optimized) // Assumes 'tex' is already normalized to [-1,1] // UV coordinates remain in [0,1] and are normalized internally // weights: array, 72> (9 pos × 4 ch × 2 vec4) fn cnn_conv3x3_7to4( tex: texture_2d, samp: sampler, uv: vec2, resolution: vec2, gray: f32, weights: array, 72> ) -> vec4 { let step = 1.0 / resolution; // Normalize UV to [-1,1] let uv_norm = (uv - 0.5) * 2.0; var sum = vec4(0.0); var pos = 0; for (var dy = -1; dy <= 1; dy++) { for (var dx = -1; dx <= 1; dx++) { let offset = vec2(f32(dx), f32(dy)) * step; let rgbd = textureSample(tex, samp, uv + offset); let in1 = vec4(uv_norm, gray, 1.0); sum.r += dot(weights[pos+0], rgbd) + dot(weights[pos+1], in1); sum.g += dot(weights[pos+2], rgbd) + dot(weights[pos+3], in1); sum.b += dot(weights[pos+4], rgbd) + dot(weights[pos+5], in1); sum.a += dot(weights[pos+6], rgbd) + dot(weights[pos+7], in1); pos += 8; } } return sum; } // Final layer: 7→1 channel (vec4-optimized) // Assumes 'tex' is already normalized to [-1,1] // UV coordinates remain in [0,1] and are normalized internally // weights: array, 18> (9 pos × 2 vec4) fn cnn_conv3x3_7to1( tex: texture_2d, samp: sampler, uv: vec2, resolution: vec2, gray: f32, weights: array, 18> ) -> f32 { let step = 1.0 / resolution; // Normalize UV to [-1,1] let uv_norm = (uv - 0.5) * 2.0; let in1 = vec4(uv_norm, gray, 1.0); var sum = 0.0; var pos = 0; for (var dy = -1; dy <= 1; dy++) { for (var dx = -1; dx <= 1; dx++) { let offset = vec2(f32(dx), f32(dy)) * step; let rgbd = textureSample(tex, samp, uv + offset); sum += dot(weights[pos], rgbd) + dot(weights[pos+1], in1); pos += 2; } } return sum; }