From 1af829bf49239197d49645268b20f3626f809f3c Mon Sep 17 00:00:00 2001 From: Vladislav Khorev Date: Mon, 29 Dec 2025 19:05:10 +0300 Subject: [PATCH] Finally fog is working --- Game.cpp | 39 +++++- PlanetData.cpp | 125 ++++++++++++++++-- PlanetData.h | 4 +- PlanetObject.cpp | 65 ++++++--- PlanetObject.h | 2 +- ShaderManager.cpp | 4 +- shaders/defaultColor_bake_desktop.fragment | 21 --- ...ltColor_bake.vertex => planet_bake.vertex} | 3 - shaders/planet_bake_desktop.fragment | 13 ++ shaders/planet_land.vertex | 33 +++++ shaders/planet_land_desktop.fragment | 90 +++++++++++++ ...anet_land_desktop_debug_normalmap.fragment | 14 ++ ...lanet_land_desktop_debug_parallax.fragment | 32 +++++ shaders/planet_stone.vertex | 31 +++++ shaders/planet_stone_desktop.fragment | 60 +++++++++ 15 files changed, 476 insertions(+), 60 deletions(-) delete mode 100644 shaders/defaultColor_bake_desktop.fragment rename shaders/{defaultColor_bake.vertex => planet_bake.vertex} (89%) create mode 100644 shaders/planet_bake_desktop.fragment create mode 100644 shaders/planet_land.vertex create mode 100644 shaders/planet_land_desktop.fragment create mode 100644 shaders/planet_land_desktop_debug_normalmap.fragment create mode 100644 shaders/planet_land_desktop_debug_parallax.fragment create mode 100644 shaders/planet_stone.vertex create mode 100644 shaders/planet_stone_desktop.fragment diff --git a/Game.cpp b/Game.cpp index 48ae6ec..0bda6a7 100755 --- a/Game.cpp +++ b/Game.cpp @@ -146,7 +146,10 @@ namespace ZL renderer.shaderManager.AddShaderFromFiles("defaultAtmosphere", "./shaders/defaultAtmosphere.vertex", "./shaders/defaultAtmosphere.fragment", CONST_ZIP_FILE); renderer.shaderManager.AddShaderFromFiles("defaultColor2", "./shaders/defaultColor_fog2.vertex", "./shaders/defaultColor_fog2_desktop.fragment", CONST_ZIP_FILE); renderer.shaderManager.AddShaderFromFiles("defaultColorStones", "./shaders/defaultColor_fog_stones.vertex", "./shaders/defaultColor_fog_stones_desktop.fragment", CONST_ZIP_FILE); - renderer.shaderManager.AddShaderFromFiles("defaultColorBake", "./shaders/defaultColor_bake.vertex", "./shaders/defaultColor_bake_desktop.fragment", CONST_ZIP_FILE); + renderer.shaderManager.AddShaderFromFiles("planetBake", "./shaders/planet_bake.vertex", "./shaders/planet_bake_desktop.fragment", CONST_ZIP_FILE); + renderer.shaderManager.AddShaderFromFiles("planetStone", "./shaders/planet_stone.vertex", "./shaders/planet_stone_desktop.fragment", CONST_ZIP_FILE); + renderer.shaderManager.AddShaderFromFiles("planetLand", "./shaders/planet_land.vertex", "./shaders/planet_land_desktop.fragment", CONST_ZIP_FILE); + #endif cubemapTexture = std::make_shared( @@ -664,6 +667,40 @@ namespace ZL { Environment::shipVelocity -= 50.f; } + + if (event.key.keysym.sym == SDLK_1) + { + planetObject.planetData.ZScale = 1000.f; + } + if (event.key.keysym.sym == SDLK_2) + { + planetObject.planetData.ZScale = 500.f; + } + if (event.key.keysym.sym == SDLK_3) + { + planetObject.planetData.ZScale = 250.f; + } + if (event.key.keysym.sym == SDLK_4) + { + planetObject.planetData.ZScale = 125.f; + } + if (event.key.keysym.sym == SDLK_5) + { + planetObject.planetData.ZScale = 65.f; + } + if (event.key.keysym.sym == SDLK_6) + { + planetObject.planetData.ZScale = 32.f; + } + if (event.key.keysym.sym == SDLK_7) + { + planetObject.planetData.ZScale = 16.f; + } + if (event.key.keysym.sym == SDLK_8) + { + planetObject.planetData.ZScale = 8.f; + } + } } render(); diff --git a/PlanetData.cpp b/PlanetData.cpp index fc19a4d..cf0f34c 100644 --- a/PlanetData.cpp +++ b/PlanetData.cpp @@ -10,19 +10,41 @@ namespace ZL { const Vector3f PlanetData::PLANET_CENTER_OFFSET = Vector3f{ 0.f, 0.f, 0.0f }; // --- ( PlanetObject.cpp) --- + + static constexpr float FAR_Z_NEAR = 2000.0f; + static constexpr float FAR_Z_FAR = 200000.0f; + + static constexpr float TRANSITION_FAR_START = 3000.0f; + static constexpr float MIDDLE_Z_NEAR = 300.f; + static constexpr float MIDDLE_Z_FAR = 100000.f; + + static constexpr float TRANSITION_MIDDLE_START = 500.f; + static constexpr float NEAR_Z_NEAR = 80.0f; + static constexpr float NEAR_Z_FAR = 20000.0f; + + static constexpr float TRANSITION_NEAR_END = 100.f; + + + //static constexpr float SUPER_NEAR_Z_NEAR = 5.0f; + //static constexpr float SUPER_NEAR_Z_FAR = 15000.f; + static constexpr float SUPER_NEAR_Z_NEAR = 100.0f; + static constexpr float SUPER_NEAR_Z_FAR = 10000.0f; + static constexpr float TRANSITION_SUPER_NEAR_END = 30.f; + + /* static constexpr float FAR_Z_NEAR = 2000.0f; static constexpr float FAR_Z_FAR = 200000.0f; static constexpr float TRANSITION_FAR_START = 3000.0f; - static constexpr float MIDDLE_Z_NEAR = 500.f; + static constexpr float MIDDLE_Z_NEAR = 300.f; static constexpr float MIDDLE_Z_FAR = 100000.f; static constexpr float TRANSITION_MIDDLE_START = 500.f; - static constexpr float NEAR_Z_NEAR = 100.0f; + static constexpr float NEAR_Z_NEAR = 80.0f; static constexpr float NEAR_Z_FAR = 20000.0f; static constexpr float TRANSITION_NEAR_END = 100.f; static constexpr float SUPER_NEAR_Z_NEAR = 5.0f; static constexpr float SUPER_NEAR_Z_FAR = 5000.0f; static constexpr float TRANSITION_SUPER_NEAR_END = 30.f; - + */ VertexID generateEdgeID(const VertexID& id1, const VertexID& id2) { return id1 < id2 ? id1 + "_" + id2 : id2 + "_" + id1; } @@ -56,7 +78,7 @@ namespace ZL { void PlanetData::init() { for (int i = 0; i < planetMeshLods.size(); i++) { - planetMeshLods[i] = generateSphere(i, 0); + planetMeshLods[i] = generateSphere(i, 0.025f); planetMeshLods[i].Scale(PLANET_RADIUS); planetMeshLods[i].Move(PLANET_CENTER_OFFSET); } @@ -83,10 +105,50 @@ namespace ZL { } std::pair PlanetData::calculateZRange(float dToPlanetSurface) { + + float currentZNear; float currentZFar; float alpha; + if (dToPlanetSurface > 2000) + { + currentZNear = 1000; + currentZFar = currentZNear * 100; + } + else if (dToPlanetSurface > 1200) + { + currentZNear = 500; + currentZFar = currentZNear * 100; + } + else if (dToPlanetSurface > 650) + { + currentZNear = 250; + currentZFar = currentZNear * 100; + } + else if (dToPlanetSurface > 160) + { + currentZNear = 125; + currentZFar = currentZNear * 150; + } + else if (dToPlanetSurface > 100) + { + currentZNear = 65; + currentZFar = currentZNear * 170; + } + else if (dToPlanetSurface > 40) + { + currentZNear = 32; + currentZFar = 10000.f; + } + else + { + currentZNear = 16; + currentZFar = 5000.f; + } + + + /* if (dToPlanetSurface >= TRANSITION_FAR_START) { currentZNear = FAR_Z_NEAR; currentZFar = FAR_Z_FAR; @@ -98,6 +160,7 @@ namespace ZL { currentZNear = FAR_Z_NEAR * (1.0f - alpha) + MIDDLE_Z_NEAR * alpha; currentZFar = FAR_Z_FAR * (1.0f - alpha) + MIDDLE_Z_FAR * alpha; } + else if (dToPlanetSurface > TRANSITION_NEAR_END) { const float transitionLength = TRANSITION_MIDDLE_START - TRANSITION_NEAR_END; float normalizedDist = (dToPlanetSurface - TRANSITION_NEAR_END) / transitionLength; @@ -116,7 +179,7 @@ namespace ZL { currentZNear = SUPER_NEAR_Z_NEAR; currentZFar = SUPER_NEAR_Z_FAR; } - + */ return { currentZNear, currentZFar }; } @@ -145,6 +208,8 @@ namespace ZL { return (shipLocalPosition.length() - PLANET_RADIUS); } + float lowestDistance; + int tri_index = targetTriangles[0]; const auto& posData = planetMeshLods[currentLod].vertexData.PositionData; @@ -160,7 +225,39 @@ namespace ZL { Vector3f P_proj = projectPointOnPlane(shipLocalPosition, A, B, C); Vector3f P_closest = P_proj; - return (shipLocalPosition - P_closest).length(); + lowestDistance = (shipLocalPosition - P_closest).length(); + + if (targetTriangles.size() <= 1) + { + return lowestDistance; + } + else + { + for (int i = 0; i < targetTriangles.size(); i++) + { + int tri_index = targetTriangles[i]; + const auto& posData = planetMeshLods[currentLod].vertexData.PositionData; + + size_t data_index = tri_index * 3; + if (data_index + 2 >= posData.size()) { + return (shipLocalPosition.length() - PLANET_RADIUS); + } + + const Vector3f& A = posData[data_index]; + const Vector3f& B = posData[data_index + 1]; + const Vector3f& C = posData[data_index + 2]; + + Vector3f P_proj = projectPointOnPlane(shipLocalPosition, A, B, C); + Vector3f P_closest = P_proj; + + if (lowestDistance < (shipLocalPosition - P_closest).length()) + { + lowestDistance = (shipLocalPosition - P_closest).length(); + } + } + + return lowestDistance; + } } // --- getTrianglesUnderCamera ( triangleUnderCamera) --- @@ -247,7 +344,7 @@ namespace ZL { // PlanetObject.cpp " ", PlanetData:: . // , perlin planetMeshLods this. - std::vector PlanetData::subdivideTriangles(const std::vector& input) { + std::vector PlanetData::subdivideTriangles(const std::vector& input, float noiseCoeff) { std::vector output; for (const auto& t : input) { @@ -264,16 +361,20 @@ namespace ZL { Vector3f m_bc = ((b + c) * 0.5f).normalized(); Vector3f m_ac = ((a + c) * 0.5f).normalized(); + Vector3f pm_ab = m_ab * perlin.getSurfaceHeight(m_ab, noiseCoeff); + Vector3f pm_bc = m_bc * perlin.getSurfaceHeight(m_bc, noiseCoeff); + Vector3f pm_ac = m_ac * perlin.getSurfaceHeight(m_ac, noiseCoeff); + // 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. 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 + output.emplace_back(Triangle{ {a, pm_ab, pm_ac}, {id_a, id_mab, id_mac} }); // 0 + output.emplace_back(Triangle{ {pm_ab, b, pm_bc}, {id_mab, id_b, id_mbc} }); // 1 + output.emplace_back(Triangle{ {pm_ac, pm_bc, c}, {id_mac, id_mbc, id_c} }); // 2 + output.emplace_back(Triangle{ {pm_ab, pm_bc, pm_ac}, {id_mab, id_mbc, id_mac} }); // 3 } return output; } @@ -403,7 +504,7 @@ namespace ZL { // 3. N ( subdivideTriangles ID ) for (int i = 0; i < subdivisions; i++) { - geometry = subdivideTriangles(geometry); + geometry = subdivideTriangles(geometry, noiseCoeff); } // 4. PositionData, NormalData VertexIDs diff --git a/PlanetData.h b/PlanetData.h index 0884974..2bc52d0 100644 --- a/PlanetData.h +++ b/PlanetData.h @@ -68,6 +68,8 @@ namespace ZL { static const float PLANET_RADIUS; static const Vector3f PLANET_CENTER_OFFSET; + float ZScale = 1000.f; + private: PerlinNoise perlin; PerlinNoise colorPerlin; @@ -80,7 +82,7 @@ namespace ZL { std::map initialVertexMap; // - std::vector subdivideTriangles(const std::vector& inputTriangles); + std::vector subdivideTriangles(const std::vector& inputTriangles, float noiseCoeff); Vector3f calculateSurfaceNormal(Vector3f p_sphere, float noiseCoeff); LodLevel trianglesToVertices(const std::vector& triangles); LodLevel generateSphere(int subdivisions, float noiseCoeff); diff --git a/PlanetObject.cpp b/PlanetObject.cpp index a7f9382..ebc54df 100644 --- a/PlanetObject.cpp +++ b/PlanetObject.cpp @@ -97,7 +97,7 @@ namespace ZL { planetAtmosphereRenderStruct.RefreshVBO(); - planetStones = CreateStoneGroupData(777, planetData.getLodLevel(lodIndex)); + planetStones = CreateStoneGroupData(778, planetData.getLodLevel(lodIndex)); planetStones.inflate({ 0/*,1,2,3,4,5,6,7*/ }); planetStonesToBakeRenderStruct.AssignFrom(planetStones.mesh); planetStonesToBakeRenderStruct.RefreshVBO(); @@ -131,6 +131,12 @@ namespace ZL { auto neighbors2 = planetData.findNeighbors(n, currentLod); for (int n2 : neighbors2) { if (used.insert(n2).second) newIndices.push_back(n2); + + auto neighbors3 = planetData.findNeighbors(n, currentLod); + + for (int n3 : neighbors3) { + if (used.insert(n3).second) newIndices.push_back(n3); + } } } } @@ -172,15 +178,13 @@ namespace ZL { } - - void PlanetObject::bakeStoneTexture(Renderer& renderer) { glViewport(0, 0, 512, 512); glClearColor(224 / 255.f, 201 / 255.f, 167 / 255.f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - static const std::string defaultShaderName2 = "defaultColorBake"; + static const std::string defaultShaderName2 = "planetBake"; static const std::string vPositionName = "vPosition"; static const std::string vTexCoordName = "vTexCoord"; static const std::string textureUniformName = "Texture"; @@ -312,7 +316,7 @@ namespace ZL { void PlanetObject::drawPlanet(Renderer& renderer) { - static const std::string defaultShaderName = "defaultColorStones"; + static const std::string defaultShaderName = "planetLand"; static const std::string vPositionName = "vPosition"; static const std::string vColorName = "vColor"; @@ -336,7 +340,7 @@ namespace ZL { auto zRange = planetData.calculateZRange(dist); const float currentZNear = zRange.first; const float currentZFar = zRange.second; - + // 2. Применяем динамическую матрицу проекции renderer.PushPerspectiveProjectionMatrix(1.0 / 1.5, static_cast(Environment::width) / static_cast(Environment::height), @@ -344,12 +348,16 @@ namespace ZL { renderer.PushMatrix(); renderer.LoadIdentity(); - //renderer.TranslateMatrix({ 0,0, -1.0f * Environment::zoom }); + renderer.TranslateMatrix({ 0,0, -1.0f * Environment::zoom }); renderer.RotateMatrix(Environment::inverseShipMatrix); //renderer.RotateMatrix(QuatToMatrix(QuatFromRotateAroundX(M_PI / 4.0))); //renderer.RotateMatrix(QuatToMatrix(QuatFromRotateAroundY(-M_PI / 4.0))); - + + //Environment::shipPosition.v[0] = -1130; + //Environment::shipPosition.v[1] = 9693; + //Environment::shipPosition.v[2] = -20500; + renderer.TranslateMatrix(-Environment::shipPosition); const Matrix4f viewMatrix = renderer.GetCurrentModelViewMatrix(); @@ -374,6 +382,7 @@ namespace ZL { */ renderer.RenderUniform1i("Texture", 0); + Triangle tr = planetData.getLodLevel(planetData.getCurrentLodIndex()).triangles[0]; // Берем базовый треугольник Matrix3f mr = GetRotationForTriangle(tr); // Та же матрица, что и при запекании @@ -381,13 +390,19 @@ namespace ZL { renderer.RenderUniform3fv("uViewPos", &Environment::shipPosition.v[0]); // Передаем матрицу вращения треугольника для перехода в Tangent Space - renderer.RenderUniformMatrix3fv("uTangentMatrix", false, &mr.m[0]); + renderer.RenderUniformMatrix3fv("uShipRotation", false, &Environment::inverseShipMatrix.m[0]); + renderer.RenderUniformMatrix4fv("ModelViewMatrix", false, &viewMatrix.m[0]); // Не забудьте масштаб эффекта (глубина камней) - renderer.RenderUniform1f("uHeightScale", 0.03f); + //renderer.RenderUniform1f("uHeightScale", 0.03f); //renderer.RenderUniform1f("uHeightScale", -0.01f); //renderer.RenderUniform1f("uHeightScale", 0.0f + x / 1000.f); - //renderer.RenderUniform1f("uHeightScale", 0.0f); + renderer.RenderUniform1f("uHeightScale", 0.0f); + + + + renderer.RenderUniform1f("uDistanceToPlanetSurface", dist); + renderer.RenderUniform1f("uCurrentZFar", currentZFar); glBindTexture(GL_TEXTURE_2D, stoneMapFB->getTextureID()); renderer.DrawVertexRenderStruct(planetRenderStruct); @@ -396,7 +411,7 @@ namespace ZL { renderer.PopMatrix(); renderer.PopProjectionMatrix(); //renderer.DisableVertexAttribArray(vTexCoord3Name); - renderer.DisableVertexAttribArray(vTexCoord2Name); + //renderer.DisableVertexAttribArray(vTexCoord2Name); renderer.DisableVertexAttribArray(vTexCoordName); renderer.DisableVertexAttribArray(vNormalName); renderer.DisableVertexAttribArray("vTangent"); @@ -412,7 +427,7 @@ namespace ZL { void PlanetObject::drawStones(Renderer& renderer) { //static const std::string defaultShaderName = "defaultColor"; - static const std::string defaultShaderName2 = "defaultColor2"; + static const std::string defaultShaderName2 = "planetStone"; static const std::string vPositionName = "vPosition"; static const std::string vColorName = "vColor"; static const std::string vNormalName = "vNormal"; @@ -467,13 +482,17 @@ namespace ZL { renderer.RenderUniform3fv("uColor", &color2.v[0]); + renderer.RenderUniform3fv("uViewPos", &Environment::shipPosition.v[0]); + + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); // Отсекаем задние грани if (planetStonesRenderStruct.data.PositionData.size() > 0) { glBindTexture(GL_TEXTURE_2D, stoneTexture->getTexID()); renderer.DrawVertexRenderStruct(planetStonesRenderStruct); CheckGlError(); } - + glDisable(GL_CULL_FACE); renderer.PopMatrix(); renderer.PopProjectionMatrix(); @@ -491,13 +510,11 @@ namespace ZL { void PlanetObject::drawYellowZone(Renderer& renderer) { - static const std::string defaultShaderName = "defaultColor"; - static const std::string defaultShaderName2 = "defaultColor2"; + static const std::string defaultShaderName = "planetLand"; static const std::string vPositionName = "vPosition"; static const std::string vColorName = "vColor"; static const std::string vNormalName = "vNormal"; static const std::string vTexCoordName = "vTexCoord"; - //static const std::string vTexCoord3Name = "vTexCoord3"; static const std::string textureUniformName = "Texture"; float dist = planetData.distanceToPlanetSurface(Environment::shipPosition); @@ -510,12 +527,15 @@ namespace ZL { if (planetRenderYellowStruct.data.PositionData.size() > 0) { - renderer.shaderManager.PushShader(defaultShaderName2); + renderer.shaderManager.PushShader(defaultShaderName); renderer.RenderUniform1i(textureUniformName, 0); renderer.EnableVertexAttribArray(vPositionName); + renderer.EnableVertexAttribArray(vColorName); + renderer.EnableVertexAttribArray(vNormalName); + renderer.EnableVertexAttribArray("vTangent"); + renderer.EnableVertexAttribArray("vBinormal"); renderer.EnableVertexAttribArray(vTexCoordName); - // 2. Применяем динамическую матрицу проекции renderer.PushPerspectiveProjectionMatrix(1.0 / 1.5, static_cast(Environment::width) / static_cast(Environment::height), @@ -533,6 +553,8 @@ namespace ZL { renderer.RenderUniform1f("uDistanceToPlanetSurface", dist); renderer.RenderUniform1f("uCurrentZFar", currentZFar); + renderer.RenderUniform3fv("uViewPos", &Environment::shipPosition.v[0]); + Vector3f color2 = { 1.0, 1.0, 0.0 }; glBindTexture(GL_TEXTURE_2D, sandTexture->getTexID()); @@ -546,7 +568,10 @@ namespace ZL { renderer.PopMatrix(); renderer.PopProjectionMatrix(); renderer.DisableVertexAttribArray(vTexCoordName); - + renderer.DisableVertexAttribArray(vNormalName); + renderer.DisableVertexAttribArray("vTangent"); + renderer.DisableVertexAttribArray("vBinormal"); + renderer.DisableVertexAttribArray(vColorName); renderer.DisableVertexAttribArray(vPositionName); renderer.shaderManager.PopShader(); CheckGlError(); diff --git a/PlanetObject.h b/PlanetObject.h index 1619fd1..3ca9d9c 100644 --- a/PlanetObject.h +++ b/PlanetObject.h @@ -21,7 +21,7 @@ namespace ZL { class PlanetObject { - private: + public: // Агрегация: логика и данные теперь здесь PlanetData planetData; diff --git a/ShaderManager.cpp b/ShaderManager.cpp index b953977..33c37b8 100755 --- a/ShaderManager.cpp +++ b/ShaderManager.cpp @@ -11,6 +11,8 @@ namespace ZL { char infoLog[CONST_INFOLOG_LENGTH]; int infoLogLength; + char infoLog2[CONST_INFOLOG_LENGTH]; + int infoLogLength2; int vertexShaderCompiled; int fragmentShaderCompiled; @@ -37,7 +39,7 @@ namespace ZL { glCompileShader(fragmentShader); glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &fragmentShaderCompiled); - glGetShaderInfoLog(fragmentShader, CONST_INFOLOG_LENGTH, &infoLogLength, infoLog); + glGetShaderInfoLog(fragmentShader, CONST_INFOLOG_LENGTH, &infoLogLength2, infoLog2); if (!vertexShaderCompiled) diff --git a/shaders/defaultColor_bake_desktop.fragment b/shaders/defaultColor_bake_desktop.fragment deleted file mode 100644 index 44c5bb2..0000000 --- a/shaders/defaultColor_bake_desktop.fragment +++ /dev/null @@ -1,21 +0,0 @@ -// Fragment Shader (Bake Stage) -varying vec2 TexCoord; -varying float vHeight; -varying vec3 vWorldNormal; - -uniform sampler2D Texture; // Текстура камня (rock.png) -uniform vec3 uLightDir; // Направление света для базового затенения камней при запекании - -void main() -{ - vec4 stoneColor = texture2D(Texture, TexCoord); - - // Простое Lambert-освещение, чтобы камни не были "плоскими" в текстуре - //float diff = max(dot(normalize(vWorldNormal), normalize(uLightDir)), 0.3); - float diff = 1.0; - - // RGB - цвет камня с учетом света, A - нормализованная высота - gl_FragColor = vec4(stoneColor.rgb * diff, vHeight); - //gl_FragColor = vec4(vHeight, vHeight, vHeight, vHeight); - //gl_FragColor = vec4(1.0, 0.0, 1.0, 1.0); -} \ No newline at end of file diff --git a/shaders/defaultColor_bake.vertex b/shaders/planet_bake.vertex similarity index 89% rename from shaders/defaultColor_bake.vertex rename to shaders/planet_bake.vertex index 66305c6..17ccb83 100644 --- a/shaders/defaultColor_bake.vertex +++ b/shaders/planet_bake.vertex @@ -1,11 +1,9 @@ // Vertex Shader (Bake Stage) attribute vec3 vPosition; attribute vec2 vTexCoord; -attribute vec3 vNormal; // Нормаль самого камня (для освещения при запекании) varying vec2 TexCoord; varying float vHeight; -varying vec3 vWorldNormal; // Данные о плоскости треугольника планеты uniform vec3 uPlanePoint; // Любая вершина треугольника (например, tri.data[0]) @@ -28,7 +26,6 @@ void main() vHeight = clamp(distance / uMaxHeight, 0.0, 1.0); TexCoord = vTexCoord; - vWorldNormal = vNormal; gl_Position = ProjectionModelViewMatrix * vec4(vPosition, 1.0); } \ No newline at end of file diff --git a/shaders/planet_bake_desktop.fragment b/shaders/planet_bake_desktop.fragment new file mode 100644 index 0000000..83779aa --- /dev/null +++ b/shaders/planet_bake_desktop.fragment @@ -0,0 +1,13 @@ +varying vec2 TexCoord; +varying float vHeight; + +uniform sampler2D Texture; + +void main() +{ + vec4 stoneColor = texture2D(Texture, TexCoord); + + gl_FragColor = vec4(stoneColor.rgb, vHeight); + //gl_FragColor = vec4(vHeight, vHeight, vHeight, vHeight); + //gl_FragColor = vec4(1.0, 0.0, 1.0, 1.0); +} \ No newline at end of file diff --git a/shaders/planet_land.vertex b/shaders/planet_land.vertex new file mode 100644 index 0000000..15caf5e --- /dev/null +++ b/shaders/planet_land.vertex @@ -0,0 +1,33 @@ +attribute vec3 vPosition; +attribute vec2 vTexCoord; +attribute vec3 vNormal; +attribute vec3 vTangent; // Новые атрибуты +attribute vec3 vBinormal; + +varying vec2 TexCoord; +varying vec3 vViewDirTangent; +//varying float realDist; +varying vec3 worldPosition; + +uniform mat4 ProjectionModelViewMatrix; +uniform mat4 ModelViewMatrix; + +uniform vec3 uViewPos; + +void main() { + gl_Position = ProjectionModelViewMatrix * vec4(vPosition, 1.0); + TexCoord = vTexCoord; + + vec3 viewDirWorld = normalize(uViewPos - vPosition); + + // Строим матрицу перехода из атрибутов + // Так как базис ортонормирован, TBN^-1 == TBN_transpose + vViewDirTangent = vec3( + dot(viewDirWorld, vTangent), + dot(viewDirWorld, vBinormal), + dot(viewDirWorld, vNormal) + ); + vec4 viewPosition = ModelViewMatrix * vec4(vPosition.xyz, 1.0); + + worldPosition = vPosition; +} \ No newline at end of file diff --git a/shaders/planet_land_desktop.fragment b/shaders/planet_land_desktop.fragment new file mode 100644 index 0000000..a876f81 --- /dev/null +++ b/shaders/planet_land_desktop.fragment @@ -0,0 +1,90 @@ +varying vec2 TexCoord; +varying vec3 vViewDirTangent; + +uniform sampler2D Texture; +uniform float uHeightScale; +uniform float uDistanceToPlanetSurface; +uniform float uCurrentZFar; +//varying float realDist; +varying vec3 worldPosition; + +uniform vec3 uViewPos; +const vec4 FOG_COLOR = vec4(0.0, 0.5, 1.0, 1.0); // Синий туман + +void main() { + vec3 viewDir = normalize(vViewDirTangent); + + // Получаем высоту из альфа-канала запеченной текстуры + float height = texture2D(Texture, TexCoord).a; + + // Смещение. Знак минус используется, если мы хотим "вдавить" камни + // Деление на viewDir.z помогает избежать сильных искажений под углом + //vec2 p = viewDir.xy * (height * uHeightScale) / viewDir.z; + vec2 p = vec2(viewDir.x, -viewDir.y) * (height * uHeightScale); + //vec2 p = vec2(0,0); + vec2 finalTexCoord = TexCoord + p; + + float realDist = distance(worldPosition, uViewPos); + + vec4 finalColor = texture2D(Texture, finalTexCoord); + + float fogFactor; + if (uDistanceToPlanetSurface > 1000) + { + gl_FragColor = vec4(finalColor.rgb, 1.0); + } + else if (uDistanceToPlanetSurface > 100) + { + float t = clamp((uDistanceToPlanetSurface - 100) / 900.0, 0.0, 1.0); // 1 upstairs, 0 downstairs + + fogFactor = clamp((realDist - 2400) / (300.0*(1 + 10*t)), 0.0, 1.0); + + gl_FragColor = mix(vec4(finalColor.rgb, 1.0), FOG_COLOR, fogFactor*(1.0 - t)); + } + else if (uDistanceToPlanetSurface > 40) + { + //From 100 to 40: + //(1000 < realDist < 1800) + + float t = clamp((uDistanceToPlanetSurface - 40) / 60.0, 0.0, 1.0); // 1 upstairs, 0 downstairs + + fogFactor = clamp((realDist - 2400) / 300.0, 0.0, 1.0); // old fog factor + + float fogFactor2 = clamp((realDist - 1000) / 800.0, 0.0, 1.0); + + gl_FragColor = mix(vec4(finalColor.rgb, 1.0), FOG_COLOR, max(fogFactor, fogFactor2*(1.0 - t))); + } + else + { + fogFactor = clamp((realDist - 1000) / (800.0), 0.0, 1.0); + + gl_FragColor = mix(vec4(finalColor.rgb, 1.0), FOG_COLOR, fogFactor); + } + + +/* + if (realDist < 500) + { + gl_FragColor = vec4(0.5, 0.0, 0.0, 1.0); + } + else if (realDist < 1000) + { + gl_FragColor = vec4(1.0, 0.2, 0.0, 1.0); + } + else if (realDist < 1800) + { + gl_FragColor = vec4(1.0, 0.7, 0.0, 1.0); + } + else if (realDist < 2400) + { + gl_FragColor = vec4(1.0, 0.7, 0.5, 1.0); + } + else if (realDist < 2700) + { + gl_FragColor = vec4(1.0, 0.7, 1.0, 1.0); + } + else + { + gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); + }*/ +} diff --git a/shaders/planet_land_desktop_debug_normalmap.fragment b/shaders/planet_land_desktop_debug_normalmap.fragment new file mode 100644 index 0000000..8400e0a --- /dev/null +++ b/shaders/planet_land_desktop_debug_normalmap.fragment @@ -0,0 +1,14 @@ + +varying vec2 TexCoord; +varying vec3 vViewDirTangent; // Тот самый вектор из VS + +void main() { + // 1. Нормализуем входящий вектор + vec3 v = normalize(vViewDirTangent); + + // 2. Преобразуем компоненты из [-1, 1] в [0, 1] для визуализации + // X -> Red, Y -> Green, Z -> Blue + vec3 debugColor = v * 0.5 + 0.5; + + gl_FragColor = vec4(debugColor, 1.0); +} diff --git a/shaders/planet_land_desktop_debug_parallax.fragment b/shaders/planet_land_desktop_debug_parallax.fragment new file mode 100644 index 0000000..2b00b70 --- /dev/null +++ b/shaders/planet_land_desktop_debug_parallax.fragment @@ -0,0 +1,32 @@ +varying vec2 TexCoord; +varying vec3 vViewDirTangent; + +uniform sampler2D Texture; // Нам нужен только Alpha канал (высота) +uniform float uHeightScale; + +void main() { + vec3 viewDir = normalize(vViewDirTangent); + float height = texture2D(Texture, TexCoord).a; + + // Рассчитываем вектор смещения P + //vec2 p = viewDir.xy * (height * uHeightScale) / viewDir.z; + //vec2 p = vec2(viewDir.y, -viewDir.x) * (height * uHeightScale); + //vec2 p = viewDir.xy * (height * uHeightScale); + vec2 p = vec2(viewDir.x, -viewDir.y) * (height * uHeightScale); + vec2 finalTexCoord = TexCoord + p; + + // 1. Визуализация сетки по смещенным координатам + // Если сетка кривая или ломается на стыках — значит T, B, N векторы не сошлись + vec2 grid = fract(finalTexCoord * 20.0); // 20 ячеек сетки + float line = (step(0.9, grid.x) + step(0.9, grid.y)); + + // 2. Визуализация вектора смещения через цвет + // Красный = смещение по U, Зеленый = смещение по V + vec3 offsetColor = vec3(p * 10.0 + 0.5, 0.0); // Умножаем на 10 для видимости + + vec3 finalColor = mix(offsetColor, vec3(1.0), line); // Накладываем сетку поверх цвета + + // 3. Подмешиваем карту высот, чтобы видеть "объемы" + gl_FragColor = vec4(finalColor * height, 1.0); +} + diff --git a/shaders/planet_stone.vertex b/shaders/planet_stone.vertex new file mode 100644 index 0000000..baaf37a --- /dev/null +++ b/shaders/planet_stone.vertex @@ -0,0 +1,31 @@ +// Вершинный шейдер (Vertex Shader) + +attribute vec3 vPosition; +attribute vec2 vTexCoord; + +varying vec2 TexCoord; +varying float viewZ; +varying vec3 pos; +varying vec3 worldPosition; + + +uniform mat4 ProjectionModelViewMatrix; +uniform mat4 ModelViewMatrix; + +void main() +{ + // Преобразование позиции в пространство вида (View Space) + vec4 viewPosition = ModelViewMatrix * vec4(vPosition.xyz, 1.0); + + // Сохраняем отрицательную Z-координату. В OpenGL Z-координата (глубина) + // в пространстве вида обычно отрицательна, но для расчета тумана + // удобнее использовать положительное значение. + viewZ = -viewPosition.z; + + pos = vPosition.xyz; + + gl_Position = ProjectionModelViewMatrix * vec4(vPosition.xyz, 1.0); + + TexCoord = vTexCoord; + worldPosition = vPosition; +} \ No newline at end of file diff --git a/shaders/planet_stone_desktop.fragment b/shaders/planet_stone_desktop.fragment new file mode 100644 index 0000000..450fb51 --- /dev/null +++ b/shaders/planet_stone_desktop.fragment @@ -0,0 +1,60 @@ +// ---Фрагментный шейдер (Fragment Shader) + +varying vec2 TexCoord; +varying float viewZ; +varying vec3 pos; + +uniform sampler2D Texture; +uniform float uDistanceToPlanetSurface; +uniform float uCurrentZFar; + +// Константы для тумана: +//const vec4 FOG_COLOR = vec4(0.0, 0.3, 0.3, 1.0); // Синий туман +const vec4 FOG_COLOR = vec4(0.0, 0.5, 1.0, 1.0); // Синий туман + +varying vec3 worldPosition; + +uniform vec3 uViewPos; + +void main() +{ + + vec4 textureColor = texture2D(Texture, TexCoord); + vec3 finalColor = textureColor.rgb; + + float realDist = distance(worldPosition, uViewPos); + + float fogFactor; + if (uDistanceToPlanetSurface > 1000) + { + gl_FragColor = vec4(finalColor.rgb, 1.0); + } + else if (uDistanceToPlanetSurface > 100) + { + float t = clamp((uDistanceToPlanetSurface - 100) / 900.0, 0.0, 1.0); // 1 upstairs, 0 downstairs + + fogFactor = clamp((realDist - 2400) / (300.0*(1 + 10*t)), 0.0, 1.0); + + gl_FragColor = mix(vec4(finalColor.rgb, 1.0), FOG_COLOR, fogFactor*(1.0 - t)); + } + else if (uDistanceToPlanetSurface > 40) + { + //From 100 to 40: + //(1000 < realDist < 1800) + + float t = clamp((uDistanceToPlanetSurface - 40) / 60.0, 0.0, 1.0); // 1 upstairs, 0 downstairs + + fogFactor = clamp((realDist - 2400) / 300.0, 0.0, 1.0); // old fog factor + + float fogFactor2 = clamp((realDist - 1000) / 800.0, 0.0, 1.0); + + gl_FragColor = mix(vec4(finalColor.rgb, 1.0), FOG_COLOR, max(fogFactor, fogFactor2*(1.0 - t))); + } + else + { + fogFactor = clamp((realDist - 1000) / (800.0), 0.0, 1.0); + + gl_FragColor = mix(vec4(finalColor.rgb, 1.0), FOG_COLOR, fogFactor); + } + +} \ No newline at end of file