Files
rfcp/docs/devlog/gpu_supp/SESSION-2026-02-06-WebGL-Radial-Summary.md
2026-02-07 12:56:25 +02:00

6.0 KiB
Raw Blame History

RFCP v3.10.5 Session Summary - 2026-02-06

Що зробили сьогодні

1. WebGL Texture-Based Coverage (ЗАВЕРШЕНО )

Проблема: Canvas heatmap був blocky, хотіли smooth interpolation.

Рішення: Texture-based WebGL з smoothstep shader + nearest neighbor fill.

Файл: frontend/src/components/map/WebGLCoverageLayer.tsx

Як працює:

  1. Створюємо texture де кожен pixel = RSRP value
  2. Nearest neighbor fill для заповнення gaps (circular coverage → rectangular texture)
  3. Smoothstep shader для C2 continuity interpolation
  4. Colormap applied AFTER interpolation

Статус: Працює, але все ще blocky на zoom in через nearest neighbor fill.


2. WebGL Radial Gradients Coverage (В ПРОЦЕСІ 🔄)

Мета: Красиві smooth gradients як Canvas heatmap, але GPU-accelerated.

Файл: frontend/src/components/map/WebGLRadialCoverageLayer.tsx

Як працює:

  1. Кожна точка = quad з Gaussian radial falloff
  2. Additive blending в float framebuffer: (weight × rsrp, weight)
  3. Final composite pass: normalize (R/G) + colormap

Поточний статус:

  • Framebuffer створюється правильно
  • Points рендеряться (framebuffer має дані)
  • Composite pass працює (final pixel має колір)
  • 50m показує beautiful smooth gradients!
  • 200m тепер теж показує (після radius fix)
  • ⚠️ Coverage radius не повний (обрізається раніше ніж 10km)
  • ⚠️ Темне коло на периферії (falloff занадто різкий?)
  • ⚠️ Selector dropdown сірий на білому (CSS issue)

3. Coverage Renderer Selector (ЗАВЕРШЕНО )

Файл: frontend/src/store/settings.ts

Додано: coverageRenderer: 'radial' | 'texture' | 'canvas'

UI: Dropdown в Coverage Settings panel

Fallback chain:

  • Radial fails → Texture
  • Texture fails → Canvas

Залишилось зробити (Next Session)

Priority 1: Fix Radial Coverage Radius

Симптом: Coverage не покриває повні 10km, обрізається раніше.

Можливі причини:

  1. Canvas bounds не включають padding для point radius
  2. Points на краю мають gradient що виходить за canvas
  3. Normalized coordinates calculation wrong at edges

Debug:

// Перевірити bounds vs actual coverage extent
console.log('Canvas bounds:', bounds);
console.log('Points extent:', {
  minLat: Math.min(...points.map(p => p.lat)),
  maxLat: Math.max(...points.map(p => p.lat)),
  // ...
});

Fix approach:

  1. Додати padding до canvas bounds = point radius
  2. Або clip points що виходять за межі

Priority 2: Fix Dark Ring on Periphery

Симптом: Темне коло на краю coverage area.

Причина: Точки на периферії мають менше сусідів → менший total weight → темніший колір після normalization.

Fix options:

  1. Збільшити radius multiplier (3.0× замість 2.5×)
  2. Або додати edge detection і boost alpha там
  3. Або використати min weight threshold перед normalization

Priority 3: Fix Selector Dropdown Styling

Симптом: Сірий текст на білому фоні (погано видно).

Fix: Update CSS classes в App.tsx для dropdown.


Priority 4: Performance Testing

Протестувати з великою кількістю точок:

  • 10,000+ points
  • 50,000+ points
  • Measure frame time

Якщо повільно — implement instanced rendering.


Files Changed Today

frontend/src/components/map/
├── WebGLCoverageLayer.tsx      # Texture-based (updated with NN fill)
├── WebGLRadialCoverageLayer.tsx # NEW - Radial gradients
└── GeographicHeatmap.tsx       # Canvas fallback (unchanged)

frontend/src/store/
└── settings.ts                 # Added coverageRenderer option

frontend/src/
└── App.tsx                     # Integrated renderer selector

Console Debug Commands

// Check which renderer is active
document.querySelectorAll('canvas').forEach(c => 
  console.log(c.className, c.width, c.height)
);

// Check WebGL errors
const canvas = document.querySelector('.webgl-radial-coverage');
const gl = canvas?.getContext('webgl');
console.log('WebGL error:', gl?.getError());

// Read center pixel
gl?.readPixels(canvas.width/2, canvas.height/2, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array(4));

Key Insights Learned

  1. Texture-based vs Radial: Texture good for terrain detail accuracy, Radial good for beautiful visualization.

  2. Float framebuffer: Need EXT_color_buffer_float extension. Fallback: use RGBA8 with encoding.

  3. Additive blending: gl.blendFunc(gl.ONE, gl.ONE) for accumulation, then gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA) for final composite.

  4. Weighted average in shader: Store (weight × value, weight), then normalize: value = R / G.

  5. Radius scaling: Higher resolution = more points = smaller radius. Lower resolution = fewer points = larger radius to compensate.


Git Status

  • Pushed working WebGL texture-based coverage
  • 🔄 WebGL radial in progress (functional but incomplete)

Next Session Start Point

  1. Відкрити RFCP project
  2. npm run dev в frontend
  3. Test radial coverage з 50m і 200m
  4. Fix radius issue (Priority 1)
  5. Fix dark ring (Priority 2)
  6. Polish UI (Priority 3)

Session Stats

  • Duration: ~6 hours
  • Iterations: 15+ fix attempts
  • Final result: Working radial gradients renderer (90% complete)
  • Key breakthrough: Discovering framebuffer had data but composite pass wasn't reading it