mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-10 18:44:05 +09:00
deploying new skybox model
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"skyboxGradColourMap": "generic_skybox.tga",
|
"skyboxGradColourMap": "generic_skybox.tga",
|
||||||
|
"daylightClut": "clut_daylight.tga",
|
||||||
"classification": "generic",
|
"classification": "generic",
|
||||||
"extraImages": [
|
"extraImages": [
|
||||||
|
|
||||||
|
|||||||
BIN
assets/mods/basegame/weathers/clut_daylight.tga
LFS
Normal file
BIN
assets/mods/basegame/weathers/clut_daylight.tga
LFS
Normal file
Binary file not shown.
@@ -123,12 +123,6 @@ class Application(val WIDTH: Int, val HEIGHT: Int) : Game() {
|
|||||||
private fun Float.scaleFun() =
|
private fun Float.scaleFun() =
|
||||||
(1f - 1f / 2f.pow(this/6f)) * 0.97f
|
(1f - 1f / 2f.pow(this/6f)) * 0.97f
|
||||||
|
|
||||||
private fun Float.negativeElevationScale() =
|
|
||||||
minOf(
|
|
||||||
(1f - 1f / 2f.pow(this/6f)) * 0.97f,
|
|
||||||
1f - (1f - 1f / 2f.pow(this/6f)) * 0.97f
|
|
||||||
)
|
|
||||||
|
|
||||||
private fun CIEXYZ.scaleToFit(elevation: Double): CIEXYZ {
|
private fun CIEXYZ.scaleToFit(elevation: Double): CIEXYZ {
|
||||||
return if (elevation >= 0) {
|
return if (elevation >= 0) {
|
||||||
CIEXYZ(
|
CIEXYZ(
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
package net.torvald.terrarum.gameworld
|
package net.torvald.terrarum.gameworld
|
||||||
|
|
||||||
|
import net.torvald.terrarum.modulebasegame.worldgenerator.TWO_PI
|
||||||
|
import kotlin.math.cos
|
||||||
|
import kotlin.math.sin
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Please also see:
|
* Please also see:
|
||||||
@@ -117,9 +121,22 @@ class WorldTime(initTime: Long = 0L) {
|
|||||||
inline val moonPhase: Double
|
inline val moonPhase: Double
|
||||||
get() = (TIME_T.plus(1700000L) % LUNAR_CYCLE).toDouble() / LUNAR_CYCLE
|
get() = (TIME_T.plus(1700000L) % LUNAR_CYCLE).toDouble() / LUNAR_CYCLE
|
||||||
|
|
||||||
|
val solarElevationDeg: Double
|
||||||
|
get() {
|
||||||
|
val x = (TIME_T % YEAR_SECONDS).toDouble() / DAY_LENGTH + 15 // decimal days. One full day = 1.0
|
||||||
|
val d = -23.44 * cos(TWO_PI * x / YEAR_DAYS)
|
||||||
|
|
||||||
|
// 51.56 and 23.44 will make yearly min/max elevation to be 75deg
|
||||||
|
// -0.2504264: a number that makes y=min when x=0 (x=0 is midnight)
|
||||||
|
return 51.56 * sin(TWO_PI * (x - 0.2504264)) + d
|
||||||
|
}
|
||||||
|
val solarElevationRad: Double
|
||||||
|
get() = Math.toRadians(solarElevationDeg)
|
||||||
|
|
||||||
@Transient private var realSecAcc: Double = 0.0
|
@Transient private var realSecAcc: Double = 0.0
|
||||||
@Transient private val REAL_SEC_TO_GAME_SECS = 1.0 / GAME_MIN_TO_REAL_SEC // how slow is real-life clock (second-wise) relative to the ingame one
|
@Transient private val REAL_SEC_TO_GAME_SECS = 1.0 / GAME_MIN_TO_REAL_SEC // how slow is real-life clock (second-wise) relative to the ingame one
|
||||||
|
|
||||||
|
// NOTE: ingame calendars (the fixture with GUI) should use symbols AND fullnames; the watch already uses shot daynames
|
||||||
val DAY_NAMES = arrayOf(//daynames are taken from Nynorsk (å -> o)
|
val DAY_NAMES = arrayOf(//daynames are taken from Nynorsk (å -> o)
|
||||||
"Mondag", "Tysdag", "Midtveke" //middle-week
|
"Mondag", "Tysdag", "Midtveke" //middle-week
|
||||||
, "Torsdag", "Fredag", "Laurdag", "Sundag", "Verddag" //From Norsk word 'verd'
|
, "Torsdag", "Fredag", "Laurdag", "Sundag", "Verddag" //From Norsk word 'verd'
|
||||||
@@ -138,19 +155,21 @@ class WorldTime(initTime: Long = 0L) {
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
/** Each day is displayed as 24 hours, but in real-life clock it's 22 mins long */
|
/** Each day is displayed as 24 hours, but in real-life clock it's 22 mins long */
|
||||||
val DAY_LENGTH = 86400 //must be the multiple of 3600
|
const val DAY_LENGTH = 86400 //must be the multiple of 3600
|
||||||
|
|
||||||
val HOUR_SEC: Int = 3600
|
const val HOUR_SEC: Int = 3600
|
||||||
val MINUTE_SEC: Int = 60
|
const val MINUTE_SEC: Int = 60
|
||||||
val HOUR_MIN: Int = 60
|
const val HOUR_MIN: Int = 60
|
||||||
val GAME_MIN_TO_REAL_SEC: Double = 720.0 / 11.0
|
const val GAME_MIN_TO_REAL_SEC: Double = 720.0 / 11.0
|
||||||
val HOURS_PER_DAY = DAY_LENGTH / HOUR_SEC
|
const val HOURS_PER_DAY = DAY_LENGTH / HOUR_SEC
|
||||||
|
|
||||||
val YEAR_DAYS: Int = 120
|
const val YEAR_DAYS: Int = 120
|
||||||
|
|
||||||
val MONTH_LENGTH = 30 // ingame calendar specific
|
const val MONTH_LENGTH = 30 // ingame calendar specific
|
||||||
|
|
||||||
val EPOCH_YEAR = 125
|
const val EPOCH_YEAR = 125
|
||||||
|
|
||||||
|
val YEAR_SECONDS = DAY_LENGTH * YEAR_DAYS
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse a time in the format of "8h30" (hour and minute) or "39882" (second) and return a time of day, in seconds
|
* Parse a time in the format of "8h30" (hour and minute) or "39882" (second) and return a time of day, in seconds
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import net.torvald.terrarum.gameparticles.ParticleBase
|
|||||||
import net.torvald.terrarum.gameworld.GameWorld
|
import net.torvald.terrarum.gameworld.GameWorld
|
||||||
import net.torvald.terrarum.gameworld.WorldSimulator
|
import net.torvald.terrarum.gameworld.WorldSimulator
|
||||||
import net.torvald.terrarum.langpack.Lang
|
import net.torvald.terrarum.langpack.Lang
|
||||||
|
import net.torvald.terrarum.modulebasegame.clut.Skybox
|
||||||
import net.torvald.terrarum.modulebasegame.gameactors.*
|
import net.torvald.terrarum.modulebasegame.gameactors.*
|
||||||
import net.torvald.terrarum.modulebasegame.gameactors.physicssolver.CollisionSolver
|
import net.torvald.terrarum.modulebasegame.gameactors.physicssolver.CollisionSolver
|
||||||
import net.torvald.terrarum.modulebasegame.gameitems.PickaxeCore
|
import net.torvald.terrarum.modulebasegame.gameitems.PickaxeCore
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import net.torvald.terrarum.gameworld.GameWorld
|
|||||||
import net.torvald.terrarum.gameworld.WorldTime
|
import net.torvald.terrarum.gameworld.WorldTime
|
||||||
import net.torvald.terrarum.gameworld.fmod
|
import net.torvald.terrarum.gameworld.fmod
|
||||||
import net.torvald.terrarum.langpack.Lang
|
import net.torvald.terrarum.langpack.Lang
|
||||||
|
import net.torvald.terrarum.modulebasegame.clut.Skybox
|
||||||
import net.torvald.terrarum.modulebasegame.ui.UILoadGovernor
|
import net.torvald.terrarum.modulebasegame.ui.UILoadGovernor
|
||||||
import net.torvald.terrarum.modulebasegame.ui.UIRemoCon
|
import net.torvald.terrarum.modulebasegame.ui.UIRemoCon
|
||||||
import net.torvald.terrarum.modulebasegame.ui.UITitleRemoConYaml
|
import net.torvald.terrarum.modulebasegame.ui.UITitleRemoConYaml
|
||||||
@@ -239,6 +240,7 @@ class TitleScreen(batch: FlippingSpriteBatch) : IngameInstance(batch) {
|
|||||||
uiContainer.add(uiRemoCon)
|
uiContainer.add(uiRemoCon)
|
||||||
|
|
||||||
CommandDict // invoke
|
CommandDict // invoke
|
||||||
|
Skybox // invoke
|
||||||
// TODO add console here
|
// TODO add console here
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,16 +1,123 @@
|
|||||||
package net.torvald.terrarum.modulebasegame.clut
|
package net.torvald.terrarum.modulebasegame.clut
|
||||||
|
|
||||||
|
import com.badlogic.gdx.graphics.Pixmap
|
||||||
import com.badlogic.gdx.graphics.Texture
|
import com.badlogic.gdx.graphics.Texture
|
||||||
|
import com.badlogic.gdx.utils.Disposable
|
||||||
|
import net.torvald.colourutil.CIEXYZ
|
||||||
|
import net.torvald.colourutil.toColor
|
||||||
|
import net.torvald.colourutil.toRGB
|
||||||
|
import net.torvald.parametricsky.ArHosekSkyModel
|
||||||
|
import net.torvald.terrarum.App
|
||||||
|
import net.torvald.terrarum.App.printdbg
|
||||||
|
import net.torvald.terrarum.abs
|
||||||
|
import net.torvald.terrarum.modulebasegame.worldgenerator.HALF_PI
|
||||||
|
import kotlin.math.*
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by minjaesong on 2023-07-09.
|
* Created by minjaesong on 2023-07-09.
|
||||||
*/
|
*/
|
||||||
object Skybox {
|
object Skybox : Disposable {
|
||||||
|
|
||||||
const val gradSize = 64
|
const val gradSize = 128
|
||||||
|
|
||||||
operator fun get(elevation: Double, turbidity: Double): Array<Texture> {
|
private val gradTexBin: Array<Texture>
|
||||||
TODO()
|
|
||||||
|
operator fun get(elevationDeg: Double, turbidity: Double): Texture {
|
||||||
|
// if (elevationDeg !in elevationsD) {
|
||||||
|
// throw IllegalArgumentException("Elevation not in ±75° (got $elevationDeg)")
|
||||||
|
// }
|
||||||
|
// if (turbidity !in turbiditiesD) {
|
||||||
|
// throw IllegalArgumentException("Turbidity not in 1..10 (got $turbidity)")
|
||||||
|
// }
|
||||||
|
|
||||||
|
val elev = elevationDeg.coerceIn(elevationsD).toInt() - elevations.first
|
||||||
|
val turb = ((turbidity.coerceIn(turbiditiesD) - turbiditiesD.start) / (turbidities.step / 100.0)).toInt()
|
||||||
|
|
||||||
|
// printdbg(this, "$elevationDeg $turbidity ; $elev $turb")
|
||||||
|
|
||||||
|
return gradTexBin[elev * turbCnt + turb]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun Float.scaleFun() =
|
||||||
|
(1f - 1f / 2f.pow(this/6f)) * 0.97f
|
||||||
|
|
||||||
|
private fun CIEXYZ.scaleToFit(elevationDeg: Double): CIEXYZ {
|
||||||
|
return if (elevationDeg >= 0) {
|
||||||
|
CIEXYZ(
|
||||||
|
this.X.scaleFun(),
|
||||||
|
this.Y.scaleFun(),
|
||||||
|
this.Z.scaleFun(),
|
||||||
|
this.alpha
|
||||||
|
)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
val elevation1 = -elevationDeg
|
||||||
|
val elevation2 = -elevationDeg / 28.5
|
||||||
|
val scale = (1f - (1f - 1f / 1.8.pow(elevation1)) * 0.97f).toFloat()
|
||||||
|
val scale2 = (1.0 - (elevation2.pow(E) / E.pow(elevation2))*0.8).toFloat()
|
||||||
|
CIEXYZ(
|
||||||
|
this.X.scaleFun() * scale * scale2,
|
||||||
|
this.Y.scaleFun() * scale * scale2,
|
||||||
|
this.Z.scaleFun() * scale * scale2,
|
||||||
|
this.alpha
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 elevCnt = elevations.count()
|
||||||
|
private val turbCnt = turbidities.count()
|
||||||
|
private val albedo = 0.1
|
||||||
|
private val gamma = HALF_PI
|
||||||
|
|
||||||
|
private fun Double.mapCircle() = sin(HALF_PI * this)
|
||||||
|
|
||||||
|
init {
|
||||||
|
printdbg(this, "Initialising skybox model")
|
||||||
|
|
||||||
|
gradTexBin = Array(elevCnt * turbCnt) {
|
||||||
|
|
||||||
|
val elevationDeg = (it / turbCnt).plus(elevations.first).toDouble()
|
||||||
|
val elevationRad = Math.toRadians(elevationDeg)
|
||||||
|
val turbidity = 1.0 + (it % turbCnt) / 100.0
|
||||||
|
|
||||||
|
val state = ArHosekSkyModel.arhosek_xyz_skymodelstate_alloc_init(turbidity, albedo, elevationRad.abs())
|
||||||
|
val pixmap = Pixmap(1, gradSize, Pixmap.Format.RGBA8888)
|
||||||
|
|
||||||
|
// printdbg(this, "elev $elevationDeg turb $turbidity")
|
||||||
|
|
||||||
|
for (y in 0 until gradSize) {
|
||||||
|
val theta = (y.toDouble() / gradSize * 1.0).coerceIn(0.0, 1.0).mapCircle() * HALF_PI
|
||||||
|
// vertical angle, where 0 is zenith, ±90 is ground (which is odd)
|
||||||
|
|
||||||
|
val xyz = CIEXYZ(
|
||||||
|
ArHosekSkyModel.arhosek_tristim_skymodel_radiance(state, theta, gamma, 0).toFloat(),
|
||||||
|
ArHosekSkyModel.arhosek_tristim_skymodel_radiance(state, theta, gamma, 1).toFloat(),
|
||||||
|
ArHosekSkyModel.arhosek_tristim_skymodel_radiance(state, theta, gamma, 2).toFloat()
|
||||||
|
)
|
||||||
|
val xyz2 = xyz.scaleToFit(elevationDeg)
|
||||||
|
val rgb = xyz2.toRGB().toColor()
|
||||||
|
|
||||||
|
pixmap.setColor(rgb)
|
||||||
|
pixmap.drawPixel(0, gradSize - 1 - y)
|
||||||
|
}
|
||||||
|
|
||||||
|
val texture = Texture(pixmap).also {
|
||||||
|
it.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear)
|
||||||
|
}
|
||||||
|
pixmap.dispose()
|
||||||
|
texture
|
||||||
|
}
|
||||||
|
|
||||||
|
App.disposables.add(this)
|
||||||
|
|
||||||
|
printdbg(this, "Skybox model generated!")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun dispose() {
|
||||||
|
gradTexBin.forEach { it.dispose() }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -13,6 +13,7 @@ import java.util.*
|
|||||||
*/
|
*/
|
||||||
data class BaseModularWeather(
|
data class BaseModularWeather(
|
||||||
var skyboxGradColourMap: GdxColorMap, // row 0: skybox grad top, row 1: skybox grad bottom, row 2: sunlight (RGBA)
|
var skyboxGradColourMap: GdxColorMap, // row 0: skybox grad top, row 1: skybox grad bottom, row 2: sunlight (RGBA)
|
||||||
|
val daylightClut: GdxColorMap,
|
||||||
val classification: String,
|
val classification: String,
|
||||||
var extraImages: ArrayList<Texture>,
|
var extraImages: ArrayList<Texture>,
|
||||||
val mixFrom: String? = null,
|
val mixFrom: String? = null,
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package net.torvald.terrarum.weather
|
package net.torvald.terrarum.weather
|
||||||
|
|
||||||
import com.badlogic.gdx.Gdx
|
|
||||||
import com.badlogic.gdx.Input
|
import com.badlogic.gdx.Input
|
||||||
import com.badlogic.gdx.graphics.*
|
import com.badlogic.gdx.graphics.*
|
||||||
import com.jme3.math.FastMath
|
import com.jme3.math.FastMath
|
||||||
@@ -13,8 +12,10 @@ import net.torvald.terrarum.gameactors.ActorWithBody
|
|||||||
import net.torvald.terrarum.gamecontroller.KeyToggler
|
import net.torvald.terrarum.gamecontroller.KeyToggler
|
||||||
import net.torvald.terrarum.gameworld.GameWorld
|
import net.torvald.terrarum.gameworld.GameWorld
|
||||||
import net.torvald.terrarum.gameworld.WorldTime
|
import net.torvald.terrarum.gameworld.WorldTime
|
||||||
|
import net.torvald.terrarum.gameworld.WorldTime.Companion.DAY_LENGTH
|
||||||
import net.torvald.terrarum.modulebasegame.RNGConsumer
|
import net.torvald.terrarum.modulebasegame.RNGConsumer
|
||||||
import net.torvald.terrarum.modulebasegame.TerrarumIngame
|
import net.torvald.terrarum.modulebasegame.TerrarumIngame
|
||||||
|
import net.torvald.terrarum.modulebasegame.clut.Skybox
|
||||||
import net.torvald.terrarum.modulebasegame.gameactors.ParticleMegaRain
|
import net.torvald.terrarum.modulebasegame.gameactors.ParticleMegaRain
|
||||||
import net.torvald.terrarum.utils.JsonFetcher
|
import net.torvald.terrarum.utils.JsonFetcher
|
||||||
import net.torvald.terrarum.worlddrawer.WorldCamera
|
import net.torvald.terrarum.worlddrawer.WorldCamera
|
||||||
@@ -105,9 +106,10 @@ internal object WeatherMixer : RNGConsumer {
|
|||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
|
|
||||||
val defaultWeather = BaseModularWeather(
|
val defaultWeather = BaseModularWeather(
|
||||||
GdxColorMap(1, 3, Color(0x55aaffff), Color(0xaaffffff.toInt()), Color.WHITE),
|
GdxColorMap(1, 3, Color(0x55aaffff), Color(0xaaffffff.toInt()), Color.WHITE),
|
||||||
"default",
|
GdxColorMap(2, 2, Color.WHITE, Color.WHITE, Color.WHITE, Color.WHITE),
|
||||||
ArrayList<Texture>()
|
"default",
|
||||||
|
ArrayList<Texture>()
|
||||||
)
|
)
|
||||||
|
|
||||||
currentWeather = defaultWeather
|
currentWeather = defaultWeather
|
||||||
@@ -142,27 +144,28 @@ internal object WeatherMixer : RNGConsumer {
|
|||||||
if (!globalLightOverridden) {
|
if (!globalLightOverridden) {
|
||||||
world.globalLight = WeatherMixer.globalLightNow
|
world.globalLight = WeatherMixer.globalLightNow
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//private val parallaxZeroPos = WorldGenerator.TERRAIN_AVERAGE_HEIGHT * 0.75f // just an arb multiplier (266.66666 -> 200)
|
private var turbidity = 2.0
|
||||||
|
private var gH = 2f * App.scr.height
|
||||||
private val skyboxPixmap = Pixmap(2, 2, Pixmap.Format.RGBA8888)
|
|
||||||
private var skyboxTexture = Texture(skyboxPixmap)
|
|
||||||
|
|
||||||
|
private val HALF_DAY = DAY_LENGTH / 2
|
||||||
/**
|
/**
|
||||||
* Sub-portion of IngameRenderer. You are not supposed to directly deal with this.
|
* Sub-portion of IngameRenderer. You are not supposed to directly deal with this.
|
||||||
*/
|
*/
|
||||||
internal fun render(camera: Camera, batch: FlippingSpriteBatch, world: GameWorld) {
|
internal fun render(camera: Camera, batch: FlippingSpriteBatch, world: GameWorld) {
|
||||||
val parallaxZeroPos = (world.height / 3f) * 0.8888f
|
val parallaxZeroPos = (world.height / 3f)
|
||||||
val parallaxDomainSize = world.height / 4f
|
val parallaxDomainSize = world.height / 6f
|
||||||
|
|
||||||
|
|
||||||
// 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 skyboxColourMap = currentWeather.skyboxGradColourMap
|
val skyboxColourMap = currentWeather.skyboxGradColourMap
|
||||||
|
val daylightClut = currentWeather.daylightClut
|
||||||
|
|
||||||
// calculate global light
|
// calculate global light
|
||||||
val globalLight = getGradientColour(world, skyboxColourMap, 2, timeNow)
|
val globalLight = getGradientColour2(daylightClut, world.worldTime.solarElevationDeg, timeNow)
|
||||||
globalLightNow.set(globalLight)
|
globalLightNow.set(globalLight)
|
||||||
|
|
||||||
|
|
||||||
@@ -178,56 +181,30 @@ internal object WeatherMixer : RNGConsumer {
|
|||||||
-+ <- 0.0 =
|
-+ <- 0.0 =
|
||||||
*/
|
*/
|
||||||
val parallax = ((parallaxZeroPos - WorldCamera.gdxCamY.div(TILE_SIZEF)) / parallaxDomainSize).times(-1f).coerceIn(-1f, 1f)
|
val parallax = ((parallaxZeroPos - WorldCamera.gdxCamY.div(TILE_SIZEF)) / parallaxDomainSize).times(-1f).coerceIn(-1f, 1f)
|
||||||
val parallaxSize = 1f / 3f
|
// println(parallax) // parallax value works as intended.
|
||||||
val parallaxMidpt = (parallax + 1f) / 2f
|
|
||||||
val parallaxTop = (parallaxMidpt - (parallaxSize / 2f)).coerceIn(0f, 1f)
|
|
||||||
val parallaxBottom = (parallaxMidpt + (parallaxSize / 2f)).coerceIn(0f, 1f)
|
|
||||||
|
|
||||||
//println("$parallaxZeroPos, $parallax | $parallaxTop - $parallaxMidpt - $parallaxBottom | $parallaxDomainSize")
|
|
||||||
|
|
||||||
// draw skybox to provided graphics instance
|
|
||||||
val colTopmost = getGradientColour(world, skyboxColourMap, 0, timeNow).toGdxColor()
|
|
||||||
val colBottommost = getGradientColour(world, skyboxColourMap, 1, timeNow).toGdxColor()
|
|
||||||
val colMid = colorMix(colTopmost, colBottommost, 0.5f)
|
|
||||||
|
|
||||||
//println(parallax) // parallax value works as intended.
|
|
||||||
|
|
||||||
val colTop = colorMix(colTopmost, colBottommost, parallaxTop)
|
|
||||||
val colBottom = colorMix(colTopmost, colBottommost, parallaxBottom)
|
|
||||||
|
|
||||||
// draw using shaperenderer or whatever
|
|
||||||
|
|
||||||
//Terrarum.textureWhiteSquare.bind(0)
|
|
||||||
gdxBlendNormalStraightAlpha()
|
gdxBlendNormalStraightAlpha()
|
||||||
|
|
||||||
// draw to skybox texture
|
val deg =world.worldTime.solarElevationDeg
|
||||||
skyboxPixmap.setColor(colBottom)
|
val degThis = deg.floor()
|
||||||
skyboxPixmap.drawPixel(0, 0); skyboxPixmap.drawPixel(1, 0)
|
val degNext = degThis + if (timeNow < HALF_DAY) 1 else -1 // Skybox.get has internal coerceIn
|
||||||
skyboxPixmap.setColor(colTop)
|
|
||||||
skyboxPixmap.drawPixel(0, 1); skyboxPixmap.drawPixel(1, 1)
|
|
||||||
skyboxTexture.dispose()
|
|
||||||
skyboxTexture = Texture(skyboxPixmap); skyboxTexture.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear)
|
|
||||||
|
|
||||||
|
val texture1 = Skybox.get(degThis, turbidity)
|
||||||
|
val texture2 = Skybox.get(degNext, turbidity)
|
||||||
|
val lerpScale = (if (timeNow < HALF_DAY) deg - degThis else 1f - (deg - degThis)).toFloat()
|
||||||
|
|
||||||
|
val gradY = -(gH - App.scr.height) * ((parallax + 1f) / 2f)
|
||||||
batch.inUse {
|
batch.inUse {
|
||||||
batch.shader = null
|
batch.shader = null
|
||||||
batch.drawFlipped(skyboxTexture, 0f, -App.scr.halfhf, App.scr.wf, App.scr.hf * 2f) // because of how the linear filter works, we extend the image by two
|
batch.color = Color.WHITE
|
||||||
|
batch.drawFlipped(texture1, 0f, gradY, App.scr.wf, gH)
|
||||||
|
|
||||||
|
batch.color = Color(1f, 1f, 1f, lerpScale)
|
||||||
|
batch.drawFlipped(texture2, 0f, gradY, App.scr.wf, gH)
|
||||||
|
|
||||||
|
batch.color = Color.WHITE
|
||||||
}
|
}
|
||||||
|
|
||||||
// don't use shader to just fill the whole screen... frag shader will be called a million times and it's best to not burden it
|
|
||||||
/*
|
|
||||||
IngameRenderer.shaderSkyboxFill.bind()
|
|
||||||
IngameRenderer.shaderSkyboxFill.setUniformMatrix("u_projTrans", camera.combined)
|
|
||||||
IngameRenderer.shaderSkyboxFill.setUniformf("topColor", topCol.r, topCol.g, topCol.b)
|
|
||||||
IngameRenderer.shaderSkyboxFill.setUniformf("bottomColor", bottomCol.r, bottomCol.g, bottomCol.b)
|
|
||||||
IngameRenderer.shaderSkyboxFill.setUniformf("parallax", parallax.coerceIn(-1f, 1f))
|
|
||||||
IngameRenderer.shaderSkyboxFill.setUniformf("parallax_size", 1f/3f)
|
|
||||||
IngameRenderer.shaderSkyboxFill.setUniformf("zoomInv", 1f / (Terrarum.ingame?.screenZoom ?: 1f))
|
|
||||||
AppLoader.fullscreenQuad.render(IngameRenderer.shaderSkyboxFill, GL20.GL_TRIANGLES)
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
Gdx.gl.glActiveTexture(GL20.GL_TEXTURE0) // so that batch that comes next will bind any tex to it
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -275,6 +252,36 @@ internal object WeatherMixer : RNGConsumer {
|
|||||||
return Cvec(newCol)
|
return Cvec(newCol)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getGradientColour2(colorMap: GdxColorMap, solarAngleInDeg: Double, timeOfDay: Int): Cvec {
|
||||||
|
val pNowRaw = (solarAngleInDeg + 75.0) / 150.0 * colorMap.width
|
||||||
|
|
||||||
|
val pStartRaw = pNowRaw.floorInt()
|
||||||
|
val pNextRaw = pStartRaw + 1
|
||||||
|
|
||||||
|
val pSx: Int; val pSy: Int; val pNx: Int; val pNy: Int
|
||||||
|
if (timeOfDay < HALF_DAY) {
|
||||||
|
pSx = pStartRaw; pSy = 0
|
||||||
|
if (pSx == colorMap.width-1) { pNx = pSx; pNy = 1 }
|
||||||
|
else { pNx = pNextRaw; pNy = 0 }
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pSx = pStartRaw; pSy = 1
|
||||||
|
if (pSx == 0) { pNx = 0; pNy = 0 }
|
||||||
|
else { pNx = pSx - 1; pNy = 1 }
|
||||||
|
}
|
||||||
|
|
||||||
|
val colourThis = colorMap.get(pSx, pSy)
|
||||||
|
val colourNext = colorMap.get(pNx, pNy)
|
||||||
|
|
||||||
|
// interpolate R, G, B and A
|
||||||
|
var scale = (pNowRaw - pStartRaw).toFloat()
|
||||||
|
if (timeOfDay >= HALF_DAY) scale = 1f - scale
|
||||||
|
|
||||||
|
val newCol = colourThis.cpy().lerp(colourNext, scale)//CIELuvUtil.getGradient(scale, colourThis, colourNext)
|
||||||
|
|
||||||
|
return Cvec(newCol)
|
||||||
|
}
|
||||||
|
|
||||||
fun getWeatherList(classification: String) = weatherList[classification]!!
|
fun getWeatherList(classification: String) = weatherList[classification]!!
|
||||||
fun getRandomWeather(classification: String) =
|
fun getRandomWeather(classification: String) =
|
||||||
getWeatherList(classification)[HQRNG().nextInt(getWeatherList(classification).size)]
|
getWeatherList(classification)[HQRNG().nextInt(getWeatherList(classification).size)]
|
||||||
@@ -299,10 +306,12 @@ internal object WeatherMixer : RNGConsumer {
|
|||||||
val JSON = JsonFetcher(path)
|
val JSON = JsonFetcher(path)
|
||||||
|
|
||||||
val skyboxInJson = JSON.getString("skyboxGradColourMap")
|
val skyboxInJson = JSON.getString("skyboxGradColourMap")
|
||||||
|
val lightbox = JSON.getString("daylightClut")
|
||||||
val extraImagesPath = JSON.get("extraImages").asStringArray()
|
val extraImagesPath = JSON.get("extraImages").asStringArray()
|
||||||
|
|
||||||
val skybox = GdxColorMap(ModMgr.getGdxFile("basegame", "$pathToImage/${skyboxInJson}"))
|
val skybox = GdxColorMap(ModMgr.getGdxFile("basegame", "$pathToImage/${skyboxInJson}"))
|
||||||
|
|
||||||
|
val daylight = GdxColorMap(ModMgr.getGdxFile("basegame", "$pathToImage/${lightbox}"))
|
||||||
|
|
||||||
|
|
||||||
val extraImages = ArrayList<Texture>()
|
val extraImages = ArrayList<Texture>()
|
||||||
@@ -327,18 +336,14 @@ internal object WeatherMixer : RNGConsumer {
|
|||||||
|
|
||||||
|
|
||||||
return BaseModularWeather(
|
return BaseModularWeather(
|
||||||
skyboxGradColourMap = skybox,
|
skyboxGradColourMap = skybox,
|
||||||
classification = classification,
|
daylightClut = daylight,
|
||||||
extraImages = extraImages
|
classification = classification,
|
||||||
|
extraImages = extraImages
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun dispose() {
|
fun dispose() {
|
||||||
try {
|
|
||||||
skyboxTexture.dispose()
|
|
||||||
}
|
|
||||||
catch (e: Throwable) {}
|
|
||||||
|
|
||||||
skyboxPixmap.dispose()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user