Cool working
This commit is contained in:
parent
27fb7a448c
commit
af550f56a7
31
Game.cpp
31
Game.cpp
@ -152,11 +152,13 @@ namespace ZL
|
|||||||
renderer.shaderManager.AddShaderFromFiles("default", "./shaders/default.vertex", "./shaders/default_web.fragment", CONST_ZIP_FILE);
|
renderer.shaderManager.AddShaderFromFiles("default", "./shaders/default.vertex", "./shaders/default_web.fragment", CONST_ZIP_FILE);
|
||||||
renderer.shaderManager.AddShaderFromFiles("defaultColor", "./shaders/defaultColor.vertex", "./shaders/defaultColor_web.fragment", CONST_ZIP_FILE);
|
renderer.shaderManager.AddShaderFromFiles("defaultColor", "./shaders/defaultColor.vertex", "./shaders/defaultColor_web.fragment", CONST_ZIP_FILE);
|
||||||
renderer.shaderManager.AddShaderFromFiles("env", "./shaders/env.vertex", "./shaders/env_web.fragment", CONST_ZIP_FILE);
|
renderer.shaderManager.AddShaderFromFiles("env", "./shaders/env.vertex", "./shaders/env_web.fragment", CONST_ZIP_FILE);
|
||||||
|
renderer.shaderManager.AddShaderFromFiles("defaultAtmosphere", "./shaders/defaultAtmosphere.vertex", "./shaders/defaultAtmosphere.fragment", CONST_ZIP_FILE);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
renderer.shaderManager.AddShaderFromFiles("default", "./shaders/default.vertex", "./shaders/default_desktop.fragment", CONST_ZIP_FILE);
|
renderer.shaderManager.AddShaderFromFiles("default", "./shaders/default.vertex", "./shaders/default_desktop.fragment", CONST_ZIP_FILE);
|
||||||
renderer.shaderManager.AddShaderFromFiles("defaultColor", "./shaders/defaultColor.vertex", "./shaders/defaultColor_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.vertex", "./shaders/env_desktop.fragment", CONST_ZIP_FILE);
|
renderer.shaderManager.AddShaderFromFiles("env", "./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);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -267,16 +269,18 @@ namespace ZL
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Game::drawCubemap()
|
void Game::drawCubemap(float skyPercent)
|
||||||
{
|
{
|
||||||
static const std::string defaultShaderName = "default";
|
static const std::string defaultShaderName = "default";
|
||||||
static const std::string envShaderName = "env";
|
static const std::string envShaderName = "env";
|
||||||
static const std::string vPositionName = "vPosition";
|
static const std::string vPositionName = "vPosition";
|
||||||
static const std::string vTexCoordName = "vTexCoord";
|
static const std::string vTexCoordName = "vTexCoord";
|
||||||
static const std::string textureUniformName = "Texture";
|
static const std::string textureUniformName = "Texture";
|
||||||
|
static const std::string skyPercentUniformName = "skyPercent";
|
||||||
|
|
||||||
renderer.shaderManager.PushShader(envShaderName);
|
renderer.shaderManager.PushShader(envShaderName);
|
||||||
renderer.RenderUniform1i(textureUniformName, 0);
|
renderer.RenderUniform1i(textureUniformName, 0);
|
||||||
|
renderer.RenderUniform1f(skyPercentUniformName, skyPercent);
|
||||||
renderer.EnableVertexAttribArray(vPositionName);
|
renderer.EnableVertexAttribArray(vPositionName);
|
||||||
renderer.PushPerspectiveProjectionMatrix(1.0 / 1.5,
|
renderer.PushPerspectiveProjectionMatrix(1.0 / 1.5,
|
||||||
static_cast<float>(Environment::width) / static_cast<float>(Environment::height),
|
static_cast<float>(Environment::width) / static_cast<float>(Environment::height),
|
||||||
@ -455,16 +459,31 @@ namespace ZL
|
|||||||
static const std::string vTexCoordName = "vTexCoord";
|
static const std::string vTexCoordName = "vTexCoord";
|
||||||
static const std::string textureUniformName = "Texture";
|
static const std::string textureUniformName = "Texture";
|
||||||
|
|
||||||
glClearColor(0.0f, 0.5f, 1.0f, 1.0f);
|
glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
|
||||||
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
|
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
glViewport(0, 0, Environment::width, Environment::height);
|
glViewport(0, 0, Environment::width, Environment::height);
|
||||||
|
|
||||||
CheckGlError();
|
CheckGlError();
|
||||||
|
|
||||||
drawCubemap();
|
float skyPercent = 0.0;
|
||||||
|
float distance = planetObject.distanceToPlanetSurface();
|
||||||
|
if (distance > 2000.f)
|
||||||
|
{
|
||||||
|
skyPercent = 0.0f;
|
||||||
|
}
|
||||||
|
else if (distance < 1000.f)
|
||||||
|
{
|
||||||
|
skyPercent = 1.0f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
skyPercent = (2000.f - distance) / 1000.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
drawCubemap(skyPercent);
|
||||||
planetObject.draw(renderer);
|
planetObject.draw(renderer);
|
||||||
if (planetObject.planetIsFar(Environment::shipPosition))
|
if (planetObject.planetIsFar())
|
||||||
{
|
{
|
||||||
glClear(GL_DEPTH_BUFFER_BIT);
|
glClear(GL_DEPTH_BUFFER_BIT);
|
||||||
}
|
}
|
||||||
|
|||||||
2
Game.h
2
Game.h
@ -32,7 +32,7 @@ namespace ZL {
|
|||||||
private:
|
private:
|
||||||
void processTickCount();
|
void processTickCount();
|
||||||
void drawScene();
|
void drawScene();
|
||||||
void drawCubemap();
|
void drawCubemap(float skyPercent);
|
||||||
void drawShip();
|
void drawShip();
|
||||||
void drawBoxes();
|
void drawBoxes();
|
||||||
void drawUI();
|
void drawUI();
|
||||||
|
|||||||
131
PlanetObject.cpp
131
PlanetObject.cpp
@ -154,14 +154,23 @@ namespace ZL {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool PlanetObject::planetIsFar(const Vector3f& shipPosition)
|
bool PlanetObject::planetIsFar()
|
||||||
{
|
{
|
||||||
const Vector3f planetWorldPosition = PLANET_CENTER_OFFSET;
|
const Vector3f planetWorldPosition = PLANET_CENTER_OFFSET;
|
||||||
const float distanceToPlanetCenter = (planetWorldPosition - shipPosition).length();
|
const float distanceToPlanetCenter = (planetWorldPosition - Environment::shipPosition).length();
|
||||||
const float distanceToPlanetSurface = distanceToPlanetCenter - PLANET_RADIUS;
|
const float distanceToPlanetSurface = distanceToPlanetCenter - PLANET_RADIUS;
|
||||||
|
|
||||||
return distanceToPlanetSurface > 0.1*TRANSITION_MIDDLE_START;
|
return distanceToPlanetSurface > 0.1*TRANSITION_MIDDLE_START;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float PlanetObject::distanceToPlanetSurface()
|
||||||
|
{
|
||||||
|
const Vector3f planetWorldPosition = PLANET_CENTER_OFFSET;
|
||||||
|
const float distanceToPlanetCenter = (planetWorldPosition - Environment::shipPosition).length();
|
||||||
|
const float distanceToPlanetSurface = distanceToPlanetCenter - PLANET_RADIUS;
|
||||||
|
return distanceToPlanetSurface;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
PlanetObject::PlanetObject()
|
PlanetObject::PlanetObject()
|
||||||
@ -184,6 +193,18 @@ namespace ZL {
|
|||||||
sandTexture = std::make_unique<Texture>(CreateTextureDataFromPng("./resources/sand.png", ""));
|
sandTexture = std::make_unique<Texture>(CreateTextureDataFromPng("./resources/sand.png", ""));
|
||||||
//sandTexture = std::make_unique<Texture>(CreateTextureDataFromPng("./resources/rock.png", ""));
|
//sandTexture = std::make_unique<Texture>(CreateTextureDataFromPng("./resources/rock.png", ""));
|
||||||
|
|
||||||
|
planetAtmosphere.data = CreateRect2D({ 0.f, 0.f }, { 1.f, 1.f }, 0.f);
|
||||||
|
planetAtmosphere.data.TexCoordData.clear();
|
||||||
|
planetAtmosphere.data.ColorData.push_back({ 0,0.5,1 });
|
||||||
|
planetAtmosphere.data.ColorData.push_back({ 0,0.5,1 });
|
||||||
|
planetAtmosphere.data.ColorData.push_back({ 0,0.5,1 });
|
||||||
|
planetAtmosphere.data.ColorData.push_back({ 0,0.5,1 });
|
||||||
|
planetAtmosphere.data.ColorData.push_back({ 0,0.5,1 });
|
||||||
|
planetAtmosphere.data.ColorData.push_back({ 0,0.5,1 });
|
||||||
|
planetAtmosphere.data.Scale(1000.f);
|
||||||
|
//planetAtmosphere.data.Scale(PLANET_RADIUS*1.25f);
|
||||||
|
//planetAtmosphere.data.Move(PLANET_CENTER_OFFSET);
|
||||||
|
planetAtmosphere.RefreshVBO();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlanetObject::prepareDrawData() {
|
void PlanetObject::prepareDrawData() {
|
||||||
@ -245,6 +266,11 @@ namespace ZL {
|
|||||||
renderer.RenderUniform3fv("uLightDirection", &lightDirection_View.v[0]);
|
renderer.RenderUniform3fv("uLightDirection", &lightDirection_View.v[0]);
|
||||||
renderer.RenderUniformMatrix4fv("ModelViewMatrix", false, &viewMatrix.m[0]);
|
renderer.RenderUniformMatrix4fv("ModelViewMatrix", false, &viewMatrix.m[0]);
|
||||||
|
|
||||||
|
float dist = distanceToPlanetSurface();
|
||||||
|
|
||||||
|
renderer.RenderUniform1f("uDistanceToPlanetSurface", dist);
|
||||||
|
renderer.RenderUniform1f("uCurrentZFar", currentZFar);
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, sandTexture->getTexID());
|
glBindTexture(GL_TEXTURE_2D, sandTexture->getTexID());
|
||||||
renderer.DrawVertexRenderStruct(planetRenderStruct);
|
renderer.DrawVertexRenderStruct(planetRenderStruct);
|
||||||
|
|
||||||
@ -261,6 +287,107 @@ namespace ZL {
|
|||||||
renderer.shaderManager.PopShader();
|
renderer.shaderManager.PopShader();
|
||||||
CheckGlError();
|
CheckGlError();
|
||||||
|
|
||||||
|
//drawAtmosphere(renderer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlanetObject::drawAtmosphere(Renderer& renderer) {
|
||||||
|
static const std::string defaultShaderName = "defaultAtmosphere";
|
||||||
|
static const std::string vPositionName = "vPosition";
|
||||||
|
static const std::string vColorName = "vColor";
|
||||||
|
|
||||||
|
glClear(GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
|
|
||||||
|
renderer.shaderManager.PushShader(defaultShaderName);
|
||||||
|
renderer.EnableVertexAttribArray(vPositionName);
|
||||||
|
renderer.EnableVertexAttribArray(vColorName);
|
||||||
|
|
||||||
|
const auto zRange = calculateZRange(Environment::shipPosition);
|
||||||
|
const float currentZNear = zRange.first;
|
||||||
|
const float currentZFar = zRange.second;
|
||||||
|
|
||||||
|
// 2. Применяем динамическую матрицу проекции
|
||||||
|
renderer.PushPerspectiveProjectionMatrix(1.0 / 1.5,
|
||||||
|
static_cast<float>(Environment::width) / static_cast<float>(Environment::height),
|
||||||
|
currentZNear, currentZFar);
|
||||||
|
|
||||||
|
renderer.PushMatrix();
|
||||||
|
renderer.LoadIdentity();
|
||||||
|
renderer.TranslateMatrix({ 0,0, -1.0f * Environment::zoom });
|
||||||
|
renderer.RotateMatrix(Environment::inverseShipMatrix);
|
||||||
|
renderer.TranslateMatrix(-Environment::shipPosition);
|
||||||
|
|
||||||
|
Matrix4f projMatrix = renderer.GetProjectionModelViewMatrix();
|
||||||
|
Matrix4f modelViewMatrix = renderer.GetCurrentModelViewMatrix();
|
||||||
|
|
||||||
|
|
||||||
|
renderer.PopMatrix();
|
||||||
|
renderer.PopProjectionMatrix();
|
||||||
|
|
||||||
|
renderer.PushProjectionMatrix((Environment::width), static_cast<float>(Environment::height), -1, 1);
|
||||||
|
renderer.PushMatrix();
|
||||||
|
renderer.LoadIdentity();
|
||||||
|
|
||||||
|
// Преобразуем центр планеты в экранные координаты
|
||||||
|
int screenX = 0;
|
||||||
|
int screenY = 0;
|
||||||
|
worldToScreenCoordinates(
|
||||||
|
PLANET_CENTER_OFFSET,
|
||||||
|
projMatrix,
|
||||||
|
Environment::width,
|
||||||
|
Environment::height,
|
||||||
|
screenX,
|
||||||
|
screenY
|
||||||
|
);
|
||||||
|
|
||||||
|
// Позиция центра в пикселях
|
||||||
|
Vector3f centerPos = Vector3f(static_cast<float>(screenX), static_cast<float>(screenY), 0.0f);
|
||||||
|
|
||||||
|
renderer.TranslateMatrix(centerPos);
|
||||||
|
renderer.RenderUniform1f("uCenterRadius", 0.f);
|
||||||
|
renderer.RenderUniform3fv("uCenterPos", ¢erPos.v[0]);
|
||||||
|
|
||||||
|
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE);// Аддитивное смешивание для эффекта свечения
|
||||||
|
|
||||||
|
renderer.DrawVertexRenderStruct(planetAtmosphere);
|
||||||
|
glDisable(GL_BLEND);
|
||||||
|
renderer.PopMatrix();
|
||||||
|
renderer.PopProjectionMatrix();
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
renderer.PushPerspectiveProjectionMatrix(1.0 / 1.5,
|
||||||
|
static_cast<float>(Environment::width) / static_cast<float>(Environment::height),
|
||||||
|
currentZNear, currentZFar);
|
||||||
|
|
||||||
|
renderer.PushMatrix();
|
||||||
|
renderer.LoadIdentity();
|
||||||
|
renderer.TranslateMatrix({ 0,0, -1.0f * Environment::zoom });
|
||||||
|
renderer.RotateMatrix(Environment::inverseShipMatrix);
|
||||||
|
renderer.TranslateMatrix(-Environment::shipPosition);
|
||||||
|
|
||||||
|
float centerRadius = PLANET_RADIUS*1.2f;
|
||||||
|
|
||||||
|
Vector3f centerPos = PLANET_CENTER_OFFSET;
|
||||||
|
|
||||||
|
|
||||||
|
renderer.RenderUniform1f("uCenterRadius", centerRadius);
|
||||||
|
renderer.RenderUniform3fv("uCenterPos", ¢erPos.v[0]);
|
||||||
|
|
||||||
|
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE);// Аддитивное смешивание для эффекта свечения
|
||||||
|
|
||||||
|
renderer.DrawVertexRenderStruct(planetAtmosphere);
|
||||||
|
glDisable(GL_BLEND);
|
||||||
|
renderer.PopMatrix();
|
||||||
|
renderer.PopProjectionMatrix();*/
|
||||||
|
renderer.DisableVertexAttribArray(vColorName);
|
||||||
|
renderer.DisableVertexAttribArray(vPositionName);
|
||||||
|
renderer.shaderManager.PopShader();
|
||||||
|
CheckGlError();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -48,6 +48,9 @@ namespace ZL {
|
|||||||
VertexDataStruct planetMesh;
|
VertexDataStruct planetMesh;
|
||||||
VertexRenderStruct planetRenderStruct;
|
VertexRenderStruct planetRenderStruct;
|
||||||
|
|
||||||
|
VertexRenderStruct planetAtmosphere;
|
||||||
|
|
||||||
|
|
||||||
std::shared_ptr<Texture> sandTexture;
|
std::shared_ptr<Texture> sandTexture;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -58,8 +61,10 @@ namespace ZL {
|
|||||||
void update(float deltaTimeMs);
|
void update(float deltaTimeMs);
|
||||||
|
|
||||||
void draw(Renderer& renderer);
|
void draw(Renderer& renderer);
|
||||||
|
void drawAtmosphere(Renderer& renderer);
|
||||||
|
|
||||||
bool planetIsFar(const Vector3f& shipPosition);
|
bool planetIsFar();
|
||||||
|
float distanceToPlanetSurface();
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
12
Renderer.cpp
12
Renderer.cpp
@ -727,6 +727,18 @@ namespace ZL {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Renderer::RenderUniform1f(const std::string& uniformName, float value)
|
||||||
|
{
|
||||||
|
auto shader = shaderManager.GetCurrentShader();
|
||||||
|
|
||||||
|
auto uniform = shader->uniformList.find(uniformName);
|
||||||
|
|
||||||
|
if (uniform != shader->uniformList.end())
|
||||||
|
{
|
||||||
|
glUniform1fv(uniform->second, 1, &value);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Renderer::VertexAttribPointer2fv(const std::string& attribName, int stride, const char* pointer)
|
void Renderer::VertexAttribPointer2fv(const std::string& attribName, int stride, const char* pointer)
|
||||||
|
|||||||
@ -124,7 +124,7 @@ namespace ZL {
|
|||||||
void RenderUniformMatrix4fv(const std::string& uniformName, bool transpose, const float* value);
|
void RenderUniformMatrix4fv(const std::string& uniformName, bool transpose, const float* value);
|
||||||
void RenderUniform1i(const std::string& uniformName, const int value);
|
void RenderUniform1i(const std::string& uniformName, const int value);
|
||||||
void RenderUniform3fv(const std::string& uniformName, const float* value);
|
void RenderUniform3fv(const std::string& uniformName, const float* value);
|
||||||
|
void RenderUniform1f(const std::string& uniformName, float value);
|
||||||
|
|
||||||
void VertexAttribPointer2fv(const std::string& attribName, int stride, const char* pointer);
|
void VertexAttribPointer2fv(const std::string& attribName, int stride, const char* pointer);
|
||||||
|
|
||||||
|
|||||||
41
shaders/defaultAtmosphere.fragment
Normal file
41
shaders/defaultAtmosphere.fragment
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
varying vec3 color;
|
||||||
|
varying vec3 vViewPosition; // Получаем позицию фрагмента в пространстве вида
|
||||||
|
|
||||||
|
uniform vec3 uCenterPos; // Центр планеты/атмосферы (в пространстве вида)
|
||||||
|
uniform float uCenterRadius; // Радиус атмосферы (точка, где прозрачность = 0.5)
|
||||||
|
|
||||||
|
// Определение зоны плавного спада alpha
|
||||||
|
const float FADE_WIDTH = 0.05; // Например, 5% от радиуса для плавного перехода
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// 1. Расчет расстояния от фрагмента до центра
|
||||||
|
float distanceToCenter = length(vViewPosition - uCenterPos);
|
||||||
|
|
||||||
|
// 2. Расчет границ для плавного перехода
|
||||||
|
// Начало спада (R)
|
||||||
|
float startRadius = uCenterRadius;
|
||||||
|
// Конец спада (R + dR)
|
||||||
|
float endRadius = uCenterRadius + FADE_WIDTH * uCenterRadius;
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
20
shaders/defaultAtmosphere.vertex
Normal file
20
shaders/defaultAtmosphere.vertex
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
attribute vec3 vPosition;
|
||||||
|
attribute vec3 vColor;
|
||||||
|
|
||||||
|
uniform mat4 ProjectionModelViewMatrix;
|
||||||
|
uniform mat4 ModelViewMatrix;
|
||||||
|
|
||||||
|
varying vec3 color;
|
||||||
|
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;
|
||||||
|
}
|
||||||
32
shaders/defaultColor_fog.vertex
Normal file
32
shaders/defaultColor_fog.vertex
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
// Вершинный шейдер (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)
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
gl_Position = ProjectionModelViewMatrix * vec4(vPosition.xyz, 1.0);
|
||||||
|
|
||||||
|
normal = normalize((ModelViewMatrix * vec4(vNormal, 0.0)).xyz);
|
||||||
|
color = vColor;
|
||||||
|
TexCoord = vTexCoord;
|
||||||
|
}
|
||||||
89
shaders/defaultColor_fog_desktop.fragment
Normal file
89
shaders/defaultColor_fog_desktop.fragment
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
// ---Фрагментный шейдер (Fragment Shader)
|
||||||
|
|
||||||
|
varying vec3 color;
|
||||||
|
varying vec3 normal;
|
||||||
|
varying vec2 TexCoord;
|
||||||
|
varying float viewZ;
|
||||||
|
|
||||||
|
uniform sampler2D Texture;
|
||||||
|
uniform vec3 uLightDirection;
|
||||||
|
uniform float uDistanceToPlanetSurface;
|
||||||
|
uniform float uCurrentZFar;
|
||||||
|
|
||||||
|
// Константы для тумана:
|
||||||
|
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;
|
||||||
|
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// ... (1. Получаем цвет и 2. Расчет освещения)
|
||||||
|
vec4 textureColor = texture2D(Texture, TexCoord);
|
||||||
|
vec3 finalColor = textureColor.rgb * color;
|
||||||
|
|
||||||
|
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 = 2000.0;
|
||||||
|
// Длина перехода тумана: 10% от uCurrentZFar
|
||||||
|
float depthRange = 2500.0;
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- 3.3. Объединение ---
|
||||||
|
|
||||||
|
// Когда мы далеко (fogFactor > 0.0), Distance Fog доминирует.
|
||||||
|
// Когда мы близко (fogFactor = 0.0), Z-Far Fog берет управление.
|
||||||
|
// Если оба активны, берем максимум (например, когда фрагмент далек от игрока, но игрок все еще в зоне Distance Fog).
|
||||||
|
//fogFactor = max(fogFactor, farFogFactor);
|
||||||
|
fogFactor = fogFactor * farFogFactor;
|
||||||
|
|
||||||
|
|
||||||
|
// 4. Смешивание цвета с туманом
|
||||||
|
gl_FragColor = mix(vec4(litColor, 1.0), FOG_COLOR, fogFactor);
|
||||||
|
}
|
||||||
12
shaders/env_sky.vertex
Normal file
12
shaders/env_sky.vertex
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
attribute vec3 vPosition;
|
||||||
|
|
||||||
|
uniform mat4 ProjectionModelViewMatrix;
|
||||||
|
|
||||||
|
varying vec3 dir;
|
||||||
|
|
||||||
|
void main(){
|
||||||
|
vec4 realVertexPos = vec4(vPosition.xyz, 1.0);
|
||||||
|
gl_Position = ProjectionModelViewMatrix * realVertexPos;
|
||||||
|
|
||||||
|
dir = vPosition;
|
||||||
|
}
|
||||||
11
shaders/env_sky_desktop.fragment
Normal file
11
shaders/env_sky_desktop.fragment
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
uniform samplerCube Texture;
|
||||||
|
uniform float skyPercent;
|
||||||
|
|
||||||
|
varying vec3 dir;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user