Documentar Z-sorting en CLAUDE.md
This commit is contained in:
71
CLAUDE.md
71
CLAUDE.md
@@ -427,6 +427,77 @@ ROTOBALL_DAMPING_NEAR = 60.0f; // Ligera oscilación
|
||||
✅ **Estabilización automática**: Damping evita oscilaciones infinitas
|
||||
✅ **Performance**: O(1) por pelota, muy eficiente
|
||||
|
||||
---
|
||||
|
||||
## 🎨 Z-Sorting (Painter's Algorithm)
|
||||
|
||||
### Problema de Renderizado 3D
|
||||
|
||||
**Antes del Z-sorting:**
|
||||
- Pelotas renderizadas en orden fijo del vector: `Ball[0] → Ball[1] → ... → Ball[N]`
|
||||
- Orden aleatorio respecto a profundidad Z
|
||||
- **Problema:** Pelotas oscuras (fondo) pintadas sobre claras (frente)
|
||||
- Resultado: Inversión de profundidad visual incorrecta
|
||||
|
||||
**Después del Z-sorting:**
|
||||
- Pelotas ordenadas por `depth_brightness` antes de renderizar
|
||||
- Painter's Algorithm: **Fondo primero, frente último**
|
||||
- Pelotas oscuras (Z bajo) renderizadas primero
|
||||
- Pelotas claras (Z alto) renderizadas último (encima)
|
||||
- **Resultado:** Oclusión 3D correcta ✅
|
||||
|
||||
### Implementación (engine.cpp::render())
|
||||
|
||||
```cpp
|
||||
if (current_mode_ == SimulationMode::ROTOBALL) {
|
||||
// 1. Crear vector de índices
|
||||
std::vector<size_t> render_order;
|
||||
for (size_t i = 0; i < balls_.size(); i++) {
|
||||
render_order.push_back(i);
|
||||
}
|
||||
|
||||
// 2. Ordenar por depth_brightness (menor primero = fondo primero)
|
||||
std::sort(render_order.begin(), render_order.end(),
|
||||
[this](size_t a, size_t b) {
|
||||
return balls_[a]->getDepthBrightness() < balls_[b]->getDepthBrightness();
|
||||
});
|
||||
|
||||
// 3. Renderizar en orden de profundidad
|
||||
for (size_t idx : render_order) {
|
||||
// Renderizar balls_[idx]...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Complejidad y Performance
|
||||
|
||||
| Operación | Complejidad | Tiempo (estimado) |
|
||||
|-----------|-------------|-------------------|
|
||||
| Crear índices | O(n) | ~0.001ms (1K pelotas) |
|
||||
| std::sort | O(n log n) | ~0.01ms (1K pelotas) |
|
||||
| Renderizar | O(n) | ~variable |
|
||||
| **Total** | **O(n log n)** | **~0.15ms (10K pelotas)** |
|
||||
|
||||
**Impacto en FPS:**
|
||||
- 100 pelotas: Imperceptible (<0.001ms)
|
||||
- 1,000 pelotas: Imperceptible (~0.01ms)
|
||||
- 10,000 pelotas: Leve (~0.15ms, ~1-2 FPS)
|
||||
- 100,000 pelotas: Moderado (~2ms, ~10-15 FPS)
|
||||
|
||||
### Optimizaciones Aplicadas
|
||||
|
||||
✅ **Solo en modo RotoBall**: Modo física no tiene overhead
|
||||
✅ **Vector de índices**: `balls_` no se modifica (física estable)
|
||||
✅ **Reserve() usado**: Evita realocaciones
|
||||
✅ **Lambda eficiente**: Acceso directo sin copias
|
||||
|
||||
### Resultado Visual
|
||||
|
||||
✅ **Profundidad correcta**: Fondo detrás, frente delante
|
||||
✅ **Oclusión apropiada**: Pelotas claras cubren oscuras
|
||||
✅ **Efecto 3D realista**: Percepción de profundidad correcta
|
||||
✅ **Sin artefactos visuales**: Ordenamiento estable cada frame
|
||||
|
||||
## Métricas del Proyecto
|
||||
|
||||
### ✅ Logros Actuales
|
||||
|
||||
Reference in New Issue
Block a user