This commit is contained in:
Vlad committed 2026-01-12 14:55:16 +06:00
commit ec30cbe810
2195 files changed
+8017 -321451

No files matched your search

Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+72
View File
@@ -0,0 +1,72 @@
{
"root": {
"type": "FrameLayout",
"x": 0,
"y": 0,
"width": 1280,
"height": 720,
"children": [
{
"type": "FrameLayout",
"name": "centerPanel",
"x": 480,
"y": 160,
"width": 320,
"height": 400,
"children": [
{
"type": "LinearLayout",
"name": "settingsButtons",
"orientation": "vertical",
"spacing": 10,
"x": 0,
"y": 0,
"width": 300,
"height": 300,
"children": [
{
"type": "Button",
"name": "Opt1",
"x": 100,
"y": 300,
"width": 200,
"height": 50,
"textures": {
"normal": "resources/sand2.png",
"hover": "resources/sand2.png",
"pressed": "resources/sand2.png"
}
},
{
"type": "Button",
"name": "Opt2",
"x": 100,
"y": 200,
"width": 200,
"height": 50,
"textures": {
"normal": "resources/sand2.png",
"hover": "resources/sand2.png",
"pressed": "resources/sand2.png"
}
},
{
"type": "Button",
"name": "backButton",
"x": 100,
"y": 100,
"width": 200,
"height": 50,
"textures": {
"normal": "resources/sand2.png",
"hover": "resources/sand2.png",
"pressed": "resources/sand2.png"
}
}
]
}
]
}
]
}
}
+22
View File
@@ -0,0 +1,22 @@
{
"emissionRate": 100.0,
"maxParticles": 200,
"particleSize": 0.3,
"biasX": 0.3,
"emissionPoints": [
{
"position": [-1.3, 0, 0.0]
},
{
"position": [1.3, 0.0, 0.0]
}
],
"speedRange": [0.5, 2.0],
"zSpeedRange": [1.0, 3.0],
"scaleRange": [0.8, 1.2],
"lifeTimeRange": [600.0, 1400.0],
"texture": "resources/spark.png",
"shaderProgramName": "default",
"vertexShader": "resources/shaders/spark.vertex",
"fragmentShader": "resources/shaders/spark.fragment"
}
@@ -0,0 +1,15 @@
{
"emissionPoints": [
{ "position": [0.0, 0.0, 0.0] }
],
"texture": "resources/spark_white.png",
"speedRange": [10.0, 30.0],
"zSpeedRange": [-1.0, 1.0],
"scaleRange": [0.5, 1.0],
"lifeTimeRange": [200.0, 800.0],
"emissionRate": 50.0,
"maxParticles": 10,
"particleSize": 0.09,
"biasX": 0.1,
"shaderProgramName": "default"
}
+169
View File
@@ -0,0 +1,169 @@
{
"root": {
"type": "FrameLayout",
"x": 0,
"y": 0,
"width": 1280,
"height": 720,
"children": [
{
"type": "FrameLayout",
"name": "leftPanel",
"x": 100,
"y": 100,
"width": 320,
"height": 400,
"children": [
{
"type": "LinearLayout",
"name": "mainButtons",
"orientation": "vertical",
"spacing": 10,
"x": 0,
"y": 0,
"width": 300,
"height": 300,
"children": [
{
"type": "Button",
"name": "playButton",
"x": 100,
"y": 500,
"width": 200,
"height": 50,
"animations": {
"buttonsExit": {
"repeat": false,
"steps": [
{
"type": "move",
"to": [
-400,
0
],
"duration": 1.0,
"easing": "easein"
}
]
}
},
"textures": {
"normal": "./resources/sand2.png",
"hover": "./resources/sand2.png",
"pressed": "./resources/sand2.png"
}
},
{
"type": "Button",
"name": "settingsButton",
"x": 100,
"y": 400,
"width": 200,
"height": 50,
"animations": {
"buttonsExit": {
"repeat": false,
"steps": [
{
"type": "wait",
"duration": 0.5
},
{
"type": "move",
"to": [
-400,
0
],
"duration": 1.0,
"easing": "easein"
}
]
}
},
"textures": {
"normal": "./resources/sand2.png",
"hover": "./resources/sand2.png",
"pressed": "./resources/sand2.png"
}
},
{
"type": "Button",
"name": "exitButton",
"x": 100,
"y": 300,
"width": 200,
"height": 50,
"animations": {
"buttonsExit": {
"repeat": false,
"steps": [
{
"type": "wait",
"duration": 1.0
},
{
"type": "move",
"to": [
-400,
0
],
"duration": 1.0,
"easing": "easein"
}
]
},
"bgScroll": {
"repeat": true,
"steps": [
{
"type": "move",
"to": [
1280,
0
],
"duration": 5.0,
"easing": "linear"
}
]
}
},
"textures": {
"normal": "./resources/sand2.png",
"hover": "./resources/sand2.png",
"pressed": "./resources/sand2.png"
}
}
]
}
]
},
{
"type": "Slider",
"name": "velocitySlider",
"x": 1140,
"y": 100,
"width": 50,
"height": 500,
"value": 0.0,
"orientation": "vertical",
"textures": {
"track": "resources/velocitySliderTexture.png",
"knob": "resources/velocitySliderButton.png"
}
},
{
"type": "Button",
"name": "shootButton",
"x": 100,
"y": 100,
"width": 100,
"height": 100,
"textures": {
"normal": "resources/shoot_normal.png",
"hover": "resources/shoot_hover.png",
"pressed": "resources/shoot_pressed.png"
}
}
]
}
}
Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+11
View File
@@ -0,0 +1,11 @@
attribute vec3 vPosition;
attribute vec2 vTexCoord;
varying vec2 texCoord;
uniform mat4 ProjectionModelViewMatrix;
void main()
{
gl_Position = ProjectionModelViewMatrix * vec4(vPosition.xyz, 1.0);
texCoord = vTexCoord;
}
@@ -0,0 +1,17 @@
// Вершинный шейдер:
attribute vec3 vPosition;
attribute vec3 vNormal;
uniform mat4 ProjectionModelViewMatrix;
uniform mat4 ModelViewMatrix;
varying vec3 vWorldNormal;
varying vec3 vViewNormal;
varying vec3 vViewPosition;
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);
}
@@ -0,0 +1,125 @@
precision highp float;
// Фрагментный шейдер:
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()
{
//gl_FragColor = vec4(1.0, 0.0, 0.0, 0.5);
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.0)
{
//finalCloudAlpha = 0.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);
//vec3 finalRGB = currentAtmo;
// Для дымки (atmo) оставляем затухание при посадке
float atmoAlpha = atmosphereDensity * distanceFactor;
//float atmoAlpha = distanceFactor;
float finalAtmoAlpha = atmoAlpha;
if (uDistanceToPlanetSurface < layerHeight) {
finalCloudAlpha *= horizonMask;
finalAtmoAlpha *= horizonMask; // Принудительно гасим дымку под горизонтом
}
gl_FragColor = vec4(finalRGB, max(finalAtmoAlpha, finalCloudAlpha));
}
+23
View File
@@ -0,0 +1,23 @@
attribute vec3 vPosition;
attribute vec3 vColor;
attribute vec3 vNormal;
attribute vec2 vTexCoord; // <-- Обычные UV (если используются)
varying vec3 color;
varying vec3 normal;
varying vec2 TexCoord; // <-- Передаем UV
uniform mat4 ProjectionModelViewMatrix;
uniform mat4 ModelViewMatrix;
uniform vec3 uLightDirection;
void main()
{
gl_Position = ProjectionModelViewMatrix * vec4(vPosition.xyz, 1.0);
normal = normalize((ModelViewMatrix * vec4(vNormal, 0.0)).xyz);
color = vColor;
TexCoord = vTexCoord;
}
@@ -0,0 +1,9 @@
precision mediump float;
varying vec3 color;
void main()
{
//gl_FragColor = vec4(color, 1.0);
gl_FragColor = vec4(1.0, 1.0, 0.5, 1.0);
}
+12
View 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;
}
@@ -0,0 +1,8 @@
precision mediump float;
uniform samplerCube Texture;
varying vec3 dir;
void main(){
gl_FragColor = textureCube(Texture, normalize(dir));
}
+11
View File
@@ -0,0 +1,11 @@
attribute vec3 vPosition;
attribute vec2 vTexCoord;
varying vec2 texCoord;
uniform mat4 ProjectionModelViewMatrix;
void main()
{
gl_Position = ProjectionModelViewMatrix * vec4(vPosition.xyz, 1.0);
texCoord = vTexCoord;
}
@@ -0,0 +1,9 @@
precision mediump float;
uniform sampler2D Texture;
varying vec2 texCoord;
void main()
{
vec4 color = texture2D(Texture,texCoord).rgba;
gl_FragColor = color;
}
+12
View File
@@ -0,0 +1,12 @@
precision mediump float;
uniform sampler2D Texture;
varying vec2 texCoord;
void main()
{
vec4 color = texture2D(Texture,texCoord).rgba;
//gl_FragColor = vec4(color.rgb*0.1 + vec3(0.9, 0.9, 0.9), 1.0);
gl_FragColor = color;
}
+9
View File
@@ -0,0 +1,9 @@
attribute vec3 vPosition;
uniform mat4 ProjectionModelViewMatrix;
varying vec3 vViewDir;
void main() {
gl_Position = ProjectionModelViewMatrix * vec4(vPosition, 1.0);
// Направление взгляда в пространстве вида (вершина куба относительно центра)
vViewDir = vPosition;
}
+37
View File
@@ -0,0 +1,37 @@
precision mediump float;
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);
}
+31
View File
@@ -0,0 +1,31 @@
// Vertex Shader (Bake Stage)
attribute vec3 vPosition;
attribute vec2 vTexCoord;
varying vec2 TexCoord;
varying float vHeight;
// Данные о плоскости треугольника планеты
uniform vec3 uPlanePoint; // Любая вершина треугольника (например, tri.data[0])
uniform vec3 uPlaneNormal; // Нормаль треугольника планеты (ось Z из GetRotationForTriangle)
uniform float uMaxHeight; // Максимальный размер камня (BASE_SCALE)
uniform mat4 ProjectionModelViewMatrix;
void main()
{
// 1. Вычисляем вектор от плоскости до текущей вершины камня
vec3 vecToVertex = vPosition - uPlanePoint;
// 2. Проецируем этот вектор на нормаль плоскости (скалярное произведение)
// Это и есть кратчайшее расстояние от точки до плоскости
float distance = dot(vecToVertex, uPlaneNormal);
// 3. Нормализуем высоту для записи в текстуру (0.0 - уровень земли, 1.0 - пик)
// Clamp гарантирует, что значения не выйдут за пределы, если камень "утоплен"
vHeight = clamp(distance / uMaxHeight, 0.0, 1.0);
TexCoord = vTexCoord;
gl_Position = ProjectionModelViewMatrix * vec4(vPosition, 1.0);
}
@@ -0,0 +1,14 @@
precision mediump float;
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);
}
+40
View File
@@ -0,0 +1,40 @@
attribute vec3 vPosition;
attribute vec2 vTexCoord;
attribute vec3 vNormal;
attribute vec3 vTangent; // Новые атрибуты
attribute vec3 vBinormal;
attribute vec3 vColor;
varying vec3 Color;
varying vec2 TexCoord;
varying vec3 vViewDirTangent;
varying vec3 worldPosition;
varying vec3 vWorldNormal;
uniform mat4 ProjectionModelViewMatrix;
uniform mat4 ModelViewMatrix;
uniform highp 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)
);
vec4 viewPosition = ModelViewMatrix * vec4(vPosition.xyz, 1.0);
worldPosition = vPosition;
vWorldNormal = vPosition;
Color = vColor;
}
+116
View File
@@ -0,0 +1,116 @@
precision highp float;
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);
}
}
+36
View File
@@ -0,0 +1,36 @@
attribute vec3 vPosition;
attribute vec2 vTexCoord;
attribute vec3 vNormal;
attribute vec3 vTangent;
attribute vec3 vBinormal;
attribute vec3 vColor;
varying vec2 TexCoord;
varying vec3 Color;
varying vec3 vViewDirTangent;
varying vec3 worldPosition;
varying vec3 vWorldNormal;
uniform mat4 ProjectionModelViewMatrix;
uniform mat4 ModelViewMatrix;
uniform highp vec3 uViewPos;
void main() {
vWorldNormal = vNormal;
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)
);
vec4 viewPosition = ModelViewMatrix * vec4(vPosition.xyz, 1.0);
worldPosition = vPosition;
}
+102
View File
@@ -0,0 +1,102 @@
precision highp float;
// 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);
}
}
+9
View File
@@ -0,0 +1,9 @@
precision mediump float;
uniform sampler2D Texture;
varying vec2 texCoord;
void main()
{
vec4 color = texture2D(Texture,texCoord).rgba;
gl_FragColor = color;
}
+11
View File
@@ -0,0 +1,11 @@
attribute vec3 vPosition;
attribute vec2 vTexCoord;
varying vec2 texCoord;
uniform mat4 ProjectionModelViewMatrix;
void main()
{
gl_Position = ProjectionModelViewMatrix * vec4(vPosition.xyz, 1.0);
texCoord = vTexCoord;
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
Binary file not shown.