Lighting and clouds are somehow working
This commit is contained in:
parent
8168734fbb
commit
34fee1005a
@ -6,43 +6,113 @@ 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()
|
||||
{
|
||||
// --- 1. Расчет плотности по Френелю (краевой эффект) ---
|
||||
vec3 viewVector = normalize(-vViewPosition);
|
||||
float NdotV = dot(vViewNormal, viewVector);
|
||||
float factor = 1.0 - abs(NdotV);
|
||||
float atmosphereDensity = pow(factor, 5.0);
|
||||
vec3 normal = normalize(vViewNormal);
|
||||
vec3 viewVector = normalize(-vViewPosition);
|
||||
float NdotV = dot(normal, viewVector);
|
||||
|
||||
// --- 2. Расчет коэффициента затухания по дистанции ---
|
||||
// Вектор направления от центра планеты к текущему фрагменту атмосферы (Мировой)
|
||||
vec3 fragmentDir = normalize(vWorldNormal);
|
||||
// Вектор направления от центра планеты к игроку (нужно передать как uniform)
|
||||
// Передай его в C++: renderer.RenderUniform3fv("uPlayerDirWorld", playerDirWorld.data());
|
||||
|
||||
|
||||
float distanceFactor = 1.0;
|
||||
// --- 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);
|
||||
|
||||
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);
|
||||
|
||||
// --- 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; // Принудительно гасим дымку под горизонтом
|
||||
}
|
||||
|
||||
// --- 3. Финальный цвет и прозрачность ---
|
||||
|
||||
float finalAlpha = atmosphereDensity * distanceFactor;
|
||||
|
||||
gl_FragColor = vec4(uColor, finalAlpha);
|
||||
gl_FragColor = vec4(finalRGB, max(finalAtmoAlpha, finalCloudAlpha));
|
||||
}
|
||||
@ -1,28 +1,17 @@
|
||||
// Вершинный шейдер:
|
||||
attribute vec3 vPosition;
|
||||
attribute vec3 vNormal; // <-- Новый атрибут
|
||||
attribute vec3 vNormal;
|
||||
|
||||
uniform mat4 ProjectionModelViewMatrix;
|
||||
uniform mat4 ModelViewMatrix;
|
||||
|
||||
// Выходные переменные (передаются во фрагментный шейдер)
|
||||
varying vec3 vViewNormal;
|
||||
varying vec3 vWorldNormal;
|
||||
varying vec3 vViewNormal;
|
||||
varying vec3 vViewPosition;
|
||||
|
||||
void main()
|
||||
{
|
||||
// 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);
|
||||
void main() {
|
||||
vWorldNormal = vPosition; // Локальная позиция вершины на сфере радиуса 1.0
|
||||
vViewPosition = (ModelViewMatrix * vec4(vPosition, 1.0)).xyz;
|
||||
vViewNormal = normalize((ModelViewMatrix * vec4(vNormal, 0.0)).xyz);
|
||||
gl_Position = ProjectionModelViewMatrix * vec4(vPosition, 1.0);
|
||||
}
|
||||
118
shaders/defaultAtmosphere_debug1.fragment
Normal file
118
shaders/defaultAtmosphere_debug1.fragment
Normal file
@ -0,0 +1,118 @@
|
||||
// Фрагментный шейдер:
|
||||
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));
|
||||
}
|
||||
122
shaders/defaultAtmosphere_debug2.fragment
Normal file
122
shaders/defaultAtmosphere_debug2.fragment
Normal file
@ -0,0 +1,122 @@
|
||||
// Фрагментный шейдер:
|
||||
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,12 +1,9 @@
|
||||
attribute vec3 vPosition;
|
||||
|
||||
uniform mat4 ProjectionModelViewMatrix;
|
||||
varying vec3 vViewDir;
|
||||
|
||||
varying vec3 dir;
|
||||
|
||||
void main(){
|
||||
vec4 realVertexPos = vec4(vPosition.xyz, 1.0);
|
||||
gl_Position = ProjectionModelViewMatrix * realVertexPos;
|
||||
|
||||
dir = vPosition;
|
||||
void main() {
|
||||
gl_Position = ProjectionModelViewMatrix * vec4(vPosition, 1.0);
|
||||
// Направление взгляда в пространстве вида (вершина куба относительно центра)
|
||||
vViewDir = vPosition;
|
||||
}
|
||||
@ -1,11 +1,36 @@
|
||||
uniform samplerCube Texture;
|
||||
uniform float skyPercent;
|
||||
uniform float skyPercent;
|
||||
uniform float uPlayerLightFactor; // Глобальный фактор дня/ночи для позиции игрока
|
||||
uniform vec3 uSkyColor;
|
||||
|
||||
varying vec3 dir;
|
||||
varying vec3 vViewDir;
|
||||
|
||||
void main(){
|
||||
vec4 skyBoxColor = textureCube(Texture, normalize(dir));
|
||||
vec4 skyColor = vec4(0.0, 0.5, 1.0, 1.0);
|
||||
gl_FragColor = skyPercent*skyColor + (1.0 - skyPercent) * skyBoxColor;
|
||||
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);
|
||||
}
|
||||
@ -10,6 +10,7 @@ varying vec3 Color;
|
||||
varying vec2 TexCoord;
|
||||
varying vec3 vViewDirTangent;
|
||||
varying vec3 worldPosition;
|
||||
varying vec3 vWorldNormal;
|
||||
|
||||
uniform mat4 ProjectionModelViewMatrix;
|
||||
uniform mat4 ModelViewMatrix;
|
||||
@ -33,5 +34,7 @@ void main() {
|
||||
|
||||
worldPosition = vPosition;
|
||||
|
||||
vWorldNormal = vPosition;
|
||||
|
||||
Color = vColor;
|
||||
}
|
||||
@ -2,6 +2,7 @@ varying vec2 TexCoord;
|
||||
varying vec3 vViewDirTangent;
|
||||
varying vec3 Color;
|
||||
varying vec3 worldPosition;
|
||||
varying vec3 vWorldNormal;
|
||||
|
||||
uniform sampler2D Texture;
|
||||
uniform sampler2D BakedTexture;
|
||||
@ -12,41 +13,58 @@ 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.15; // Базовая освещенность ночной стороны
|
||||
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;
|
||||
|
||||
// Смещение. Знак минус используется, если мы хотим "вдавить" камни
|
||||
// Деление на 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 p = vec2(viewDir.x, -viewDir.y) * (height * uHeightScale);
|
||||
vec2 finalTexCoord = TexCoord + p;
|
||||
|
||||
float realDist = distance(worldPosition, uViewPos);
|
||||
|
||||
|
||||
float textureMixFactor = clamp((2000 - realDist) / 500.0, 0.0, 1.0);
|
||||
|
||||
vec4 bakedTextureColor = texture2D(BakedTexture, finalTexCoord);
|
||||
vec4 textureColor = texture2D(Texture, TexCoord);
|
||||
|
||||
vec3 flavoredRGB = mix(textureColor.rgb, textureColor.rgb * Color, 0.7);
|
||||
vec4 textureFlavoredColor = vec4(textureColor.rgb * Color, 1.0);
|
||||
|
||||
if (bakedTextureColor.x < 0.01 && bakedTextureColor.y < 0.01 && bakedTextureColor.y < 0.01)
|
||||
{
|
||||
textureMixFactor = 1.0;
|
||||
}
|
||||
|
||||
vec4 finalColor = textureMixFactor*textureFlavoredColor + (1 - textureMixFactor) * bakedTextureColor;
|
||||
|
||||
float h = uDistanceToPlanetSurface;
|
||||
|
||||
float fogStart;
|
||||
float fogEnd;
|
||||
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);
|
||||
@ -86,12 +104,11 @@ float h = uDistanceToPlanetSurface;
|
||||
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, FOG_COLOR.rgb, fogFactor);
|
||||
// Смешиваем с динамическим цветом тумана
|
||||
vec3 mixedColor = mix(finalColor.rgb, dynamicFogColor, fogFactor);
|
||||
|
||||
gl_FragColor = vec4(mixedColor, 1.0);
|
||||
}
|
||||
|
||||
@ -9,6 +9,7 @@ varying vec2 TexCoord;
|
||||
varying vec3 Color;
|
||||
varying vec3 vViewDirTangent;
|
||||
varying vec3 worldPosition;
|
||||
varying vec3 vWorldNormal;
|
||||
|
||||
uniform mat4 ProjectionModelViewMatrix;
|
||||
uniform mat4 ModelViewMatrix;
|
||||
@ -16,6 +17,7 @@ uniform mat4 ModelViewMatrix;
|
||||
uniform vec3 uViewPos;
|
||||
|
||||
void main() {
|
||||
vWorldNormal = vNormal;
|
||||
gl_Position = ProjectionModelViewMatrix * vec4(vPosition, 1.0);
|
||||
TexCoord = vTexCoord;
|
||||
|
||||
|
||||
@ -1,34 +1,60 @@
|
||||
// --- Улучшенный Фрагментный шейдер
|
||||
// planetStone фрагментный шейдер
|
||||
|
||||
varying vec2 TexCoord;
|
||||
varying vec3 worldPosition;
|
||||
varying vec3 vWorldNormal;
|
||||
|
||||
uniform sampler2D Texture;
|
||||
uniform float uDistanceToPlanetSurface;
|
||||
uniform vec3 uViewPos;
|
||||
|
||||
const vec4 FOG_COLOR = vec4(0.0, 0.5, 1.0, 1.0);
|
||||
|
||||
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.15;
|
||||
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 fogStart;
|
||||
float fogEnd;
|
||||
|
||||
// --- Логика AlphaFactor (строго 2000-2500) ---
|
||||
// Объект полностью исчезает на 2500.
|
||||
// Если fogStart на высоте 1000 равен 2500, то туман и объект исчезнут одновременно.
|
||||
float alphaFactor = clamp((2000.0 - realDist) / 500.0, 0.0, 1.0);
|
||||
float alphaFactor = clamp((2000.0 - realDist) / 500.0, 0.0, 1.0);
|
||||
|
||||
float fogStart, fogEnd;
|
||||
|
||||
// --- Логика расчета границ тумана ---
|
||||
|
||||
if (h >= 1000.0) {
|
||||
gl_FragColor = vec4(textureColor.rgb, alphaFactor);
|
||||
gl_FragColor = vec4(litColor, alphaFactor);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -67,11 +93,10 @@ void main()
|
||||
|
||||
// Расчет фактора тумана
|
||||
float fogRange = max(fogEnd - fogStart, 1.0);
|
||||
float fogFactor = clamp((realDist - fogStart) / fogRange, 0.0, 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);
|
||||
// Смешивание освещенного камня с динамическим туманом
|
||||
vec3 mixedColor = mix(litColor, dynamicFogColor, fogFactor);
|
||||
gl_FragColor = vec4(mixedColor, alphaFactor);
|
||||
}
|
||||
}
|
||||
40
src/Game.cpp
40
src/Game.cpp
@ -139,7 +139,7 @@ namespace ZL
|
||||
#else
|
||||
renderer.shaderManager.AddShaderFromFiles("default", "./shaders/default.vertex", "./shaders/default_desktop.fragment", CONST_ZIP_FILE);
|
||||
renderer.shaderManager.AddShaderFromFiles("defaultColor", "./shaders/defaultColor_fog.vertex", "./shaders/defaultColor_fog_desktop.fragment", CONST_ZIP_FILE);
|
||||
renderer.shaderManager.AddShaderFromFiles("env", "./shaders/env_sky.vertex", "./shaders/env_sky_desktop.fragment", CONST_ZIP_FILE);
|
||||
renderer.shaderManager.AddShaderFromFiles("env_sky", "./shaders/env_sky.vertex", "./shaders/env_sky_desktop.fragment", CONST_ZIP_FILE);
|
||||
renderer.shaderManager.AddShaderFromFiles("defaultAtmosphere", "./shaders/defaultAtmosphere.vertex", "./shaders/defaultAtmosphere.fragment", CONST_ZIP_FILE);
|
||||
renderer.shaderManager.AddShaderFromFiles("defaultColor2", "./shaders/defaultColor_fog2.vertex", "./shaders/defaultColor_fog2_desktop.fragment", CONST_ZIP_FILE);
|
||||
renderer.shaderManager.AddShaderFromFiles("defaultColorStones", "./shaders/defaultColor_fog_stones.vertex", "./shaders/defaultColor_fog_stones_desktop.fragment", CONST_ZIP_FILE);
|
||||
@ -303,7 +303,7 @@ namespace ZL
|
||||
void Game::drawCubemap(float skyPercent)
|
||||
{
|
||||
static const std::string defaultShaderName = "default";
|
||||
static const std::string envShaderName = "env";
|
||||
static const std::string envShaderName = "env_sky";
|
||||
static const std::string vPositionName = "vPosition";
|
||||
static const std::string vTexCoordName = "vTexCoord";
|
||||
static const std::string textureUniformName = "Texture";
|
||||
@ -320,6 +320,36 @@ namespace ZL
|
||||
renderer.LoadIdentity();
|
||||
renderer.RotateMatrix(Environment::inverseShipMatrix);
|
||||
|
||||
|
||||
Vector3f worldLightDir = Vector3f(1.0f, -1.0f, -1.0f).normalized();
|
||||
Matrix3f viewMatrix = Environment::inverseShipMatrix;
|
||||
Vector3f viewLightDir = (viewMatrix * worldLightDir).normalized();
|
||||
|
||||
|
||||
// Передаем вектор НА источник света
|
||||
Vector3f lightToSource = -viewLightDir;
|
||||
renderer.RenderUniform3fv("uLightDirView", lightToSource.data());
|
||||
|
||||
// 2. Базовый цвет атмосферы (голубой)
|
||||
Vector3f skyColor = { 0.0f, 0.5f, 1.0f };
|
||||
renderer.RenderUniform3fv("uSkyColor", skyColor.data());
|
||||
|
||||
// 1. Вектор направления от центра планеты к игроку (в мировых координатах)
|
||||
// Предполагаем, что планета в (0,0,0). Если нет, то (shipPosition - planetCenter)
|
||||
Vector3f playerDirWorld = Environment::shipPosition.normalized();
|
||||
|
||||
// 2. Направление света в мировом пространстве
|
||||
//Vector3f worldLightDir = Vector3f(1.0f, -1.0f, -1.0f).normalized();
|
||||
|
||||
// 3. Считаем глобальную освещенность для игрока (насколько он на свету)
|
||||
// Это одно число для всего кадра
|
||||
float playerLightFactor = playerDirWorld.dot(-worldLightDir);
|
||||
// Ограничиваем и делаем переход мягче
|
||||
playerLightFactor = std::clamp((playerLightFactor + 0.2f) / 1.2f, 0.0f, 1.0f);
|
||||
|
||||
renderer.RenderUniform1f("uPlayerLightFactor", playerLightFactor);
|
||||
renderer.RenderUniform1f("skyPercent", skyPercent);
|
||||
|
||||
CheckGlError();
|
||||
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, cubemapTexture->getTexID());
|
||||
@ -509,17 +539,17 @@ namespace ZL
|
||||
|
||||
float skyPercent = 0.0;
|
||||
float distance = planetObject.distanceToPlanetSurface(Environment::shipPosition);
|
||||
if (distance > 1900.f)
|
||||
if (distance > 1500.f)
|
||||
{
|
||||
skyPercent = 0.0f;
|
||||
}
|
||||
else if (distance < 1000.f)
|
||||
else if (distance < 800.f)
|
||||
{
|
||||
skyPercent = 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
skyPercent = (1900.f - distance) / 900.f;
|
||||
skyPercent = (1500.f - distance) / (1500.f - 800.f);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -275,7 +275,18 @@ namespace ZL {
|
||||
renderer.RenderUniform1f("uDistanceToPlanetSurface", dist);
|
||||
renderer.RenderUniform1f("uCurrentZFar", currentZFar);
|
||||
|
||||
// Направление на солнце в мировом пространстве
|
||||
Vector3f sunDirWorld = Vector3f(1.0f, -1.0f, -1.0f).normalized();
|
||||
renderer.RenderUniform3fv("uLightDirWorld", sunDirWorld.data());
|
||||
|
||||
// Направление от центра планеты к игроку для расчета дня/ночи
|
||||
Vector3f playerDirWorld = Environment::shipPosition.normalized();
|
||||
renderer.RenderUniform3fv("uPlayerDirWorld", playerDirWorld.data());
|
||||
|
||||
// Тот же фактор освещенности игрока
|
||||
float playerLightFactor = playerDirWorld.dot(-sunDirWorld);
|
||||
playerLightFactor = max(0.0f, (playerLightFactor + 0.2f) / 1.2f);
|
||||
renderer.RenderUniform1f("uPlayerLightFactor", playerLightFactor);
|
||||
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glBindTexture(GL_TEXTURE_2D, stoneMapFB->getTextureID());
|
||||
@ -337,6 +348,14 @@ namespace ZL {
|
||||
renderer.RenderUniform1f("uCurrentZFar", currentZFar);
|
||||
renderer.RenderUniform3fv("uViewPos", Environment::shipPosition.data());
|
||||
|
||||
// PlanetObject.cpp, метод drawStones
|
||||
Vector3f sunDirWorld = Vector3f(1.0f, -1.0f, -1.0f).normalized();
|
||||
renderer.RenderUniform3fv("uLightDirWorld", sunDirWorld.data());
|
||||
|
||||
Vector3f playerDirWorld = Environment::shipPosition.normalized();
|
||||
float playerLightFactor = max(0.0f, (playerDirWorld.dot(-sunDirWorld) + 0.2f) / 1.2f);
|
||||
renderer.RenderUniform1f("uPlayerLightFactor", playerLightFactor);
|
||||
|
||||
glEnable(GL_CULL_FACE);
|
||||
glCullFace(GL_BACK);
|
||||
glEnable(GL_BLEND);
|
||||
@ -377,11 +396,16 @@ namespace ZL {
|
||||
renderer.EnableVertexAttribArray(vPositionName);
|
||||
renderer.EnableVertexAttribArray(vNormalName);
|
||||
|
||||
|
||||
float dist = planetData.distanceToPlanetSurfaceFast(Environment::shipPosition);
|
||||
auto zRange = planetData.calculateZRange(dist);
|
||||
const float currentZNear = zRange.first;
|
||||
const float currentZFar = zRange.second;
|
||||
float currentZNear = zRange.first;
|
||||
float currentZFar = zRange.second;
|
||||
|
||||
if (currentZNear < 200)
|
||||
{
|
||||
currentZNear = 200;
|
||||
currentZFar = currentZNear * 100;
|
||||
}
|
||||
|
||||
// 2. Применяем динамическую матрицу проекции
|
||||
renderer.PushPerspectiveProjectionMatrix(1.0 / 1.5,
|
||||
@ -405,6 +429,47 @@ namespace ZL {
|
||||
|
||||
renderer.RenderUniform1f("uDistanceToPlanetSurface", dist);
|
||||
|
||||
// В начале drawAtmosphere или как uniform
|
||||
float time = SDL_GetTicks() / 1000.0f;
|
||||
renderer.RenderUniform1f("uTime", time);
|
||||
|
||||
// В методе PlanetObject::drawAtmosphere
|
||||
Vector3f worldLightDir = Vector3f(1.0f, -1.0f, -1.0f).normalized();
|
||||
|
||||
// Получаем текущую матрицу вида (ModelView без трансляции объекта)
|
||||
// В вашем движке это Environment::inverseShipMatrix
|
||||
Matrix3f viewMatrix2 = Environment::inverseShipMatrix;
|
||||
|
||||
// Трансформируем вектор света в пространство вида
|
||||
Vector3f viewLightDir = viewMatrix2 * worldLightDir;
|
||||
|
||||
// Передаем инвертированный вектор (направление НА источник)
|
||||
Vector3f lightToSource = -viewLightDir.normalized();
|
||||
renderer.RenderUniform3fv("uLightDirView", lightToSource.data());
|
||||
|
||||
// В методе Game::drawCubemap
|
||||
renderer.RenderUniform1f("uTime", SDL_GetTicks() / 1000.0f);
|
||||
// Направление света в мировом пространстве для освещения облаков
|
||||
//Vector3f worldLightDir = Vector3f(1.0f, -1.0f, -1.0f).normalized();
|
||||
renderer.RenderUniform3fv("uWorldLightDir", worldLightDir.data());
|
||||
|
||||
// 1. Рассчитываем uPlayerLightFactor (как в Game.cpp)
|
||||
Vector3f playerDirWorld = Environment::shipPosition.normalized();
|
||||
Vector3f sunDirWorld = Vector3f(1.0f, -1.0f, -1.0f).normalized();
|
||||
|
||||
// Насколько игрок на свету
|
||||
float playerLightFactor = playerDirWorld.dot(-sunDirWorld);
|
||||
playerLightFactor = max(0.0f, (playerLightFactor + 0.2f) / 1.2f); // Мягкий порог
|
||||
|
||||
// 2. ОБЯЗАТЕЛЬНО передаем в шейдер
|
||||
renderer.RenderUniform1f("uPlayerLightFactor", playerLightFactor);
|
||||
|
||||
// 3. Убедитесь, что uSkyColor тоже передан (в коде выше его не было)
|
||||
renderer.RenderUniform3fv("uSkyColor", color.data());
|
||||
|
||||
//Vector3f playerDirWorld = Environment::shipPosition.normalized();
|
||||
renderer.RenderUniform3fv("uPlayerDirWorld", playerDirWorld.data());
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE);// Аддитивное смешивание для эффекта свечения
|
||||
|
||||
|
||||
@ -10,8 +10,7 @@
|
||||
namespace ZL {
|
||||
|
||||
|
||||
|
||||
const float StoneParams::BASE_SCALE = 15.0f; // Общий размер камня
|
||||
const float StoneParams::BASE_SCALE = 10.0f; // Общий размер камня
|
||||
const float StoneParams::MIN_AXIS_SCALE = 1.0f; // Минимальное растяжение/сжатие по оси
|
||||
const float StoneParams::MAX_AXIS_SCALE = 1.0f; // Максимальное растяжение/сжатие по оси
|
||||
const float StoneParams::MIN_PERTURBATION = 0.0f; // Минимальное радиальное возмущение вершины
|
||||
@ -22,6 +21,7 @@ namespace ZL {
|
||||
const float StoneParams::MAX_PERTURBATION = 0.25f; // Максимальное радиальное возмущение вершины
|
||||
*/
|
||||
const int StoneParams::STONES_PER_TRIANGLE = 40;
|
||||
//const int StoneParams::STONES_PER_TRIANGLE = 1;
|
||||
|
||||
// Вспомогательная функция для получения случайного числа в диапазоне [min, max]
|
||||
float getRandomFloat(std::mt19937& gen, float min, float max) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user