mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-11 02:54:04 +09:00
kawase blur is working i think
This commit is contained in:
23
assets/shaders/kawasedown.frag
Normal file
23
assets/shaders/kawasedown.frag
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
#version 120
|
||||||
|
#ifdef GL_ES
|
||||||
|
precision mediump float;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
varying vec4 v_color;
|
||||||
|
varying vec2 v_texCoords;
|
||||||
|
uniform sampler2D u_texture;
|
||||||
|
|
||||||
|
uniform vec2 halfpixel = vec2(0.0, 0.0);
|
||||||
|
|
||||||
|
vec2 twister = vec2(1.0, -1.0);
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec4 sum = texture2D(u_texture, v_texCoords) * 4.0;
|
||||||
|
sum += texture2D(u_texture, v_texCoords - halfpixel);
|
||||||
|
sum += texture2D(u_texture, v_texCoords + halfpixel);
|
||||||
|
sum += texture2D(u_texture, v_texCoords - halfpixel * twister);
|
||||||
|
sum += texture2D(u_texture, v_texCoords + halfpixel * twister);
|
||||||
|
gl_FragColor = sum / 8.0;
|
||||||
|
|
||||||
|
// gl_FragColor = texture2D(u_texture, v_texCoords);
|
||||||
|
}
|
||||||
28
assets/shaders/kawaseup.frag
Normal file
28
assets/shaders/kawaseup.frag
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
#version 120
|
||||||
|
#ifdef GL_ES
|
||||||
|
precision mediump float;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
varying vec4 v_color;
|
||||||
|
varying vec2 v_texCoords;
|
||||||
|
uniform sampler2D u_texture;
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec4 sum = texture2D(u_texture, v_texCoords - halfpixel * doublex);
|
||||||
|
sum += texture2D(u_texture, v_texCoords - halfpixel * twister) * 2.0;
|
||||||
|
sum += texture2D(u_texture, v_texCoords + halfpixel * doubley);
|
||||||
|
sum += texture2D(u_texture, v_texCoords + halfpixel) * 2.0;
|
||||||
|
sum += texture2D(u_texture, v_texCoords + halfpixel * doublex);
|
||||||
|
sum += texture2D(u_texture, v_texCoords + halfpixel * twister) * 2.0;
|
||||||
|
sum += texture2D(u_texture, v_texCoords - halfpixel * doubley);
|
||||||
|
sum += texture2D(u_texture, v_texCoords - halfpixel) * 2.0;
|
||||||
|
gl_FragColor = sum / 12.0;
|
||||||
|
|
||||||
|
// gl_FragColor = texture2D(u_texture, v_texCoords);
|
||||||
|
}
|
||||||
@@ -45,6 +45,8 @@ object IngameRenderer : Disposable {
|
|||||||
private lateinit var camera: OrthographicCamera
|
private lateinit var camera: OrthographicCamera
|
||||||
|
|
||||||
private lateinit var blurWriteQuad: Mesh
|
private lateinit var blurWriteQuad: Mesh
|
||||||
|
private lateinit var blurWriteQuad2: Mesh
|
||||||
|
private lateinit var blurWriteQuad4: Mesh
|
||||||
|
|
||||||
private lateinit var lightmapFboA: FrameBuffer
|
private lateinit var lightmapFboA: FrameBuffer
|
||||||
private lateinit var lightmapFboB: FrameBuffer
|
private lateinit var lightmapFboB: FrameBuffer
|
||||||
@@ -59,6 +61,9 @@ object IngameRenderer : Disposable {
|
|||||||
private lateinit var lightTex: TextureRegion
|
private lateinit var lightTex: TextureRegion
|
||||||
private lateinit var blurTex: TextureRegion
|
private lateinit var blurTex: TextureRegion
|
||||||
|
|
||||||
|
private lateinit var fboBlurHalf: FrameBuffer
|
||||||
|
private lateinit var fboBlurQuarter: FrameBuffer
|
||||||
|
|
||||||
// you must have lightMixed FBO; otherwise you'll be reading from unbaked FBO and it freaks out GPU
|
// you must have lightMixed FBO; otherwise you'll be reading from unbaked FBO and it freaks out GPU
|
||||||
|
|
||||||
inline fun isDither() = App.getConfigBoolean("fx_dither")
|
inline fun isDither() = App.getConfigBoolean("fx_dither")
|
||||||
@@ -79,6 +84,9 @@ object IngameRenderer : Disposable {
|
|||||||
val shaderAtoGreyDither: ShaderProgram
|
val shaderAtoGreyDither: ShaderProgram
|
||||||
val shaderAtoGreyRaw: ShaderProgram
|
val shaderAtoGreyRaw: ShaderProgram
|
||||||
|
|
||||||
|
val shaderKawaseDown: ShaderProgram
|
||||||
|
val shaderKawaseUp: ShaderProgram
|
||||||
|
|
||||||
val shaderBayer: ShaderProgram
|
val shaderBayer: ShaderProgram
|
||||||
val shaderPassthru = SpriteBatch.createDefaultShader()
|
val shaderPassthru = SpriteBatch.createDefaultShader()
|
||||||
|
|
||||||
@@ -94,7 +102,8 @@ object IngameRenderer : Disposable {
|
|||||||
|
|
||||||
private var player: ActorWithBody? = null
|
private var player: ActorWithBody? = null
|
||||||
|
|
||||||
const val lightmapDownsample = 1f//4f //2f: still has choppy look when the camera moves but unnoticeable when blurred
|
/** lower value = greater lozenge artefact from linear intp */
|
||||||
|
const val lightmapDownsample = 2f // still has choppy look when the camera moves but unnoticeable when blurred
|
||||||
|
|
||||||
private var debugMode = 0
|
private var debugMode = 0
|
||||||
|
|
||||||
@@ -128,11 +137,18 @@ object IngameRenderer : Disposable {
|
|||||||
shaderBlendGlow = App.loadShaderFromFile("assets/shaders/blendGlow.vert", "assets/shaders/blendGlow.frag")
|
shaderBlendGlow = App.loadShaderFromFile("assets/shaders/blendGlow.vert", "assets/shaders/blendGlow.frag")
|
||||||
|
|
||||||
|
|
||||||
|
shaderKawaseDown = App.loadShaderFromFile("assets/shaders/4096.vert", "assets/shaders/kawasedown.frag")
|
||||||
|
shaderKawaseUp = App.loadShaderFromFile("assets/shaders/4096.vert", "assets/shaders/kawaseup.frag")
|
||||||
|
|
||||||
if (!shaderBlendGlow.isCompiled) {
|
if (!shaderBlendGlow.isCompiled) {
|
||||||
Gdx.app.log("shaderBlendGlow", shaderBlendGlow.log)
|
Gdx.app.log("shaderBlendGlow", shaderBlendGlow.log)
|
||||||
exitProcess(1)
|
exitProcess(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!shaderKawaseDown.isCompiled) {
|
||||||
|
Gdx.app.log("shaderKawaseDown", shaderKawaseDown.log)
|
||||||
|
exitProcess(1)
|
||||||
|
}
|
||||||
|
|
||||||
if (isDither()) {
|
if (isDither()) {
|
||||||
if (!shaderBayer.isCompiled) {
|
if (!shaderBayer.isCompiled) {
|
||||||
@@ -405,7 +421,21 @@ object IngameRenderer : Disposable {
|
|||||||
Gdx.gl.glDisable(GL20.GL_BLEND)
|
Gdx.gl.glDisable(GL20.GL_BLEND)
|
||||||
}
|
}
|
||||||
|
|
||||||
processBlur(lightmapFboA, lightmapFboB)
|
// processBlur(lightmapFboA, lightmapFboB)
|
||||||
|
processKawaseBlur(lightmapFboB)
|
||||||
|
|
||||||
|
/*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)
|
||||||
|
}*/
|
||||||
|
|
||||||
|
|
||||||
|
blendNormal(batch)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Volatile internal var screencapRequested = false
|
@Volatile internal var screencapRequested = false
|
||||||
@@ -653,6 +683,59 @@ object IngameRenderer : Disposable {
|
|||||||
batch.projectionMatrix = camera.combined
|
batch.projectionMatrix = camera.combined
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun processKawaseBlur(outFbo: FrameBuffer) {
|
||||||
|
|
||||||
|
// initialise readBuffer with untreated lightmap
|
||||||
|
outFbo.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)
|
||||||
|
}
|
||||||
|
|
||||||
|
fboBlurHalf.inAction(camera, batch) {
|
||||||
|
val texture = outFbo.colorBufferTexture
|
||||||
|
texture.bind(0)
|
||||||
|
shaderKawaseDown.bind()
|
||||||
|
shaderKawaseDown.setUniformMatrix("u_projTrans", camera.combined)
|
||||||
|
shaderKawaseDown.setUniformi("u_texture", 0)
|
||||||
|
shaderKawaseDown.setUniformf("halfpixel", 1f / fboBlurHalf.width, 1f / fboBlurHalf.height)
|
||||||
|
blurWriteQuad2.render(shaderKawaseDown, GL20.GL_TRIANGLES)
|
||||||
|
}
|
||||||
|
|
||||||
|
fboBlurQuarter.inAction(camera, batch) {
|
||||||
|
val texture = fboBlurHalf.colorBufferTexture
|
||||||
|
texture.bind(0)
|
||||||
|
shaderKawaseDown.bind()
|
||||||
|
shaderKawaseDown.setUniformMatrix("u_projTrans", camera.combined)
|
||||||
|
shaderKawaseDown.setUniformi("u_texture", 0)
|
||||||
|
shaderKawaseDown.setUniformf("halfpixel", 1f / fboBlurQuarter.width, 1f / fboBlurQuarter.height)
|
||||||
|
blurWriteQuad4.render(shaderKawaseDown, GL20.GL_TRIANGLES)
|
||||||
|
}
|
||||||
|
|
||||||
|
fboBlurHalf.inAction(camera, batch) {
|
||||||
|
val texture = fboBlurQuarter.colorBufferTexture
|
||||||
|
texture.bind(0)
|
||||||
|
shaderKawaseUp.bind()
|
||||||
|
shaderKawaseUp.setUniformMatrix("u_projTrans", camera.combined)
|
||||||
|
shaderKawaseUp.setUniformi("u_texture", 0)
|
||||||
|
shaderKawaseUp.setUniformf("halfpixel", 1f / fboBlurQuarter.width, 1f / fboBlurQuarter.height)
|
||||||
|
blurWriteQuad2.render(shaderKawaseUp, GL20.GL_TRIANGLES)
|
||||||
|
}
|
||||||
|
|
||||||
|
outFbo.inAction(camera, batch) {
|
||||||
|
val texture = fboBlurHalf.colorBufferTexture
|
||||||
|
texture.bind(0)
|
||||||
|
shaderKawaseUp.bind()
|
||||||
|
shaderKawaseUp.setUniformMatrix("u_projTrans", camera.combined)
|
||||||
|
shaderKawaseUp.setUniformi("u_texture", 0)
|
||||||
|
shaderKawaseUp.setUniformf("halfpixel", 1f / fboBlurHalf.width, 1f / fboBlurHalf.height)
|
||||||
|
blurWriteQuad.render(shaderKawaseUp, GL20.GL_TRIANGLES)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun processBlur(lightmapFboA: FrameBuffer, lightmapFboB: FrameBuffer) {
|
fun processBlur(lightmapFboA: FrameBuffer, lightmapFboB: FrameBuffer) {
|
||||||
var blurWriteBuffer = lightmapFboA
|
var blurWriteBuffer = lightmapFboA
|
||||||
var blurReadBuffer = lightmapFboB
|
var blurReadBuffer = lightmapFboB
|
||||||
@@ -721,7 +804,18 @@ object IngameRenderer : Disposable {
|
|||||||
VertexAttribute.ColorUnpacked(),
|
VertexAttribute.ColorUnpacked(),
|
||||||
VertexAttribute.TexCoords(0)
|
VertexAttribute.TexCoords(0)
|
||||||
)
|
)
|
||||||
|
blurWriteQuad2 = Mesh(
|
||||||
|
true, 4, 6,
|
||||||
|
VertexAttribute.Position(),
|
||||||
|
VertexAttribute.ColorUnpacked(),
|
||||||
|
VertexAttribute.TexCoords(0)
|
||||||
|
)
|
||||||
|
blurWriteQuad4 = Mesh(
|
||||||
|
true, 4, 6,
|
||||||
|
VertexAttribute.Position(),
|
||||||
|
VertexAttribute.ColorUnpacked(),
|
||||||
|
VertexAttribute.TexCoords(0)
|
||||||
|
)
|
||||||
init = true
|
init = true
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -731,6 +825,9 @@ object IngameRenderer : Disposable {
|
|||||||
fboA_lightMixed.dispose()
|
fboA_lightMixed.dispose()
|
||||||
lightmapFboA.dispose()
|
lightmapFboA.dispose()
|
||||||
lightmapFboB.dispose()
|
lightmapFboB.dispose()
|
||||||
|
|
||||||
|
fboBlurHalf.dispose()
|
||||||
|
fboBlurQuarter.dispose()
|
||||||
}
|
}
|
||||||
|
|
||||||
fboRGB = FrameBuffer(Pixmap.Format.RGBA8888, width, height, true)
|
fboRGB = FrameBuffer(Pixmap.Format.RGBA8888, width, height, true)
|
||||||
@@ -756,6 +853,20 @@ object IngameRenderer : Disposable {
|
|||||||
blurTex = TextureRegion()
|
blurTex = TextureRegion()
|
||||||
mixedOutTex = TextureRegion(fboMixedOut.colorBufferTexture)
|
mixedOutTex = TextureRegion(fboMixedOut.colorBufferTexture)
|
||||||
|
|
||||||
|
fboBlurHalf = FrameBuffer(
|
||||||
|
Pixmap.Format.RGBA8888,
|
||||||
|
LightmapRenderer.lightBuffer.width * LightmapRenderer.DRAW_TILE_SIZE.toInt() / 2,
|
||||||
|
LightmapRenderer.lightBuffer.height * LightmapRenderer.DRAW_TILE_SIZE.toInt() / 2,
|
||||||
|
true
|
||||||
|
)
|
||||||
|
|
||||||
|
fboBlurQuarter = FrameBuffer(
|
||||||
|
Pixmap.Format.RGBA8888,
|
||||||
|
LightmapRenderer.lightBuffer.width * LightmapRenderer.DRAW_TILE_SIZE.toInt() / 4,
|
||||||
|
LightmapRenderer.lightBuffer.height * LightmapRenderer.DRAW_TILE_SIZE.toInt() / 4,
|
||||||
|
true
|
||||||
|
)
|
||||||
|
|
||||||
BlocksDrawer.resize(width, height)
|
BlocksDrawer.resize(width, height)
|
||||||
LightmapRenderer.resize(width, height)
|
LightmapRenderer.resize(width, height)
|
||||||
|
|
||||||
@@ -767,9 +878,26 @@ object IngameRenderer : Disposable {
|
|||||||
0f,lightmapFboA.height.toFloat(),0f, 1f,1f,1f,1f, 0f,0f))
|
0f,lightmapFboA.height.toFloat(),0f, 1f,1f,1f,1f, 0f,0f))
|
||||||
blurWriteQuad.setIndices(shortArrayOf(0, 1, 2, 2, 3, 0))
|
blurWriteQuad.setIndices(shortArrayOf(0, 1, 2, 2, 3, 0))
|
||||||
|
|
||||||
|
blurWriteQuad2.setVertices(floatArrayOf(
|
||||||
|
0f,0f,0f, 1f,1f,1f,1f, 0f,1f,
|
||||||
|
lightmapFboA.width.div(2).toFloat(),0f,0f, 1f,1f,1f,1f, 1f,1f,
|
||||||
|
lightmapFboA.width.div(2).toFloat(),lightmapFboA.height.div(2).toFloat(),0f, 1f,1f,1f,1f, 1f,0f,
|
||||||
|
0f,lightmapFboA.height.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,
|
||||||
|
lightmapFboA.width.div(4).toFloat(),0f,0f, 1f,1f,1f,1f, 1f,1f,
|
||||||
|
lightmapFboA.width.div(4).toFloat(),lightmapFboA.height.div(4).toFloat(),0f, 1f,1f,1f,1f, 1f,0f,
|
||||||
|
0f,lightmapFboA.height.div(4).toFloat(),0f, 1f,1f,1f,1f, 0f,0f))
|
||||||
|
blurWriteQuad4.setIndices(shortArrayOf(0, 1, 2, 2, 3, 0))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun dispose() {
|
override fun dispose() {
|
||||||
|
blurWriteQuad.dispose()
|
||||||
|
blurWriteQuad2.dispose()
|
||||||
|
blurWriteQuad4.dispose()
|
||||||
|
|
||||||
fboRGB.dispose()
|
fboRGB.dispose()
|
||||||
fboA.dispose()
|
fboA.dispose()
|
||||||
fboRGB_lightMixed.dispose()
|
fboRGB_lightMixed.dispose()
|
||||||
@@ -778,6 +906,9 @@ object IngameRenderer : Disposable {
|
|||||||
lightmapFboA.dispose()
|
lightmapFboA.dispose()
|
||||||
lightmapFboB.dispose()
|
lightmapFboB.dispose()
|
||||||
|
|
||||||
|
fboBlurHalf.dispose()
|
||||||
|
fboBlurQuarter.dispose()
|
||||||
|
|
||||||
LightmapRenderer.dispose()
|
LightmapRenderer.dispose()
|
||||||
BlocksDrawer.dispose()
|
BlocksDrawer.dispose()
|
||||||
WeatherMixer.dispose()
|
WeatherMixer.dispose()
|
||||||
@@ -797,6 +928,9 @@ object IngameRenderer : Disposable {
|
|||||||
shaderPassthru.dispose()
|
shaderPassthru.dispose()
|
||||||
shaderAlphaDither.dispose()
|
shaderAlphaDither.dispose()
|
||||||
|
|
||||||
|
shaderKawaseDown.dispose()
|
||||||
|
shaderKawaseUp.dispose()
|
||||||
|
|
||||||
try {
|
try {
|
||||||
fboRGBexport.dispose()
|
fboRGBexport.dispose()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ import net.torvald.terrarum.modulebasegame.IngameRenderer
|
|||||||
import net.torvald.terrarum.modulebasegame.ui.abs
|
import net.torvald.terrarum.modulebasegame.ui.abs
|
||||||
import net.torvald.terrarum.realestate.LandUtil
|
import net.torvald.terrarum.realestate.LandUtil
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.collections.HashMap
|
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
import kotlin.system.exitProcess
|
import kotlin.system.exitProcess
|
||||||
|
|
||||||
@@ -578,13 +577,13 @@ object LightmapRenderer {
|
|||||||
return if (BlockCodex[world.getTileFromTerrain(x, y)].isSolid) 1.2f else 1f
|
return if (BlockCodex[world.getTileFromTerrain(x, y)].isSolid) 1.2f else 1f
|
||||||
}
|
}
|
||||||
|
|
||||||
var lightBuffer: Pixmap = Pixmap(1, 1, Pixmap.Format.RGBA8888)
|
var lightBuffer: Pixmap = Pixmap(64, 64, Pixmap.Format.RGBA8888) // must not be too small
|
||||||
|
|
||||||
private val colourNull = Cvec(0)
|
private val colourNull = Cvec(0)
|
||||||
private val gdxColorNull = Color(0)
|
private val gdxColorNull = Color(0)
|
||||||
const val epsilon = 1f/1024f
|
const val epsilon = 1f/1024f
|
||||||
|
|
||||||
private var _lightBufferAsTex: Texture = Texture(1, 1, Pixmap.Format.RGBA8888)
|
private var _lightBufferAsTex: Texture = Texture(64, 64, Pixmap.Format.RGBA8888) // must not be too small
|
||||||
|
|
||||||
internal fun draw(): Texture {
|
internal fun draw(): Texture {
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user