Somehow planet is working

This commit is contained in:
Vladislav Khorev committed 2025-12-14 13:00:39 +03:00
1 parent af550f56a7
commit 7a1961b5d1
7 files changed
+146 -134

No files matched your search

+41 -34
View File
@@ -1,41 +1,48 @@
varying vec3 color;
varying vec3 vViewPosition; // Получаем позицию фрагмента в пространстве вида
// Фрагментный шейдер:
uniform vec3 uColor;
uniform float uDistanceToPlanetSurface; // Расстояние корабля до поверхности
uniform vec3 uCenterPos; // Центр планеты/атмосферы (в пространстве вида)
uniform float uCenterRadius; // Радиус атмосферы (точка, где прозрачность = 0.5)
// Константы затухания, определенные прямо в шейдере
const float DIST_FOG_MAX = 2000.0;
const float DIST_FOG_MIN = 1000.0;
// Определение зоны плавного спада alpha
const float FADE_WIDTH = 0.05; // Например, 5% от радиуса для плавного перехода
varying vec3 vViewNormal;
varying vec3 vViewPosition;
void main()
{
// 1. Расчет расстояния от фрагмента до центра
float distanceToCenter = length(vViewPosition - uCenterPos);
// 2. Расчет границ для плавного перехода
// Начало спада (R)
float startRadius = uCenterRadius;
// Конец спада (R + dR)
float endRadius = uCenterRadius + FADE_WIDTH * uCenterRadius;
// --- 1. Расчет плотности по Френелю (краевой эффект) ---
vec3 viewVector = normalize(-vViewPosition);
float NdotV = dot(vViewNormal, viewVector);
float factor = 1.0 - abs(NdotV);
float atmosphereDensity = pow(factor, 5.0);
// 3. Расчет коэффициента прозрачности с помощью smoothstep
// smoothstep(edge0, edge1, x) возвращает 0.0, если x < edge0,
// 1.0, если x > edge1, и плавно меняется между ними.
// Нам нужно, чтобы alpha была 0.5 при startRadius и 0.0 при endRadius.
// Если мы используем smoothstep(start, end, distance), то получим:
// - 0.0, когда distance < start
// - 1.0, когда distance > end
// Нам нужен обратный результат (1.0 - smoothstep), чтобы 0.5 было внутри, а 0.0 - снаружи.
// Вычисляем множитель прозрачности (от 1.0 до 0.0)
float fadeFactor = 1.0 - smoothstep(startRadius, endRadius, distanceToCenter);
// 4. Применение нового alpha
// Если fadeFactor = 1.0 (внутри R), alpha = 0.5 * 1.0 = 0.5
// Если fadeFactor = 0.0 (вне R+dR), alpha = 0.5 * 0.0 = 0.0
// Если между ними - плавная интерполяция.
float finalAlpha = 0.5 * fadeFactor;
gl_FragColor = vec4(color, 0.5);
// --- 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);
}
+19 -11
View File
@@ -1,20 +1,28 @@
// Вершинный шейдер:
attribute vec3 vPosition;
attribute vec3 vColor;
attribute vec3 vNormal; // <-- Новый атрибут
uniform mat4 ProjectionModelViewMatrix;
uniform mat4 ModelViewMatrix;
varying vec3 color;
varying vec3 vViewPosition; // Новая переменная: позиция вершины в пространстве вида
// Выходные переменные (передаются во фрагментный шейдер)
varying vec3 vViewNormal;
varying vec3 vViewPosition;
void main()
{
// Расчет позиции в пространстве отсечения (как у вас)
gl_Position = ProjectionModelViewMatrix * vec4(vPosition.xyz, 1.0);
// Передача позиции в пространстве вида во фрагментный шейдер
vViewPosition = vec3(ModelViewMatrix * vec4(vPosition.xyz, 1.0));
//vViewPosition = vPosition.xyz;
color = vColor;
// 1. Позиция в пространстве вида (View Space)
vec4 positionView = ModelViewMatrix * vec4(vPosition, 1.0);
vViewPosition = positionView.xyz;
// 2. Нормаль в пространстве вида (View Space)
// Преобразуем нормаль, используя ModelViewMatrix. Поскольку нормаль - это вектор,
// трансляционная часть (четвертый столбец) матрицы нам не нужна.
// Если бы было неединообразное масштабирование, потребовалась бы Inverse Transpose Matrix.
// В вашем случае, где есть только униформное масштабирование и вращение,
// достаточно просто умножить на ModelViewMatrix:
vViewNormal = normalize((ModelViewMatrix * vec4(vNormal, 0.0)).xyz);
// W=0.0 для векторов, чтобы игнорировать трансляцию
gl_Position = ProjectionModelViewMatrix * vec4(vPosition.xyz, 1.0);
}
+3
View File
@@ -9,6 +9,7 @@ varying vec3 color;
varying vec3 normal;
varying vec2 TexCoord;
varying float viewZ; // <--- НОВОЕ: Z-координата в пространстве вида (View Space)
varying vec3 pos;
uniform mat4 ProjectionModelViewMatrix;
uniform mat4 ModelViewMatrix; // Нужна для преобразования vPosition в View Space
@@ -23,6 +24,8 @@ void main()
// в пространстве вида обычно отрицательна, но для расчета тумана
// удобнее использовать положительное значение.
viewZ = -viewPosition.z;
pos = vPosition.xyz;
gl_Position = ProjectionModelViewMatrix * vec4(vPosition.xyz, 1.0);
+20 -4
View File
@@ -4,6 +4,7 @@ varying vec3 color;
varying vec3 normal;
varying vec2 TexCoord;
varying float viewZ;
varying vec3 pos;
uniform sampler2D Texture;
uniform vec3 uLightDirection;
@@ -64,15 +65,26 @@ void main()
// гарантируя, что все, что подходит к границе uCurrentZFar, будет скрыто.
// Точка начала тумана: 90% от uCurrentZFar
float farFogStart = 2000.0;
float farFogStart = 2000.f;//uCurrentZFar * 0.7;
// Длина перехода тумана: 10% от uCurrentZFar
float depthRange = 2500.0;
float depthRange = 2000.f;//uCurrentZFar * 0.25;
if (abs(uDistanceToPlanetSurface) < 410.f)
{
farFogStart = 1800.f * abs(uDistanceToPlanetSurface-10.f) * 0.0025 + 200.f;
depthRange = farFogStart;
}
if (abs(uDistanceToPlanetSurface) < 10.f)
{
farFogStart = 200.f;
depthRange = 200.f;
}
float farFogFactor = 0.0;
if (depthRange > 0.0) {
// Нормализация Z-глубины: 0.0f при farFogStart, 1.0f при farFogStart + depthRange
farFogFactor = clamp((viewZ - farFogStart) / depthRange, 0.0, 1.0);
farFogFactor = clamp((abs(viewZ) - farFogStart) / depthRange, 0.0, 1.0);
}
// --- 3.3. Объединение ---
@@ -85,5 +97,9 @@ void main()
// 4. Смешивание цвета с туманом
gl_FragColor = mix(vec4(litColor, 1.0), FOG_COLOR, fogFactor);
//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 = 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);
}