124 lines
4.3 KiB
Markdown
124 lines
4.3 KiB
Markdown
|
|
# Runtime pipeline
|
|||
|
|
|
|||
|
|
Документ фиксирует runtime-поведение движка: кто кого вызывает в кадре, как проходят рендер, коллизия и подключение эффектов.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 1.15. Алгоритм рендера модели (реконструкция)
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
Вход: model, instanceTransform, cameraFrustum
|
|||
|
|
|
|||
|
|
1. Определить current_lod ∈ {0, 1, 2} (по дистанции до камеры / настройкам).
|
|||
|
|
|
|||
|
|
2. Для каждого node (nodeIndex = 0 .. nodeCount−1):
|
|||
|
|
a. Вычислить nodeTransform = instanceTransform × nodeLocalTransform
|
|||
|
|
|
|||
|
|
b. slotIndex = nodeTable[nodeIndex].slotMatrix[current_lod][group=0]
|
|||
|
|
если slotIndex == 0xFFFF → пропустить узел
|
|||
|
|
|
|||
|
|
c. slot = slotTable[slotIndex]
|
|||
|
|
|
|||
|
|
d. // Frustum culling:
|
|||
|
|
transformedAABB = transform(slot.aabb, nodeTransform)
|
|||
|
|
если transformedAABB вне cameraFrustum → пропустить
|
|||
|
|
|
|||
|
|
// Альтернативно по сфере:
|
|||
|
|
transformedCenter = nodeTransform × slot.sphereCenter
|
|||
|
|
scaledRadius = slot.sphereRadius × max(scaleX, scaleY, scaleZ)
|
|||
|
|
если сфера вне frustum → пропустить
|
|||
|
|
|
|||
|
|
e. Для i = 0 .. slot.batchCount − 1:
|
|||
|
|
batch = batchTable[slot.batchStart + i]
|
|||
|
|
|
|||
|
|
// Фильтрация по batchFlags (если нужна)
|
|||
|
|
|
|||
|
|
// Установить материал:
|
|||
|
|
setMaterial(batch.materialIndex)
|
|||
|
|
|
|||
|
|
// Установить transform:
|
|||
|
|
setWorldMatrix(nodeTransform)
|
|||
|
|
|
|||
|
|
// Нарисовать:
|
|||
|
|
DrawIndexedPrimitive(
|
|||
|
|
baseVertex = batch.baseVertex,
|
|||
|
|
indexStart = batch.indexStart,
|
|||
|
|
indexCount = batch.indexCount,
|
|||
|
|
primitiveType = TRIANGLE_LIST
|
|||
|
|
)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 1.16. Алгоритм обхода треугольников (коллизия / пикинг)
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
Вход: model, nodeIndex, lod, group, filterMask, callback
|
|||
|
|
|
|||
|
|
1. slotIndex = nodeTable[nodeIndex].slotMatrix[lod][group]
|
|||
|
|
если slotIndex == 0xFFFF → выход
|
|||
|
|
|
|||
|
|
2. slot = slotTable[slotIndex]
|
|||
|
|
triDescIndex = slot.triStart
|
|||
|
|
|
|||
|
|
3. Для каждого batch в диапазоне [slot.batchStart .. slot.batchStart + slot.batchCount − 1]:
|
|||
|
|
batch = batchTable[batchIndex]
|
|||
|
|
triCount = batch.indexCount / 3 // округление: (indexCount + 2) / 3
|
|||
|
|
|
|||
|
|
Для t = 0 .. triCount − 1:
|
|||
|
|
triDesc = triDescTable[triDescIndex]
|
|||
|
|
|
|||
|
|
// Фильтрация:
|
|||
|
|
если (triDesc.triFlags & filterMask) → пропустить
|
|||
|
|
|
|||
|
|
// Получить индексы вершин:
|
|||
|
|
idx0 = indexBuffer[batch.indexStart + t*3 + 0] + batch.baseVertex
|
|||
|
|
idx1 = indexBuffer[batch.indexStart + t*3 + 1] + batch.baseVertex
|
|||
|
|
idx2 = indexBuffer[batch.indexStart + t*3 + 2] + batch.baseVertex
|
|||
|
|
|
|||
|
|
// Получить позиции:
|
|||
|
|
p0 = positions[idx0]
|
|||
|
|
p1 = positions[idx1]
|
|||
|
|
p2 = positions[idx2]
|
|||
|
|
|
|||
|
|
callback(triDesc, idx0, idx1, idx2, p0, p1, p2)
|
|||
|
|
|
|||
|
|
triDescIndex += 1
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 3.1. Архитектурный обзор
|
|||
|
|
|
|||
|
|
Подсистема эффектов реализована в `Effect.dll` и интегрирована в рендер через `Terrain.dll`.
|
|||
|
|
|
|||
|
|
### Экспорты Effect.dll
|
|||
|
|
|
|||
|
|
| Функция | Описание |
|
|||
|
|
|----------------------|--------------------------------------------------------|
|
|||
|
|
| `CreateFxManager` | Создать менеджер эффектов (3 параметра: int, int, int) |
|
|||
|
|
| `InitializeSettings` | Инициализировать настройки эффектов |
|
|||
|
|
|
|||
|
|
`CreateFxManager` возвращает объект‑менеджер, который регистрируется в движке и управляет всеми эффектами.
|
|||
|
|
|
|||
|
|
### Телеметрия из Terrain.dll
|
|||
|
|
|
|||
|
|
Terrain.dll содержит отладочную статистику рендера:
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
"Rendered meshes : %d"
|
|||
|
|
"Rendered primitives : %d"
|
|||
|
|
"Rendered faces : %d"
|
|||
|
|
"Rendered particles/batches : %d/%d"
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Из этого следует:
|
|||
|
|
|
|||
|
|
- Частицы рендерятся **батчами** (группами).
|
|||
|
|
- Статистика частиц отделена от статистики мешей.
|
|||
|
|
- Частицы интегрированы в общий 3D‑рендер‑пайплайн.
|
|||
|
|
|