mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-17 11:35:08 -04:00
fix wrong fog colour for a few frames
This commit is contained in:
parent
b1ffb93fe5
commit
20c273ef64
@ -24,7 +24,7 @@ namespace ClassicalSharp.Renderers {
|
||||
return blend;
|
||||
}
|
||||
|
||||
void BlockOn(out float fogDensity, out PackedCol fogCol) {
|
||||
void CalcFog(out float density, out PackedCol col) {
|
||||
Vector3 pos = game.CurrentCameraPos;
|
||||
Vector3I coords = Vector3I.Floor(pos);
|
||||
|
||||
@ -34,13 +34,13 @@ namespace ClassicalSharp.Renderers {
|
||||
(Vector3)coords + BlockInfo.MaxBB[block]);
|
||||
|
||||
if (blockBB.Contains(pos) && BlockInfo.FogDensity[block] != 0) {
|
||||
fogDensity = BlockInfo.FogDensity[block];
|
||||
fogCol = BlockInfo.FogCol[block];
|
||||
density = BlockInfo.FogDensity[block];
|
||||
col = BlockInfo.FogCol[block];
|
||||
} else {
|
||||
fogDensity = 0;
|
||||
density = 0;
|
||||
// Blend fog and sky together
|
||||
float blend = (float)BlendFactor(game.ViewDistance);
|
||||
fogCol = PackedCol.Lerp(map.Env.FogCol, map.Env.SkyCol, blend);
|
||||
col = PackedCol.Lerp(map.Env.FogCol, map.Env.SkyCol, blend);
|
||||
}
|
||||
}
|
||||
|
||||
@ -58,12 +58,11 @@ namespace ClassicalSharp.Renderers {
|
||||
}
|
||||
|
||||
public void Render(double deltaTime) {
|
||||
if (minimal) { RenderMinimal(deltaTime); return; }
|
||||
if (skyVb == 0 || cloudsVb == 0) return;
|
||||
UpdateFog();
|
||||
if (minimal || skyVb == 0 || cloudsVb == 0) return;
|
||||
|
||||
RenderSky(deltaTime);
|
||||
RenderClouds(deltaTime);
|
||||
UpdateFog();
|
||||
}
|
||||
|
||||
void EnvVariableChanged(object sender, EnvVarEventArgs e) {
|
||||
@ -112,10 +111,7 @@ namespace ClassicalSharp.Renderers {
|
||||
}
|
||||
}
|
||||
|
||||
void ResetAllEnv(object sender, EventArgs e) {
|
||||
UpdateFog();
|
||||
ContextRecreated();
|
||||
}
|
||||
void ResetAllEnv(object sender, EventArgs e) { ContextRecreated(); }
|
||||
|
||||
void IDisposable.Dispose() {
|
||||
game.Graphics.DeleteTexture(ref cloudsTex);
|
||||
@ -136,33 +132,13 @@ namespace ClassicalSharp.Renderers {
|
||||
void ContextRecreated() {
|
||||
ContextLost();
|
||||
game.Graphics.Fog = !minimal;
|
||||
UpdateFog();
|
||||
|
||||
if (minimal) return;
|
||||
ResetClouds();
|
||||
ResetSky();
|
||||
}
|
||||
|
||||
void RenderMinimal(double deltaTime) {
|
||||
if (!map.HasBlocks) return;
|
||||
PackedCol fogCol = PackedCol.White;
|
||||
float fogDensity = 0;
|
||||
BlockOn(out fogDensity, out fogCol);
|
||||
game.Graphics.ClearCol(fogCol);
|
||||
|
||||
// TODO: rewrite this to avoid raising the event? want to avoid recreating vbos too many times often
|
||||
if (fogDensity != 0) {
|
||||
// Exp fog mode: f = e^(-density*coord)
|
||||
// Solve coord for f = 0.05 (good approx for fog end)
|
||||
// i.e. log(0.05) = -density * coord
|
||||
|
||||
const double log005 = -2.99573227355399;
|
||||
double dist = log005 / -fogDensity;
|
||||
game.SetViewDistance((int)dist, false);
|
||||
} else {
|
||||
game.SetViewDistance(game.UserViewDistance, false);
|
||||
}
|
||||
}
|
||||
|
||||
void RenderSky(double delta) {
|
||||
if (game.SkyboxRenderer.ShouldRender) return;
|
||||
Vector3 pos = game.CurrentCameraPos;
|
||||
@ -211,13 +187,23 @@ namespace ClassicalSharp.Renderers {
|
||||
gfx.SetMatrixMode(MatrixType.Modelview);
|
||||
}
|
||||
|
||||
void UpdateFog() {
|
||||
if (!map.HasBlocks || minimal) return;
|
||||
PackedCol fogCol = PackedCol.White;
|
||||
float fogDensity = 0;
|
||||
BlockOn(out fogDensity, out fogCol);
|
||||
IGraphicsApi gfx = game.Graphics;
|
||||
void UpdateFogMinimal(float fogDensity) {
|
||||
// TODO: rewrite this to avoid raising the event? want to avoid recreating vbos too many times often
|
||||
if (fogDensity != 0) {
|
||||
// Exp fog mode: f = e^(-density*coord)
|
||||
// Solve coord for f = 0.05 (good approx for fog end)
|
||||
// i.e. log(0.05) = -density * coord
|
||||
|
||||
const double log005 = -2.99573227355399;
|
||||
double dist = log005 / -fogDensity;
|
||||
game.SetViewDistance((int)dist, false);
|
||||
} else {
|
||||
game.SetViewDistance(game.UserViewDistance, false);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateFogNormal(float fogDensity, PackedCol fogCol) {
|
||||
IGraphicsApi gfx = game.Graphics;
|
||||
if (fogDensity != 0) {
|
||||
gfx.SetFogMode(Fog.Exp);
|
||||
gfx.SetFogDensity(fogDensity);
|
||||
@ -237,10 +223,22 @@ namespace ClassicalSharp.Renderers {
|
||||
gfx.SetFogMode(Fog.Linear);
|
||||
gfx.SetFogEnd(game.ViewDistance);
|
||||
}
|
||||
gfx.ClearCol(fogCol);
|
||||
gfx.SetFogCol(fogCol);
|
||||
}
|
||||
|
||||
void UpdateFog() {
|
||||
float fogDensity; PackedCol fogCol;
|
||||
CalcFog(out fogDensity, out fogCol);
|
||||
game.Graphics.ClearCol(fogCol);
|
||||
|
||||
if (!map.HasBlocks) return;
|
||||
if (minimal) {
|
||||
UpdateFogMinimal(fogDensity);
|
||||
} else {
|
||||
UpdateFogNormal(fogDensity, fogCol);
|
||||
}
|
||||
}
|
||||
|
||||
void ResetClouds() {
|
||||
if (!map.HasBlocks || game.Graphics.LostContext) return;
|
||||
game.Graphics.DeleteVb(ref cloudsVb);
|
||||
@ -297,9 +295,9 @@ namespace ClassicalSharp.Renderers {
|
||||
if (z2 > endZ) z2 = endZ;
|
||||
|
||||
v.X = x1; v.Z = z1; vertices[i++] = v;
|
||||
v.Z = z2; vertices[i++] = v;
|
||||
v.Z = z2; vertices[i++] = v;
|
||||
v.X = x2; vertices[i++] = v;
|
||||
v.Z = z1; vertices[i++] = v;
|
||||
v.Z = z1; vertices[i++] = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -324,9 +322,9 @@ namespace ClassicalSharp.Renderers {
|
||||
float u1 = x1 / 2048f + offset, u2 = x2 / 2048f + offset;
|
||||
float v1 = z1 / 2048f + offset, v2 = z2 / 2048f + offset;
|
||||
v.X = x1; v.Z = z1; v.U = u1; v.V = v1; vertices[i++] = v;
|
||||
v.Z = z2; v.V = v2; vertices[i++] = v;
|
||||
v.Z = z2; v.V = v2; vertices[i++] = v;
|
||||
v.X = x2; v.U = u2; vertices[i++] = v;
|
||||
v.Z = z1; v.V = v1; vertices[i++] = v;
|
||||
v.Z = z1; v.V = v1; vertices[i++] = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -38,6 +38,27 @@ Int32 EnvRenderer_Vertices(Int32 axis1Len, Int32 axis2Len) {
|
||||
/*########################################################################################################################*
|
||||
*------------------------------------------------------------Fog----------------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
static void EnvRenderer_CalcFog(Real32* density, PackedCol* col) {
|
||||
Vector3 pos = Game_CurrentCameraPos; Vector3I coords;
|
||||
Vector3I_Floor(&coords, &pos); /* coords = floor(pos); */
|
||||
Vector3I_ToVector3(&pos, &coords); /* pos = coords; */
|
||||
|
||||
BlockID block = World_SafeGetBlock_3I(coords);
|
||||
struct AABB blockBB;
|
||||
Vector3_Add(&blockBB.Min, &pos, &Block_MinBB[block]);
|
||||
Vector3_Add(&blockBB.Max, &pos, &Block_MaxBB[block]);
|
||||
|
||||
if (AABB_ContainsPoint(&blockBB, &pos) && Block_FogDensity[block] != 0.0f) {
|
||||
*density = Block_FogDensity[block];
|
||||
*col = Block_FogCol[block];
|
||||
} else {
|
||||
*density = 0.0f;
|
||||
/* Blend fog and sky together */
|
||||
Real32 blend = EnvRenderer_BlendFactor((Real32)Game_ViewDistance);
|
||||
*col = PackedCol_Lerp(WorldEnv_FogCol, WorldEnv_SkyCol, blend);
|
||||
}
|
||||
}
|
||||
|
||||
static void EnvRenderer_UpdateFogMinimal(Real32 fogDensity) {
|
||||
/* TODO: rewrite this to avoid raising the event? want to avoid recreating vbos too many times often */
|
||||
if (fogDensity != 0.0f) {
|
||||
@ -77,29 +98,11 @@ static void EnvRenderer_UpdateFogNormal(Real32 fogDensity, PackedCol fogCol) {
|
||||
}
|
||||
|
||||
void EnvRenderer_UpdateFog(void) {
|
||||
if (World_Blocks == NULL) return;
|
||||
Vector3 pos = Game_CurrentCameraPos; Vector3I coords;
|
||||
Vector3I_Floor(&coords, &pos); /* coords = floor(pos); */
|
||||
Vector3I_ToVector3(&pos, &coords); /* pos = coords; */
|
||||
|
||||
BlockID block = World_SafeGetBlock_3I(coords);
|
||||
struct AABB blockBB;
|
||||
Vector3_Add(&blockBB.Min, &pos, &Block_MinBB[block]);
|
||||
Vector3_Add(&blockBB.Max, &pos, &Block_MaxBB[block]);
|
||||
|
||||
PackedCol fogCol;
|
||||
Real32 fogDensity;
|
||||
if (AABB_ContainsPoint(&blockBB, &pos) && Block_FogDensity[block] != 0.0f) {
|
||||
fogDensity = Block_FogDensity[block];
|
||||
fogCol = Block_FogCol[block];
|
||||
} else {
|
||||
fogDensity = 0.0f;
|
||||
/* Blend fog and sky together */
|
||||
Real32 blend = EnvRenderer_BlendFactor((Real32)Game_ViewDistance);
|
||||
fogCol = PackedCol_Lerp(WorldEnv_FogCol, WorldEnv_SkyCol, blend);
|
||||
}
|
||||
|
||||
Real32 fogDensity; PackedCol fogCol;
|
||||
EnvRenderer_CalcFog(&fogDensity, &fogCol);
|
||||
Gfx_ClearCol(fogCol);
|
||||
|
||||
if (World_Blocks == NULL) return;
|
||||
if (EnvRenderer_Minimal) {
|
||||
EnvRenderer_UpdateFogMinimal(fogDensity);
|
||||
} else {
|
||||
@ -740,6 +743,7 @@ static void EnvRenderer_UpdateAll(void) {
|
||||
EnvRenderer_UpdateClouds();
|
||||
EnvRenderer_UpdateSky();
|
||||
EnvRenderer_UpdateSkybox();
|
||||
EnvRenderer_UpdateFog();
|
||||
|
||||
/* TODO: Don't allocate unless used? */
|
||||
weather_vb = Gfx_CreateDynamicVb(VERTEX_FORMAT_P3FT2FC4B, WEATHER_VERTS_COUNT);
|
||||
@ -793,6 +797,7 @@ static void EnvRenderer_TexturePackChanged(void* obj) {
|
||||
static void EnvRenderer_TerrainAtlasChanged(void* obj) {
|
||||
EnvRenderer_UpdateBorderTextures();
|
||||
}
|
||||
|
||||
static void EnvRenderer_ViewDistanceChanged(void* obj) {
|
||||
EnvRenderer_UpdateAll();
|
||||
}
|
||||
|
@ -582,9 +582,9 @@ static void Game_Render3D(Real64 delta, Real32 t) {
|
||||
Particles_Render(delta, t);
|
||||
Camera_Active->GetPickedBlock(&Game_SelectedPos); /* TODO: only pick when necessary */
|
||||
|
||||
EnvRenderer_UpdateFog();
|
||||
EnvRenderer_RenderSky(delta);
|
||||
EnvRenderer_RenderClouds(delta);
|
||||
EnvRenderer_UpdateFog();
|
||||
|
||||
ChunkUpdater_Update(delta);
|
||||
MapRenderer_RenderNormal(delta);
|
||||
|
Loading…
x
Reference in New Issue
Block a user