titlescreen: weather change is reflected to the skybox AND daylight

This commit is contained in:
minjaesong
2023-07-15 13:33:09 +09:00
parent e328457259
commit df8bcf79af
3 changed files with 41 additions and 32 deletions

View File

@@ -176,7 +176,7 @@ class TitleScreen(batch: FlippingSpriteBatch) : IngameInstance(batch) {
} }
// set time to summer // set initial time to summer
demoWorld.worldTime.addTime(WorldTime.DAY_LENGTH * 32) demoWorld.worldTime.addTime(WorldTime.DAY_LENGTH * 32)
// construct camera nodes // construct camera nodes
@@ -194,13 +194,14 @@ class TitleScreen(batch: FlippingSpriteBatch) : IngameInstance(batch) {
} }
// apply gaussian blur to the camera nodes // apply gaussian blur to the camera nodes
for (i in cameraNodes.indices) { for (i in cameraNodes.indices) {
val offM2 = cameraNodes[(i-2) fmod cameraNodes.size] * 1f // val offM2 = cameraNodes[(i-2) fmod cameraNodes.size] * 1f
val offM1 = cameraNodes[(i-1) fmod cameraNodes.size] * 4f val offM1 = cameraNodes[(i-1) fmod cameraNodes.size] * 1f
val off0 = cameraNodes[i] * 6f val off0 = cameraNodes[i] * 2f
val off1 = cameraNodes[(i+1) fmod cameraNodes.size] * 4f val off1 = cameraNodes[(i+1) fmod cameraNodes.size] * 1f
val off2 = cameraNodes[(i+2) fmod cameraNodes.size] * 1f // val off2 = cameraNodes[(i+2) fmod cameraNodes.size] * 1f
cameraNodes[i] = (offM2 + offM1 + off0 + off1 + off2) / 16f // cameraNodes[i] = (offM2 + offM1 + off0 + off1 + off2) / 16f
cameraNodes[i] = (offM1 + off0 + off1) / 4f
} }
@@ -285,9 +286,9 @@ class TitleScreen(batch: FlippingSpriteBatch) : IngameInstance(batch) {
private val updateScreen = { delta: Float -> private val updateScreen = { delta: Float ->
// TODO: desynched weather and time-of-day change // TODO: desynched weather and time-of-day change
val forcedTime = 39693 val forcedTime = 32880 // 9h08m
// demoWorld.globalLight = WeatherMixer.globalLightNow demoWorld.globalLight = WeatherMixer.globalLightNow
demoWorld.globalLight = WeatherMixer.getGlobalLightOfTimeOfNoon() // demoWorld.globalLight = WeatherMixer.getGlobalLightOfTimeOfNoon()
demoWorld.updateWorldTime(delta) demoWorld.updateWorldTime(delta)
// WeatherMixer.update(delta, cameraPlayer, demoWorld) // WeatherMixer.update(delta, cameraPlayer, demoWorld)
WeatherMixer.forceTimeAt = forcedTime WeatherMixer.forceTimeAt = forcedTime

View File

@@ -20,9 +20,10 @@ object Skybox : Disposable {
const val gradSize = 128 const val gradSize = 128
private val gradTexBin: Array<Texture> private val gradTexBinLowAlbedo: Array<Texture>
private val gradTexBinHighAlbedo: Array<Texture>
operator fun get(elevationDeg: Double, turbidity: Double): Texture { operator fun get(elevationDeg: Double, turbidity: Double, highAlbedo: Boolean = false): Texture {
// if (elevationDeg !in elevationsD) { // if (elevationDeg !in elevationsD) {
// throw IllegalArgumentException("Elevation not in ±75° (got $elevationDeg)") // throw IllegalArgumentException("Elevation not in ±75° (got $elevationDeg)")
// } // }
@@ -31,11 +32,11 @@ object Skybox : Disposable {
// } // }
val elev = elevationDeg.coerceIn(elevationsD).toInt() - elevations.first val elev = elevationDeg.coerceIn(elevationsD).toInt() - elevations.first
val turb = ((turbidity.coerceIn(turbiditiesD) - turbiditiesD.start) / (turbidities.step / 100.0)).toInt() val turb = ((turbidity.coerceIn(turbiditiesD) - turbiditiesD.start) / (turbidities.step / 10.0)).toInt()
// printdbg(this, "$elevationDeg $turbidity ; $elev $turb") // printdbg(this, "$elevationDeg $turbidity ; $elev $turb")
return gradTexBin[elev * turbCnt + turb] return (if (highAlbedo) gradTexBinHighAlbedo else gradTexBinLowAlbedo)[elev * turbCnt + turb]
} }
private fun Float.scaleFun() = private fun Float.scaleFun() =
@@ -66,11 +67,12 @@ object Skybox : Disposable {
private val elevations = (-75..75) // 151 private val elevations = (-75..75) // 151
private val elevationsD = (elevations.first.toDouble() .. elevations.last.toDouble()) private val elevationsD = (elevations.first.toDouble() .. elevations.last.toDouble())
private val turbidities = (1_00..10_00 step 50) // 19 private val turbidities = (1_0..10_0 step 1) // 99
private val turbiditiesD = (turbidities.first / 100.0..turbidities.last / 100.0) private val turbiditiesD = (turbidities.first / 10.0..turbidities.last / 10.0)
private val elevCnt = elevations.count() private val elevCnt = elevations.count()
private val turbCnt = turbidities.count() private val turbCnt = turbidities.count()
private val albedo = 0.1 private val albedoLow = 0.1
private val albedoHight = 0.8 // for theoretical "winter wonderland"?
private val gamma = HALF_PI private val gamma = HALF_PI
private fun Double.mapCircle() = sin(HALF_PI * this) private fun Double.mapCircle() = sin(HALF_PI * this)
@@ -78,11 +80,20 @@ object Skybox : Disposable {
init { init {
printdbg(this, "Initialising skybox model") printdbg(this, "Initialising skybox model")
gradTexBin = Array(elevCnt * turbCnt) { gradTexBinLowAlbedo = getTexturmaps(albedoLow)
gradTexBinHighAlbedo = getTexturmaps(albedoHight)
App.disposables.add(this)
printdbg(this, "Skybox model generated!")
}
private fun getTexturmaps(albedo: Double): Array<Texture> {
return Array(elevCnt * turbCnt) {
val elevationDeg = (it / turbCnt).plus(elevations.first).toDouble() val elevationDeg = (it / turbCnt).plus(elevations.first).toDouble()
val elevationRad = Math.toRadians(elevationDeg) val elevationRad = Math.toRadians(elevationDeg)
val turbidity = 1.0 + (it % turbCnt) / 2.0 val turbidity = 1.0 + (it % turbCnt) / 10.0
val state = ArHosekSkyModel.arhosek_xyz_skymodelstate_alloc_init(turbidity, albedo, elevationRad.abs()) val state = ArHosekSkyModel.arhosek_xyz_skymodelstate_alloc_init(turbidity, albedo, elevationRad.abs())
val pixmap = Pixmap(1, gradSize, Pixmap.Format.RGBA8888) val pixmap = Pixmap(1, gradSize, Pixmap.Format.RGBA8888)
@@ -111,13 +122,10 @@ object Skybox : Disposable {
pixmap.dispose() pixmap.dispose()
texture texture
} }
App.disposables.add(this)
printdbg(this, "Skybox model generated!")
} }
override fun dispose() { override fun dispose() {
gradTexBin.forEach { it.dispose() } gradTexBinLowAlbedo.forEach { it.dispose() }
gradTexBinHighAlbedo.forEach { it.dispose() }
} }
} }

View File

@@ -160,9 +160,13 @@ internal object WeatherMixer : RNGConsumer {
// we will not care for nextSkybox for now // we will not care for nextSkybox for now
val timeNow = (forceTimeAt ?: world.worldTime.TIME_T.toInt()) % WorldTime.DAY_LENGTH val timeNow = (forceTimeAt ?: world.worldTime.TIME_T.toInt()) % WorldTime.DAY_LENGTH
val solarElev = if (forceTimeAt != null)
world.worldTime.getSolarElevationAt(world.worldTime.ordinalDay, forceTimeAt!!)
else
world.worldTime.solarElevationDeg
val daylightClut = currentWeather.daylightClut val daylightClut = currentWeather.daylightClut
// calculate global light // calculate global light
val globalLight = getGradientColour2(daylightClut, world.worldTime.solarElevationDeg, timeNow) val globalLight = getGradientColour2(daylightClut, solarElev, timeNow)
globalLightNow.set(globalLight) globalLightNow.set(globalLight)
/* (copied from the shader source) /* (copied from the shader source)
@@ -181,16 +185,12 @@ internal object WeatherMixer : RNGConsumer {
gdxBlendNormalStraightAlpha() gdxBlendNormalStraightAlpha()
val deg = if (forceTimeAt != null) val degThis = solarElev.floorToDouble()
world.worldTime.getSolarElevationAt(world.worldTime.ordinalDay, forceTimeAt!!)
else
world.worldTime.solarElevationDeg
val degThis = deg.floorToDouble()
val degNext = degThis + if (timeNow < HALF_DAY) 1 else -1 // Skybox.get has internal coerceIn val degNext = degThis + if (timeNow < HALF_DAY) 1 else -1 // Skybox.get has internal coerceIn
val texture1 = Skybox[degThis, turbidity] val texture1 = Skybox[degThis, turbidity]
val texture2 = Skybox[degNext, turbidity] val texture2 = Skybox[degNext, turbidity]
val lerpScale = (if (timeNow < HALF_DAY) deg - degThis else 1f - (deg - degThis)).toFloat() val lerpScale = (if (timeNow < HALF_DAY) solarElev - degThis else 1f - (solarElev - degThis)).toFloat()
val gradY = -(gH - App.scr.height) * ((parallax + 1f) / 2f) val gradY = -(gH - App.scr.height) * ((parallax + 1f) / 2f)
batch.inUse { batch.inUse {