From b5da05c9a0a59ff811ae6a31f7dfa72fff6fa61b Mon Sep 17 00:00:00 2001 From: minjaesong Date: Wed, 29 Apr 2020 08:47:27 +0900 Subject: [PATCH] both idea works --- .../terrarum/tests/WorldgenNoiseSandbox.kt | 32 +++++++++++++------ 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/src/net/torvald/terrarum/tests/WorldgenNoiseSandbox.kt b/src/net/torvald/terrarum/tests/WorldgenNoiseSandbox.kt index f86e9360a..eb5867308 100644 --- a/src/net/torvald/terrarum/tests/WorldgenNoiseSandbox.kt +++ b/src/net/torvald/terrarum/tests/WorldgenNoiseSandbox.kt @@ -44,8 +44,6 @@ class WorldgenNoiseSandbox : ApplicationAdapter() { private lateinit var testTex: Pixmap private lateinit var tempTex: Texture - private lateinit var joise: List - private val RNG = HQRNG() private var seed = 10000L @@ -76,7 +74,6 @@ class WorldgenNoiseSandbox : ApplicationAdapter() { override fun render() { if (!initialGenDone) { - joise = getNoiseGenerator(seed) renderNoise() } @@ -91,7 +88,6 @@ class WorldgenNoiseSandbox : ApplicationAdapter() { if (!generateKeyLatched && Gdx.input.isKeyPressed(Input.Keys.SPACE)) { generateKeyLatched = true seed = RNG.nextLong() - joise = getNoiseGenerator(seed) renderNoise() } @@ -161,8 +157,8 @@ class WorldgenNoiseSandbox : ApplicationAdapter() { } } - //private val xSlices = (0 until WIDTH).sliceEvenly(ThreadExecutor.threadCount) - private val xSlices = (0 until WIDTH).sliceEvenly(WIDTH / 8) + private val xSlices = (0 until WIDTH).sliceEvenly(ThreadExecutor.threadCount) + //private val xSlices = (0 until WIDTH).sliceEvenly(WIDTH / 8) private val runs = (0 until WIDTH).map { x -> (x until WIDTH * HEIGHT step WIDTH) }.flatten() @@ -179,6 +175,8 @@ class WorldgenNoiseSandbox : ApplicationAdapter() { testColSet.shuffle() testColSet2.shuffle() + // render noisemap to pixmap + /* I've got two ideas to resolve noisy artefact when noise generation runs concurrently: @@ -186,13 +184,13 @@ class WorldgenNoiseSandbox : ApplicationAdapter() { 2) 1 thread has its own copy of Joise (threads have different INSTANCEs of Joise with same params) Method 1) seemingly works but may break if the operation is more complex - Method 2) needs testing + Method 2) also works --CuriousTorvald, 2020-04-29 */ - // render noisemap to pixmap - // 0. naive coucurrent approach + // 0. naive concurrent approach + // CULPRIT: one global instance of Joise that all the threads try to access (and modify local variables) at the same time /*val runnables: List = xSlices.map { range -> { for (x in range) { @@ -209,6 +207,7 @@ class WorldgenNoiseSandbox : ApplicationAdapter() { }*/ // 1. stupid one-block-is-one-coroutine approach (seemingly works?) + /*val joise = getNoiseGenerator(seed) val runnables: List = runs.map { i -> { val (x, y) = (i % WIDTH) to (i / WIDTH) val sampleTheta = (x.toDouble() / WIDTH) * TWO_PI @@ -217,6 +216,21 @@ class WorldgenNoiseSandbox : ApplicationAdapter() { val sampleY = y.toDouble() NOISE_MAKER.draw(x, y, joise.map { it.get(sampleX, sampleY, sampleZ) }, testTex) + } }*/ + + // 2. each runner gets their own copy of Joise + val runnables: List = xSlices.map { range -> { + val localJoise = getNoiseGenerator(seed) + for (x in range) { + for (y in 0 until HEIGHT) { + val sampleTheta = (x.toDouble() / WIDTH) * TWO_PI + val sampleX = sin(sampleTheta) * sampleOffset + sampleOffset // plus sampleOffset to make only + val sampleZ = cos(sampleTheta) * sampleOffset + sampleOffset // positive points are to be sampled + val sampleY = y.toDouble() + + NOISE_MAKER.draw(x, y, localJoise.map { it.get(sampleX, sampleY, sampleZ) }, testTex) + } + } } }