diff --git a/src/net/torvald/terrarum/clut/Skybox.kt b/src/net/torvald/terrarum/clut/Skybox.kt index fb68e3fcf..ded74fa29 100644 --- a/src/net/torvald/terrarum/clut/Skybox.kt +++ b/src/net/torvald/terrarum/clut/Skybox.kt @@ -60,17 +60,27 @@ object Skybox : Disposable { data class SkyboxRenderInfo( val texture: Texture, val uvs: FloatArray, - val turbidityPoint: Float, - val albedoPoint: Float, + val turbidityThisBlend: Float, + val albedoThisBlend: Float, + val turbidityOldBlend: Float, + val albedoOldBlend: Float, ) - fun getUV(elevationDeg: Double, turbidity: Double, albedo: Double): SkyboxRenderInfo { - val turb = turbidity.coerceIn(turbiditiesD.first(), turbiditiesD.last()).minus(1.0).times(turbDivisor) - val turbLo = turb.floorToInt() - val turbHi = min(turbCnt - 1, turbLo + 1) - val alb = albedo.coerceIn(albedos.first(), albedos.last()).times(5.0) - val albLo = alb.floorToInt() - val albHi = min(albedoCnt - 1, albLo + 1) + fun getUV(elevationDeg: Double, oldTurbidity: Double, oldAlbedo: Double, thisTurbidity: Double, thisAlbedo: Double): SkyboxRenderInfo { + val turb2 = thisTurbidity.coerceIn(turbiditiesD.first(), turbiditiesD.last()).minus(1.0).times(turbDivisor) + val turb2Lo = turb2.floorToInt() + val turb2Hi = min(turbCnt - 1, turb2Lo + 1) + val alb2 = thisAlbedo.coerceIn(albedos.first(), albedos.last()).times(5.0) + val alb2Lo = alb2.floorToInt() + val alb2Hi = min(albedoCnt - 1, alb2Lo + 1) + + val turb1 = oldTurbidity.coerceIn(turbiditiesD.first(), turbiditiesD.last()).minus(1.0).times(turbDivisor) + val turb1Lo = turb1.floorToInt() + val turb1Hi = min(turbCnt - 1, turb1Lo + 1) + val alb1 = oldAlbedo.coerceIn(albedos.first(), albedos.last()).times(5.0) + val alb1Lo = alb1.floorToInt() + val alb1Hi = min(albedoCnt - 1, alb1Lo + 1) + val elev = elevationDeg.coerceIn(-elevMax, elevMax).plus(elevMax).div(elevations.last.toDouble()).div(albedoCnt * 2).times((elevCnt - 1.0) / elevCnt) // A: morn, turbLow, albLow @@ -82,14 +92,14 @@ object Skybox : Disposable { // G: morn, turbHigh, albHigh // H: noon, turbHigh, albHigh - val regionA = texStripRegions.get(albLo + albedoCnt * 0, turbLo) - val regionB = texStripRegions.get(albLo + albedoCnt * 1, turbLo) - val regionC = texStripRegions.get(albLo + albedoCnt * 0, turbHi) - val regionD = texStripRegions.get(albLo + albedoCnt * 1, turbHi) - val regionE = texStripRegions.get(albHi + albedoCnt * 0, turbLo) - val regionF = texStripRegions.get(albHi + albedoCnt * 1, turbLo) - val regionG = texStripRegions.get(albHi + albedoCnt * 0, turbHi) - val regionH = texStripRegions.get(albHi + albedoCnt * 1, turbHi) + val regionA = texStripRegions.get(alb1Lo, turb1Lo) + val regionB = texStripRegions.get(alb2Lo, turb2Lo) + val regionC = texStripRegions.get(alb1Lo, turb1Hi) + val regionD = texStripRegions.get(alb2Lo, turb2Hi) + val regionE = texStripRegions.get(alb1Hi, turb1Lo) + val regionF = texStripRegions.get(alb2Hi, turb2Lo) + val regionG = texStripRegions.get(alb1Hi, turb1Hi) + val regionH = texStripRegions.get(alb2Hi, turb2Hi) // (0.5f / tex.width): because of the nature of bilinear interpolation, half pixels from the edges must be discarded val uA = regionA.u + (0.5f / tex.width) + elev.toFloat() val uB = regionB.u + (0.5f / tex.width) + elev.toFloat() @@ -112,8 +122,10 @@ object Skybox : Disposable { uG, regionG.v, uG, regionG.v2, uH, regionH.v, uH, regionH.v2, ), - (turb - turbLo).toFloat(), - (alb - albLo).toFloat(), + (turb2 - turb2Lo).toFloat(), + (alb2 - alb2Lo).toFloat(), + (turb1 - turb1Lo).toFloat(), + (alb1 - alb1Lo).toFloat(), ) } diff --git a/src/net/torvald/terrarum/weather/WeatherMixer.kt b/src/net/torvald/terrarum/weather/WeatherMixer.kt index 30836deff..88b67caed 100644 --- a/src/net/torvald/terrarum/weather/WeatherMixer.kt +++ b/src/net/torvald/terrarum/weather/WeatherMixer.kt @@ -493,6 +493,9 @@ internal object WeatherMixer : RNGConsumer { } + private var turbidity0 = 1.0 + private var turbidity1 = 1.0 + /** Interpolated value, controlled by the weatherbox */ var turbidity = 1.0; private set private var gH = 1.8f * App.scr.height // private var gH = 0.8f * App.scr.height @@ -524,6 +527,7 @@ internal object WeatherMixer : RNGConsumer { private val turbidityDomainSize = 533.3333f private fun drawSkybox(camera: OrthographicCamera, batch: FlippingSpriteBatch, world: GameWorld) { + val weatherbox = world.weatherbox val currentWeather = world.weatherbox.currentWeather val parallaxZeroPos = (world.height / 3f) @@ -562,14 +566,19 @@ internal object WeatherMixer : RNGConsumer { gdxBlendNormalStraightAlpha() - turbidity = (currentWeather.json.getDouble("atmoTurbidity") + turbidityCoeff * 2.5).coerceIn(1.0, 10.0) - val thisTurbidity = forceTurbidity ?: turbidity + val oldNewBlend = weatherbox.weatherBlend.times(2f).coerceAtMost(1f) + + turbidity0 = (world.weatherbox.oldWeather.json.getDouble("atmoTurbidity") + turbidityCoeff * 2.5).coerceIn(1.0, 10.0) + turbidity1 = (currentWeather.json.getDouble("atmoTurbidity") + turbidityCoeff * 2.5).coerceIn(1.0, 10.0) + turbidity = FastMath.interpolateLinear(oldNewBlend.toDouble(), turbidity0, turbidity1) + + val oldTurbidity = forceTurbidity ?: turbidity0 + val thisTurbidity = forceTurbidity ?: turbidity1 + val gradY = -(gH - App.scr.height) * ((parallax + 1f) / 2f) - val (tex, uvs, turbX, albX) = Skybox.getUV(solarElev, thisTurbidity, 0.3) - - val mornNoonBlend = (1f/4000f * (timeNow - 43200) + 0.5f).coerceIn(0f, 1f) // 0.0 at T41200; 0.5 at T43200; 1.0 at T45200; + val (tex, uvs, turbTihsBlend, albThisBlend, turbOldBlend, albOldBlend) = Skybox.getUV(solarElev, oldTurbidity, 0.3, thisTurbidity, 0.3) starmapTex.texture.bind(1) Gdx.gl.glActiveTexture(GL20.GL_TEXTURE0) // so that batch that comes next will bind any tex to it @@ -589,13 +598,10 @@ internal object WeatherMixer : RNGConsumer { shaderAstrum.setUniform4fv("uvF", uvs, 20, 4) shaderAstrum.setUniform4fv("uvG", uvs, 24, 4) shaderAstrum.setUniform4fv("uvH", uvs, 28, 4) - shaderAstrum.setUniformf("texBlend", mornNoonBlend, turbX, albX, 0f) + shaderAstrum.setUniformf("texBlend1", turbTihsBlend, albThisBlend, turbOldBlend, albOldBlend) + shaderAstrum.setUniformf("texBlend2", oldNewBlend, 0f, 0f, 0f) shaderAstrum.setUniformf("astrumScroll", astrumOffX + astrumX, astrumOffY + astrumY) shaderAstrum.setUniformf("randomNumber", -// (world.worldTime.TIME_T.plus(31L) xor 1453L + 31L).and(1023).toFloat(), -// (world.worldTime.TIME_T.plus(37L) xor 862L + 31L).and(1023).toFloat(), -// (world.worldTime.TIME_T.plus(23L) xor 1639L + 29L).and(1023).toFloat(), -// (world.worldTime.TIME_T.plus(29L) xor 2971L + 41L).and(1023).toFloat(), world.worldTime.TIME_T.div(+14.1f).plus(31L), world.worldTime.TIME_T.div(-13.8f).plus(37L), world.worldTime.TIME_T.div(+13.9f).plus(23L), diff --git a/src/shaders/blendSkyboxStars.frag b/src/shaders/blendSkyboxStars.frag index 5f63b83f2..2a4880b59 100644 --- a/src/shaders/blendSkyboxStars.frag +++ b/src/shaders/blendSkyboxStars.frag @@ -14,15 +14,16 @@ out vec4 fragColor; const vec2 boolean = vec2(0.0, 1.0); uniform vec4 drawOffsetSize; // (gradX, gradY, gradW, gradH) -uniform vec4 uvA; // (u, v, u2, v2) for morn, turbLow, albLow -uniform vec4 uvB; // (u, v, u2, v2) for noon, turbLow, albLow -uniform vec4 uvC; // (u, v, u2, v2) for morn, turbHigh, albLow -uniform vec4 uvD; // (u, v, u2, v2) for noon, turbHigh, albLow -uniform vec4 uvE; // (u, v, u2, v2) for morn, turbLow, albHigh -uniform vec4 uvF; // (u, v, u2, v2) for noon, turbLow, albHigh -uniform vec4 uvG; // (u, v, u2, v2) for morn, turbHigh, albHigh -uniform vec4 uvH; // (u, v, u2, v2) for noon, turbHigh, albHigh -uniform vec4 texBlend; // (morn/noon, turbidity, albedo, unused) +uniform vec4 uvA; // (u, v, u2, v2) for now, turbLow, albLow +uniform vec4 uvB; // (u, v, u2, v2) for old, turbLow, albLow +uniform vec4 uvC; // (u, v, u2, v2) for now, turbHigh, albLow +uniform vec4 uvD; // (u, v, u2, v2) for old, turbHigh, albLow +uniform vec4 uvE; // (u, v, u2, v2) for now, turbLow, albHigh +uniform vec4 uvF; // (u, v, u2, v2) for old, turbLow, albHigh +uniform vec4 uvG; // (u, v, u2, v2) for now, turbHigh, albHigh +uniform vec4 uvH; // (u, v, u2, v2) for old, turbHigh, albHigh +uniform vec4 texBlend1; // (turbidity now, albedo now, turbidity old, albedo old) +uniform vec4 texBlend2; // (old-now blend, unused, unused, unused) uniform vec2 tex1Size = vec2(4096.0); uniform vec2 astrumScroll = vec2(0.0); uniform vec4 randomNumber = vec4(1.0, -2.0, 3.0, -4.0); @@ -136,17 +137,17 @@ void main(void) { // notations used: https://en.wikipedia.org/wiki/File:Enclosing_points.svg and https://en.wikipedia.org/wiki/File:3D_interpolation2.svg vec4 colorTex0 = mix( - mix( - mix(colorTexA, colorTexE, texBlend.z), // c00 = c000..c100 - mix(colorTexC, colorTexG, texBlend.z), // c10 = c010..c110 - texBlend.y + mix( // now-values + mix(colorTexA, colorTexE, texBlend1.y), // c00 = c000..c100 + mix(colorTexC, colorTexG, texBlend1.y), // c10 = c010..c110 + texBlend1.x ), // c0 = c00..c10 - mix( - mix(colorTexB, colorTexF, texBlend.z), // c01 = c001..c101 - mix(colorTexD, colorTexH, texBlend.z), // c11 = c011..c111 - texBlend.y + mix( // old-values + mix(colorTexB, colorTexF, texBlend1.w), // c01 = c001..c101 + mix(colorTexD, colorTexH, texBlend1.w), // c11 = c011..c111 + texBlend1.z ), // c1 = c01..c11 - texBlend.x + texBlend2.x ); // c = c0..c1