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)
// construct camera nodes
@@ -194,13 +194,14 @@ class TitleScreen(batch: FlippingSpriteBatch) : IngameInstance(batch) {
}
// apply gaussian blur to the camera nodes
for (i in cameraNodes.indices) {
val offM2 = cameraNodes[(i-2) fmod cameraNodes.size] * 1f
val offM1 = cameraNodes[(i-1) fmod cameraNodes.size] * 4f
val off0 = cameraNodes[i] * 6f
val off1 = cameraNodes[(i+1) fmod cameraNodes.size] * 4f
val off2 = cameraNodes[(i+2) fmod cameraNodes.size] * 1f
// val offM2 = cameraNodes[(i-2) fmod cameraNodes.size] * 1f
val offM1 = cameraNodes[(i-1) fmod cameraNodes.size] * 1f
val off0 = cameraNodes[i] * 2f
val off1 = cameraNodes[(i+1) 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 ->
// TODO: desynched weather and time-of-day change
val forcedTime = 39693
// demoWorld.globalLight = WeatherMixer.globalLightNow
demoWorld.globalLight = WeatherMixer.getGlobalLightOfTimeOfNoon()
val forcedTime = 32880 // 9h08m
demoWorld.globalLight = WeatherMixer.globalLightNow
// demoWorld.globalLight = WeatherMixer.getGlobalLightOfTimeOfNoon()
demoWorld.updateWorldTime(delta)
// WeatherMixer.update(delta, cameraPlayer, demoWorld)
WeatherMixer.forceTimeAt = forcedTime

View File

@@ -20,9 +20,10 @@ object Skybox : Disposable {
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) {
// throw IllegalArgumentException("Elevation not in ±75° (got $elevationDeg)")
// }
@@ -31,11 +32,11 @@ object Skybox : Disposable {
// }
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")
return gradTexBin[elev * turbCnt + turb]
return (if (highAlbedo) gradTexBinHighAlbedo else gradTexBinLowAlbedo)[elev * turbCnt + turb]
}
private fun Float.scaleFun() =
@@ -66,11 +67,12 @@ object Skybox : Disposable {
private val elevations = (-75..75) // 151
private val elevationsD = (elevations.first.toDouble() .. elevations.last.toDouble())
private val turbidities = (1_00..10_00 step 50) // 19
private val turbiditiesD = (turbidities.first / 100.0..turbidities.last / 100.0)
private val turbidities = (1_0..10_0 step 1) // 99
private val turbiditiesD = (turbidities.first / 10.0..turbidities.last / 10.0)
private val elevCnt = elevations.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 fun Double.mapCircle() = sin(HALF_PI * this)
@@ -78,11 +80,20 @@ object Skybox : Disposable {
init {
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 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 pixmap = Pixmap(1, gradSize, Pixmap.Format.RGBA8888)
@@ -111,13 +122,10 @@ object Skybox : Disposable {
pixmap.dispose()
texture
}
App.disposables.add(this)
printdbg(this, "Skybox model generated!")
}
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
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
// calculate global light
val globalLight = getGradientColour2(daylightClut, world.worldTime.solarElevationDeg, timeNow)
val globalLight = getGradientColour2(daylightClut, solarElev, timeNow)
globalLightNow.set(globalLight)
/* (copied from the shader source)
@@ -180,17 +184,13 @@ internal object WeatherMixer : RNGConsumer {
// println(parallax) // parallax value works as intended.
gdxBlendNormalStraightAlpha()
val deg = if (forceTimeAt != null)
world.worldTime.getSolarElevationAt(world.worldTime.ordinalDay, forceTimeAt!!)
else
world.worldTime.solarElevationDeg
val degThis = deg.floorToDouble()
val degThis = solarElev.floorToDouble()
val degNext = degThis + if (timeNow < HALF_DAY) 1 else -1 // Skybox.get has internal coerceIn
val texture1 = Skybox[degThis, 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)
batch.inUse {