Ladies and Gents, we have shader-powered smooth lighting!

This commit is contained in:
minjaesong
2017-07-05 02:20:10 +09:00
parent f5d229105c
commit 4d04aadc58
3 changed files with 49 additions and 140 deletions

View File

@@ -371,8 +371,6 @@ class StateInGameGDX(val batch: SpriteBatch) : Screen {
} }
val testTex = Texture("assets/test_texture.tga")
private fun renderGame(batch: SpriteBatch) { private fun renderGame(batch: SpriteBatch) {
Gdx.gl.glClearColor(.157f, .157f, .157f, 0f) Gdx.gl.glClearColor(.157f, .157f, .157f, 0f)
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT) Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT)
@@ -397,8 +395,8 @@ class StateInGameGDX(val batch: SpriteBatch) : Screen {
/////////////////// ///////////////////
// blur lightmap // // blur lightmap //
/////////////////// ///////////////////
val blurIterations = 16 // ideally, 4 * radius; must be even number -- odd number will flip the image val blurIterations = 5 // ideally, 4 * radius; must be even/odd number -- odd/even number will flip the image
val blurRadius = 4f val blurRadius = 4f // (5, 4f); using low numbers for pixel-y aesthetics
@@ -418,8 +416,6 @@ class StateInGameGDX(val batch: SpriteBatch) : Screen {
var blurReadBuffer = lightmapFboB var blurReadBuffer = lightmapFboB
KeyToggler.forceSet(Input.Keys.F6, false)
KeyToggler.forceSet(Input.Keys.F7, true)
// initialise readBuffer with untreated lightmap // initialise readBuffer with untreated lightmap
@@ -433,54 +429,44 @@ class StateInGameGDX(val batch: SpriteBatch) : Screen {
blendNormal() blendNormal()
batch.color = Color.WHITE batch.color = Color.WHITE
//LightmapRenderer.draw(batch) LightmapRenderer.draw(batch)
batch.draw(testTex, 0f, 0f)
} }
} }
if (TerrarumGDX.getConfigBoolean("smoothlighting")) {
for (i in 0..blurIterations - 1) {
blurWriteBuffer.inAction(camera, batch) {
for (i in 0..blurIterations - 1) { batch.inUse {
blurWriteBuffer.inAction(camera, batch) { val texture = blurReadBuffer.colorBufferTexture
batch.inUse { texture.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear)
val texture = if (i == 0)
testTex
else
blurReadBuffer.colorBufferTexture
texture.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear)
batch.shader = TerrarumGDX.shaderBlur batch.shader = TerrarumGDX.shaderBlur
batch.shader.setUniformf("iResolution", blurWriteBuffer.width.toFloat(), blurWriteBuffer.height.toFloat()) batch.shader.setUniformf("iResolution", blurWriteBuffer.width.toFloat(), blurWriteBuffer.height.toFloat())
batch.shader.setUniformf("flip", 1f) batch.shader.setUniformf("flip", 1f)
if (i % 2 == 0) if (i % 2 == 0)
batch.shader.setUniformf("direction", blurRadius, 0f) batch.shader.setUniformf("direction", blurRadius, 0f)
else else
batch.shader.setUniformf("direction", 0f, blurRadius) batch.shader.setUniformf("direction", 0f, blurRadius)
batch.color = Color.WHITE batch.color = Color.WHITE
batch.draw(texture, 0f, 0f) batch.draw(texture, 0f, 0f)
// swap // swap
val t = blurWriteBuffer val t = blurWriteBuffer
blurWriteBuffer = blurReadBuffer blurWriteBuffer = blurReadBuffer
blurReadBuffer = t blurReadBuffer = t
}
} }
} }
} }
else {
blurWriteBuffer = blurReadBuffer
// TEST: passthru to writeBuffer }
/*blurWriteBuffer.inAction(camera, batch) {
batch.inUse {
batch.color = Color.WHITE
batch.draw(testTex, 0f, 0f)
}
}*/
@@ -536,13 +522,10 @@ class StateInGameGDX(val batch: SpriteBatch) : Screen {
setCameraPosition(0f, 0f) setCameraPosition(0f, 0f)
val lightTex = blurWriteBuffer.colorBufferTexture // TODO zoom! val lightTex = blurWriteBuffer.colorBufferTexture // TODO zoom!
if (KeyToggler.isOn(Input.Keys.F7)) blendNormal() if (KeyToggler.isOn(KEY_LIGHTMAP_RENDER)) blendNormal()
else blendMul() else blendMul()
batch.color = Color.WHITE batch.color = Color.WHITE
//batch.draw(lightTex, 0f, 0f, lightTex.width * lightmapDownsample, lightTex.height * lightmapDownsample) batch.draw(lightTex, 0f, 0f, lightTex.width * lightmapDownsample, lightTex.height * lightmapDownsample)
TerrarumGDX.fontGame.draw(batch, "Thumbnail:", 100f, 80f)
batch.draw(lightTex, 100f, 100f, 100f, 100f)
} }

View File

