more clouds

This commit is contained in:
minjaesong
2023-08-22 00:06:03 +09:00
parent dc83e12170
commit 7dd520393c
4 changed files with 53 additions and 32 deletions

View File

@@ -2,17 +2,17 @@
"skyboxGradColourMap": "generic_skybox.tga",
"daylightClut": "clut_daylight.tga",
"classification": "generic",
"cloudChance": 6,
"cloudChance": 10,
"cloudGamma": [0.59, 2.0],
"cloudDriftSpeed": 0.4,
"cloudDriftSpeed": 10.4,
"clouds": {
"normal": {
"filename": "cloud_normal.png",
"tw": 1024, "th": 512, "probability": 1.0, "baseScale": 0.4, "scaleVariance": 0.2
},
"large": {
"filename": "cloud_large.png",
"tw": 2048, "th": 1024, "probability": 0.1, "baseScale": 0.26, "scaleVariance": 0.2
"tw": 2048, "th": 1024, "probability": 0.2, "baseScale": 0.45, "scaleVariance": 0.7
},
"normal": {
"filename": "cloud_normal.png",
"tw": 1024, "th": 512, "probability": 1.0, "baseScale": 0.5, "scaleVariance": 0.8
}
}
}

View File

@@ -2,6 +2,7 @@ package net.torvald.terrarum.weather
import com.badlogic.gdx.Gdx
import com.badlogic.gdx.graphics.*
import com.badlogic.gdx.graphics.g2d.SpriteBatch
import com.badlogic.gdx.graphics.g2d.TextureRegion
import com.badlogic.gdx.math.Vector2
import com.badlogic.gdx.math.Vector3
@@ -192,7 +193,9 @@ internal object WeatherMixer : RNGConsumer {
it?.let {
it.update(cloudDriftVector, currentWeather.cloudDriftSpeed)
if (it.posX < -1500f || it.posX > App.scr.width + 1500f || it.scale < 1f / 2048f) {
val pjx = it.posX / it.posZ
if (pjx !in -1500f..App.scr.wf + 1500f || it.scale < 1f / 2048f) {
it.flagToDespawn = true
}
}
@@ -211,11 +214,20 @@ internal object WeatherMixer : RNGConsumer {
private val scrHscaler = App.scr.height / 720f
/**
* @param range: range of the randomised number
* @param random: random number in the range of `[-1, 1]`
*/
private fun randomPosWithin(range: ClosedFloatingPointRange<Float>, random: Float) =
((range.start + range.endInclusive) / 2f) + random * (range.endInclusive - range.start) / 2f
private fun tryToSpawnCloud(currentWeather: BaseModularWeather) {
printdbg(this, "Trying to spawn a cloud... (${cloudsSpawned} / ${clouds.size})")
if (cloudsSpawned < clouds.size) {
val flip = Math.random() < 0.5
val rC = Math.random().toFloat()
val rZ = (Math.random() * 3.0 + 1.0).toFloat() // 1..4
val r0 = (Math.random() * 2.0 - 1.0).toFloat() // -1..1
val r1 = (Math.random() * 2.0 - 1.0).toFloat() // -1..1
val r2 = (Math.random() * 2.0 - 1.0).toFloat() // -1..1
@@ -237,15 +249,15 @@ internal object WeatherMixer : RNGConsumer {
cloudsToSpawn?.let { cloud ->
val scaleVariance = 1f + rT1.absoluteValue * cloud.scaleVariance
val cloudScale = cloud.baseScale * (if (rT1 < 0) 1f / scaleVariance else scaleVariance)
val hCloudSize = cloud.spriteSheet.tileW * cloudScale + 1f
val posX = if (cloudDriftVector.x < 0) App.scr.width + hCloudSize else -hCloudSize
val hCloudSize = (cloud.spriteSheet.tileW * cloudScale) + 1f
val posX = if (cloudDriftVector.x < 0) (App.scr.width + hCloudSize) * rZ else -hCloudSize * rZ
val posY = when (cloud.category) {
"large" -> (100f + r0 * 80f) * scrHscaler
else -> (150f + r0 * 50f) * scrHscaler
"large" -> randomPosWithin(-10f..120f, r0) * scrHscaler
else -> randomPosWithin(-50f..150f, r0) * scrHscaler // -50..150
}
val sheetX = rA % cloud.spriteSheet.horizontalCount
val sheetY = rB % cloud.spriteSheet.verticalCount
WeatherObjectCloud(cloud.spriteSheet.get(sheetX, sheetY)).also {
WeatherObjectCloud(cloud.spriteSheet.get(sheetX, sheetY), flip).also {
it.scale = cloudScale
it.darkness.set(currentWeather.cloudGamma)
@@ -255,12 +267,13 @@ internal object WeatherMixer : RNGConsumer {
it.posX = posX
it.posY = posY
it.posZ = rZ
clouds.addAtFreeSpot(it)
cloudsSpawned += 1
printdbg(this, "... Spawning ${cloud.category}($sheetX, $sheetY) cloud at pos ${it.pos}, invGamma ${it.darkness}")
printdbg(this, "... Spawning ${cloud.category}($sheetX, $sheetY) cloud at pos ${it.pos}, scale ${it.scale}, invGamma ${it.darkness}")
}
}
@@ -289,25 +302,21 @@ internal object WeatherMixer : RNGConsumer {
*/
internal fun render(camera: Camera, batch: FlippingSpriteBatch, world: GameWorld) {
drawSkybox(camera, batch, world)
drawClouds(batch)
batch.color = Color.WHITE
}
private fun drawClouds(batch: SpriteBatch) {
batch.color = globalLightNow.toGdxColor().also {
it.a = 1f
} // TODO add cloud-only colour strip on the CLUT
batch.shader = shaderClouds
clouds.forEach {
it?.let {
batch.inUse { _ ->
batch.shader.setUniformf("gamma", it.darkness)
it.render(batch, 0f, 0f) // TODO parallax
}
clouds.filterNotNull().sortedByDescending { it.posZ }.forEach {
batch.inUse { _ ->
batch.shader.setUniformf("gamma", it.darkness)
it.render(batch, 0f, 0f) // TODO parallax
}
}
batch.color = Color.WHITE
}
private val parallaxDomainSize = 400f

View File

@@ -10,7 +10,7 @@ import com.badlogic.gdx.utils.Disposable
abstract class WeatherObject : Disposable {
/** vec3(posX, posY, scale) */
var pos: Vector3 = Vector3()
var pos: Vector3 = Vector3(0f, 0f, 1f)
var posX: Float
get() = pos.x
@@ -18,9 +18,10 @@ abstract class WeatherObject : Disposable {
var posY: Float
get() = pos.y
set(value) { pos.y = value }
var scale: Float
var posZ: Float
get() = pos.z
set(value) { pos.z = value }
var scale: Float = 1f
var flagToDespawn = false

View File

@@ -4,12 +4,13 @@ import com.badlogic.gdx.graphics.g2d.SpriteBatch
import com.badlogic.gdx.graphics.g2d.TextureRegion
import com.badlogic.gdx.math.Vector2
import com.badlogic.gdx.math.Vector3
import net.torvald.terrarum.App
import kotlin.math.sign
/**
* Created by minjaesong on 2023-08-21.
*/
class WeatherObjectCloud(private val texture: TextureRegion) : WeatherObject() {
class WeatherObjectCloud(private val texture: TextureRegion, private val flipW: Boolean) : WeatherObject() {
/**
* To actually utilise this value, your render code must begin the spritebatch per-object, like so:
@@ -32,8 +33,8 @@ class WeatherObjectCloud(private val texture: TextureRegion) : WeatherObject() {
* Resulting vector: (x + dX, y + dY, scale * dScale)
*/
fun update(flowVector: Vector3, gait: Float) {
posX += flowVector.x * gait * scale * scale
posY += flowVector.y * gait * scale * scale
posX += flowVector.x * gait * scale
posY += flowVector.y * gait * scale
scale *= flowVector.z
}
@@ -44,8 +45,18 @@ class WeatherObjectCloud(private val texture: TextureRegion) : WeatherObject() {
override fun render(batch: SpriteBatch, offsetX: Float, offsetY: Float) {
val x = posX + offsetX - texture.regionWidth * scale * 0.5f
val y = posY + offsetY - texture.regionHeight * scale
val z = posZ // must be at least 1.0
val w = App.scr.halfwf
val h = App.scr.halfhf // 50% to the screen height, or 35%?
batch.draw(texture, x, y, texture.regionWidth * scale, texture.regionHeight * scale)
val drawX = (x + w * (z-1)) / z
val drawY = (y + h * (z-1)) / z
val drawScale = scale / z
if (flipW)
batch.draw(texture, drawX + texture.regionWidth / z, drawY, -texture.regionWidth * drawScale, texture.regionHeight * drawScale)
else
batch.draw(texture, drawX, drawY, texture.regionWidth * drawScale, texture.regionHeight * drawScale)
}
override fun dispose() { /* cloud texture will be disposed of by the WeatherMixer */ }