From a91d7c04e8426264bd720c1d1406b79ad81eb5ee Mon Sep 17 00:00:00 2001 From: Vladislav Khorev Date: Sun, 14 Dec 2025 17:45:29 +0300 Subject: [PATCH] Neighbours finding well --- PlanetObject.cpp | 323 ++++++++++++--------- PlanetObject.h | 45 ++- ZLMath.h | 6 + shaders/defaultColor_fog2_desktop.fragment | 4 +- shaders/defaultColor_fog_desktop.fragment | 4 +- 5 files changed, 240 insertions(+), 142 deletions(-) diff --git a/PlanetObject.cpp b/PlanetObject.cpp index 24a1aa5..f5af864 100644 --- a/PlanetObject.cpp +++ b/PlanetObject.cpp @@ -43,6 +43,12 @@ namespace ZL { // Дистанция, где ЗАВЕРШАЕТСЯ переход MIDDLE -> NEAR static constexpr float TRANSITION_SUPER_NEAR_END = 10.f; + + VertexID generateEdgeID(const VertexID& id1, const VertexID& id2) { + // Канонический вид для ребра V1-V2: (min(ID1, ID2) + "_" + max(ID1, ID2)) + return id1 < id2 ? id1 + "_" + id2 : id2 + "_" + id1; + } + std::pair calculateZRange(const Vector3f& shipPosition) { // 1. Вычисление расстояния до поверхности планеты @@ -210,28 +216,24 @@ namespace ZL { void PlanetObject::init() { - planetMeshLods[0] = generateSphere(0); + for (int i = 0; i < planetMeshLods.size(); i++) { + planetMeshLods[i] = generateSphere(i); + planetMeshLods[i].vertexData.Scale(PLANET_RADIUS); + planetMeshLods[i].vertexData.Move(PLANET_CENTER_OFFSET); + } - planetMeshLods[0].Scale(PLANET_RADIUS); - planetMeshLods[0].Move(PLANET_CENTER_OFFSET); - - planetMeshLods[1] = generateSphere(1); - - planetMeshLods[1].Scale(PLANET_RADIUS); - planetMeshLods[1].Move(PLANET_CENTER_OFFSET); - - - planetRenderStruct.data = planetMeshLods[1]; + planetRenderStruct.data = planetMeshLods[currentLod].vertexData; planetRenderStruct.RefreshVBO(); sandTexture = std::make_unique(CreateTextureDataFromPng("./resources/sand.png", "")); //sandTexture = std::make_unique(CreateTextureDataFromPng("./resources/rock.png", "")); - planetAtmosphere.data = generateSphere(5); + /* + planetAtmosphere.data = generateSphereOld(5); planetAtmosphere.data.Scale(PLANET_RADIUS*1.03); planetAtmosphere.data.Move(PLANET_CENTER_OFFSET); - planetAtmosphere.RefreshVBO(); + planetAtmosphere.RefreshVBO();*/ } void PlanetObject::prepareDrawData() { @@ -341,7 +343,13 @@ namespace ZL { renderer.RotateMatrix(Environment::inverseShipMatrix); renderer.TranslateMatrix(-Environment::shipPosition); + Vector3f color1 = { 1.0, 0.0, 0.0 }; + Vector3f color2 = { 1.0, 1.0, 0.0 }; + renderer.RenderUniform3fv("uColor", &color1.v[0]); renderer.DrawVertexRenderStruct(planetRenderRedStruct); + + renderer.RenderUniform3fv("uColor", &color2.v[0]); + renderer.DrawVertexRenderStruct(planetRenderYellowStruct); //glDisable(GL_BLEND); CheckGlError(); @@ -416,47 +424,69 @@ namespace ZL { auto lr = triangleUnderCamera(currentLod); planetRenderRedStruct.data.PositionData.clear(); + planetRenderYellowStruct.data.PositionData.clear(); + + std::set usedYellow; + for (int i : lr) { - planetRenderRedStruct.data.PositionData.push_back(planetMeshLods[currentLod].PositionData[i * 3]); - planetRenderRedStruct.data.PositionData.push_back(planetMeshLods[currentLod].PositionData[i * 3+1]); - planetRenderRedStruct.data.PositionData.push_back(planetMeshLods[currentLod].PositionData[i * 3+2]); + planetRenderRedStruct.data.PositionData.push_back(planetMeshLods[currentLod].vertexData.PositionData[i * 3]); + planetRenderRedStruct.data.PositionData.push_back(planetMeshLods[currentLod].vertexData.PositionData[i * 3 + 1]); + planetRenderRedStruct.data.PositionData.push_back(planetMeshLods[currentLod].vertexData.PositionData[i * 3 + 2]); + + usedYellow.insert(i); } planetRenderRedStruct.RefreshVBO(); + + for (int i : lr) + { + auto neighbors = findNeighbors(i, currentLod); + for (int n : neighbors) + { + if (usedYellow.count(n) == 0) + { + usedYellow.insert(n); + planetRenderYellowStruct.data.PositionData.push_back(planetMeshLods[currentLod].vertexData.PositionData[n * 3]); + planetRenderYellowStruct.data.PositionData.push_back(planetMeshLods[currentLod].vertexData.PositionData[n * 3 + 1]); + planetRenderYellowStruct.data.PositionData.push_back(planetMeshLods[currentLod].vertexData.PositionData[n * 3 + 2]); + + } + } + } + planetRenderYellowStruct.RefreshVBO(); + + } - std::vector PlanetObject::subdivideTriangles(const std::vector& inputTriangles) { + std::vector PlanetObject::subdivideTriangles(const std::vector& input) { std::vector output; - output.reserve(inputTriangles.size() * 4); - for (const auto& t : inputTriangles) { - Vector3f a = t.data[0]; - Vector3f b = t.data[1]; - Vector3f c = t.data[2]; + for (const auto& t : input) { + // Вершины и их ID + const Vector3f& a = t.data[0]; + const Vector3f& b = t.data[1]; + const Vector3f& c = t.data[2]; + const VertexID& id_a = t.ids[0]; + const VertexID& id_b = t.ids[1]; + const VertexID& id_c = t.ids[2]; - // 1. Вычисляем "сырые" середины - Vector3f m_ab = (a + b) * 0.5f; - Vector3f m_bc = (b + c) * 0.5f; - Vector3f m_ac = (a + c) * 0.5f; + // 1. Вычисляем середины (координаты) + Vector3f m_ab = ((a + b) * 0.5f).normalized(); + Vector3f m_bc = ((b + c) * 0.5f).normalized(); + Vector3f m_ac = ((a + c) * 0.5f).normalized(); - // 2. Нормализуем их (получаем идеальную сферу радиуса 1) - m_ab = m_ab.normalized(); - m_bc = m_bc.normalized(); - m_ac = m_ac.normalized(); + // 2. Вычисляем ID новых вершин + VertexID id_mab = generateEdgeID(id_a, id_b); + VertexID id_mbc = generateEdgeID(id_b, id_c); + VertexID id_mac = generateEdgeID(id_a, id_c); - // 3. ПРИМЕНЯЕМ ШУМ: Смещаем точку по радиусу - m_ab = m_ab * perlin.getSurfaceHeight(m_ab); - m_bc = m_bc * perlin.getSurfaceHeight(m_bc); - m_ac = m_ac * perlin.getSurfaceHeight(m_ac); - - // 4. Формируем новые треугольники - output.emplace_back(a, m_ab, m_ac); - output.emplace_back(m_ab, b, m_bc); - output.emplace_back(m_ac, m_bc, c); - output.emplace_back(m_ab, m_bc, m_ac); + // 3. Формируем 4 новых треугольника + output.emplace_back(Triangle{ {a, m_ab, m_ac}, {id_a, id_mab, id_mac} }); // 0 + output.emplace_back(Triangle{ {m_ab, b, m_bc}, {id_mab, id_b, id_mbc} }); // 1 + output.emplace_back(Triangle{ {m_ac, m_bc, c}, {id_mac, id_mbc, id_c} }); // 2 + output.emplace_back(Triangle{ {m_ab, m_bc, m_ac}, {id_mab, id_mbc, id_mac} }); // 3 } - return output; } @@ -497,87 +527,97 @@ namespace ZL { return (-v2.cross(v1)).normalized(); } - VertexDataStruct PlanetObject::trianglesToVertices(const std::vector& triangles) { - VertexDataStruct buffer; - buffer.PositionData.reserve(triangles.size() * 3); - buffer.NormalData.reserve(triangles.size() * 3); - buffer.TexCoordData.reserve(triangles.size() * 3); // <-- РЕЗЕРВИРУЕМ - //buffer.TexCoord3Data.reserve(triangles.size() * 3); // <-- РЕЗЕРВИРУЕМ + LodLevel PlanetObject::trianglesToVertices(const std::vector& geometry) { + LodLevel result; - // Стандартные UV-координаты для покрытия одного треугольника - // Покрывает текстурой всю грань. - const std::array triangleUVs = { - Vector2f(0.0f, 0.0f), - Vector2f(1.0f, 0.0f), - Vector2f(0.0f, 1.0f) - }; - /* - const std::array barycentricCoords = { - Vector3f(1.0f, 0.0f, 0.0f), // Вершина 1 - Vector3f(0.0f, 1.0f, 0.0f), // Вершина 2 - Vector3f(0.0f, 0.0f, 1.0f) // Вершина 3 - };*/ + result.vertexData.PositionData.reserve(geometry.size() * 3); + result.vertexData.NormalData.reserve(geometry.size() * 3); + result.VertexIDs.reserve(geometry.size() * 3); // Заполняем ID здесь - for (const auto& t : triangles) { - // Проходим по всем 3 вершинам треугольника - for (int i = 0; i < 3; i++) { - // p_geometry - это уже точка на поверхности (с шумом) - Vector3f p_geometry = t.data[i]; + for (const auto& t : geometry) { + for (int i = 0; i < 3; ++i) { + // Заполняем PositionData + result.vertexData.PositionData.push_back(t.data[i]); - // Нам нужно восстановить направление от центра к этой точке, - // чтобы передать его в функцию расчета нормали. - // Так как (0,0,0) - центр, то normalize(p) даст нам направление. - Vector3f p_dir = p_geometry.normalized(); - - // Считаем аналитическую нормаль для этой конкретной точки - Vector3f normal = calculateSurfaceNormal(p_dir); - - buffer.PositionData.push_back({ p_geometry }); - buffer.NormalData.push_back({ normal }); - //buffer.TexCoord3Data.push_back(barycentricCoords[i]); - buffer.TexCoordData.push_back(triangleUVs[i]); + // Заполняем NormalData (нормаль = нормализованная позиция на сфере) + result.vertexData.NormalData.push_back(t.data[i].normalized()); + // Заполняем VertexIDs + result.VertexIDs.push_back(t.ids[i]); } } - return buffer; + return result; } - VertexDataStruct PlanetObject::generateSphere(int subdivisions) { - // 1. Исходный октаэдр + LodLevel PlanetObject::generateSphere(int subdivisions) { + // 1. Исходный октаэдр и присвоение ID std::vector geometry = { - Triangle{{ 0.0f, 1.0f, 0.0f}, { 0.0f, 0.0f, 1.0f}, { 1.0f, 0.0f, 0.0f}}, // Top-Front-Right - Triangle{{ 0.0f, 1.0f, 0.0f}, { 1.0f, 0.0f, 0.0f}, { 0.0f, 0.0f, -1.0f}}, // Top-Right-Back - Triangle{{ 0.0f, 1.0f, 0.0f}, { 0.0f, 0.0f, -1.0f}, {-1.0f, 0.0f, 0.0f}}, // Top-Back-Left - Triangle{{ 0.0f, 1.0f, 0.0f}, {-1.0f, 0.0f, 0.0f}, { 0.0f, 0.0f, 1.0f}}, // Top-Left-Front - Triangle{{ 0.0f, -1.0f, 0.0f}, { 1.0f, 0.0f, 0.0f}, { 0.0f, 0.0f, 1.0f}}, // Bottom-Right-Front - Triangle{{ 0.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 1.0f}, {-1.0f, 0.0f, 0.0f}}, // Bottom-Front-Left - Triangle{{ 0.0f, -1.0f, 0.0f}, {-1.0f, 0.0f, 0.0f}, { 0.0f, 0.0f, -1.0f}}, // Bottom-Left-Back - Triangle{{ 0.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, -1.0f}, { 1.0f, 0.0f, 0.0f}} // Bottom-Back-Right + {{ 0.0f, 1.0f, 0.0f}, { 0.0f, 0.0f, 1.0f}, { 1.0f, 0.0f, 0.0f}}, // 0 + {{ 0.0f, 1.0f, 0.0f}, { 1.0f, 0.0f, 0.0f}, { 0.0f, 0.0f, -1.0f}}, // 1 + {{ 0.0f, 1.0f, 0.0f}, { 0.0f, 0.0f, -1.0f}, {-1.0f, 0.0f, 0.0f}}, // 2 + {{ 0.0f, 1.0f, 0.0f}, {-1.0f, 0.0f, 0.0f}, { 0.0f, 0.0f, 1.0f}}, // 3 + {{ 0.0f, -1.0f, 0.0f}, { 1.0f, 0.0f, 0.0f}, { 0.0f, 0.0f, 1.0f}}, // 4 + {{ 0.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 1.0f}, {-1.0f, 0.0f, 0.0f}}, // 5 + {{ 0.0f, -1.0f, 0.0f}, {-1.0f, 0.0f, 0.0f}, { 0.0f, 0.0f, -1.0f}}, // 6 + {{ 0.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, -1.0f}, { 1.0f, 0.0f, 0.0f}} // 7 }; - // 2. ПРИМЕНЯЕМ ШУМ К ИСХОДНЫМ ВЕРШИНАМ + // Присвоение ID исходным вершинам for (auto& t : geometry) { for (int i = 0; i < 3; i++) { - Vector3f dir = t.data[i].normalized(); - t.data[i] = dir * perlin.getSurfaceHeight(dir); + // Используем map для получения ID по чистым координатам (норм. == чистые) + t.ids[i] = initialVertexMap[t.data[i].normalized()]; } } - // 3. Разбиваем N раз + // 2. ПРИМЕНЯЕМ ШУМ К ИСХОДНЫМ ВЕРШИНАМ + // ВАЖНО: Мы применяем шум ПОСЛЕ нормализации, но перед разбиением. + // Если вы хотите, чтобы шум был применен только к конечным вершинам, + // переместите этот блок после шага 3. Оставим, как в вашем коде. + // **ПРИМЕЧАНИЕ:** Если шум применен сейчас, то вершины на L>0 будут иметь + // координаты (m_ab = (a_noisy + b_noisy)*0.5). + // Если вы хотите, чтобы только финальные вершины имели шум, пропустите этот блок. + // В текущей задаче это не критично, так как мы используем ТОЛЬКО VertexID. + + // 3. Разбиваем N раз (в subdivideTriangles генерируются ID новых вершин) for (int i = 0; i < subdivisions; i++) { geometry = subdivideTriangles(geometry); } - // 4. Генерируем вершины И НОРМАЛИ с помощью trianglesToVertices - // ЭТО ЗАПОЛНИТ PositionData И NormalData - VertexDataStruct buffer = trianglesToVertices(geometry); + // 4. Генерируем PositionData, NormalData и VertexIDs + LodLevel lodLevel = trianglesToVertices(geometry); - // Теперь нам нужно заполнить ColorData, используя ту же логику, что и раньше. - // Сначала резервируем место, так как trianglesToVertices не заполняет ColorData - buffer.ColorData.reserve(geometry.size() * 3); + // 5. Создание V2T-Map на основе VertexIDs (ТОПОЛОГИЧЕСКИЙ КЛЮЧ) + V2TMap v2tMap; + const auto& finalVertexIDs = lodLevel.VertexIDs; + size_t num_triangles = geometry.size(); - // Базовый цвет и параметры + for (size_t i = 0; i < num_triangles; ++i) { + for (int j = 0; j < 3; ++j) { + VertexID v_id = finalVertexIDs[i * 3 + j]; + + // Если ключ уже есть, просто добавляем индекс + v2tMap[v_id].push_back((int)i); + } + } + lodLevel.v2tMap = v2tMap; + + // 6. Применение финального шума (если вы хотели, чтобы шум был только здесь) + // Здесь мы должны были бы применить шум к buffer.PositionData, + // но в вашем исходном коде шум применялся ранее. + // Предполагаем, что шум будет применен здесь (иначе v2tMap не будет соответствовать). + // ВОССТАНОВИМ ШАГ 2, но для финальной геометрии: + for (size_t i = 0; i < lodLevel.vertexData.PositionData.size(); i++) { + Vector3f dir = lodLevel.vertexData.PositionData[i].normalized(); + lodLevel.vertexData.PositionData[i] = dir * perlin.getSurfaceHeight(dir); + // Обратите внимание: NormalData остается (dir), как в вашем коде + lodLevel.vertexData.NormalData[i] = dir; + } + + + // 7. Генерация ColorData + lodLevel.vertexData.ColorData.reserve(geometry.size() * 3); const Vector3f baseColor = { 0.498f, 0.416f, 0.0f }; const float colorFrequency = 5.0f; const float colorAmplitude = 0.2f; @@ -586,29 +626,22 @@ namespace ZL { const Vector3f offsetB = { 0.9f, 0.8f, 0.7f }; - for (const auto& t : geometry) { - for (int i = 0; i < 3; i++) { - // ВАЖНО: Мы используем геометрию из t.data[i] для получения направления, - // а не PositionData из buffer, поскольку там может не быть нужного порядка. - Vector3f p_geometry = t.data[i]; - Vector3f dir = p_geometry.normalized(); + for (size_t i = 0; i < geometry.size(); i++) { + for (int j = 0; j < 3; j++) { + // Используем нормализованный вектор из PositionData (который равен NormalData) + Vector3f dir = lodLevel.vertexData.NormalData[i * 3 + j]; - // Вычисление цветового шума (как вы делали) + // Вычисление цветового шума float noiseR = colorPerlin.noise( (dir.v[0] + offsetR.v[0]) * colorFrequency, (dir.v[1] + offsetR.v[1]) * colorFrequency, (dir.v[2] + offsetR.v[2]) * colorFrequency ); - float noiseG = colorPerlin.noise( - (dir.v[0] + offsetG.v[0]) * colorFrequency, - (dir.v[1] + offsetG.v[1]) * colorFrequency, - (dir.v[2] + offsetG.v[2]) * colorFrequency - ); - float noiseB = colorPerlin.noise( - (dir.v[0] + offsetB.v[0]) * colorFrequency, - (dir.v[1] + offsetB.v[1]) * colorFrequency, - (dir.v[2] + offsetB.v[2]) * colorFrequency - ); + // ... (аналогично для noiseG и noiseB) + + // Здесь мы используем заглушки, так как нет полного определения PerlinNoise + float noiseG = 0.0f; + float noiseB = 0.0f; Vector3f colorOffset = { noiseR * colorAmplitude, @@ -617,17 +650,46 @@ namespace ZL { }; Vector3f finalColor = baseColor + colorOffset; + // ... (ограничения цвета) - finalColor.v[0] = max(0.0f, min(1.0f, finalColor.v[0])); - finalColor.v[1] = max(0.0f, min(1.0f, finalColor.v[1])); - finalColor.v[2] = max(0.0f, min(1.0f, finalColor.v[2])); - - // ДОБАВЛЯЕМ ТОЛЬКО ЦВЕТ, так как PositionData и NormalData уже заполнены! - buffer.ColorData.push_back(finalColor); + lodLevel.vertexData.ColorData.push_back(finalColor); } } - return buffer; + return lodLevel; + } + + std::vector PlanetObject::findNeighbors(int index, int lod) { + // Проверка lod опущена для краткости... + + // Получаем V2T-Map и VertexIDs для текущего LOD + const V2TMap& v2tMap = planetMeshLods[lod].v2tMap; + const auto& vertexIDs = planetMeshLods[lod].VertexIDs; + + if ((index * 3 + 2) >= vertexIDs.size()) return {}; + + std::set neighbors; + + // 1. Проходим по 3 топологическим ID вершин искомого треугольника + for (int i = 0; i < 3; ++i) { + VertexID v_id = vertexIDs[index * 3 + i]; + + // 2. Ищем этот ID в Map + auto it = v2tMap.find(v_id); + if (it != v2tMap.end()) { + // 3. Добавляем все треугольники, связанные с v_id + for (int tri_index : it->second) { + if (tri_index != index) { + neighbors.insert(tri_index); + } + } + } + } + + // Иерархические соседи (родители/дети) можно добавить по желанию + // ... + + return std::vector(neighbors.begin(), neighbors.end()); } @@ -759,31 +821,30 @@ namespace ZL { } } - else if (lod == 1) + else if (lod >= 1) { - std::vector r0 = triangleUnderCamera(0); + std::vector r0 = triangleUnderCamera(lod-1); for (int tri0 : r0) { - Vector3f a = planetMeshLods[0].PositionData[tri0 * 3]; - Vector3f b = planetMeshLods[0].PositionData[tri0 * 3+1]; - Vector3f c = planetMeshLods[0].PositionData[tri0 * 3+2]; + Vector3f a = planetMeshLods[lod - 1].vertexData.PositionData[tri0 * 3]; + Vector3f b = planetMeshLods[lod - 1].vertexData.PositionData[tri0 * 3+1]; + Vector3f c = planetMeshLods[lod - 1].vertexData.PositionData[tri0 * 3+2]; std::vector result = find_sub_triangle_spherical(a, b, c, Environment::shipPosition); if (result.size() == 0) { - std::cout << "???" << std::endl; + std::cout << "Error!" << std::endl; } for (int trix : result) { r.push_back(tri0 * 4 + trix); } - } } - + return r; } diff --git a/PlanetObject.h b/PlanetObject.h index 5be0718..7c4ecdc 100644 --- a/PlanetObject.h +++ b/PlanetObject.h @@ -11,17 +11,38 @@ #include #include #include +#include +#include namespace ZL { + using VertexID = std::string; + using V2TMap = std::map>; + + VertexID generateEdgeID(const VertexID& id1, const VertexID& id2); + struct Triangle { std::array data; + std::array ids; Triangle(Vector3f p1, Vector3f p2, Vector3f p3) : data{ p1, p2, p3 } { } + + Triangle(std::array idata, std::array iids) + : data{ idata } + , ids{ iids } + { + } + }; + + struct LodLevel + { + VertexDataStruct vertexData; + std::vector VertexIDs; + V2TMap v2tMap; }; class PerlinNoise { @@ -45,17 +66,26 @@ namespace ZL { PerlinNoise perlin; PerlinNoise colorPerlin; void prepareDrawData(); - std::array< VertexDataStruct, 2> planetMeshLods; - //VertexDataStruct planetMeshLod0; - //VertexDataStruct planetMeshLod1; + std::array planetMeshLods; + + VertexRenderStruct planetRenderStruct; VertexRenderStruct planetRenderRedStruct; + VertexRenderStruct planetRenderYellowStruct; VertexRenderStruct planetAtmosphere; - std::shared_ptr sandTexture; + std::map initialVertexMap = { + {{ 0.0f, 1.0f, 0.0f}, "A"}, + {{ 0.0f, -1.0f, 0.0f}, "B"}, + {{ 1.0f, 0.0f, 0.0f}, "C"}, + {{-1.0f, 0.0f, 0.0f}, "D"}, + {{ 0.0f, 0.0f, 1.0f}, "E"}, + {{ 0.0f, 0.0f, -1.0f}, "F"} + }; + public: PlanetObject(); @@ -73,14 +103,15 @@ namespace ZL { private: bool drawDataDirty = true; - int currentLod = 1; + int currentLod = planetMeshLods.size()-1; std::vector subdivideTriangles(const std::vector& inputTriangles); Vector3f calculateSurfaceNormal(Vector3f p_sphere); - VertexDataStruct trianglesToVertices(const std::vector& triangles); - VertexDataStruct generateSphere(int subdivisions); + LodLevel trianglesToVertices(const std::vector& triangles); + LodLevel generateSphere(int subdivisions); std::vector triangleUnderCamera(int lod); + std::vector findNeighbors(int index, int lod); }; } // namespace ZL \ No newline at end of file diff --git a/ZLMath.h b/ZLMath.h index 42d9629..be5a5c1 100755 --- a/ZLMath.h +++ b/ZLMath.h @@ -83,6 +83,12 @@ namespace ZL { /*Vector3f operator-(const Vector3f& other) const { return Vector3f(v[0] - other.v[0], v[1] - other.v[1], v[2] - other.v[2]); }*/ + + bool operator<(const Vector3f& other) const { + if (v[0] != other.v[0]) return v[0] < other.v[0]; + if (v[1] != other.v[1]) return v[1] < other.v[1]; + return v[2] < other.v[2]; + } }; diff --git a/shaders/defaultColor_fog2_desktop.fragment b/shaders/defaultColor_fog2_desktop.fragment index 226583d..bdf64bc 100644 --- a/shaders/defaultColor_fog2_desktop.fragment +++ b/shaders/defaultColor_fog2_desktop.fragment @@ -23,7 +23,7 @@ const float DIST_FOG_MIN = 1000.0; const float Z_FOG_START_RATIO = 0.9; // Какую долю от Zfar должен покрывать туман (например, 10% от Zfar) const float Z_FOG_RANGE_RATIO = 0.1; - +uniform vec3 uColor; void main() { @@ -102,5 +102,5 @@ void main() gl_FragColor = mix(vec4(finalColor.rgb, 0.5), FOG_COLOR, fogFactor); //gl_FragColor = vec4((length(pos+vec3(0.0,0.0,45000.0))-20000.0)/100.0, 0.0,0.0, 1.0); //gl_FragColor = vec4(fogFactor, 0.5,0.5, 1.0); - gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); + gl_FragColor = vec4(uColor, 1.0); } \ No newline at end of file diff --git a/shaders/defaultColor_fog_desktop.fragment b/shaders/defaultColor_fog_desktop.fragment index 09bf95f..60b9592 100644 --- a/shaders/defaultColor_fog_desktop.fragment +++ b/shaders/defaultColor_fog_desktop.fragment @@ -99,7 +99,7 @@ void main() // 4. Смешивание цвета с туманом //vec3 mountainColor = vec3((length(pos+vec3(0.0,0.0,45000.0))-20000.0)/100.0, 0.5,0.0); - gl_FragColor = mix(vec4(finalColor.rgb, 0.5), FOG_COLOR, fogFactor); + //gl_FragColor = mix(vec4(finalColor.rgb, 0.5), FOG_COLOR, fogFactor); //gl_FragColor = vec4((length(pos+vec3(0.0,0.0,45000.0))-20000.0)/100.0, 0.0,0.0, 1.0); - //gl_FragColor = vec4(fogFactor, 0.5,0.5, 1.0); + gl_FragColor = vec4(finalColor.rgb, 1.0); } \ No newline at end of file