Somehow planet is working
This commit is contained in:
1 parent
af550f56a7
commit
7a1961b5d1
7 files changed
+146
-134
No files matched your search
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
Reference in new issue
Block a user