From e04d0284bbf5cbbfc9650ab719e1b11b465597de Mon Sep 17 00:00:00 2001 From: minjaesong Date: Tue, 25 Jul 2023 22:11:10 +0900 Subject: [PATCH] another experiments with the hosek model --- src/net/torvald/parametricsky/Application.kt | 58 +++++++++++++------- 1 file changed, 39 insertions(+), 19 deletions(-) diff --git a/src/net/torvald/parametricsky/Application.kt b/src/net/torvald/parametricsky/Application.kt index 3565ce279..c399c38db 100644 --- a/src/net/torvald/parametricsky/Application.kt +++ b/src/net/torvald/parametricsky/Application.kt @@ -23,10 +23,12 @@ import java.awt.Dimension import java.awt.FlowLayout import java.awt.GridLayout import javax.swing.* -import kotlin.math.E -import kotlin.math.PI -import kotlin.math.pow -import kotlin.math.roundToInt +import kotlin.math.* + + +val INITIAL_TURBIDITY = 4.0 +val INITIAL_ALBEDO = 0.1 +val INITIAL_ELEV = 0.0 /** @@ -64,9 +66,9 @@ class Application(val WIDTH: Int, val HEIGHT: Int) : Game() { private lateinit var oneScreen: Pixmap private lateinit var batch: SpriteBatch - var turbidity = 2.0 - var albedo = 0.1 - var elevation = Math.toRadians(45.0) + var turbidity = INITIAL_TURBIDITY + var albedo = INITIAL_ALBEDO + var elevation = Math.toRadians(INITIAL_ELEV) var solarBearing = Math.toRadians(90.0) var cameraHeading = Math.toRadians(90.0) @@ -79,13 +81,19 @@ class Application(val WIDTH: Int, val HEIGHT: Int) : Game() { super.setScreen(screen) } + var model = ArHosekSkyModel.arhosek_xyz_skymodelstate_alloc_init(turbidity, albedo, elevation.abs()) + + fun regenerateModel() { + model = ArHosekSkyModel.arhosek_xyz_skymodelstate_alloc_init(turbidity, albedo, elevation.abs()) + } + override fun render() { Gdx.graphics.setTitle("Daylight Model $EMDASH F: ${Gdx.graphics.framesPerSecond}") if (turbidity <= 0) throw IllegalStateException() // we need to use different model-state to accommodate different albedo for each spectral band but oh well... - genTexLoop(ArHosekSkyModel.arhosek_xyz_skymodelstate_alloc_init(turbidity, albedo, elevation.abs())) + genTexLoop(model) val tex = Texture(oneScreen) @@ -117,8 +125,8 @@ class Application(val WIDTH: Int, val HEIGHT: Int) : Game() { oneScreen.dispose() } - val outTexWidth = 2 - val outTexHeight = 64 + val outTexWidth = 1 + val outTexHeight = 256 private fun Float.scaleFun() = (1f - 1f / 2f.pow(this/6f)) * 0.97f @@ -146,6 +154,8 @@ class Application(val WIDTH: Int, val HEIGHT: Int) : Game() { } } + private fun Double.mapCircle() = sin(HALF_PI * this) + /** * Generated texture is as if you took the panorama picture of sky: up 70deg to horizon, east-south-west; * with sun not moving (sun is at exact south, sun's height is adjustable) @@ -163,14 +173,21 @@ class Application(val WIDTH: Int, val HEIGHT: Int) : Game() { val ys = ArrayList() val ys2 = ArrayList() - for (x in 0 until oneScreen.width) { -// val elevation = Math.toRadians((x.toDouble() / oneScreen.width * 2.0 - 1.0) * 75) -// val state = ArHosekSkyModel.arhosek_xyz_skymodelstate_alloc_init(turbidity, albedo, elevation.abs()) -// val gamma = (x / oneScreen.width.toDouble()) * PI // bearing, where 0 is right at the sun - val gamma = HALF_PI + val halfHeight = oneScreen.height * 0.5 + for (x in 0 until oneScreen.width) { for (y in 0 until oneScreen.height) { - val theta = (y / oneScreen.height.toDouble()) * HALF_PI // vertical angle, where 0 is zenith, ±90 is ground (which is odd) + + // sky-sphere mapping + /*val xf = ((x + 0.5) / oneScreen.width) * 2.0 - 1.0 + val yf = ((y + 0.5) / oneScreen.height) * 2.0 - 1.0 + val gamma = atan2(yf, xf) + PI + val theta = sqrt(xf*xf + yf*yf) * HALF_PI*/ + + // AM-PM mapping (use with WIDTH=1) + val yf = (y * 2.0 / oneScreen.height) % 1.0 + val gamma = if (y < halfHeight) HALF_PI else 3 * HALF_PI + val theta = yf.mapCircle() * HALF_PI @@ -229,22 +246,25 @@ class Application(val WIDTH: Int, val HEIGHT: Int) : Game() { val dialSize = Dimension(45, 20) - val turbidityControl = JSpinner(SpinnerNumberModel(2.0, 1.0, 10.0, 0.1)).also { + val turbidityControl = JSpinner(SpinnerNumberModel(INITIAL_TURBIDITY, 1.0, 10.0, 0.1)).also { it.preferredSize = dialSize it.addChangeListener { _ -> app.turbidity = it.value as Double + app.regenerateModel() } } - val albedoControl = JSpinner(SpinnerNumberModel(0.1, 0.0, 1.0, 0.05)).also { + val albedoControl = JSpinner(SpinnerNumberModel(INITIAL_ALBEDO, 0.0, 1.0, 0.05)).also { it.preferredSize = dialSize it.addChangeListener { _ -> app.albedo = it.value as Double + app.regenerateModel() } } - val elevationControl = JSpinner(SpinnerNumberModel(45.0, -75.0, 75.0, 0.5)).also { + val elevationControl = JSpinner(SpinnerNumberModel(INITIAL_ELEV, -75.0, 75.0, 0.5)).also { it.preferredSize = dialSize it.addChangeListener { _ -> app.elevation = Math.toRadians(it.value as Double) + app.regenerateModel() } } val solarBearing = JSpinner(SpinnerNumberModel(90.0, 0.0, 180.0, 1.0)).also {