Lighting and clouds are somehow working

This commit is contained in:
Vladislav Khorev committed 2026-01-04 18:11:10 +03:00
1 parent 8168734fbb
commit 34fee1005a
13 files changed
+586 -123

No files matched your search

+35 -5
View File
@@ -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);
}
+68 -3
View File
@@ -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);// Аддитивное смешивание для эффекта свечения
+2 -2
View File
@@ -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) {