97 lines
3.2 KiB
Plaintext
97 lines
3.2 KiB
Plaintext
varying vec2 TexCoord;
|
||
varying vec3 vViewDirTangent;
|
||
varying vec3 Color;
|
||
varying vec3 worldPosition;
|
||
|
||
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); // Синий туман
|
||
|
||
void main() {
|
||
vec3 viewDir = normalize(vViewDirTangent);
|
||
|
||
// Получаем высоту из альфа-канала запеченной текстуры
|
||
float height = texture2D(Texture, TexCoord).a;
|
||
|
||
// Смещение. Знак минус используется, если мы хотим "вдавить" камни
|
||
// Деление на viewDir.z помогает избежать сильных искажений под углом
|
||
//vec2 p = viewDir.xy * (height * uHeightScale) / viewDir.z;
|
||
vec2 p = vec2(viewDir.x, -viewDir.y) * (height * uHeightScale);
|
||
//vec2 p = vec2(0,0);
|
||
vec2 finalTexCoord = TexCoord + p;
|
||
|
||
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);
|
||
|
||
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;
|
||
|
||
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, FOG_COLOR.rgb, fogFactor);
|
||
|
||
gl_FragColor = vec4(mixedColor, 1.0);
|
||
}
|
||
} |