summaryrefslogtreecommitdiff
path: root/workspaces/main/shaders/cnn/cnn_conv5x5.wgsl
blob: 51367408a8f9c6bec120a4a1aeb9d8d962e02aa6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
// 5×5 variant for 7→4 channels (RGBD output)
// Assumes 'tex' and 'original' are already normalized to [-1,1]
// UV coordinates remain in [0,1] and are normalized internally
// weights: array<array<f32, 8>, 100> (25 positions × 4 channels, each with 7 weights + bias)
fn cnn_conv5x5_7to4(
  tex: texture_2d<f32>,
  samp: sampler,
  uv: vec2<f32>,
  resolution: vec2<f32>,
  original: vec4<f32>,
  weights: array<array<f32, 8>, 100>
) -> vec4<f32> {
  let step = 1.0 / resolution;

  let gray = 0.2126*original.r + 0.7152*original.g + 0.0722*original.b;
  let uv_norm = (uv - 0.5) * 2.0;

  var sum = vec4<f32>(0.0);
  var pos = 0;

  for (var dy = -2; dy <= 2; dy++) {
    for (var dx = -2; dx <= 2; dx++) {
      let offset = vec2<f32>(f32(dx), f32(dy)) * step;
      let rgbd = textureSample(tex, samp, uv + offset);  // Already in [-1,1]

      let inputs = array<f32, 7>(
        rgbd.r, rgbd.g, rgbd.b, rgbd.a,
        uv_norm.x, uv_norm.y, gray
      );

      for (var out_c = 0; out_c < 4; out_c++) {
        let idx = pos * 4 + out_c;
        var channel_sum = weights[idx][7];
        for (var in_c = 0; in_c < 7; in_c++) {
          channel_sum += weights[idx][in_c] * inputs[in_c];
        }
        sum[out_c] += channel_sum;
      }
      pos++;
    }
  }

  return sum;
}

// 5×5 variant for 7→1 channel (scalar output)
// Assumes 'tex' and 'original' are already normalized to [-1,1]
// UV coordinates remain in [0,1] and are normalized internally
// weights: array<array<f32, 8>, 25> (25 positions, each with 7 weights + bias)
fn cnn_conv5x5_7to1(
  tex: texture_2d<f32>,
  samp: sampler,
  uv: vec2<f32>,
  resolution: vec2<f32>,
  original: vec4<f32>,
  weights: array<array<f32, 8>, 25>
) -> f32 {
  let step = 1.0 / resolution;

  let gray = 0.2126*original.r + 0.7152*original.g + 0.0722*original.b;
  let uv_norm = (uv - 0.5) * 2.0;

  var sum = 0.0;
  var pos = 0;

  for (var dy = -2; dy <= 2; dy++) {
    for (var dx = -2; dx <= 2; dx++) {
      let offset = vec2<f32>(f32(dx), f32(dy)) * step;
      let rgbd = textureSample(tex, samp, uv + offset);  // Already in [-1,1]

      sum += weights[pos][0] * rgbd.r;
      sum += weights[pos][1] * rgbd.g;
      sum += weights[pos][2] * rgbd.b;
      sum += weights[pos][3] * rgbd.a;
      sum += weights[pos][4] * uv_norm.x;
      sum += weights[pos][5] * uv_norm.y;
      sum += weights[pos][6] * gray;
      sum += weights[pos][7];  // Bias

      pos++;
    }
  }

  return sum;  // Output in [-1,1]
}