// --- Улучшенный Фрагментный шейдер varying vec2 TexCoord; varying vec3 worldPosition; uniform sampler2D Texture; uniform float uDistanceToPlanetSurface; uniform vec3 uViewPos; const vec4 FOG_COLOR = vec4(0.0, 0.5, 1.0, 1.0); void main() { vec4 textureColor = texture2D(Texture, TexCoord); float realDist = distance(worldPosition, uViewPos); float h = uDistanceToPlanetSurface; float fogStart; float fogEnd; // --- Логика AlphaFactor (строго 2000-2500) --- // Объект полностью исчезает на 2500. // Если fogStart на высоте 1000 равен 2500, то туман и объект исчезнут одновременно. float alphaFactor = clamp((2000.0 - realDist) / 500.0, 0.0, 1.0); // --- Логика расчета границ тумана --- if (h >= 1000.0) { gl_FragColor = vec4(textureColor.rgb, alphaFactor); } else { if (h > 100.0) { // Нормализуем высоту от 100 до 1000 (t: 0 -> 1) float t = (h - 100.0) / 900.0; // На высоте 100 туман начинается со 100. // К высоте 1000 он плавно "убегает" к границе 2500, где объект исчезает. fogStart = mix(1500.0, 15000.0, t); // Держим ширину зоны тумана в пределах 400-600 единиц float fogRange = mix(1000.0, 6000.0, t); fogEnd = fogStart + fogRange; } else if (h > 40.0) { float t = (h - 40.0) / 60.0; // На высоте 100 туман начинается со 100. // К высоте 1000 он плавно "убегает" к границе 2500, где объект исчезает. fogStart = mix(800.0, 1500.0, t); fogEnd = mix(1000.0, 2500.0, t); } else if (h > 20.0) { float t = (h - 20.0) / 20.0; fogStart = mix(200.0, 800.0, t); fogEnd = mix(500.0, 1000.0, t); } else { // Минимумы при h = 0: start 25, end 125 float t = clamp(h / 20.0, 0.0, 1.0); fogStart = mix(100.0, 200.0, t); fogEnd = mix(250.0, 500.0, t); } // Расчет фактора тумана float fogRange = max(fogEnd - fogStart, 1.0); float fogFactor = clamp((realDist - fogStart) / fogRange, 0.0, 1.0); // --- Смешивание --- vec3 mixedColor = mix(textureColor.rgb, FOG_COLOR.rgb, fogFactor); gl_FragColor = vec4(mixedColor, alphaFactor); } }