From df1b3dc680fa0324d8f0455901006583b1cee2da Mon Sep 17 00:00:00 2001 From: minjaesong Date: Fri, 10 Dec 2021 23:22:13 +0900 Subject: [PATCH] using weaker and faster fullscreen blurring; this is a style choice --- assets/shaders/boxdown.frag | 31 +++++ assets/shaders/boxup.frag | 31 +++++ .../terrarum/modulebasegame/IngameRenderer.kt | 111 +++++------------- src/net/torvald/terrarum/ui/Toolkit.kt | 110 +++++++++++------ 4 files changed, 166 insertions(+), 117 deletions(-) create mode 100644 assets/shaders/boxdown.frag create mode 100644 assets/shaders/boxup.frag diff --git a/assets/shaders/boxdown.frag b/assets/shaders/boxdown.frag new file mode 100644 index 000000000..6d1e1b777 --- /dev/null +++ b/assets/shaders/boxdown.frag @@ -0,0 +1,31 @@ +#version 120 +#ifdef GL_ES + precision mediump float; +#endif + +varying vec4 v_color; +varying vec2 v_texCoords; +uniform sampler2D u_texture; + +// recommended value: n / vec2(fbo_width, fbo_height) where n is something like {0.5, 1, 2, 4, ... } +// that, or simply 0.5, depending on how your uv coord works +uniform vec2 halfpixel = vec2(0.0, 0.0); + +vec2 doublex = vec2(2.0, 0.0); +vec2 doubley = vec2(0.0, 2.0); +vec2 twister = vec2(1.0, -1.0); +vec2 boolean = vec2(1.0, 0.0); + +void main() { + vec4 sum = texture2D(u_texture, v_texCoords) + + texture2D(u_texture, v_texCoords + halfpixel) + + texture2D(u_texture, v_texCoords - halfpixel) + + texture2D(u_texture, v_texCoords + halfpixel * twister) + + texture2D(u_texture, v_texCoords - halfpixel * twister) + + texture2D(u_texture, v_texCoords + halfpixel * boolean.xy) + + texture2D(u_texture, v_texCoords - halfpixel * boolean.xy) + + texture2D(u_texture, v_texCoords + halfpixel * boolean.yx) + + texture2D(u_texture, v_texCoords - halfpixel * boolean.yx) ; + + gl_FragColor = sum / 9.0; +} \ No newline at end of file diff --git a/assets/shaders/boxup.frag b/assets/shaders/boxup.frag new file mode 100644 index 000000000..6d1e1b777 --- /dev/null +++ b/assets/shaders/boxup.frag @@ -0,0 +1,31 @@ +#version 120 +#ifdef GL_ES + precision mediump float; +#endif + +varying vec4 v_color; +varying vec2 v_texCoords; +uniform sampler2D u_texture; + +// recommended value: n / vec2(fbo_width, fbo_height) where n is something like {0.5, 1, 2, 4, ... } +// that, or simply 0.5, depending on how your uv coord works +uniform vec2 halfpixel = vec2(0.0, 0.0); + +vec2 doublex = vec2(2.0, 0.0); +vec2 doubley = vec2(0.0, 2.0); +vec2 twister = vec2(1.0, -1.0); +vec2 boolean = vec2(1.0, 0.0); + +void main() { + vec4 sum = texture2D(u_texture, v_texCoords) + + texture2D(u_texture, v_texCoords + halfpixel) + + texture2D(u_texture, v_texCoords - halfpixel) + + texture2D(u_texture, v_texCoords + halfpixel * twister) + + texture2D(u_texture, v_texCoords - halfpixel * twister) + + texture2D(u_texture, v_texCoords + halfpixel * boolean.xy) + + texture2D(u_texture, v_texCoords - halfpixel * boolean.xy) + + texture2D(u_texture, v_texCoords + halfpixel * boolean.yx) + + texture2D(u_texture, v_texCoords - halfpixel * boolean.yx) ; + + gl_FragColor = sum / 9.0; +} \ No newline at end of file diff --git a/src/net/torvald/terrarum/modulebasegame/IngameRenderer.kt b/src/net/torvald/terrarum/modulebasegame/IngameRenderer.kt index 65568488a..ac66777a9 100644 --- a/src/net/torvald/terrarum/modulebasegame/IngameRenderer.kt +++ b/src/net/torvald/terrarum/modulebasegame/IngameRenderer.kt @@ -8,10 +8,10 @@ import com.badlogic.gdx.graphics.g2d.TextureRegion import com.badlogic.gdx.graphics.glutils.FrameBuffer import com.badlogic.gdx.graphics.glutils.ShaderProgram import com.badlogic.gdx.utils.Disposable +import com.badlogic.gdx.utils.GdxRuntimeException import net.torvald.random.HQRNG import net.torvald.terrarum.* import net.torvald.terrarum.App.measureDebugTime -import net.torvald.terrarum.App.printdbg import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZEF import net.torvald.terrarum.gameactors.ActorWithBody @@ -677,12 +677,22 @@ object IngameRenderer : Disposable { private const val KAWASE_POWER = 0.667f + private var blurtex0 = Texture(16, 16, Pixmap.Format.RGBA8888) + private var blurtex1 = Texture(16, 16, Pixmap.Format.RGBA8888) + private var blurtex2 = Texture(16, 16, Pixmap.Format.RGBA8888) + private var blurtex3 = Texture(16, 16, Pixmap.Format.RGBA8888) + private var blurtex4 = Texture(16, 16, Pixmap.Format.RGBA8888) + + fun processKawaseBlur(outFbo: FrameBuffer) { + blurtex0.dispose() + // initialise readBuffer with untreated lightmap outFbo.inAction(camera, batch) { - val texture = LightmapRenderer.draw() - texture.bind(0) + blurtex0 = LightmapRenderer.draw() + blurtex0.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear) + blurtex0.bind(0) shaderPassthru.bind() shaderPassthru.setUniformMatrix("u_projTrans", camera.combined) shaderPassthru.setUniformi("u_texture", 0) @@ -690,8 +700,9 @@ object IngameRenderer : Disposable { } fboBlurHalf.inAction(camera, batch) { - val texture = outFbo.colorBufferTexture - texture.bind(0) + blurtex1 = outFbo.colorBufferTexture + blurtex1.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear) + blurtex1.bind(0) shaderKawaseDown.bind() shaderKawaseDown.setUniformMatrix("u_projTrans", camera.combined) shaderKawaseDown.setUniformi("u_texture", 0) @@ -700,8 +711,9 @@ object IngameRenderer : Disposable { } fboBlurQuarter.inAction(camera, batch) { - val texture = fboBlurHalf.colorBufferTexture - texture.bind(0) + blurtex2 = fboBlurHalf.colorBufferTexture + blurtex2.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear) + blurtex2.bind(0) shaderKawaseDown.bind() shaderKawaseDown.setUniformMatrix("u_projTrans", camera.combined) shaderKawaseDown.setUniformi("u_texture", 0) @@ -710,8 +722,9 @@ object IngameRenderer : Disposable { } fboBlurHalf.inAction(camera, batch) { - val texture = fboBlurQuarter.colorBufferTexture - texture.bind(0) + blurtex3 = fboBlurQuarter.colorBufferTexture + blurtex3.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear) + blurtex3.bind(0) shaderKawaseUp.bind() shaderKawaseUp.setUniformMatrix("u_projTrans", camera.combined) shaderKawaseUp.setUniformi("u_texture", 0) @@ -721,8 +734,8 @@ object IngameRenderer : Disposable { // TODO apply dithering on this specific draw call outFbo.inAction(camera, batch) { - val texture = fboBlurHalf.colorBufferTexture - texture.bind(0) + blurtex4 = fboBlurHalf.colorBufferTexture + blurtex4.bind(0) shaderKawaseUp.bind() shaderKawaseUp.setUniformMatrix("u_projTrans", camera.combined) shaderKawaseUp.setUniformi("u_texture", 0) @@ -732,76 +745,6 @@ object IngameRenderer : Disposable { } - fun processNoBlur() { - lightmapFboB.inAction(camera, batch) { - val texture = LightmapRenderer.draw() - texture.bind(0) - - shaderPassthru.bind() - shaderPassthru.setUniformMatrix("u_projTrans", camera.combined) - shaderPassthru.setUniformi("u_texture", 0) - blurWriteQuad.render(shaderPassthru, GL20.GL_TRIANGLES) - } - } - - fun processBlur(lightmapFboA: FrameBuffer, lightmapFboB: FrameBuffer) { - var blurWriteBuffer = lightmapFboA - var blurReadBuffer = lightmapFboB - - - // buffers must be cleared beforehand - - - // initialise readBuffer with untreated lightmap - blurReadBuffer.inAction(camera, batch) { - val texture = LightmapRenderer.draw() - texture.bind(0) - - shaderPassthru.bind() - shaderPassthru.setUniformMatrix("u_projTrans", camera.combined) - shaderPassthru.setUniformi("u_texture", 0) - blurWriteQuad.render(shaderPassthru, GL20.GL_TRIANGLES) - } - - // do blurring - for (i in 0 until 4) { - val blurRadius = (4f / lightmapDownsample) * (1 shl i.ushr(1)) - - blurWriteBuffer.inAction(camera, batch) { - - - blurTex.texture = blurReadBuffer.colorBufferTexture - blurTex.texture.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear) - blurTex.texture.bind(0) - App.getCurrentDitherTex().bind(1) // order is important! - - shaderBlur.bind() - shaderBlur.setUniformMatrix("u_projTrans", camera.combined) - shaderBlur.setUniformi("rnd", rng.nextInt(8192), rng.nextInt(8192)) - shaderBlur.setUniformi("u_pattern", 1) - shaderBlur.setUniformi("u_texture", 0) - shaderBlur.setUniformf("iResolution", - blurWriteBuffer.width.toFloat(), blurWriteBuffer.height.toFloat()) - shaderBlur.setUniformf("flip", 1f) - if (i % 2 == 0) - shaderBlur.setUniformf("direction", blurRadius, 0f) - else - shaderBlur.setUniformf("direction", 0f, blurRadius) - blurWriteQuad.render(shaderBlur, GL20.GL_TRIANGLES) - - - // swap - val t = blurWriteBuffer - blurWriteBuffer = blurReadBuffer - blurReadBuffer = t - } - } - - - - blendNormal(batch) - } - private var init = false fun resize(width: Int, height: Int) { @@ -914,6 +857,12 @@ object IngameRenderer : Disposable { lightmapFboA.dispose() lightmapFboB.dispose() + try { blurtex0.dispose() } catch (e: GdxRuntimeException) {} +// try { blurtex1.dispose() } catch (e: GdxRuntimeException) {} +// try { blurtex2.dispose() } catch (e: GdxRuntimeException) {} +// try { blurtex3.dispose() } catch (e: GdxRuntimeException) {} +// try { blurtex4.dispose() } catch (e: GdxRuntimeException) {} + fboBlurHalf.dispose() fboBlurQuarter.dispose() diff --git a/src/net/torvald/terrarum/ui/Toolkit.kt b/src/net/torvald/terrarum/ui/Toolkit.kt index 51e905b78..4752893c5 100644 --- a/src/net/torvald/terrarum/ui/Toolkit.kt +++ b/src/net/torvald/terrarum/ui/Toolkit.kt @@ -6,14 +6,10 @@ import com.badlogic.gdx.graphics.g2d.SpriteBatch import com.badlogic.gdx.graphics.g2d.TextureRegion import com.badlogic.gdx.graphics.glutils.FrameBuffer import com.badlogic.gdx.utils.Disposable -import com.badlogic.gdx.utils.GdxRuntimeException -import com.badlogic.gdx.utils.ScreenUtils import net.torvald.random.HQRNG import net.torvald.terrarum.App -import net.torvald.terrarum.App.printdbg import net.torvald.terrarum.CommonResourcePool import net.torvald.terrarum.inAction -import net.torvald.terrarum.modulebasegame.IngameRenderer import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack import org.lwjgl.opengl.GL20 @@ -35,8 +31,8 @@ object Toolkit : Disposable { } - private val shaderKawaseDown = App.loadShaderFromFile("assets/shaders/4096.vert", "assets/shaders/kawasedown.frag") - private val shaderKawaseUp = App.loadShaderFromFile("assets/shaders/4096.vert", "assets/shaders/kawaseup.frag") + private val shaderKawaseDown = App.loadShaderFromFile("assets/shaders/4096.vert", "assets/shaders/boxdown.frag") + private val shaderKawaseUp = App.loadShaderFromFile("assets/shaders/4096.vert", "assets/shaders/boxup.frag") private lateinit var fboBlur: FrameBuffer private lateinit var fboBlurHalf: FrameBuffer @@ -80,7 +76,10 @@ object Toolkit : Disposable { shaderKawaseUp.dispose() shaderKawaseDown.dispose() - try { blurIntexture.dispose() } catch (e: GdxRuntimeException) {} +// try { blurtex0.dispose() } catch (e: GdxRuntimeException) {} +// try { blurtex1.dispose() } catch (e: GdxRuntimeException) {} +// try { blurtex2.dispose() } catch (e: GdxRuntimeException) {} +// try { blurtex3.dispose() } catch (e: GdxRuntimeException) {} } val drawWidth: Int @@ -152,17 +151,31 @@ object Toolkit : Disposable { } - private var blurIntexture = Texture(16, 16, Pixmap.Format.RGBA8888) +// private var blurtex0 = Texture(16, 16, Pixmap.Format.RGBA8888) + private var blurtex1 = Texture(16, 16, Pixmap.Format.RGBA8888) + private var blurtex2 = Texture(16, 16, Pixmap.Format.RGBA8888) + private var blurtex3 = Texture(16, 16, Pixmap.Format.RGBA8888) fun blurEntireScreen(batch: SpriteBatch, camera: OrthographicCamera, blurRadius0: Float, x: Int, y: Int, w: Int, h: Int) { - batch.end() - val blurRadius = blurRadius0 * 2f - blurIntexture = Texture(Pixmap.createFromFrameBuffer(x, y, w, h)) + val blurRadius = blurRadius0 - fboBlurHalf.inAction(camera, batch) { - blurIntexture.bind(0) +// blurtex0.dispose() +// blurtex1.dispose() +// blurtex2.dispose() +// blurtex3.dispose() + + + + val pixmap = Pixmap.createFromFrameBuffer(x, y, w, h) + val texture: Texture = Texture(pixmap) + val t = TextureRegion(texture, 0, h, w, -h) + pixmap.dispose() + + + /*fboBlurHalf.inAction(camera, batch) { + t.texture.bind(0) shaderKawaseDown.bind() shaderKawaseDown.setUniformMatrix("u_projTrans", camera.combined) shaderKawaseDown.setUniformi("u_texture", 0) @@ -171,8 +184,8 @@ object Toolkit : Disposable { } fboBlurQuarter.inAction(camera, batch) { - val texture = fboBlurHalf.colorBufferTexture - texture.bind(0) + blurtex1 = fboBlurHalf.colorBufferTexture + blurtex1.bind(0) shaderKawaseDown.bind() shaderKawaseDown.setUniformMatrix("u_projTrans", camera.combined) shaderKawaseDown.setUniformi("u_texture", 0) @@ -181,8 +194,8 @@ object Toolkit : Disposable { } fboBlurHalf.inAction(camera, batch) { - val texture = fboBlurQuarter.colorBufferTexture - texture.bind(0) + blurtex2 = fboBlurQuarter.colorBufferTexture + blurtex2.bind(0) shaderKawaseUp.bind() shaderKawaseUp.setUniformMatrix("u_projTrans", camera.combined) shaderKawaseUp.setUniformi("u_texture", 0) @@ -192,8 +205,30 @@ object Toolkit : Disposable { // TODO apply dithering on this specific draw call fboBlur.inAction(camera, batch) { - val texture = fboBlurHalf.colorBufferTexture - texture.bind(0) + blurtex3 = fboBlurHalf.colorBufferTexture + blurtex3.bind(0) + shaderKawaseUp.bind() + shaderKawaseUp.setUniformMatrix("u_projTrans", camera.combined) + shaderKawaseUp.setUniformi("u_texture", 0) + shaderKawaseUp.setUniformf("halfpixel", blurRadius / fboBlurHalf.width, blurRadius / fboBlurHalf.height) + blurWriteQuad.render(shaderKawaseUp, GL20.GL_TRIANGLES) + }*/ + + + fboBlurHalf.inAction(camera, batch) { + t.texture.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear) + t.texture.bind(0) + shaderKawaseDown.bind() + shaderKawaseDown.setUniformMatrix("u_projTrans", camera.combined) + shaderKawaseDown.setUniformi("u_texture", 0) + shaderKawaseDown.setUniformf("halfpixel", blurRadius / fboBlurHalf.width, blurRadius / fboBlurHalf.height) + blurWriteQuad2.render(shaderKawaseDown, GL20.GL_TRIANGLES) + } + + fboBlur.inAction(camera, batch) { + blurtex3 = fboBlurHalf.colorBufferTexture + blurtex3.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear) + blurtex3.bind(0) shaderKawaseUp.bind() shaderKawaseUp.setUniformMatrix("u_projTrans", camera.combined) shaderKawaseUp.setUniformi("u_texture", 0) @@ -201,13 +236,13 @@ object Toolkit : Disposable { blurWriteQuad.render(shaderKawaseUp, GL20.GL_TRIANGLES) } + t.texture.dispose() - blurIntexture.dispose() Gdx.gl.glActiveTexture(GL20.GL_TEXTURE0) // so that batch that comes next will bind any tex to it batch.begin() batch.shader = null - batch.draw(fboBlur.colorBufferTexture, x.toFloat(), y.toFloat(), w.toFloat(), h.toFloat()) + batch.draw(fboBlur.colorBufferTexture, x.toFloat(), y.toFloat()) } fun drawBaloon(batch: SpriteBatch, x: Float, y: Float, w: Float, h: Float) { @@ -264,44 +299,47 @@ object Toolkit : Disposable { VertexAttribute.TexCoords(0) ) + val fw = App.scr.width//MathUtils.nextPowerOfTwo(App.scr.width) + val fh = App.scr.height//MathUtils.nextPowerOfTwo(App.scr.height) + fboBlur = FrameBuffer( Pixmap.Format.RGBA8888, - App.scr.width, - App.scr.height, + fw, + fh, true ) fboBlurHalf = FrameBuffer( Pixmap.Format.RGBA8888, - App.scr.width / 2, - App.scr.height / 2, + fw / 2, + fh / 2, true ) fboBlurQuarter = FrameBuffer( Pixmap.Format.RGBA8888, - App.scr.width / 4, - App.scr.height / 4, + fw / 4, + fh / 4, true ) blurWriteQuad.setVertices(floatArrayOf( 0f,0f,0f, 1f,1f,1f,1f, 0f,1f, - App.scr.width.toFloat(),0f,0f, 1f,1f,1f,1f, 1f,1f, - App.scr.width.toFloat(), App.scr.height.toFloat(),0f, 1f,1f,1f,1f, 1f,0f, - 0f, App.scr.height.toFloat(),0f, 1f,1f,1f,1f, 0f,0f)) + fw.toFloat(),0f,0f, 1f,1f,1f,1f, 1f,1f, + fw.toFloat(), fh.toFloat(),0f, 1f,1f,1f,1f, 1f,0f, + 0f, fh.toFloat(),0f, 1f,1f,1f,1f, 0f,0f)) blurWriteQuad.setIndices(shortArrayOf(0, 1, 2, 2, 3, 0)) blurWriteQuad2.setVertices(floatArrayOf( 0f,0f,0f, 1f,1f,1f,1f, 0f,1f, - App.scr.width.div(2).toFloat(),0f,0f, 1f,1f,1f,1f, 1f,1f, - App.scr.width.div(2).toFloat(), App.scr.height.div(2).toFloat(),0f, 1f,1f,1f,1f, 1f,0f, - 0f, App.scr.height.div(2).toFloat(),0f, 1f,1f,1f,1f, 0f,0f)) + fw.div(2).toFloat(),0f,0f, 1f,1f,1f,1f, 1f,1f, + fw.div(2).toFloat(), fh.div(2).toFloat(),0f, 1f,1f,1f,1f, 1f,0f, + 0f, fh.div(2).toFloat(),0f, 1f,1f,1f,1f, 0f,0f)) blurWriteQuad2.setIndices(shortArrayOf(0, 1, 2, 2, 3, 0)) blurWriteQuad4.setVertices(floatArrayOf( 0f,0f,0f, 1f,1f,1f,1f, 0f,1f, - App.scr.width.div(4).toFloat(),0f,0f, 1f,1f,1f,1f, 1f,1f, - App.scr.width.div(4).toFloat(), App.scr.height.div(4).toFloat(),0f, 1f,1f,1f,1f, 1f,0f, - 0f, App.scr.height.div(4).toFloat(),0f, 1f,1f,1f,1f, 0f,0f)) + fw.div(4).toFloat(),0f,0f, 1f,1f,1f,1f, 1f,1f, + fw.div(4).toFloat(), fh.div(4).toFloat(),0f, 1f,1f,1f,1f, 1f,0f, + 0f, fh.div(4).toFloat(),0f, 1f,1f,1f,1f, 0f,0f)) blurWriteQuad4.setIndices(shortArrayOf(0, 1, 2, 2, 3, 0)) } } \ No newline at end of file