From 450129f650db85774f2bdf3788de3cfe49e5588a Mon Sep 17 00:00:00 2001 From: minjaesong Date: Sat, 30 Nov 2024 20:52:52 +0900 Subject: [PATCH] better shadow for wall-stickers --- .../terrarum/modulebasegame/IngameRenderer.kt | 2 +- src/net/torvald/terrarum/ui/BlurMgr.kt | 47 +++++++++++++++++++ src/shaders/gaussian3x3.frag | 30 ++++++++++++ src/shaders/shadowshallow.frag | 4 +- 4 files changed, 80 insertions(+), 3 deletions(-) create mode 100644 src/shaders/gaussian3x3.frag diff --git a/src/net/torvald/terrarum/modulebasegame/IngameRenderer.kt b/src/net/torvald/terrarum/modulebasegame/IngameRenderer.kt index 3521418f6..fd25ca523 100644 --- a/src/net/torvald/terrarum/modulebasegame/IngameRenderer.kt +++ b/src/net/torvald/terrarum/modulebasegame/IngameRenderer.kt @@ -525,7 +525,7 @@ object IngameRenderer : Disposable { actorsRenderBehind?.forEach { it.drawBody(frameDelta, batch) } } } - BlurMgr.makeBlur(fboRGBactorsBehind, fboRGBactorsBehindShadow, 0.25f) + BlurMgr.makeBlurSmall(fboRGBactorsBehind, fboRGBactorsBehindShadow, 1f) fboRGBactorsMiddle.inAction(camera, batch) { clearBuffer() diff --git a/src/net/torvald/terrarum/ui/BlurMgr.kt b/src/net/torvald/terrarum/ui/BlurMgr.kt index 833ffba58..d1adcc905 100644 --- a/src/net/torvald/terrarum/ui/BlurMgr.kt +++ b/src/net/torvald/terrarum/ui/BlurMgr.kt @@ -20,6 +20,7 @@ object BlurMgr { private val internalHeight = (height.toFloat() / 4f).ceilToInt() * 4 val full = Float16FrameBuffer(width, height, false) +// val full2 = Float16FrameBuffer(width, height, false) val half = Float16FrameBuffer(internalWidth / 2, internalHeight / 2, false) val quarter = Float16FrameBuffer(internalWidth / 4, internalHeight / 4, false) val camera = OrthographicCamera(width.toFloat(), height.toFloat()) @@ -70,6 +71,7 @@ object BlurMgr { fun dispose() { full.dispose() +// full2.dispose() half.dispose() quarter.dispose() } @@ -84,12 +86,15 @@ object BlurMgr { private val shaderKawaseDown = App.loadShaderFromClasspath("shaders/default.vert", "shaders/kawasedown.frag") private val shaderKawaseUp = App.loadShaderFromClasspath("shaders/default.vert", "shaders/kawaseup.frag") + private val shaderGauss3 = App.loadShaderFromClasspath("shaders/default.vert", "shaders/gaussian3x3.frag") fun makeBlur(`in`: FrameBuffer, out: FrameBuffer, strength: Float) { assert(`in`.width == out.width && `in`.height == out.height) { "Input and Output dimension mismatch: In(${`in`.width}x${`in`.height}), Out(${out.width}x${out.height})" } + if (strength.isNaN() || strength.isInfinite()) throw IllegalArgumentException("Strength not a number ($strength)") + val fbos = fboDict.getOrPut(`in`.width.toLong().shl(32) or `in`.height.toLong()) { FrameBufferSet(`in`.width, `in`.height) } @@ -150,10 +155,52 @@ object BlurMgr { } } + fun makeBlurSmall(`in`: FrameBuffer, out: FrameBuffer, strength: Float) { + assert(`in`.width == out.width && `in`.height == out.height) { + "Input and Output dimension mismatch: In(${`in`.width}x${`in`.height}), Out(${out.width}x${out.height})" + } + + if (strength.isNaN() || strength.isInfinite()) throw IllegalArgumentException("Strength not a number ($strength)") + if (strength > 1f) throw IllegalArgumentException("strength too high ($strength); Use makeBlur() instead") + + val fbos = fboDict.getOrPut(`in`.width.toLong().shl(32) or `in`.height.toLong()) { + FrameBufferSet(`in`.width, `in`.height) + } + + val batch: SpriteBatch? = null // placeholder + + fbos.full.inAction(fbos.camera, batch) { + gdxClearAndEnableBlend(0f,0f,0f,0f) + + blurtex0 = `in`.colorBufferTexture + blurtex0.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear) + blurtex0.bind(0) + shaderGauss3.bind() + shaderGauss3.setUniformMatrix("u_projTrans", fbos.camera.combined) + shaderGauss3.setUniformi("u_texture", 0) + shaderGauss3.setUniformf("halfpixel", strength / fbos.full.width, strength / fbos.full.height) + fbos.quadFull.render(shaderGauss3, GL20.GL_TRIANGLE_FAN) + } + + out.inAction(fbos.camera, batch) { + gdxClearAndEnableBlend(0f,0f,0f,0f) + + blurtex3 = fbos.full.colorBufferTexture + blurtex3.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear) + blurtex3.bind(0) + shaderGauss3.bind() + shaderGauss3.setUniformMatrix("u_projTrans", fbos.camera.combined) + shaderGauss3.setUniformi("u_texture", 0) + shaderGauss3.setUniformf("halfpixel", strength / fbos.full.width, strength / fbos.full.height) + fbos.quadFull.render(shaderGauss3, GL20.GL_TRIANGLE_FAN) + } + } + fun dispose() { fboDict.values.forEach { it.dispose() } shaderKawaseUp.dispose() shaderKawaseDown.dispose() + shaderGauss3.dispose() } } \ No newline at end of file diff --git a/src/shaders/gaussian3x3.frag b/src/shaders/gaussian3x3.frag new file mode 100644 index 000000000..9b78d7500 --- /dev/null +++ b/src/shaders/gaussian3x3.frag @@ -0,0 +1,30 @@ +#ifdef GL_ES +precision mediump float; +#endif + +in vec4 v_color; +in 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); + +const vec2 twister = vec2(1.0, -1.0); +const vec2 boolean = vec2(1.0, 0.0); + +out vec4 fragColor; + +void main() { + vec4 sum = texture(u_texture, v_texCoords) * 4.0 + // C + texture(u_texture, v_texCoords + halfpixel) + // SE + texture(u_texture, v_texCoords - halfpixel) + // NW + texture(u_texture, v_texCoords + halfpixel * twister) + // NE + texture(u_texture, v_texCoords - halfpixel * twister) + // SW + texture(u_texture, v_texCoords + halfpixel * boolean.xy) * 2.0 + // E + texture(u_texture, v_texCoords - halfpixel * boolean.xy) * 2.0 + // W + texture(u_texture, v_texCoords + halfpixel * boolean.yx) * 2.0 + // S + texture(u_texture, v_texCoords - halfpixel * boolean.yx) * 2.0 ; // N + + fragColor = sum / 16.0; +} \ No newline at end of file diff --git a/src/shaders/shadowshallow.frag b/src/shaders/shadowshallow.frag index c960d1817..42fad31cb 100644 --- a/src/shaders/shadowshallow.frag +++ b/src/shaders/shadowshallow.frag @@ -10,11 +10,11 @@ uniform sampler2D u_texture; uniform sampler2D u_wall; out vec4 fragColor; -vec4 mult = vec4(0.0, 0.0, 0.0, 1.5); +vec4 mult = vec4(0.0, 0.0, 0.0, 1.0); void main() { vec4 backcol = texture(u_wall, v_texCoords); vec4 incol = texture(u_texture, v_texCoords); - vec4 outcol = vec4(incol.rgb, backcol.a * pow(incol.a, 2.0)); + vec4 outcol = vec4(incol.rgb, backcol.a * incol.a); fragColor = mult * outcol; } \ No newline at end of file