Улучшено поведение дымки
This commit is contained in:
@@ -8,8 +8,9 @@ public final class FogEnvironmentContext {
|
|||||||
|
|
||||||
private static float emissionMultiplier = 1.0f;
|
private static float emissionMultiplier = 1.0f;
|
||||||
private static float targetDensityMultiplier = 0.0f;
|
private static float targetDensityMultiplier = 0.0f;
|
||||||
private static float fogDayRandom = 0.5f; // НОВЫЙ uniform
|
private static float fogDayRandom = 0.5f;
|
||||||
private static float rainMultiplier = 0.0f;
|
private static float rainMultiplier = 0.0f;
|
||||||
|
private static float heightFadeMax = 90.0f; // НОВОЕ
|
||||||
|
|
||||||
private static float smoothEmission = 1.0f;
|
private static float smoothEmission = 1.0f;
|
||||||
private static float smoothTargetDensity = 0.0f;
|
private static float smoothTargetDensity = 0.0f;
|
||||||
@@ -43,7 +44,7 @@ public final class FogEnvironmentContext {
|
|||||||
double noiseValue = dayNoise.sample(totalDays * 0.05, 0);
|
double noiseValue = dayNoise.sample(totalDays * 0.05, 0);
|
||||||
float dayOffset = (float)(noiseValue * 1000);
|
float dayOffset = (float)(noiseValue * 1000);
|
||||||
|
|
||||||
float p1 = 16000 + dayOffset;
|
float p1 = 16000 - dayOffset;
|
||||||
float p2 = 20000;
|
float p2 = 20000;
|
||||||
float p3 = 23000;
|
float p3 = 23000;
|
||||||
float p4 = 3000 + dayOffset;
|
float p4 = 3000 + dayOffset;
|
||||||
@@ -65,23 +66,26 @@ public final class FogEnvironmentContext {
|
|||||||
float t4 = 6000; // полдень
|
float t4 = 6000; // полдень
|
||||||
|
|
||||||
float baseTargetDensity = trapezoid(timeOfDay, t1, t2, t3, t4);
|
float baseTargetDensity = trapezoid(timeOfDay, t1, t2, t3, t4);
|
||||||
|
|
||||||
// В дождь дымка всегда
|
|
||||||
float rainFactor = rain + thunder * 0.5f;
|
float rainFactor = rain + thunder * 0.5f;
|
||||||
float rawTargetDensity = Math.max(baseTargetDensity, rainFactor);
|
float rawTargetDensity = Math.max(baseTargetDensity, rainFactor);
|
||||||
|
|
||||||
// === 3. Случайное значение для "туманного дня" ===
|
// === 3. Случайное значение для "туманного дня" ===
|
||||||
// Это ОТДЕЛЬНЫЙ uniform, НЕ умноженный на трапецию
|
|
||||||
double dayNoiseValue = dayNoise.sample(totalDays * 0.1, 100);
|
double dayNoiseValue = dayNoise.sample(totalDays * 0.1, 100);
|
||||||
float rawFogDayRandom = (float)(0.5 + dayNoiseValue * 0.5); // 0..1
|
float rawFogDayRandom = (float)(0.5 + dayNoiseValue * 0.5);
|
||||||
|
|
||||||
// === 4. Сглаживание ===
|
// === 4. HeightFadeMax (90 ± 10 от дневного шума) ===
|
||||||
|
double heightNoise = dayNoise.sample(totalDays * 0.1, 200);
|
||||||
|
float rawHeightFadeMax = 90.0f + (float)(heightNoise * 10.0);
|
||||||
|
rawHeightFadeMax = Math.max(80.0f, Math.min(100.0f, rawHeightFadeMax));
|
||||||
|
|
||||||
|
// === 5. Сглаживание ===
|
||||||
float lerpSpeed = 0.08f;
|
float lerpSpeed = 0.08f;
|
||||||
smoothEmission = lerp(smoothEmission, rawEmission, lerpSpeed);
|
smoothEmission = lerp(smoothEmission, rawEmission, lerpSpeed);
|
||||||
smoothTargetDensity = lerp(smoothTargetDensity, rawTargetDensity, lerpSpeed * 2.0f);
|
smoothTargetDensity = lerp(smoothTargetDensity, rawTargetDensity, lerpSpeed * 2.0f);
|
||||||
smoothRain = lerp(smoothRain, rainFactor, lerpSpeed * 2.0f);
|
smoothRain = lerp(smoothRain, rainFactor, lerpSpeed * 2.0f);
|
||||||
// FogDayRandom НЕ сглаживаем — он постоянен в течение дня
|
|
||||||
fogDayRandom = rawFogDayRandom;
|
fogDayRandom = rawFogDayRandom;
|
||||||
|
heightFadeMax = rawHeightFadeMax; // Не сглаживаем, постоянен в течение дня
|
||||||
|
|
||||||
emissionMultiplier = smoothEmission;
|
emissionMultiplier = smoothEmission;
|
||||||
targetDensityMultiplier = smoothTargetDensity;
|
targetDensityMultiplier = smoothTargetDensity;
|
||||||
@@ -113,4 +117,5 @@ public final class FogEnvironmentContext {
|
|||||||
public static float getTargetDensityMultiplier() { return targetDensityMultiplier; }
|
public static float getTargetDensityMultiplier() { return targetDensityMultiplier; }
|
||||||
public static float getFogDayRandom() { return fogDayRandom; }
|
public static float getFogDayRandom() { return fogDayRandom; }
|
||||||
public static float getRainMultiplier() { return rainMultiplier; }
|
public static float getRainMultiplier() { return rainMultiplier; }
|
||||||
|
public static float getHeightFadeMax() { return heightFadeMax; }
|
||||||
}
|
}
|
||||||
@@ -37,6 +37,8 @@ public final class FogSimulationShader {
|
|||||||
private static int biomeParamsSamplerLocation;
|
private static int biomeParamsSamplerLocation;
|
||||||
private static int fogDayRandomLocation;
|
private static int fogDayRandomLocation;
|
||||||
private static int rainMultiplierLocation;
|
private static int rainMultiplierLocation;
|
||||||
|
private static int heightFadeMaxLocation;
|
||||||
|
private static int skyLightSamplerLocation;
|
||||||
|
|
||||||
private FogSimulationShader() {
|
private FogSimulationShader() {
|
||||||
}
|
}
|
||||||
@@ -74,6 +76,8 @@ public final class FogSimulationShader {
|
|||||||
targetDensityMultiplierLocation = program.uniform("TargetDensityMultiplier");
|
targetDensityMultiplierLocation = program.uniform("TargetDensityMultiplier");
|
||||||
fogDayRandomLocation = program.uniform("FogDayRandom");
|
fogDayRandomLocation = program.uniform("FogDayRandom");
|
||||||
rainMultiplierLocation = program.uniform("RainMultiplier");
|
rainMultiplierLocation = program.uniform("RainMultiplier");
|
||||||
|
heightFadeMaxLocation = program.uniform("HeightFadeMax");
|
||||||
|
skyLightSamplerLocation = program.uniform("SkyLightSampler");
|
||||||
|
|
||||||
fbo = GL30.glGenFramebuffers();
|
fbo = GL30.glGenFramebuffers();
|
||||||
|
|
||||||
@@ -139,7 +143,7 @@ public final class FogSimulationShader {
|
|||||||
// Активный текстурный юнит
|
// Активный текстурный юнит
|
||||||
int previousActiveTexture = GL11.glGetInteger(GL13.GL_ACTIVE_TEXTURE);
|
int previousActiveTexture = GL11.glGetInteger(GL13.GL_ACTIVE_TEXTURE);
|
||||||
|
|
||||||
// Привязки текстур для юнитов 0 и 1 (2D и 3D)
|
// Привязки текстур для юнитов (2D и 3D)
|
||||||
GL13.glActiveTexture(GL13.GL_TEXTURE0);
|
GL13.glActiveTexture(GL13.GL_TEXTURE0);
|
||||||
int previousTex0_2D = GL11.glGetInteger(GL_TEXTURE_BINDING_2D);
|
int previousTex0_2D = GL11.glGetInteger(GL_TEXTURE_BINDING_2D);
|
||||||
int previousTex0_3D = GL11.glGetInteger(GL_TEXTURE_BINDING_3D);
|
int previousTex0_3D = GL11.glGetInteger(GL_TEXTURE_BINDING_3D);
|
||||||
@@ -152,6 +156,10 @@ public final class FogSimulationShader {
|
|||||||
int previousTex2_2D = GL11.glGetInteger(GL_TEXTURE_BINDING_2D);
|
int previousTex2_2D = GL11.glGetInteger(GL_TEXTURE_BINDING_2D);
|
||||||
int previousTex2_3D = GL11.glGetInteger(GL_TEXTURE_BINDING_3D);
|
int previousTex2_3D = GL11.glGetInteger(GL_TEXTURE_BINDING_3D);
|
||||||
|
|
||||||
|
GL13.glActiveTexture(GL13.GL_TEXTURE3);
|
||||||
|
int previousTex3_2D = GL11.glGetInteger(GL_TEXTURE_BINDING_2D);
|
||||||
|
int previousTex3_3D = GL11.glGetInteger(GL_TEXTURE_BINDING_3D);
|
||||||
|
|
||||||
// Blend state (на всякий случай)
|
// Blend state (на всякий случай)
|
||||||
boolean previousBlend = GL11.glIsEnabled(GL11.GL_BLEND);
|
boolean previousBlend = GL11.glIsEnabled(GL11.GL_BLEND);
|
||||||
boolean previousDepthTest = GL11.glIsEnabled(GL11.GL_DEPTH_TEST);
|
boolean previousDepthTest = GL11.glIsEnabled(GL11.GL_DEPTH_TEST);
|
||||||
@@ -197,6 +205,10 @@ public final class FogSimulationShader {
|
|||||||
GL11.glBindTexture(GL11.GL_TEXTURE_2D, FogBiomeTexture.getTexture());
|
GL11.glBindTexture(GL11.GL_TEXTURE_2D, FogBiomeTexture.getTexture());
|
||||||
GL20.glUniform1i(biomeParamsSamplerLocation, 2);
|
GL20.glUniform1i(biomeParamsSamplerLocation, 2);
|
||||||
|
|
||||||
|
GL13.glActiveTexture(GL13.GL_TEXTURE3);
|
||||||
|
GL11.glBindTexture(GL12.GL_TEXTURE_3D, FogLightVolume.getSkyLightTexture());
|
||||||
|
GL20.glUniform1i(skyLightSamplerLocation, 3);
|
||||||
|
|
||||||
// Устанавливаем параметры
|
// Устанавливаем параметры
|
||||||
GL20.glUniform1f(globalEmissionMultiplierLocation, globalEmissionMultiplier);
|
GL20.glUniform1f(globalEmissionMultiplierLocation, globalEmissionMultiplier);
|
||||||
GL20.glUniform1f(globalAbsorptionMultiplierLocation, globalAbsorptionMultiplier);
|
GL20.glUniform1f(globalAbsorptionMultiplierLocation, globalAbsorptionMultiplier);
|
||||||
@@ -209,6 +221,7 @@ public final class FogSimulationShader {
|
|||||||
GL20.glUniform1f(targetDensityMultiplierLocation, FogEnvironmentContext.getTargetDensityMultiplier());
|
GL20.glUniform1f(targetDensityMultiplierLocation, FogEnvironmentContext.getTargetDensityMultiplier());
|
||||||
GL20.glUniform1f(fogDayRandomLocation, FogEnvironmentContext.getFogDayRandom());
|
GL20.glUniform1f(fogDayRandomLocation, FogEnvironmentContext.getFogDayRandom());
|
||||||
GL20.glUniform1f(rainMultiplierLocation, FogEnvironmentContext.getRainMultiplier());
|
GL20.glUniform1f(rainMultiplierLocation, FogEnvironmentContext.getRainMultiplier());
|
||||||
|
GL20.glUniform1f(heightFadeMaxLocation, FogEnvironmentContext.getHeightFadeMax());
|
||||||
|
|
||||||
GL20.glUniform3f(voxelSizeLocation,
|
GL20.glUniform3f(voxelSizeLocation,
|
||||||
1.0f / FogWorldVolume.SIZE_X,
|
1.0f / FogWorldVolume.SIZE_X,
|
||||||
@@ -268,6 +281,10 @@ public final class FogSimulationShader {
|
|||||||
GL11.glBindTexture(GL11.GL_TEXTURE_2D, previousTex2_2D);
|
GL11.glBindTexture(GL11.GL_TEXTURE_2D, previousTex2_2D);
|
||||||
GL11.glBindTexture(GL12.GL_TEXTURE_3D, previousTex2_3D);
|
GL11.glBindTexture(GL12.GL_TEXTURE_3D, previousTex2_3D);
|
||||||
|
|
||||||
|
GL13.glActiveTexture(GL13.GL_TEXTURE3);
|
||||||
|
GL11.glBindTexture(GL11.GL_TEXTURE_2D, previousTex3_2D);
|
||||||
|
GL11.glBindTexture(GL12.GL_TEXTURE_3D, previousTex3_3D);
|
||||||
|
|
||||||
// Восстанавливаем активный текстурный юнит
|
// Восстанавливаем активный текстурный юнит
|
||||||
GL13.glActiveTexture(previousActiveTexture);
|
GL13.glActiveTexture(previousActiveTexture);
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
uniform usampler3D WorldInfoSampler;
|
uniform usampler3D WorldInfoSampler;
|
||||||
uniform sampler3D FogReadSampler;
|
uniform sampler3D FogReadSampler;
|
||||||
|
uniform sampler3D SkyLightSampler;
|
||||||
uniform sampler2D BiomeParamsSampler;
|
uniform sampler2D BiomeParamsSampler;
|
||||||
|
|
||||||
uniform float GlobalEmissionMultiplier;
|
uniform float GlobalEmissionMultiplier;
|
||||||
@@ -17,12 +18,19 @@ uniform float CurrentZ;
|
|||||||
|
|
||||||
uniform float EmissionMultiplier;
|
uniform float EmissionMultiplier;
|
||||||
uniform float TargetDensityMultiplier;
|
uniform float TargetDensityMultiplier;
|
||||||
uniform float FogDayRandom; // НОВЫЙ: случайное значение [0, 1]
|
uniform float FogDayRandom;
|
||||||
uniform float RainMultiplier;
|
uniform float RainMultiplier;
|
||||||
|
uniform float HeightFadeMax;
|
||||||
|
|
||||||
in vec2 texCoord;
|
in vec2 texCoord;
|
||||||
out vec4 FragColor;
|
out vec4 FragColor;
|
||||||
|
|
||||||
|
const float HEIGHT_FADE_MIN = 75.0;
|
||||||
|
const float MIN_Y = -64.0;
|
||||||
|
const float SIZE_Y = 384.0;
|
||||||
|
|
||||||
|
const float UNDERGROUND_TARGET_DENSITY = 0.008; // Подземная дымка (слабее поверхностной)
|
||||||
|
|
||||||
float getEmission(uint magnitude, bool isAbsorber) {
|
float getEmission(uint magnitude, bool isAbsorber) {
|
||||||
if (isAbsorber || magnitude == 0u) return 0.0;
|
if (isAbsorber || magnitude == 0u) return 0.0;
|
||||||
return float(magnitude) / 63.0 * 0.05;
|
return float(magnitude) / 63.0 * 0.05;
|
||||||
@@ -60,8 +68,17 @@ void main() {
|
|||||||
// Для джунглей (timeSensitivity = 0.3): дымка почти всегда
|
// Для джунглей (timeSensitivity = 0.3): дымка почти всегда
|
||||||
float timeFactor = mix(1.0, TargetDensityMultiplier, biomeTimeSensitivity);
|
float timeFactor = mix(1.0, TargetDensityMultiplier, biomeTimeSensitivity);
|
||||||
|
|
||||||
// 3. Итоговая плотность
|
// 3. Дымка плавно затухает к высоте 80-100
|
||||||
float finalTargetDensity = biomeTargetDensityBase * hasFogToday * timeFactor;
|
float worldY = uv.y * SIZE_Y + MIN_Y;
|
||||||
|
float heightFade = 1.0 - clamp((worldY - HEIGHT_FADE_MIN) / (HeightFadeMax - HEIGHT_FADE_MIN), 0.0, 1.0);
|
||||||
|
|
||||||
|
// 4. Под землёй дымка другая
|
||||||
|
float skyLight = texture(SkyLightSampler, uv).r;
|
||||||
|
float skyLightSmooth = smoothstep(0.2, 0.8, skyLight);
|
||||||
|
|
||||||
|
// 4. Итоговая плотность
|
||||||
|
float surfaceTargetDensity = biomeTargetDensityBase * hasFogToday * timeFactor * heightFade;
|
||||||
|
float finalTargetDensity = mix(UNDERGROUND_TARGET_DENSITY, surfaceTargetDensity, skyLightSmooth);
|
||||||
|
|
||||||
// Читаем воксель мира
|
// Читаем воксель мира
|
||||||
uint packedSelf = texture(WorldInfoSampler, uv).r;
|
uint packedSelf = texture(WorldInfoSampler, uv).r;
|
||||||
|
|||||||
Reference in New Issue
Block a user