Major refactoring + web adaptation
This commit is contained in:
1 parent
197423b572
commit
9fc0adf210
66 files changed
+134
-30966
No files matched your search
@@ -1,118 +0,0 @@
|
||||
// Фрагментный шейдер:
|
||||
uniform vec3 uColor;
|
||||
uniform float uDistanceToPlanetSurface; // Расстояние корабля до поверхности
|
||||
|
||||
// Константы затухания, определенные прямо в шейдере
|
||||
const float DIST_FOG_MAX = 2000.0;
|
||||
const float DIST_FOG_MIN = 1000.0;
|
||||
|
||||
varying vec3 vWorldNormal;
|
||||
varying vec3 vViewNormal;
|
||||
varying vec3 vViewPosition;
|
||||
|
||||
|
||||
// Добавь эти uniform-ы
|
||||
uniform float uTime;
|
||||
uniform vec3 uLightDirView;
|
||||
uniform vec3 uPlayerDirWorld;
|
||||
|
||||
// Простая функция псевдослучайного шума
|
||||
float hash(float n) { return fract(sin(n) * 43758.5453123); }
|
||||
|
||||
float noise(vec3 x) {
|
||||
vec3 p = floor(x);
|
||||
vec3 f = fract(x);
|
||||
f = f * f * (3.0 - 2.0 * f);
|
||||
float n = p.x + p.y * 57.0 + 113.0 * p.z;
|
||||
return mix(mix(mix(hash(n + 0.0), hash(n + 1.0), f.x),
|
||||
mix(hash(n + 57.0), hash(n + 58.0), f.x), f.y),
|
||||
mix(mix(hash(n + 113.0), hash(n + 114.0), f.x),
|
||||
mix(hash(n + 170.0), hash(n + 171.0), f.x), f.y), f.z);
|
||||
}
|
||||
|
||||
// Fractal Brownian Motion для "кучевости" облаков
|
||||
float fbm(vec3 p) {
|
||||
float f = 0.5000 * noise(p); p *= 2.02;
|
||||
f += 0.2500 * noise(p); p *= 2.03;
|
||||
f += 0.1250 * noise(p);
|
||||
return f;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 normal = normalize(vViewNormal);
|
||||
vec3 viewVector = normalize(-vViewPosition);
|
||||
float NdotV = dot(normal, viewVector);
|
||||
|
||||
// Вектор направления от центра планеты к текущему фрагменту атмосферы (Мировой)
|
||||
vec3 fragmentDir = normalize(vWorldNormal);
|
||||
// Вектор направления от центра планеты к игроку (нужно передать как uniform)
|
||||
// Передай его в C++: renderer.RenderUniform3fv("uPlayerDirWorld", playerDirWorld.data());
|
||||
|
||||
|
||||
// --- 1. Плавное отсечение за горизонтом (Horizon Mask) ---
|
||||
// Считаем косинус угла между игроком и точкой атмосферы
|
||||
float cosAngle = dot(fragmentDir, uPlayerDirWorld);
|
||||
// Плавно затухаем от 0.0 (горизонт) до 0.2 (над головой)
|
||||
//float horizonMask = smoothstep(0.0, 0.4, cosAngle);
|
||||
float horizonMask = 1.0 - smoothstep(0.9, 1.0, cosAngle);
|
||||
|
||||
|
||||
// --- 2. Плавный переход при прохождении сквозь слой (Transition Mask) ---
|
||||
// Определяем "высоту" игрока относительно слоя (напр. слой на 1.03 * R)
|
||||
// uDistanceToPlanetSurface уже вычислен в PlanetData
|
||||
float layerHeight = 600.0; // Примерная толщина слоя атмосферы (3% от 20000)
|
||||
|
||||
// Делаем прозрачным при приближении к границе (dist около layerHeight)
|
||||
// и снова видимым, когда спустились ниже
|
||||
float distToLayer = abs(uDistanceToPlanetSurface - layerHeight);
|
||||
float transitionMask = smoothstep(0.0, 200.0, distToLayer);
|
||||
|
||||
// --- 3. Освещение и облака ---
|
||||
float diff = max(dot(normal, uLightDirView), 0.0);
|
||||
if (uDistanceToPlanetSurface < layerHeight) {
|
||||
diff = max(dot(-normal, uLightDirView), 0.0); // Инверсия для взгляда снизу
|
||||
}
|
||||
float lightIntensity = diff + 0.05;
|
||||
|
||||
vec3 cloudCoord = fragmentDir * 6.0;
|
||||
cloudCoord.x += uTime * 0.03;
|
||||
float n = fbm(cloudCoord);
|
||||
float cloudMask = smoothstep(0.4, 0.65, n);
|
||||
|
||||
// --- 4. Финальный расчет альфы ---
|
||||
float atmosphereDensity = pow(1.0 - abs(NdotV), 5.0);
|
||||
float distanceFactor = clamp((uDistanceToPlanetSurface - DIST_FOG_MIN) / (DIST_FOG_MAX - DIST_FOG_MIN), 0.0, 1.0);
|
||||
|
||||
// Базовая прозрачность облаков
|
||||
float cloudAlpha = cloudMask * 0.8;
|
||||
|
||||
// Применяем маски:
|
||||
// В космосе важен distanceFactor, на планете важен horizonMask
|
||||
float finalCloudAlpha = cloudAlpha * transitionMask;
|
||||
if (uDistanceToPlanetSurface < layerHeight) {
|
||||
finalCloudAlpha *= horizonMask; // На планете скрываем то, что под ногами
|
||||
} else {
|
||||
finalCloudAlpha *= distanceFactor; // В космосе скрываем по вашей старой логике
|
||||
if (NdotV <=0)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
}
|
||||
|
||||
vec3 currentAtmo = mix(vec3(0.01, 0.02, 0.1), uColor, lightIntensity);
|
||||
vec3 currentCloud = mix(vec3(0.1, 0.1, 0.15), vec3(1.0, 1.0, 1.0), lightIntensity);
|
||||
vec3 finalRGB = mix(currentAtmo, currentCloud, cloudMask);
|
||||
|
||||
// Для дымки (atmo) оставляем затухание при посадке
|
||||
float atmoAlpha = atmosphereDensity * distanceFactor;
|
||||
|
||||
float finalAtmoAlpha = atmoAlpha;
|
||||
|
||||
if (uDistanceToPlanetSurface < layerHeight) {
|
||||
finalCloudAlpha *= horizonMask;
|
||||
finalAtmoAlpha *= horizonMask; // Принудительно гасим дымку под горизонтом
|
||||
}
|
||||
|
||||
gl_FragColor = vec4(finalRGB, max(finalAtmoAlpha, finalCloudAlpha));
|
||||
}
|
||||
@@ -1,122 +0,0 @@
|
||||
// Фрагментный шейдер:
|
||||
uniform vec3 uColor;
|
||||
uniform float uDistanceToPlanetSurface; // Расстояние корабля до поверхности
|
||||
|
||||
// Константы затухания, определенные прямо в шейдере
|
||||
const float DIST_FOG_MAX = 2000.0;
|
||||
const float DIST_FOG_MIN = 1000.0;
|
||||
|
||||
varying vec3 vWorldNormal;
|
||||
varying vec3 vViewNormal;
|
||||
varying vec3 vViewPosition;
|
||||
|
||||
|
||||
// Добавь эти uniform-ы
|
||||
uniform float uTime;
|
||||
uniform vec3 uLightDirView;
|
||||
uniform vec3 uPlayerDirWorld;
|
||||
|
||||
// Простая функция псевдослучайного шума
|
||||
float hash(float n) { return fract(sin(n) * 43758.5453123); }
|
||||
|
||||
float noise(vec3 x) {
|
||||
vec3 p = floor(x);
|
||||
vec3 f = fract(x);
|
||||
f = f * f * (3.0 - 2.0 * f);
|
||||
float n = p.x + p.y * 57.0 + 113.0 * p.z;
|
||||
return mix(mix(mix(hash(n + 0.0), hash(n + 1.0), f.x),
|
||||
mix(hash(n + 57.0), hash(n + 58.0), f.x), f.y),
|
||||
mix(mix(hash(n + 113.0), hash(n + 114.0), f.x),
|
||||
mix(hash(n + 170.0), hash(n + 171.0), f.x), f.y), f.z);
|
||||
}
|
||||
|
||||
// Fractal Brownian Motion для "кучевости" облаков
|
||||
float fbm(vec3 p) {
|
||||
float f = 0.5000 * noise(p); p *= 2.02;
|
||||
f += 0.2500 * noise(p); p *= 2.03;
|
||||
f += 0.1250 * noise(p);
|
||||
return f;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 normal = normalize(vViewNormal);
|
||||
vec3 viewVector = normalize(-vViewPosition);
|
||||
float NdotV = dot(normal, viewVector);
|
||||
|
||||
// Вектор направления от центра планеты к текущему фрагменту атмосферы (Мировой)
|
||||
vec3 fragmentDir = normalize(vWorldNormal);
|
||||
// Вектор направления от центра планеты к игроку (нужно передать как uniform)
|
||||
// Передай его в C++: renderer.RenderUniform3fv("uPlayerDirWorld", playerDirWorld.data());
|
||||
|
||||
|
||||
// --- 1. Плавное отсечение за горизонтом (Horizon Mask) ---
|
||||
// Считаем косинус угла между игроком и точкой атмосферы
|
||||
float cosAngle = dot(fragmentDir, uPlayerDirWorld);
|
||||
// Плавно затухаем от 0.0 (горизонт) до 0.2 (над головой)
|
||||
//float horizonMask = smoothstep(0.0, 0.4, cosAngle);
|
||||
float horizonMask = smoothstep(0.9, 1.0, cosAngle);
|
||||
|
||||
gl_FragColor = vec4(horizonMask, 0.0, 0.0, 0.5);
|
||||
|
||||
return;
|
||||
|
||||
/*
|
||||
// --- 2. Плавный переход при прохождении сквозь слой (Transition Mask) ---
|
||||
// Определяем "высоту" игрока относительно слоя (напр. слой на 1.03 * R)
|
||||
// uDistanceToPlanetSurface уже вычислен в PlanetData
|
||||
float layerHeight = 600.0; // Примерная толщина слоя атмосферы (3% от 20000)
|
||||
|
||||
// Делаем прозрачным при приближении к границе (dist около layerHeight)
|
||||
// и снова видимым, когда спустились ниже
|
||||
float distToLayer = abs(uDistanceToPlanetSurface - layerHeight);
|
||||
float transitionMask = smoothstep(0.0, 200.0, distToLayer);
|
||||
|
||||
// --- 3. Освещение и облака ---
|
||||
float diff = max(dot(normal, uLightDirView), 0.0);
|
||||
if (uDistanceToPlanetSurface < layerHeight) {
|
||||
diff = max(dot(-normal, uLightDirView), 0.0); // Инверсия для взгляда снизу
|
||||
}
|
||||
float lightIntensity = diff + 0.05;
|
||||
|
||||
vec3 cloudCoord = fragmentDir * 6.0;
|
||||
cloudCoord.x += uTime * 0.03;
|
||||
float n = fbm(cloudCoord);
|
||||
float cloudMask = smoothstep(0.4, 0.65, n);
|
||||
|
||||
// --- 4. Финальный расчет альфы ---
|
||||
float atmosphereDensity = pow(1.0 - abs(NdotV), 5.0);
|
||||
float distanceFactor = clamp((uDistanceToPlanetSurface - DIST_FOG_MIN) / (DIST_FOG_MAX - DIST_FOG_MIN), 0.0, 1.0);
|
||||
|
||||
// Базовая прозрачность облаков
|
||||
float cloudAlpha = cloudMask * 0.8;
|
||||
|
||||
// Применяем маски:
|
||||
// В космосе важен distanceFactor, на планете важен horizonMask
|
||||
float finalCloudAlpha = cloudAlpha * transitionMask;
|
||||
if (uDistanceToPlanetSurface < layerHeight) {
|
||||
finalCloudAlpha *= horizonMask; // На планете скрываем то, что под ногами
|
||||
} else {
|
||||
finalCloudAlpha *= distanceFactor; // В космосе скрываем по вашей старой логике
|
||||
if (NdotV <=0)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
}
|
||||
|
||||
vec3 currentAtmo = mix(vec3(0.01, 0.02, 0.1), uColor, lightIntensity);
|
||||
vec3 currentCloud = mix(vec3(0.1, 0.1, 0.15), vec3(1.0, 1.0, 1.0), lightIntensity);
|
||||
vec3 finalRGB = mix(currentAtmo, currentCloud, cloudMask);
|
||||
|
||||
// Для дымки (atmo) оставляем затухание при посадке
|
||||
float atmoAlpha = atmosphereDensity * distanceFactor;
|
||||
|
||||
float finalAtmoAlpha = atmoAlpha;
|
||||
|
||||
if (uDistanceToPlanetSurface < layerHeight) {
|
||||
finalCloudAlpha *= horizonMask;
|
||||
finalAtmoAlpha *= horizonMask; // Принудительно гасим дымку под горизонтом
|
||||
}
|
||||
|
||||
gl_FragColor = vec4(finalRGB, max(finalAtmoAlpha, finalCloudAlpha));*/
|
||||
}
|
||||
@@ -1,118 +0,0 @@
|
||||
// Фрагментный шейдер:
|
||||
uniform vec3 uColor;
|
||||
uniform float uDistanceToPlanetSurface; // Расстояние корабля до поверхности
|
||||
|
||||
// Константы затухания, определенные прямо в шейдере
|
||||
const float DIST_FOG_MAX = 2000.0;
|
||||
const float DIST_FOG_MIN = 1000.0;
|
||||
|
||||
varying vec3 vWorldNormal;
|
||||
varying vec3 vViewNormal;
|
||||
varying vec3 vViewPosition;
|
||||
|
||||
|
||||
// Добавь эти uniform-ы
|
||||
uniform float uTime;
|
||||
uniform vec3 uLightDirView;
|
||||
uniform vec3 uPlayerDirWorld;
|
||||
|
||||
// Простая функция псевдослучайного шума
|
||||
float hash(float n) { return fract(sin(n) * 43758.5453123); }
|
||||
|
||||
float noise(vec3 x) {
|
||||
vec3 p = floor(x);
|
||||
vec3 f = fract(x);
|
||||
f = f * f * (3.0 - 2.0 * f);
|
||||
float n = p.x + p.y * 57.0 + 113.0 * p.z;
|
||||
return mix(mix(mix(hash(n + 0.0), hash(n + 1.0), f.x),
|
||||
mix(hash(n + 57.0), hash(n + 58.0), f.x), f.y),
|
||||
mix(mix(hash(n + 113.0), hash(n + 114.0), f.x),
|
||||
mix(hash(n + 170.0), hash(n + 171.0), f.x), f.y), f.z);
|
||||
}
|
||||
|
||||
// Fractal Brownian Motion для "кучевости" облаков
|
||||
float fbm(vec3 p) {
|
||||
float f = 0.5000 * noise(p); p *= 2.02;
|
||||
f += 0.2500 * noise(p); p *= 2.03;
|
||||
f += 0.1250 * noise(p);
|
||||
return f;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 normal = normalize(vViewNormal);
|
||||
vec3 viewVector = normalize(-vViewPosition);
|
||||
float NdotV = dot(normal, viewVector);
|
||||
|
||||
// Вектор направления от центра планеты к текущему фрагменту атмосферы (Мировой)
|
||||
vec3 fragmentDir = normalize(vWorldNormal);
|
||||
// Вектор направления от центра планеты к игроку (нужно передать как uniform)
|
||||
// Передай его в C++: renderer.RenderUniform3fv("uPlayerDirWorld", playerDirWorld.data());
|
||||
|
||||
|
||||
// --- 1. Плавное отсечение за горизонтом (Horizon Mask) ---
|
||||
// Считаем косинус угла между игроком и точкой атмосферы
|
||||
float cosAngle = dot(fragmentDir, uPlayerDirWorld);
|
||||
// Плавно затухаем от 0.0 (горизонт) до 0.2 (над головой)
|
||||
//float horizonMask = smoothstep(0.0, 0.4, cosAngle);
|
||||
float horizonMask = smoothstep(0.93, 1.0, cosAngle);
|
||||
|
||||
|
||||
// --- 2. Плавный переход при прохождении сквозь слой (Transition Mask) ---
|
||||
// Определяем "высоту" игрока относительно слоя (напр. слой на 1.03 * R)
|
||||
// uDistanceToPlanetSurface уже вычислен в PlanetData
|
||||
float layerHeight = 600.0; // Примерная толщина слоя атмосферы (3% от 20000)
|
||||
|
||||
// Делаем прозрачным при приближении к границе (dist около layerHeight)
|
||||
// и снова видимым, когда спустились ниже
|
||||
float distToLayer = abs(uDistanceToPlanetSurface - layerHeight);
|
||||
float transitionMask = smoothstep(0.0, 200.0, distToLayer);
|
||||
|
||||
// --- 3. Освещение и облака ---
|
||||
float diff = max(dot(normal, uLightDirView), 0.0);
|
||||
if (uDistanceToPlanetSurface < layerHeight) {
|
||||
diff = max(dot(-normal, uLightDirView), 0.0); // Инверсия для взгляда снизу
|
||||
}
|
||||
float lightIntensity = diff + 0.05;
|
||||
|
||||
vec3 cloudCoord = fragmentDir * 6.0;
|
||||
cloudCoord.x += uTime * 0.03;
|
||||
float n = fbm(cloudCoord);
|
||||
float cloudMask = smoothstep(0.4, 0.65, n);
|
||||
|
||||
// --- 4. Финальный расчет альфы ---
|
||||
float atmosphereDensity = pow(1.0 - abs(NdotV), 5.0);
|
||||
float distanceFactor = clamp((uDistanceToPlanetSurface - DIST_FOG_MIN) / (DIST_FOG_MAX - DIST_FOG_MIN), 0.0, 1.0);
|
||||
|
||||
// Базовая прозрачность облаков
|
||||
float cloudAlpha = cloudMask * 0.8;
|
||||
|
||||
// Применяем маски:
|
||||
// В космосе важен distanceFactor, на планете важен horizonMask
|
||||
float finalCloudAlpha = cloudAlpha * transitionMask;
|
||||
if (uDistanceToPlanetSurface < layerHeight) {
|
||||
finalCloudAlpha *= horizonMask; // На планете скрываем то, что под ногами
|
||||
} else {
|
||||
finalCloudAlpha *= distanceFactor; // В космосе скрываем по вашей старой логике
|
||||
if (NdotV <=0)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
}
|
||||
|
||||
vec3 currentAtmo = mix(vec3(0.01, 0.02, 0.1), uColor, lightIntensity);
|
||||
vec3 currentCloud = mix(vec3(0.1, 0.1, 0.15), vec3(1.0, 1.0, 1.0), lightIntensity);
|
||||
vec3 finalRGB = mix(currentAtmo, currentCloud, cloudMask);
|
||||
|
||||
// Для дымки (atmo) оставляем затухание при посадке
|
||||
float atmoAlpha = atmosphereDensity * distanceFactor;
|
||||
|
||||
float finalAtmoAlpha = atmoAlpha;
|
||||
|
||||
if (uDistanceToPlanetSurface < layerHeight) {
|
||||
finalCloudAlpha *= horizonMask;
|
||||
finalAtmoAlpha *= horizonMask; // Принудительно гасим дымку под горизонтом
|
||||
}
|
||||
|
||||
gl_FragColor = vec4(finalRGB, max(finalAtmoAlpha, finalCloudAlpha));
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
varying vec3 color; // Цвет вершины (с шумом)
|
||||
varying vec3 normal;
|
||||
varying vec3 lightDirection_VS;
|
||||
varying vec2 TexCoord; // UV-координаты
|
||||
|
||||
uniform sampler2D Texture;
|
||||
uniform vec3 uLightDirection;
|
||||
void main()
|
||||
{
|
||||
// 1. Получаем цвет из текстуры и смешиваем с цветовым шумом
|
||||
vec4 textureColor = texture2D(Texture, TexCoord);
|
||||
vec3 finalColor = textureColor.rgb * color;
|
||||
|
||||
// 3. Расчет освещения
|
||||
float diffuse = max(0.0, dot(normal, uLightDirection));
|
||||
float ambient = 0.2;
|
||||
float lightingFactor = min(1.0, ambient + diffuse);
|
||||
|
||||
|
||||
gl_FragColor = vec4(finalColor * lightingFactor, 1.0);
|
||||
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
// Вершинный шейдер (Vertex Shader)
|
||||
|
||||
attribute vec3 vPosition;
|
||||
attribute vec3 vColor;
|
||||
attribute vec3 vNormal;
|
||||
attribute vec2 vTexCoord;
|
||||
|
||||
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
|
||||
uniform vec3 uLightDirection;
|
||||
|
||||
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);
|
||||
|
||||
normal = normalize((ModelViewMatrix * vec4(vNormal, 0.0)).xyz);
|
||||
color = vColor;
|
||||
TexCoord = vTexCoord;
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
// Вершинный шейдер (Vertex Shader)
|
||||
|
||||
attribute vec3 vPosition;
|
||||
attribute vec3 vColor;
|
||||
attribute vec3 vNormal;
|
||||
attribute vec2 vTexCoord;
|
||||
|
||||
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
|
||||
uniform vec3 uLightDirection;
|
||||
|
||||
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);
|
||||
|
||||
normal = normalize((ModelViewMatrix * vec4(vNormal, 0.0)).xyz);
|
||||
color = vColor;
|
||||
TexCoord = vTexCoord;
|
||||
}
|
||||
@@ -1,97 +0,0 @@
|
||||
// ---Фрагментный шейдер (Fragment Shader)
|
||||
|
||||
varying vec3 color;
|
||||
varying vec3 normal;
|
||||
varying vec2 TexCoord;
|
||||
varying float viewZ;
|
||||
varying vec3 pos;
|
||||
|
||||
uniform sampler2D Texture;
|
||||
uniform vec3 uLightDirection;
|
||||
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); // Синий туман
|
||||
|
||||
// Параметры "Distance Fog"
|
||||
const float DIST_FOG_MAX = 2000.0;
|
||||
const float DIST_FOG_MIN = 1000.0;
|
||||
|
||||
// Параметры "Z-Far Fog"
|
||||
// Насколько близко к Zfar должен начинаться туман (например, 10% от Zfar)
|
||||
const float Z_FOG_START_RATIO = 0.9;
|
||||
// Какую долю от Zfar должен покрывать туман (например, 10% от Zfar)
|
||||
const float Z_FOG_RANGE_RATIO = 0.1;
|
||||
uniform vec3 uColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
// ... (1. Получаем цвет и 2. Расчет освещения)
|
||||
vec4 textureColor = texture2D(Texture, TexCoord);
|
||||
vec3 finalColor = textureColor.rgb;
|
||||
|
||||
float diffuse = max(0.0, dot(normal, uLightDirection));
|
||||
float ambient = 0.2;
|
||||
float lightingFactor = min(1.0, ambient + diffuse);
|
||||
vec3 litColor = finalColor * lightingFactor;
|
||||
|
||||
|
||||
// 3. Расчет коэффициента тумана (fogFactor)
|
||||
float fogFactor = 0.0;
|
||||
|
||||
// --- 3.1. Расчет коэффициента тумана на основе расстояния до поверхности (Distance Fog) ---
|
||||
// Этот туман работает на больших расстояниях и постепенно исчезает,
|
||||
// уступая место Z-Far Fog при приближении к планете.
|
||||
|
||||
if (uDistanceToPlanetSurface >= DIST_FOG_MIN && uDistanceToPlanetSurface <DIST_FOG_MAX) {
|
||||
// Нормализация: 0.0f при DIST_FOG_MAX, 1.0f при DIST_FOG_MIN
|
||||
float distRange = DIST_FOG_MAX - DIST_FOG_MIN;
|
||||
float distNormalized = clamp((uDistanceToPlanetSurface - DIST_FOG_MIN) / distRange, 0.0, 1.0);
|
||||
|
||||
// alpha = 0.0 (Далеко) ... 1.0 (Близко к 1000.f)
|
||||
fogFactor = 1.0 - distNormalized;
|
||||
}
|
||||
if (uDistanceToPlanetSurface < DIST_FOG_MIN)
|
||||
{
|
||||
fogFactor = 1.0;
|
||||
}
|
||||
// Если uDistanceToPlanetSurface < 1000.0f, то fogFactor = 0.0f (пока не пересчитан ниже),
|
||||
// что позволяет Z-Far Fog взять контроль.
|
||||
|
||||
|
||||
// --- 3.2. Расчет коэффициента тумана на основе Z-глубины (Z-Far Fog) ---
|
||||
// Этот туман работает всегда, но его эффект усиливается при уменьшении uCurrentZFar,
|
||||
// гарантируя, что все, что подходит к границе uCurrentZFar, будет скрыто.
|
||||
|
||||
// Точка начала тумана: 90% от uCurrentZFar
|
||||
float farFogStart = uCurrentZFar * 0.075;
|
||||
// Длина перехода тумана: 10% от uCurrentZFar
|
||||
float depthRange = uCurrentZFar * 0.1;
|
||||
|
||||
|
||||
float farFogFactor = 0.0;
|
||||
|
||||
if (depthRange > 0.0) {
|
||||
// Нормализация Z-глубины: 0.0f при farFogStart, 1.0f при farFogStart + depthRange
|
||||
farFogFactor = clamp((abs(viewZ) - farFogStart) / depthRange, 0.0, 1.0);
|
||||
}
|
||||
|
||||
// --- 3.3. Объединение ---
|
||||
|
||||
// Когда мы далеко (fogFactor > 0.0), Distance Fog доминирует.
|
||||
// Когда мы близко (fogFactor = 0.0), Z-Far Fog берет управление.
|
||||
// Если оба активны, берем максимум (например, когда фрагмент далек от игрока, но игрок все еще в зоне Distance Fog).
|
||||
//fogFactor = max(fogFactor, farFogFactor);
|
||||
fogFactor = fogFactor * farFogFactor;
|
||||
|
||||
|
||||
// 4. Смешивание цвета с туманом
|
||||
|
||||
//vec3 mountainColor = vec3((length(pos+vec3(0.0,0.0,45000.0))-20000.0)/100.0, 0.5,0.0);
|
||||
//gl_FragColor = mix(vec4(uColor* finalColor.rgb, 1.0), 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);
|
||||
gl_FragColor = vec4(textureColor.rgb, 1.0);
|
||||
}
|
||||
@@ -1,97 +0,0 @@
|
||||
// ---Фрагментный шейдер (Fragment Shader)
|
||||
|
||||
varying vec3 color;
|
||||
varying vec3 normal;
|
||||
varying vec2 TexCoord;
|
||||
varying float viewZ;
|
||||
varying vec3 pos;
|
||||
|
||||
uniform sampler2D Texture;
|
||||
uniform vec3 uLightDirection;
|
||||
uniform float uDistanceToPlanetSurface;
|
||||
uniform float uCurrentZFar;
|
||||
|
||||
// Константы для тумана:
|
||||
//const vec4 FOG_COLOR = vec4(0.0, 0.5, 0.5, 1.0); // Синий туман
|
||||
const vec4 FOG_COLOR = vec4(0.0, 0.5, 1.0, 1.0); // Синий туман
|
||||
|
||||
// Параметры "Distance Fog"
|
||||
const float DIST_FOG_MAX = 2000.0;
|
||||
const float DIST_FOG_MIN = 1000.0;
|
||||
|
||||
// Параметры "Z-Far Fog"
|
||||
// Насколько близко к Zfar должен начинаться туман (например, 10% от Zfar)
|
||||
const float Z_FOG_START_RATIO = 0.8;
|
||||
// Какую долю от Zfar должен покрывать туман (например, 10% от Zfar)
|
||||
const float Z_FOG_RANGE_RATIO = 0.15;
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
// ... (1. Получаем цвет и 2. Расчет освещения)
|
||||
vec4 textureColor = texture2D(Texture, TexCoord);
|
||||
//vec3 finalColor = textureColor.rgb * color;
|
||||
vec3 finalColor = textureColor.rgb;
|
||||
|
||||
float diffuse = max(0.0, dot(normal, uLightDirection));
|
||||
float ambient = 0.2;
|
||||
float lightingFactor = min(1.0, ambient + diffuse);
|
||||
vec3 litColor = finalColor * lightingFactor;
|
||||
|
||||
|
||||
// 3. Расчет коэффициента тумана (fogFactor)
|
||||
float fogFactor = 0.0;
|
||||
|
||||
// --- 3.1. Расчет коэффициента тумана на основе расстояния до поверхности (Distance Fog) ---
|
||||
// Этот туман работает на больших расстояниях и постепенно исчезает,
|
||||
// уступая место Z-Far Fog при приближении к планете.
|
||||
|
||||
if (uDistanceToPlanetSurface >= DIST_FOG_MIN && uDistanceToPlanetSurface <DIST_FOG_MAX) {
|
||||
// Нормализация: 0.0f при DIST_FOG_MAX, 1.0f при DIST_FOG_MIN
|
||||
float distRange = DIST_FOG_MAX - DIST_FOG_MIN;
|
||||
float distNormalized = clamp((uDistanceToPlanetSurface - DIST_FOG_MIN) / distRange, 0.0, 1.0);
|
||||
|
||||
// alpha = 0.0 (Далеко) ... 1.0 (Близко к 1000.f)
|
||||
fogFactor = 1.0 - distNormalized;
|
||||
}
|
||||
if (uDistanceToPlanetSurface < DIST_FOG_MIN)
|
||||
{
|
||||
fogFactor = 1.0;
|
||||
}
|
||||
// Если uDistanceToPlanetSurface < 1000.0f, то fogFactor = 0.0f (пока не пересчитан ниже),
|
||||
// что позволяет Z-Far Fog взять контроль.
|
||||
|
||||
|
||||
// --- 3.2. Расчет коэффициента тумана на основе Z-глубины (Z-Far Fog) ---
|
||||
// Этот туман работает всегда, но его эффект усиливается при уменьшении uCurrentZFar,
|
||||
// гарантируя, что все, что подходит к границе uCurrentZFar, будет скрыто.
|
||||
|
||||
// Точка начала тумана: 90% от uCurrentZFar
|
||||
float farFogStart = uCurrentZFar * 0.075;
|
||||
// Длина перехода тумана: 10% от uCurrentZFar
|
||||
float depthRange = uCurrentZFar * 0.1;
|
||||
|
||||
|
||||
float farFogFactor = 0.0;
|
||||
|
||||
if (depthRange > 0.0) {
|
||||
// Нормализация Z-глубины: 0.0f при farFogStart, 1.0f при farFogStart + depthRange
|
||||
farFogFactor = clamp((abs(viewZ) - farFogStart) / depthRange, 0.0, 1.0);
|
||||
}
|
||||
|
||||
// --- 3.3. Объединение ---
|
||||
|
||||
// Когда мы далеко (fogFactor > 0.0), Distance Fog доминирует.
|
||||
// Когда мы близко (fogFactor = 0.0), Z-Far Fog берет управление.
|
||||
// Если оба активны, берем максимум (например, когда фрагмент далек от игрока, но игрок все еще в зоне Distance Fog).
|
||||
//fogFactor = max(fogFactor, farFogFactor);
|
||||
fogFactor = fogFactor * farFogFactor;
|
||||
|
||||
|
||||
// 4. Смешивание цвета с туманом
|
||||
|
||||
//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(finalColor.rgb, 1.0);
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
attribute vec3 vPosition;
|
||||
attribute vec2 vTexCoord;
|
||||
attribute vec3 vNormal;
|
||||
attribute vec3 vTangent; // Новые атрибуты
|
||||
attribute vec3 vBinormal;
|
||||
|
||||
varying vec2 TexCoord;
|
||||
varying vec3 vViewDirTangent;
|
||||
|
||||
uniform mat4 ProjectionModelViewMatrix;
|
||||
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)
|
||||
);
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
/*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);
|
||||
}*/
|
||||
|
||||
|
||||
varying vec2 TexCoord;
|
||||
varying vec3 vViewDirTangent;
|
||||
|
||||
uniform sampler2D Texture;
|
||||
uniform float uHeightScale;
|
||||
|
||||
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;
|
||||
|
||||
gl_FragColor = texture2D(Texture, finalTexCoord);
|
||||
}
|
||||
|
||||
/*
|
||||
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);
|
||||
}*/
|
||||
@@ -1,12 +0,0 @@
|
||||
//precision mediump float;
|
||||
uniform sampler2D Texture;
|
||||
varying vec2 texCoord;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 color = texture2D(Texture,texCoord).rgba;
|
||||
//gl_FragColor = vec4(color.rgb*0.9 + vec3(0.1, 0.1, 0.1), 1.0);
|
||||
|
||||
gl_FragColor = color;
|
||||
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
uniform samplerCube Texture;
|
||||
|
||||
varying vec3 dir;
|
||||
|
||||
void main(){
|
||||
gl_FragColor = textureCube(Texture, normalize(dir));
|
||||
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
//precision mediump float;
|
||||
uniform sampler2D Texture;
|
||||
varying vec2 texCoord;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 color = texture2D(Texture,texCoord).rgba;
|
||||
gl_FragColor = color;
|
||||
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
uniform samplerCube Texture;
|
||||
|
||||
varying vec3 dir;
|
||||
|
||||
void main(){
|
||||
gl_FragColor = textureCube(Texture, normalize(dir));
|
||||
//if (dir.z < 0)
|
||||
//{
|
||||
// gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
|
||||
//}
|
||||
//gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
|
||||
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
attribute vec3 vPosition;
|
||||
|
||||
uniform mat4 ProjectionModelViewMatrix;
|
||||
|
||||
varying vec3 dir;
|
||||
|
||||
void main(){
|
||||
vec4 realVertexPos = vec4(vPosition.xyz, 1.0);
|
||||
gl_Position = ProjectionModelViewMatrix * realVertexPos;
|
||||
|
||||
dir = vPosition;
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
uniform samplerCube Texture;
|
||||
|
||||
varying vec3 dir;
|
||||
|
||||
void main(){
|
||||
gl_FragColor = textureCube(Texture, normalize(dir));
|
||||
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
uniform samplerCube Texture;
|
||||
uniform float skyPercent;
|
||||
uniform float uPlayerLightFactor; // Глобальный фактор дня/ночи для позиции игрока
|
||||
uniform vec3 uSkyColor;
|
||||
|
||||
varying vec3 vViewDir;
|
||||
|
||||
void main() {
|
||||
vec3 viewDir = normalize(vViewDir);
|
||||
|
||||
// 1. Получаем звезды
|
||||
vec4 starsColor = textureCube(Texture, viewDir);
|
||||
|
||||
// 2. Цвета атмосферы
|
||||
vec3 dayColor = uSkyColor;
|
||||
vec3 nightColor = vec3(0.01, 0.01, 0.04);
|
||||
|
||||
// 3. Теперь всё небо окрашивается одинаково в зависимости от положения игрока
|
||||
// Мы плавно смешиваем ночной и дневной купол
|
||||
vec3 atmosphericColor = mix(nightColor, dayColor, uPlayerLightFactor);
|
||||
|
||||
// 4. Логика видимости звезд
|
||||
// Звезды видны в космосе (skyPercent=0)
|
||||
// И в атмосфере, если сейчас ночь (uPlayerLightFactor -> 0)
|
||||
float starsVisibility = (1.0 - skyPercent) + (skyPercent * (1.0 - uPlayerLightFactor));
|
||||
|
||||
// Делаем звезды чуть ярче на ночном небе
|
||||
starsVisibility = pow(starsVisibility, 1.5);
|
||||
|
||||
// 5. Итоговый цвет
|
||||
// Добавляем слой атмосферы к звездам
|
||||
vec3 skyLayer = atmosphericColor * skyPercent;
|
||||
vec3 finalColor = (starsColor.rgb * starsVisibility) + skyLayer;
|
||||
|
||||
gl_FragColor = vec4(finalColor, 1.0);
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
precision mediump float;
|
||||
uniform samplerCube Texture;
|
||||
varying vec3 dir;
|
||||
|
||||
void main(){
|
||||
gl_FragColor = textureCube(Texture, normalize(dir));
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
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);
|
||||
}
|
||||
@@ -1,115 +0,0 @@
|
||||
varying vec2 TexCoord;
|
||||
varying vec3 vViewDirTangent;
|
||||
varying vec3 Color;
|
||||
varying vec3 worldPosition;
|
||||
varying vec3 vWorldNormal;
|
||||
|
||||
uniform sampler2D Texture;
|
||||
uniform sampler2D BakedTexture;
|
||||
uniform float uHeightScale;
|
||||
uniform float uDistanceToPlanetSurface;
|
||||
uniform float uCurrentZFar;
|
||||
|
||||
uniform vec3 uViewPos;
|
||||
const vec4 FOG_COLOR = vec4(0.0, 0.5, 1.0, 1.0); // Синий туман
|
||||
|
||||
|
||||
uniform vec3 uLightDirWorld; // Направление ЛУЧЕЙ (1, -1, -1)
|
||||
uniform float uPlayerLightFactor;
|
||||
uniform vec3 uPlayerDirWorld;
|
||||
|
||||
void main() {
|
||||
// --- 1. Расчет освещения поверхности ---
|
||||
// Направление НА источник света
|
||||
vec3 lightToSource = normalize(-uLightDirWorld);
|
||||
|
||||
vec3 fragmentDir = normalize(vWorldNormal);
|
||||
|
||||
// Используем vNormal (нормаль в мировом пространстве, так как vPosition тоже в мировом)
|
||||
// Важно: если vNormal не нормализована в вершинном, делаем это здесь
|
||||
vec3 normal = normalize(fragmentDir); // На планете-сфере нормаль совпадает с направлением от центра
|
||||
|
||||
float diff = max(dot(normal, lightToSource), 0.0);
|
||||
float ambient = 0.3; // Базовая освещенность ночной стороны
|
||||
float surfaceLightIntensity = diff + ambient;
|
||||
|
||||
// --- 2. Динамический цвет тумана ---
|
||||
// Синхронизируем туман с атмосферой: днем голубой, ночью темно-синий
|
||||
vec3 dayFog = vec3(0.0, 0.5, 1.0);
|
||||
vec3 nightFog = vec3(0.01, 0.01, 0.04);
|
||||
vec3 dynamicFogColor = mix(nightFog, dayFog, uPlayerLightFactor);
|
||||
|
||||
// --- 3. Основная логика текстур (твой код) ---
|
||||
vec3 viewDir = normalize(vViewDirTangent);
|
||||
float height = texture2D(Texture, TexCoord).a;
|
||||
vec2 p = vec2(viewDir.x, -viewDir.y) * (height * uHeightScale);
|
||||
vec2 finalTexCoord = TexCoord + p;
|
||||
|
||||
float realDist = distance(worldPosition, uViewPos);
|
||||
float textureMixFactor = clamp((2000.0 - realDist) / 500.0, 0.0, 1.0);
|
||||
|
||||
vec4 bakedTextureColor = texture2D(BakedTexture, finalTexCoord);
|
||||
vec4 textureColor = texture2D(Texture, TexCoord);
|
||||
vec4 textureFlavoredColor = vec4(textureColor.rgb * Color, 1.0);
|
||||
|
||||
if (bakedTextureColor.x < 0.01 && bakedTextureColor.y < 0.01 && bakedTextureColor.z < 0.01) {
|
||||
textureMixFactor = 1.0;
|
||||
}
|
||||
|
||||
vec4 finalColor = textureMixFactor * textureFlavoredColor + (1.0 - textureMixFactor) * bakedTextureColor;
|
||||
|
||||
// --- 4. ПРИМЕНЕНИЕ ОСВЕЩЕНИЯ ---
|
||||
// Умножаем результат текстурирования на освещенность
|
||||
finalColor.rgb *= surfaceLightIntensity;
|
||||
|
||||
// --- 5. Расчет тумана (с использованием динамического цвета) ---
|
||||
float h = uDistanceToPlanetSurface;
|
||||
float fogStart, fogEnd;
|
||||
|
||||
if (h >= 1000.0) {
|
||||
gl_FragColor = vec4(finalColor.rgb, 1.0);
|
||||
}
|
||||
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(finalColor.rgb, dynamicFogColor, fogFactor);
|
||||
|
||||
gl_FragColor = vec4(mixedColor, 1.0);
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
|
||||
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);
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -1,102 +0,0 @@
|
||||
// planetStone фрагментный шейдер
|
||||
|
||||
varying vec2 TexCoord;
|
||||
varying vec3 worldPosition;
|
||||
varying vec3 vWorldNormal;
|
||||
|
||||
uniform sampler2D Texture;
|
||||
uniform float uDistanceToPlanetSurface;
|
||||
uniform vec3 uViewPos;
|
||||
uniform vec3 uLightDirWorld;
|
||||
uniform float uPlayerLightFactor;
|
||||
|
||||
void main()
|
||||
{
|
||||
// --- 1. Подготовка векторов ---
|
||||
vec3 normal = normalize(vWorldNormal);
|
||||
vec3 lightToSource = normalize(-uLightDirWorld);
|
||||
|
||||
// Вектор от центра планеты к камню (нормаль самой поверхности планеты под камнем)
|
||||
// Предполагаем, что центр планеты в (0,0,0)
|
||||
vec3 surfaceNormal = normalize(worldPosition);
|
||||
|
||||
// --- 2. Расчет Shadow Mask ---
|
||||
// Проверяем, освещена ли точка планеты, на которой стоит камень
|
||||
float shadowMask = clamp(dot(surfaceNormal, lightToSource) * 5.0, 0.0, 1.0);
|
||||
// Коэффициент 5.0 делает переход на терминаторе более четким
|
||||
|
||||
// --- 3. Освещение камня ---
|
||||
float diff = max(dot(normal, lightToSource), 0.0);
|
||||
|
||||
// Применяем shadowMask к диффузной составляющей
|
||||
// Если точка на планете в тени, то прямой свет (diff) обнуляется
|
||||
float ambient = 0.3;
|
||||
float lightIntensity = (diff * shadowMask);
|
||||
|
||||
lightIntensity *= mix(0.2, 1.0, shadowMask);
|
||||
|
||||
lightIntensity += ambient;
|
||||
|
||||
// --- 4. Остальная логика (цвета и туман) ---
|
||||
vec3 dayFog = vec3(0.0, 0.5, 1.0);
|
||||
vec3 nightFog = vec3(0.01, 0.01, 0.04);
|
||||
vec3 dynamicFogColor = mix(nightFog, dayFog, uPlayerLightFactor);
|
||||
|
||||
vec4 textureColor = texture2D(Texture, TexCoord);
|
||||
vec3 litColor = textureColor.rgb * lightIntensity;
|
||||
|
||||
float realDist = distance(worldPosition, uViewPos);
|
||||
float h = uDistanceToPlanetSurface;
|
||||
float alphaFactor = clamp((2000.0 - realDist) / 500.0, 0.0, 1.0);
|
||||
|
||||
float fogStart, fogEnd;
|
||||
|
||||
// --- Логика расчета границ тумана ---
|
||||
|
||||
if (h >= 1000.0) {
|
||||
gl_FragColor = vec4(litColor, 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(litColor, dynamicFogColor, fogFactor);
|
||||
gl_FragColor = vec4(mixedColor, alphaFactor);
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,9 @@
|
||||
//precision mediump float;
|
||||
precision mediump float;
|
||||
uniform sampler2D Texture;
|
||||
varying vec2 texCoord;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 color = texture2D(Texture,texCoord).rgba;
|
||||
//gl_FragColor = vec4(color.rgb*0.9 + vec3(0.1, 0.1, 0.1), 1.0);
|
||||
|
||||
gl_FragColor = color;
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user