mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-07 20:31:51 +09:00
skybox: old-current weather turbidity blend
This commit is contained in:
@@ -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(),
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user