// Фрагментный шейдер: uniform vec3 uColor; uniform float uDistanceToPlanetSurface; // Расстояние корабля до поверхности // Константы затухания, определенные прямо в шейдере const float DIST_FOG_MAX = 2000.0; const float DIST_FOG_MIN = 1000.0; varying vec3 vViewNormal; varying vec3 vViewPosition; void main() { // --- 1. Расчет плотности по Френелю (краевой эффект) --- vec3 viewVector = normalize(-vViewPosition); float NdotV = dot(vViewNormal, viewVector); float factor = 1.0 - abs(NdotV); float atmosphereDensity = pow(factor, 5.0); // --- 2. Расчет коэффициента затухания по дистанции --- float distanceFactor = 1.0; if (uDistanceToPlanetSurface > DIST_FOG_MAX) { // Дистанция > 2000.0: Полностью видно (Factor = 1.0) distanceFactor = 1.0; } else if (uDistanceToPlanetSurface < DIST_FOG_MIN) { // Дистанция < 1000.0: Полностью не видно (Factor = 0.0) distanceFactor = 0.0; } else { // Плавный переход (линейная интерполяция) // normalizedDistance: от 0.0 (на DIST_FOG_MIN) до 1.0 (на DIST_FOG_MAX) float normalizedDistance = (uDistanceToPlanetSurface - DIST_FOG_MIN) / (DIST_FOG_MAX - DIST_FOG_MIN); distanceFactor = clamp(normalizedDistance, 0.0, 1.0); } // --- 3. Финальный цвет и прозрачность --- float finalAlpha = atmosphereDensity * distanceFactor; gl_FragColor = vec4(uColor, finalAlpha); }