mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-13 03:54:06 +09:00
deblocking wip
This commit is contained in:
BIN
assets/graphics/blocks/deblocking_mask.tga
LFS
Normal file
BIN
assets/graphics/blocks/deblocking_mask.tga
LFS
Normal file
Binary file not shown.
@@ -1,7 +1,10 @@
|
|||||||
package net.torvald.terrarum.worlddrawer
|
package net.torvald.terrarum.worlddrawer
|
||||||
|
|
||||||
|
import com.badlogic.gdx.Gdx
|
||||||
import com.badlogic.gdx.Input.Keys
|
import com.badlogic.gdx.Input.Keys
|
||||||
import com.badlogic.gdx.graphics.*
|
import com.badlogic.gdx.graphics.*
|
||||||
|
import com.badlogic.gdx.graphics.glutils.Float16FrameBuffer
|
||||||
|
import com.badlogic.gdx.graphics.glutils.FrameBuffer
|
||||||
import com.badlogic.gdx.math.Matrix4
|
import com.badlogic.gdx.math.Matrix4
|
||||||
import com.jme3.math.FastMath
|
import com.jme3.math.FastMath
|
||||||
import net.torvald.gdx.graphics.Cvec
|
import net.torvald.gdx.graphics.Cvec
|
||||||
@@ -98,7 +101,14 @@ internal object BlocksDrawer {
|
|||||||
private var tilesBuffer2: Pixmap = Pixmap(1, 1, Pixmap.Format.RGBA8888)
|
private var tilesBuffer2: Pixmap = Pixmap(1, 1, Pixmap.Format.RGBA8888)
|
||||||
|
|
||||||
private lateinit var tilesQuad: Mesh
|
private lateinit var tilesQuad: Mesh
|
||||||
private val shader = App.loadShaderFromClasspath("shaders/default.vert", "shaders/tiling.frag")
|
private val shaderTiling = App.loadShaderFromClasspath("shaders/default.vert", "shaders/tiling.frag")
|
||||||
|
private val shaderDeblock = App.loadShaderFromClasspath("shaders/default.vert", "shaders/deblocking.frag")
|
||||||
|
|
||||||
|
private lateinit var deblockingFBO: Float16FrameBuffer
|
||||||
|
private lateinit var blurmapFBO: Float16FrameBuffer
|
||||||
|
|
||||||
|
lateinit var batch: FlippingSpriteBatch
|
||||||
|
private lateinit var camera: OrthographicCamera
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
|
||||||
@@ -151,6 +161,10 @@ internal object BlocksDrawer {
|
|||||||
tilesTerrain = seasonalTerrains[1]
|
tilesTerrain = seasonalTerrains[1]
|
||||||
|
|
||||||
|
|
||||||
|
batch = FlippingSpriteBatch()
|
||||||
|
camera = OrthographicCamera(App.scr.width.toFloat(), App.scr.height.toFloat())
|
||||||
|
|
||||||
|
|
||||||
printdbg(this, "init() exit")
|
printdbg(this, "init() exit")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -258,6 +272,19 @@ internal object BlocksDrawer {
|
|||||||
renderUsingBuffer(OCCLUSION, projectionMatrix, false, drawEmissive)
|
renderUsingBuffer(OCCLUSION, projectionMatrix, false, drawEmissive)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun clearBuffer() {
|
||||||
|
gdxClearAndEnableBlend(0f,0f,0f,0f)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setCameraPosition(newX: Float, newY: Float) {
|
||||||
|
camera.position.set((-newX + App.scr.halfw).roundToFloat(), (-newY + App.scr.halfh).roundToFloat(), 0f)
|
||||||
|
camera.update()
|
||||||
|
batch.projectionMatrix = camera.combined
|
||||||
|
}
|
||||||
|
|
||||||
|
private val testTexture = Texture(Gdx.files.internal("./assets/test_texture.tga"))
|
||||||
|
|
||||||
internal fun drawTerrain(projectionMatrix: Matrix4, drawGlow: Boolean, drawEmissive: Boolean = false) {
|
internal fun drawTerrain(projectionMatrix: Matrix4, drawGlow: Boolean, drawEmissive: Boolean = false) {
|
||||||
gdxBlendNormalStraightAlpha()
|
gdxBlendNormalStraightAlpha()
|
||||||
|
|
||||||
@@ -277,6 +304,24 @@ internal object BlocksDrawer {
|
|||||||
gdxBlendNormalStraightAlpha()
|
gdxBlendNormalStraightAlpha()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun deblockAndWriteTexture(projectionMatrix: Matrix4, dest: FrameBuffer, blurmap: FrameBuffer) {
|
||||||
|
blurmap.colorBufferTexture.bind(1)
|
||||||
|
dest.colorBufferTexture.bind(0)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// basically this part is correct, test with any test texture
|
||||||
|
shaderDeblock.bind()
|
||||||
|
shaderDeblock.setUniformMatrix("u_projTrans", projectionMatrix)
|
||||||
|
shaderDeblock.setUniformf("resolution", oldScreenW.toFloat(), oldScreenH.toFloat())
|
||||||
|
shaderDeblock.setUniformi("u_blurmap", 1)
|
||||||
|
shaderDeblock.setUniformi("u_texture", 0)
|
||||||
|
tilesQuad.render(shaderDeblock, GL20.GL_TRIANGLE_FAN)
|
||||||
|
|
||||||
|
Gdx.gl.glActiveTexture(GL20.GL_TEXTURE0)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Turns bitmask-with-single-bit-set into its bit index. The LSB is counted as 1, and thus the index starts at one.
|
* Turns bitmask-with-single-bit-set into its bit index. The LSB is counted as 1, and thus the index starts at one.
|
||||||
* @return 0 -> -1, 1 -> 0, 2 -> 1, 4 -> 2, 8 -> 3, 16 -> 4, ...
|
* @return 0 -> -1, 1 -> 0, 2 -> 1, 4 -> 2, 8 -> 3, 16 -> 4, ...
|
||||||
@@ -491,11 +536,10 @@ internal object BlocksDrawer {
|
|||||||
(fillThis * 16f - 0.5f).floorToInt().coerceIn(0, 15)
|
(fillThis * 16f - 0.5f).floorToInt().coerceIn(0, 15)
|
||||||
}
|
}
|
||||||
else if (treeLeavesTiles.binarySearch(rawTileNum) >= 0) {
|
else if (treeLeavesTiles.binarySearch(rawTileNum) >= 0) {
|
||||||
getNearbyTilesInfoTrees(x, y, mode).swizzle8(renderTag.maskType, hash)
|
getNearbyTilesInfoTreeLeaves(x, y, mode).swizzle8(renderTag.maskType, hash)
|
||||||
}
|
}
|
||||||
else if (treeTrunkTiles.binarySearch(rawTileNum) >= 0) {
|
else if (treeTrunkTiles.binarySearch(rawTileNum) >= 0) {
|
||||||
hash = 0
|
getNearbyTilesInfoTreeTrunks(x, y, mode)
|
||||||
getNearbyTilesInfoTrees(x, y, mode)
|
|
||||||
}
|
}
|
||||||
else if (platformTiles.binarySearch(rawTileNum) >= 0) {
|
else if (platformTiles.binarySearch(rawTileNum) >= 0) {
|
||||||
hash %= 2
|
hash %= 2
|
||||||
@@ -777,23 +821,28 @@ internal object BlocksDrawer {
|
|||||||
return fluidSolidMaskLut[i]
|
return fluidSolidMaskLut[i]
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getNearbyTilesInfoTrees(x: Int, y: Int, mode: Int): Int {
|
private fun getNearbyTilesInfoTreeLeaves(x: Int, y: Int, mode: Int): Int {
|
||||||
val tileThis = world.getTileFromTerrain(x, y)
|
|
||||||
val nearbyTiles: List<ItemID> = getNearbyTilesPos(x, y).map { world.getTileFrom(mode, it.x, it.y) }
|
val nearbyTiles: List<ItemID> = getNearbyTilesPos(x, y).map { world.getTileFrom(mode, it.x, it.y) }
|
||||||
|
|
||||||
var ret = 0
|
var ret = 0
|
||||||
if (isTreeFoliage(tileThis)) {
|
for (i in nearbyTiles.indices) {
|
||||||
for (i in nearbyTiles.indices) {
|
if (isTreeFoliage(nearbyTiles[i])) { // foliage "shadow" should not connect to the tree trunk
|
||||||
if (isTreeFoliage(nearbyTiles[i])) { // foliage "shadow" should not connect to the tree trunk
|
ret += (1 shl i) // add 1, 2, 4, 8 for i = 0, 1, 2, 3
|
||||||
ret += (1 shl i) // add 1, 2, 4, 8 for i = 0, 1, 2, 3
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (isTreeTrunk(tileThis)) {
|
|
||||||
for (i in nearbyTiles.indices) {
|
return ret
|
||||||
if (isTreeTrunk(nearbyTiles[i]) || i == 6 && isTreeFoliage(nearbyTiles[6])) { // if tile above is leaves, connect to it
|
}
|
||||||
ret += (1 shl i) // add 1, 2, 4, 8 for i = 0, 1, 2, 3
|
|
||||||
}
|
private fun getNearbyTilesInfoTreeTrunks(x: Int, y: Int, mode: Int): Int {
|
||||||
|
val nearbyTiles: List<ItemID> = getNearbyTilesPos(x, y).map { world.getTileFrom(mode, it.x, it.y) }
|
||||||
|
|
||||||
|
var ret = 0
|
||||||
|
for (i in nearbyTiles.indices) {
|
||||||
|
if (isTreeTrunk(nearbyTiles[i]) ||
|
||||||
|
i == 6 && isTreeFoliage(nearbyTiles[i]) ||
|
||||||
|
i == 2 && isCultivable(nearbyTiles[i])) { // if tile above is leaves or tile below is cultivable, connect to it
|
||||||
|
ret += (1 shl i) // add 1, 2, 4, 8 for i = 0, 1, 2, 3
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1104,32 +1153,38 @@ internal object BlocksDrawer {
|
|||||||
tilesGlow.texture.bind(0) // for some fuck reason, it must be bound as last
|
tilesGlow.texture.bind(0) // for some fuck reason, it must be bound as last
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
// bind map for deblocking
|
||||||
|
if (mode == TERRAIN || mode == WALL) {
|
||||||
|
blurmapFBO.colorBufferTexture.bind(4)
|
||||||
|
}
|
||||||
|
|
||||||
_tilesBufferAsTex2.bind(3)
|
_tilesBufferAsTex2.bind(3)
|
||||||
_tilesBufferAsTex.bind(2)
|
_tilesBufferAsTex.bind(2)
|
||||||
tilesTerrainNext.texture.bind(1)
|
tilesTerrainNext.texture.bind(1)
|
||||||
tileAtlas.texture.bind(0) // for some fuck reason, it must be bound as last
|
tileAtlas.texture.bind(0) // for some fuck reason, it must be bound as last
|
||||||
}
|
}
|
||||||
|
|
||||||
shader.bind()
|
shaderTiling.bind()
|
||||||
shader.setUniformMatrix("u_projTrans", projectionMatrix)//camera.combined)
|
shaderTiling.setUniformMatrix("u_projTrans", projectionMatrix)//camera.combined)
|
||||||
shader.setUniformf("colourFilter", vertexColour)
|
shaderTiling.setUniformf("colourFilter", vertexColour)
|
||||||
shader.setUniformi("tilesAtlas", 0)
|
shaderTiling.setUniformi("tilesAtlas", 0)
|
||||||
shader.setUniformi("tilesBlendAtlas", 1)
|
shaderTiling.setUniformi("tilesBlendAtlas", 1)
|
||||||
shader.setUniformi("tilemap", 2)
|
shaderTiling.setUniformi("tilemap", 2)
|
||||||
shader.setUniformi("tilemap2", 3)
|
shaderTiling.setUniformi("tilemap2", 3)
|
||||||
shader.setUniformi("tilemapDimension", tilesBuffer.width, tilesBuffer.height)
|
shaderTiling.setUniformi("deblockingMap", 4)
|
||||||
shader.setUniformf("tilesInAxes", tilesInHorizontal.toFloat(), tilesInVertical.toFloat())
|
shaderTiling.setUniformi("tilemapDimension", tilesBuffer.width, tilesBuffer.height)
|
||||||
shader.setUniformi("cameraTranslation", WorldCamera.x fmod TILE_SIZE, WorldCamera.y fmod TILE_SIZE) // usage of 'fmod' and '%' were depend on the for_x_start, which I can't just do naive int div
|
shaderTiling.setUniformf("tilesInAxes", tilesInHorizontal.toFloat(), tilesInVertical.toFloat())
|
||||||
shader.setUniformf("tilesInAtlas", tileAtlas.horizontalCount * 2f, tileAtlas.verticalCount * 2f) //depends on the tile atlas
|
shaderTiling.setUniformi("cameraTranslation", WorldCamera.x fmod TILE_SIZE, WorldCamera.y fmod TILE_SIZE) // usage of 'fmod' and '%' were depend on the for_x_start, which I can't just do naive int div
|
||||||
shader.setUniformf("atlasTexSize", tileAtlas.texture.width.toFloat(), tileAtlas.texture.height.toFloat()) //depends on the tile atlas
|
shaderTiling.setUniformf("tilesInAtlas", tileAtlas.horizontalCount * 2f, tileAtlas.verticalCount * 2f) //depends on the tile atlas
|
||||||
|
shaderTiling.setUniformf("atlasTexSize", tileAtlas.texture.width.toFloat(), tileAtlas.texture.height.toFloat()) //depends on the tile atlas
|
||||||
// set the blend value as world's time progresses, in linear fashion
|
// set the blend value as world's time progresses, in linear fashion
|
||||||
shader.setUniformf("tilesBlend", if (mode == TERRAIN || mode == WALL)
|
shaderTiling.setUniformf("tilesBlend", if (mode == TERRAIN || mode == WALL)
|
||||||
tilesTerrainBlendDegree
|
tilesTerrainBlendDegree
|
||||||
else
|
else
|
||||||
0f
|
0f
|
||||||
)
|
)
|
||||||
shader.setUniformf("mulBlendIntensity", if (mode == OCCLUSION) occlusionIntensity else 1f)
|
shaderTiling.setUniformf("mulBlendIntensity", if (mode == OCCLUSION) occlusionIntensity else 1f)
|
||||||
tilesQuad.render(shader, GL20.GL_TRIANGLE_FAN)
|
tilesQuad.render(shaderTiling, GL20.GL_TRIANGLE_FAN)
|
||||||
|
|
||||||
//tilesBufferAsTex.dispose()
|
//tilesBufferAsTex.dispose()
|
||||||
}
|
}
|
||||||
@@ -1191,6 +1246,11 @@ internal object BlocksDrawer {
|
|||||||
tilesQuad.setIndices(shortArrayOf(0, 1, 2, 3))
|
tilesQuad.setIndices(shortArrayOf(0, 1, 2, 3))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (::deblockingFBO.isInitialized) deblockingFBO.dispose()
|
||||||
|
deblockingFBO = Float16FrameBuffer(screenW, screenH, false)
|
||||||
|
if (::blurmapFBO.isInitialized) deblockingFBO.dispose()
|
||||||
|
blurmapFBO = Float16FrameBuffer(screenW, screenH, false)
|
||||||
|
|
||||||
oldScreenW = screenW
|
oldScreenW = screenW
|
||||||
oldScreenH = screenH
|
oldScreenH = screenH
|
||||||
|
|
||||||
@@ -1237,7 +1297,8 @@ internal object BlocksDrawer {
|
|||||||
_tilesBufferAsTex.dispose()
|
_tilesBufferAsTex.dispose()
|
||||||
_tilesBufferAsTex2.dispose()
|
_tilesBufferAsTex2.dispose()
|
||||||
tilesQuad.tryDispose()
|
tilesQuad.tryDispose()
|
||||||
shader.dispose()
|
shaderTiling.dispose()
|
||||||
|
shaderDeblock.dispose()
|
||||||
|
|
||||||
if (::terrainTilesBuffer.isInitialized) terrainTilesBuffer.destroy()
|
if (::terrainTilesBuffer.isInitialized) terrainTilesBuffer.destroy()
|
||||||
if (::wallTilesBuffer.isInitialized) wallTilesBuffer.destroy()
|
if (::wallTilesBuffer.isInitialized) wallTilesBuffer.destroy()
|
||||||
@@ -1246,6 +1307,7 @@ internal object BlocksDrawer {
|
|||||||
if (::occlusionBuffer.isInitialized) occlusionBuffer.destroy()
|
if (::occlusionBuffer.isInitialized) occlusionBuffer.destroy()
|
||||||
if (::tempRenderTypeBuffer.isInitialized) tempRenderTypeBuffer.destroy()
|
if (::tempRenderTypeBuffer.isInitialized) tempRenderTypeBuffer.destroy()
|
||||||
|
|
||||||
|
if (::batch.isInitialized) batch.tryDispose()
|
||||||
|
|
||||||
App.tileMaker.dispose()
|
App.tileMaker.dispose()
|
||||||
}
|
}
|
||||||
@@ -1263,6 +1325,7 @@ internal object BlocksDrawer {
|
|||||||
//fun isBlendMul(b: Int) = TILES_BLEND_MUL.contains(b)
|
//fun isBlendMul(b: Int) = TILES_BLEND_MUL.contains(b)
|
||||||
fun isTreeFoliage(b: ItemID) = BlockCodex[b].hasAllTagsOf("TREE", "LEAVES")
|
fun isTreeFoliage(b: ItemID) = BlockCodex[b].hasAllTagsOf("TREE", "LEAVES")
|
||||||
fun isTreeTrunk(b: ItemID) = BlockCodex[b].hasAllTagsOf("TREE", "TREETRUNK")
|
fun isTreeTrunk(b: ItemID) = BlockCodex[b].hasAllTagsOf("TREE", "TREETRUNK")
|
||||||
|
fun isCultivable(b: ItemID) = BlockCodex[b].hasAllTagsOf("NATURAL", "CULTIVABLE")
|
||||||
|
|
||||||
fun tileInCamera(x: Int, y: Int) =
|
fun tileInCamera(x: Int, y: Int) =
|
||||||
x >= WorldCamera.x.div(TILE_SIZE) && y >= WorldCamera.y.div(TILE_SIZE) &&
|
x >= WorldCamera.x.div(TILE_SIZE) && y >= WorldCamera.y.div(TILE_SIZE) &&
|
||||||
|
|||||||
@@ -471,6 +471,9 @@ class CreateTileAtlas {
|
|||||||
// 0000 (0): INVALID
|
// 0000 (0): INVALID
|
||||||
// 1000 (1): connect-mutual
|
// 1000 (1): connect-mutual
|
||||||
// 0100 (2): connect-self
|
// 0100 (2): connect-self
|
||||||
|
// Line 3: Request for Post-Processing
|
||||||
|
// 0000 (0): do nothing
|
||||||
|
// 1000 (1): subtile deblocking
|
||||||
// NOTE: For this system, the "NORANDTILE" tag is ignored
|
// NOTE: For this system, the "NORANDTILE" tag is ignored
|
||||||
val maskType = if (tilesPixmap.width >= 3*W_SUBTILE_GENERIC) MASK_SUBTILE_GRASS else MASK_SUBTILE_GENERIC
|
val maskType = if (tilesPixmap.width >= 3*W_SUBTILE_GENERIC) MASK_SUBTILE_GRASS else MASK_SUBTILE_GENERIC
|
||||||
var connectionType0 = 0
|
var connectionType0 = 0
|
||||||
|
|||||||
43
src/shaders/deblocking.frag
Normal file
43
src/shaders/deblocking.frag
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
#ifdef GL_ES
|
||||||
|
precision mediump float;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
in vec4 v_color;
|
||||||
|
in vec2 v_texCoords;
|
||||||
|
|
||||||
|
out vec4 fragColor;
|
||||||
|
|
||||||
|
uniform sampler2D u_texture;
|
||||||
|
uniform sampler2D u_blurmap;
|
||||||
|
uniform vec2 resolution;
|
||||||
|
|
||||||
|
const vec4 _four = vec4(1.0 / 4.0);
|
||||||
|
const vec4 _two = vec4(1.0 / 2.0);
|
||||||
|
const float blur = 1.0;
|
||||||
|
vec2 blurUp = vec2(0.0, -blur);
|
||||||
|
vec2 blurDown = vec2(0.0, +blur);
|
||||||
|
vec2 blurLeft = vec2(-blur, 0.0);
|
||||||
|
vec2 blurRight = vec2(+blur, 0.0);
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
vec4 rgbColourIn = texture(u_texture, v_texCoords);
|
||||||
|
vec4 rgbColourL = texture(u_texture, v_texCoords + (blurLeft / resolution));
|
||||||
|
vec4 rgbColourR = texture(u_texture, v_texCoords + (blurRight / resolution));
|
||||||
|
vec4 rgbColourU = texture(u_texture, v_texCoords + (blurUp / resolution));
|
||||||
|
vec4 rgbColourD = texture(u_texture, v_texCoords + (blurDown / resolution));
|
||||||
|
|
||||||
|
vec4 blurH = (rgbColourIn + rgbColourIn + rgbColourL + rgbColourR) * _four;
|
||||||
|
vec4 blurV = (rgbColourIn + rgbColourIn + rgbColourU + rgbColourD) * _four;
|
||||||
|
|
||||||
|
vec4 mapCol = texture(u_blurmap, v_texCoords);
|
||||||
|
|
||||||
|
fragColor = v_color * mix(
|
||||||
|
mix(rgbColourIn, blurH, mapCol.x),
|
||||||
|
mix(rgbColourIn, blurV, mapCol.y),
|
||||||
|
0.5
|
||||||
|
);
|
||||||
|
|
||||||
|
fragColor = rgbColourIn;
|
||||||
|
// fragColor = vec4(v_texCoords.x, v_texCoords.y, 0.0, 1.0);
|
||||||
|
}
|
||||||
@@ -15,9 +15,10 @@ uniform vec2 tilesInAxes; // 8x8
|
|||||||
|
|
||||||
uniform sampler2D tilemap; // RGBA8888
|
uniform sampler2D tilemap; // RGBA8888
|
||||||
uniform sampler2D tilemap2; // RGBA8888
|
uniform sampler2D tilemap2; // RGBA8888
|
||||||
|
|
||||||
uniform sampler2D tilesAtlas; // terrain, wire, fluids, etc.
|
uniform sampler2D tilesAtlas; // terrain, wire, fluids, etc.
|
||||||
uniform sampler2D tilesBlendAtlas; // alternative terrain for the weather mix (e.g. yellowed grass)
|
uniform sampler2D tilesBlendAtlas; // alternative terrain for the weather mix (e.g. yellowed grass)
|
||||||
|
uniform sampler2D deblockingMap;
|
||||||
|
|
||||||
uniform float tilesBlend = 0.0; // percentage of blending [0f..1f]. 0: draws tilesAtlas, 1: draws tilesBlendAtlas
|
uniform float tilesBlend = 0.0; // percentage of blending [0f..1f]. 0: draws tilesAtlas, 1: draws tilesBlendAtlas
|
||||||
|
|
||||||
uniform vec2 tilesInAtlas = vec2(256.0, 256.0);
|
uniform vec2 tilesInAtlas = vec2(256.0, 256.0);
|
||||||
@@ -85,24 +86,26 @@ vec2 uvFlipRot(int op, vec2 uv) {
|
|||||||
return (flipRotMat[op] * vec3(uv, 1.0)).xy;
|
return (flipRotMat[op] * vec3(uv, 1.0)).xy;
|
||||||
}
|
}
|
||||||
|
|
||||||
void main() {
|
const vec4 _four = vec4(1.0 / 4.0);
|
||||||
|
const vec4 _three = vec4(1.0 / 3.0);
|
||||||
|
const vec4 _two = vec4(1.0 / 2.0);
|
||||||
|
const float blur = 1.0;
|
||||||
|
vec2 blurU = vec2(0.0, -blur);
|
||||||
|
vec2 blurD = vec2(0.0, +blur);
|
||||||
|
vec2 blurL = vec2(-blur, 0.0);
|
||||||
|
vec2 blurR = vec2(+blur, 0.0);
|
||||||
|
|
||||||
// READ THE FUCKING MANUAL, YOU DONKEY !! //
|
vec2 overscannedScreenDimension = tilesInAxes * tileSizeInPx; // how many tiles will fit into a screen; one used by the tileFromMap; we need this because screen size is not integer multiple of the tile size
|
||||||
// This code purposedly uses flipped fragcoord. //
|
|
||||||
// Make sure you don't use gl_FragCoord unknowingly! //
|
|
||||||
// Remember, if there's a compile error, shader SILENTLY won't do anything //
|
|
||||||
|
|
||||||
|
|
||||||
// default gl_FragCoord takes half-integer (represeting centre of the pixel) -- could be useful for phys solver?
|
|
||||||
// This one, however, takes exact integer by rounding down. //
|
|
||||||
vec2 overscannedScreenDimension = tilesInAxes * tileSizeInPx; // how many tiles will fit into a screen; one used by the tileFromMap; we need this because screen size is not integer multiple of the tile size
|
|
||||||
vec2 fragCoord = gl_FragCoord.xy + cameraTranslation + haalf; // manually adding half-int to the flipped gl_FragCoord: this avoids driver bug present on the Asahi Linux and possibly (but unlikely) others
|
|
||||||
|
|
||||||
// get required tile numbers //
|
|
||||||
|
|
||||||
|
vec4[2] getTileNumbersFromMap(vec2 fragCoord) {
|
||||||
vec4 tileFromMap = texture(tilemap, fragCoord / overscannedScreenDimension); // raw tile number
|
vec4 tileFromMap = texture(tilemap, fragCoord / overscannedScreenDimension); // raw tile number
|
||||||
vec4 tileFromMap2 = texture(tilemap2, fragCoord / overscannedScreenDimension); // raw tile number
|
vec4 tileFromMap2 = texture(tilemap2, fragCoord / overscannedScreenDimension); // raw tile number
|
||||||
ivec3 tbf = _colToInt(tileFromMap, tileFromMap2);
|
return vec4[2](tileFromMap, tileFromMap2);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4[2] getFragColorForOnscreenCoord(vec2 fragCoord) {
|
||||||
|
vec4[] tileFromMap = getTileNumbersFromMap(fragCoord);
|
||||||
|
ivec3 tbf = _colToInt(tileFromMap[0], tileFromMap[1]);
|
||||||
int tile = tbf.x;
|
int tile = tbf.x;
|
||||||
int breakage = tbf.y;
|
int breakage = tbf.y;
|
||||||
int flipRot = tbf.z;
|
int flipRot = tbf.z;
|
||||||
@@ -115,20 +118,76 @@ void main() {
|
|||||||
|
|
||||||
// don't really need highp here; read the GLES spec
|
// don't really need highp here; read the GLES spec
|
||||||
vec2 uvCoordForTile = uvFlipRot(flipRot, mod(fragCoord, tileSizeInPx)) * _tileSizeInPx * _tilesInAtlas; // 0..0.00390625 regardless of tile position in atlas
|
vec2 uvCoordForTile = uvFlipRot(flipRot, mod(fragCoord, tileSizeInPx)) * _tileSizeInPx * _tilesInAtlas; // 0..0.00390625 regardless of tile position in atlas
|
||||||
|
vec2 uvCoordForTile1 = mod(fragCoord, tileSizeInPx) * _tileSizeInPx * _tilesInAtlas;// 0..0.00390625 regardless of tile position in atlas
|
||||||
vec2 uvCoordOffsetTile = tileXY * _tilesInAtlas; // where the tile starts in the atlas, using uv coord (0..1)
|
vec2 uvCoordOffsetTile = tileXY * _tilesInAtlas; // where the tile starts in the atlas, using uv coord (0..1)
|
||||||
vec2 uvCoordOffsetBreakage = (breakageXY + tileQ) * _tilesInAtlas;
|
vec2 uvCoordOffsetBreakage = (breakageXY + tileQ) * _tilesInAtlas;
|
||||||
|
|
||||||
// get final UV coord for the actual sampling //
|
// get final UV coord for the actual sampling //
|
||||||
|
|
||||||
vec2 finalUVCoordForTile = uvCoordForTile + uvCoordOffsetTile;// where we should be actually looking for in atlas, using UV coord (0..1)
|
vec2 finalUVCoordForTile = uvCoordForTile + uvCoordOffsetTile;// where we should be actually looking for in atlas, using UV coord (0..1)
|
||||||
vec2 finalUVCoordForBreakage = uvCoordForTile + uvCoordOffsetBreakage;
|
vec2 finalUVCoordForBreakage = uvCoordForTile1 + uvCoordOffsetBreakage;
|
||||||
|
|
||||||
// blending a breakage tex with main tex //
|
// blending a breakage tex with main tex //
|
||||||
|
|
||||||
vec4 tileCol = texture(tilesAtlas, finalUVCoordForTile);
|
vec4 tileCol = texture(tilesAtlas, finalUVCoordForTile);
|
||||||
vec4 tileAltCol = texture(tilesBlendAtlas, finalUVCoordForTile);
|
vec4 tileAltCol = texture(tilesBlendAtlas, finalUVCoordForTile);
|
||||||
|
|
||||||
vec4 finalTile = mix(tileCol, tileAltCol, tilesBlend);
|
return vec4[](
|
||||||
|
mix(tileCol, tileAltCol, tilesBlend),
|
||||||
|
finalUVCoordForBreakage.xyxy
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 getFragColorForOnscreenCoord1(vec2 fragCoord) {
|
||||||
|
vec4[] tileFromMap = getTileNumbersFromMap(fragCoord);
|
||||||
|
ivec3 tbf = _colToInt(tileFromMap[0], tileFromMap[1]);
|
||||||
|
int tile = tbf.x;
|
||||||
|
int breakage = tbf.y;
|
||||||
|
int flipRot = tbf.z;
|
||||||
|
ivec4 tileXYnQ = tileNumberToXY(tile);
|
||||||
|
ivec2 tileXY = tileXYnQ.xy;
|
||||||
|
ivec2 tileQ = tileXYnQ.zw;
|
||||||
|
|
||||||
|
// calculate the UV coord value for texture sampling //
|
||||||
|
|
||||||
|
// don't really need highp here; read the GLES spec
|
||||||
|
vec2 uvCoordForTile = uvFlipRot(flipRot, mod(fragCoord, tileSizeInPx)) * _tileSizeInPx * _tilesInAtlas; // 0..0.00390625 regardless of tile position in atlas
|
||||||
|
vec2 uvCoordOffsetTile = tileXY * _tilesInAtlas; // where the tile starts in the atlas, using uv coord (0..1)
|
||||||
|
|
||||||
|
// get final UV coord for the actual sampling //
|
||||||
|
|
||||||
|
vec2 finalUVCoordForTile = uvCoordForTile + uvCoordOffsetTile;// where we should be actually looking for in atlas, using UV coord (0..1)
|
||||||
|
|
||||||
|
// blending a breakage tex with main tex //
|
||||||
|
|
||||||
|
vec4 tileCol = texture(tilesAtlas, finalUVCoordForTile);
|
||||||
|
vec4 tileAltCol = texture(tilesBlendAtlas, finalUVCoordForTile);
|
||||||
|
|
||||||
|
return mix(tileCol, tileAltCol, tilesBlend);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec2 fragCoord = gl_FragCoord.xy + cameraTranslation + haalf; // manually adding half-int to the flipped gl_FragCoord: this avoids driver bug present on the Asahi Linux and possibly (but unlikely) others
|
||||||
|
|
||||||
|
vec4[] fv = getFragColorForOnscreenCoord(fragCoord);
|
||||||
|
vec2 finalUVCoordForBreakage = fv[1].xy;
|
||||||
|
|
||||||
|
vec4 finalTileC = fv[0];
|
||||||
|
vec4 finalTileL = getFragColorForOnscreenCoord1(fragCoord + blurL);
|
||||||
|
vec4 finalTileR = getFragColorForOnscreenCoord1(fragCoord + blurR);
|
||||||
|
vec4 finalTileU = getFragColorForOnscreenCoord1(fragCoord + blurU);
|
||||||
|
vec4 finalTileD = getFragColorForOnscreenCoord1(fragCoord + blurD);
|
||||||
|
|
||||||
|
vec4 blurH = (finalTileC + finalTileL + finalTileR) * _three;
|
||||||
|
vec4 blurV = (finalTileC + finalTileU + finalTileD) * _three;
|
||||||
|
|
||||||
|
vec4 mapCol = vec4(1.0, 0.0, 1.0, finalTileC.a);//texture(u_blurmap, v_texCoords);
|
||||||
|
|
||||||
|
vec4 finalTile = mix(
|
||||||
|
mix(finalTileC, blurH, mapCol.x),
|
||||||
|
mix(finalTileC, blurV, mapCol.y),
|
||||||
|
0.5
|
||||||
|
);
|
||||||
|
|
||||||
vec4 finalBreakage = drawBreakage * texture(tilesAtlas, finalUVCoordForBreakage); // drawBreakeage = 0 to not draw, = 1 to draw
|
vec4 finalBreakage = drawBreakage * texture(tilesAtlas, finalUVCoordForBreakage); // drawBreakeage = 0 to not draw, = 1 to draw
|
||||||
|
|
||||||
|
|||||||
BIN
work_files/graphics/terrain/deblocking_mask.kra
LFS
Normal file
BIN
work_files/graphics/terrain/deblocking_mask.kra
LFS
Normal file
Binary file not shown.
Reference in New Issue
Block a user