@@ -43,9 +43,9 @@ fun main(args: Array<String>) {
config.foregroundFPS = TerrarumGDX.RENDER_FPS config.foregroundFPS = TerrarumGDX.RENDER_FPS
config.backgroundFPS = TerrarumGDX.RENDER_FPS config.backgroundFPS = TerrarumGDX.RENDER_FPS
//config.vSyncEnabled = true //config.vSyncEnabled = true
config.resizable = false config.resizable = true
config.width = 512//1072 config.width = 1072
config.height = 512//742 config.height = 742
config.backgroundFPS = 9999 config.backgroundFPS = 9999
config.foregroundFPS = 9999 config.foregroundFPS = 9999
//config.useGL30 = true //config.useGL30 = true

View File

@@ -335,106 +335,32 @@ object LightmapRenderer {
// loop x // loop x
var x = this_x_start var x = this_x_start
while (x < this_x_end) { while (x < this_x_end) {
// smoothing enabled and zoom is 0.75 or greater try {
// (zoom of 0.5 should not smoothed, for performance) val thisLightLevel = getLightForOpaque(x, y)
if (false && //TerrarumGDX.getConfigBoolean("smoothlighting") &&
TerrarumGDX.ingame!!.screenZoom >= 0.75) {
val thisLightLevel = getLightForOpaque(x, y) ?: 0 // coalesce identical intensity blocks to one
var sameLevelCounter = 1
if (x < this_x_end && thisLightLevel == 0 while (getLightForOpaque(x + sameLevelCounter, y) == thisLightLevel) {
&& getLightForOpaque(x, y - 1) == 0) { sameLevelCounter += 1
try {
// coalesce zero intensity blocks to one
var zeroLevelCounter = 1
while (getLightForOpaque(x + zeroLevelCounter, y) == 0) {
zeroLevelCounter += 1
if (x + zeroLevelCounter >= this_x_end) break
}
batch.color = Color.BLACK
batch.fillRect(
(x.toFloat() * TILE_SIZE).round().toFloat(),
(y.toFloat() * TILE_SIZE).round().toFloat(),
(TILE_SIZE * zeroLevelCounter).toFloat(),
(TILE_SIZE).toFloat()
)
x += zeroLevelCounter - 1
}
catch (e: ArrayIndexOutOfBoundsException) {
// do nothing
}
if (x + sameLevelCounter >= this_x_end) break
} }
else {
/** a
* +-+-+
* |i|j|
* b +-+-+ c
* |k|l|
* +-+-+
* d
*/
val a = thisLightLevel maxBlend (getLightForOpaque(x, y - 1) ?: thisLightLevel)
val d = thisLightLevel maxBlend (getLightForOpaque(x, y + 1) ?: thisLightLevel)
val b = thisLightLevel maxBlend (getLightForOpaque(x - 1, y) ?: thisLightLevel)
val c = thisLightLevel maxBlend (getLightForOpaque(x + 1, y) ?: thisLightLevel)
val colourMapItoL = IntArray(4) batch.color = (getLightForOpaque(x, y) ?: 0).normaliseToColourHDR()
val colMean = (a linMix d) linMix (b linMix c) batch.fillRect(
val colDelta = thisLightLevel colSub colMean (x * DRAW_TILE_SIZE).round().toFloat(),
(y * DRAW_TILE_SIZE).round().toFloat(),
(DRAW_TILE_SIZE.ceil() * sameLevelCounter).toFloat(),
DRAW_TILE_SIZE.ceil().toFloat()
)
colourMapItoL[0] = a linMix b colAdd colDelta x += sameLevelCounter - 1
colourMapItoL[1] = a linMix c colAdd colDelta
colourMapItoL[2] = b linMix d colAdd colDelta
colourMapItoL[3] = c linMix d colAdd colDelta
for (iy in 0..1) {
for (ix in 0..1) {
batch.color = colourMapItoL[iy * 2 + ix].normaliseToColourHDR()
batch.fillRect(
(x.toFloat() * TILE_SIZE).round()
+ ix * TILE_SIZE / 2f,
(y.toFloat() * TILE_SIZE).round()
+ iy * TILE_SIZE / 2f,
(TILE_SIZE / 2f).ceil().toFloat(),
(TILE_SIZE / 2f).ceil().toFloat()
)
}
}
}
} }
// smoothing disabled catch (e: ArrayIndexOutOfBoundsException) {
else { // do nothing
try {
val thisLightLevel = getLightForOpaque(x, y)
// coalesce identical intensity blocks to one
var sameLevelCounter = 1
while (getLightForOpaque(x + sameLevelCounter, y) == thisLightLevel) {
sameLevelCounter += 1
if (x + sameLevelCounter >= this_x_end) break
}
batch.color = (getLightForOpaque(x, y) ?: 0).normaliseToColourHDR()
batch.fillRect(
(x * DRAW_TILE_SIZE).round().toFloat(),
(y * DRAW_TILE_SIZE).round().toFloat(),
(DRAW_TILE_SIZE.ceil() * sameLevelCounter).toFloat(),
DRAW_TILE_SIZE.ceil().toFloat()
)
x += sameLevelCounter - 1
}
catch (e: ArrayIndexOutOfBoundsException) {
// do nothing
}
} }
x++ x++
} }
} }