Я разработчик интерфейса, работаю над визуализацией тепловой карты солнечного излучения, используя Three.js во внешнем интерфейсе и Ladybug / Honeybee (Radiance) на серверной части.
Я изо всех сил пытаюсь понять правильную модель визуализации для тепловых карт и почему Ladybug/Rhino дает чистые, реалистичные результаты, в то время как моя визуализация Three.js выглядит неправильно или вводит в заблуждение.
Это не физическая проблема (Ladybug правильно вычисляет значения).
Это проблема модели визуализации.
Что я строю
Цель
Визуализация годовой солнечной радиации (кВтч/м²) на модели здания.
Трубопровод
- Бэкенд (Python + Honeybee Radiance + Ladybug)
- Загрузить OBJ здания
- Создать сетку поверхности на внешних гранях (крыша + фасады)
- Запустить годовую освещенность
- Вывод:
sensorPoints: {x, y, z, значение - heatmapCells: {position, Normal, Value (по одному на ячейку сетки поверхности)
- Фронтенд (Three.js + React)
- Загрузить тот же OBJ
- Отобразить сетку здания (нейтральный серый)
- Визуализация наложения тепловой карты с использованием одного квадрата на ячейку тепловой карты
- Раскрашивание каждого квадрата на основе значения ячейки
Тепловая карта представляет собой отдельное наложение поверхности, вдохновленное Божья коровка.
Что работает
- Положения датчиков правильно совпадают со зданием
- Внутренние минимальные, средние и максимальные значения правдоподобны
- Ячейки тепловой карты генерируются только для внешних граней (за исключением нижней стороны)
- Внутренние и внешние системы координат совпадают
1. Цвета выглядят нереалистично
- Большие области схлопываются в один и тот же цвет.
- Тепловая карта выглядит плоской или мутной.
- Не похоже на вывод Ladybug/Rhino.
Я не знаю:
- Генерирует ли Ladybug цвета или только значения
- Какую цветовую карту они используют
- Следует ли мне жестко запрограммировать цветовые шкалы или вычислять их динамически
- Пользовательский синий → Красные пандусы
- Three.js Lut
- Процентильное отсечение (p2–p98)
Я не могу легко определить:
- Внутренние значения неверны или
- Визуализация вводит в заблуждение.
4. Путаница между крышей и днищем
- Бэкенд корректно пропускает нижние грани.
- Но при экспериментах с раскраской вершин нижняя часть по-прежнему кажется цветной.
- Это заставило меня понять, что я, возможно, неправильно понимаю, как тепловые карты должны сопоставляться с геометрией
Изучая Ladybug/Rhino, кажется, что:
- Тепловые карты не основаны на вершинах
- Они основаны на сетке поверхностей
- Каждая ячейка сетки окрашена независимо
- Сама сетка не «цветная»; он обеспечивает только геометрию
- Это правильная ментальная модель?
- Поэтому тепловые карты на основе вершин не работают на коробчатых сетках?
- Поэтому тепловые карты Ladybug выглядят гладкими, а мои нет?
Отрисовка одного квадрата на ячейку тепловой карты:
const quadGeom = new THREE.PlaneGeometry(1, 1);
const mesh = new THREE.InstancedMesh(
quadGeom,
new THREE.MeshBasicMaterial({
vertexColors: true,
side: THREE.DoubleSide,
}),
heatmapCells.length
);
for (let i = 0; i < heatmapCells.length; i++) {
const { position, normal, value } = heatmapCells;
backendToObjectLocal(position, modelTransform, object, tmpPos);
tmpNormal.set(normal.x, normal.y, normal.z).normalize();
tmpPos.addScaledVector(tmpNormal, 0.02); // avoid z-fighting
quat.setFromUnitVectors(new THREE.Vector3(0, 0, 1), tmpNormal);
matrix.compose(tmpPos, quat, new THREE.Vector3(cellSize, cellSize, 1));
mesh.setMatrixAt(i, matrix);
mesh.setColorAt(i, getSolarHeatmapColor(value, min, max));
}
Color mapping:
function getSolarHeatmapColor(value, min, max) {
const t = THREE.MathUtils.clamp((value - min) / (max - min), 0, 1);
// Blue → Cyan → Green → Yellow → Red
}
Подробнее здесь: https://stackoverflow.com/questions/798 ... -how-shoul
Мобильная версия