skybox: old-current weather turbidity blend

This commit is contained in:
minjaesong
2023-09-06 21:07:39 +09:00
parent b47cc17afd
commit 0b5e3d7b77
3 changed files with 66 additions and 47 deletions

View File

@@ -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(),
)
}

View File

@@ -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),

View File

@@ -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