mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-07 20:31:51 +09:00
tried to tackle the alpha blending issue but it seems the problem is on somewhere far far away
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
package net.torvald.spriteanimation
|
package net.torvald.spriteanimation
|
||||||
|
|
||||||
|
import com.badlogic.gdx.graphics.Color
|
||||||
import com.badlogic.gdx.graphics.Pixmap
|
import com.badlogic.gdx.graphics.Pixmap
|
||||||
import com.badlogic.gdx.graphics.Texture
|
import com.badlogic.gdx.graphics.Texture
|
||||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
||||||
|
|||||||
@@ -153,7 +153,6 @@ object PostProcessor : Disposable {
|
|||||||
else
|
else
|
||||||
shaderPostNoDither
|
shaderPostNoDither
|
||||||
|
|
||||||
|
|
||||||
App.getCurrentDitherTex().bind(1)
|
App.getCurrentDitherTex().bind(1)
|
||||||
fbo.colorBufferTexture.bind(0)
|
fbo.colorBufferTexture.bind(0)
|
||||||
|
|
||||||
|
|||||||
@@ -373,14 +373,17 @@ infix fun Color.mulAndAssign(other: Color): Color {
|
|||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use demultiplier shader on GL Source (foreground) if source has semitransparency
|
||||||
|
*/
|
||||||
fun blendMul(batch: SpriteBatch) {
|
fun blendMul(batch: SpriteBatch) {
|
||||||
// will break if the colour image contains semitransparency
|
|
||||||
batch.enableBlending()
|
batch.enableBlending()
|
||||||
batch.setBlendFunction(GL20.GL_DST_COLOR, GL20.GL_ONE_MINUS_SRC_ALPHA)
|
batch.setBlendFunction(GL20.GL_DST_COLOR, GL20.GL_ONE_MINUS_SRC_ALPHA)
|
||||||
// batch.setBlendFunctionSeparate(GL20.GL_DST_COLOR, GL20.GL_ONE_MINUS_SRC_ALPHA, GL20.GL_DST_ALPHA, GL20.GL_SRC_ALPHA)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use demultiplier shader on GL Source (foreground) if source has semitransparency
|
||||||
|
*/
|
||||||
fun blendScreen(batch: SpriteBatch) {
|
fun blendScreen(batch: SpriteBatch) {
|
||||||
// will break if the colour image contains semitransparency
|
// will break if the colour image contains semitransparency
|
||||||
batch.enableBlending()
|
batch.enableBlending()
|
||||||
@@ -391,21 +394,13 @@ fun blendDisable(batch: SpriteBatch) {
|
|||||||
batch.disableBlending()
|
batch.disableBlending()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GLSource (foreground) must NOT have alpha premultiplied!
|
||||||
|
*/
|
||||||
fun blendNormal(batch: SpriteBatch) {
|
fun blendNormal(batch: SpriteBatch) {
|
||||||
batch.enableBlending()
|
batch.enableBlending()
|
||||||
// batch.setBlendFunction(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA) // for premultiplied textures
|
// batch.setBlendFunction(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA) // for premultiplied textures
|
||||||
batch.setBlendFunctionSeparate(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA, GL20.GL_ONE, GL20.GL_ONE_MINUS_SRC_ALPHA) // for not premultiplied textures
|
batch.setBlendFunctionSeparate(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA, GL20.GL_ONE, GL20.GL_ONE_MINUS_SRC_ALPHA) // for not premultiplied textures
|
||||||
|
|
||||||
// ALPHA *MUST BE* PREMULTIPLIED //
|
|
||||||
|
|
||||||
// One way to tell:
|
|
||||||
// 1. Check (RGB) and (A) values.
|
|
||||||
// 2. If there exist a pixel such that max(R,G,B) > (A), then the image is NOT premultiplied.
|
|
||||||
// Easy way:
|
|
||||||
// Base game (mods/basegame/blocks/terrain.tga.gz) has impure window glass. When looking at the RGB channel only:
|
|
||||||
// premultipied if the glass looks very dark.
|
|
||||||
// not premultipied if the glass looks VERY GREEN.
|
|
||||||
|
|
||||||
// helpful links:
|
// helpful links:
|
||||||
// - https://gamedev.stackexchange.com/questions/82741/normal-blend-mode-with-opengl-trouble
|
// - https://gamedev.stackexchange.com/questions/82741/normal-blend-mode-with-opengl-trouble
|
||||||
// - https://www.andersriggelsen.dk/glblendfunc.php
|
// - https://www.andersriggelsen.dk/glblendfunc.php
|
||||||
@@ -431,17 +426,6 @@ fun gdxSetBlendNormal() {
|
|||||||
gdxSetBlend()
|
gdxSetBlend()
|
||||||
// Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA) // for premultiplied textures
|
// Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA) // for premultiplied textures
|
||||||
Gdx.gl.glBlendFuncSeparate(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA, GL20.GL_ONE, GL20.GL_ONE_MINUS_SRC_ALPHA) // for not premultiplied textures
|
Gdx.gl.glBlendFuncSeparate(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA, GL20.GL_ONE, GL20.GL_ONE_MINUS_SRC_ALPHA) // for not premultiplied textures
|
||||||
|
|
||||||
// ALPHA *MUST BE* PREMULTIPLIED //
|
|
||||||
|
|
||||||
// One way to tell:
|
|
||||||
// 1. Check (RGB) and (A) values.
|
|
||||||
// 2. If there exist a pixel such that max(R,G,B) > (A), then the image is NOT premultiplied.
|
|
||||||
// Easy way:
|
|
||||||
// Base game (mods/basegame/blocks/terrain.tga.gz) has impure window glass. When looking at the RGB channel only:
|
|
||||||
// premultipied if the glass looks very dark.
|
|
||||||
// not premultipied if the glass looks VERY GREEN.
|
|
||||||
|
|
||||||
// helpful links:
|
// helpful links:
|
||||||
// - https://gamedev.stackexchange.com/questions/82741/normal-blend-mode-with-opengl-trouble
|
// - https://gamedev.stackexchange.com/questions/82741/normal-blend-mode-with-opengl-trouble
|
||||||
// - https://www.andersriggelsen.dk/glblendfunc.php
|
// - https://www.andersriggelsen.dk/glblendfunc.php
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import com.badlogic.gdx.utils.GdxRuntimeException
|
|||||||
import net.torvald.random.HQRNG
|
import net.torvald.random.HQRNG
|
||||||
import net.torvald.terrarum.*
|
import net.torvald.terrarum.*
|
||||||
import net.torvald.terrarum.App.measureDebugTime
|
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_SIZE
|
||||||
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZEF
|
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZEF
|
||||||
import net.torvald.terrarum.gameactors.ActorWithBody
|
import net.torvald.terrarum.gameactors.ActorWithBody
|
||||||
@@ -83,7 +82,7 @@ object IngameRenderer : Disposable {
|
|||||||
val shaderKawaseUp: ShaderProgram
|
val shaderKawaseUp: ShaderProgram
|
||||||
|
|
||||||
val shaderBlendGlow: ShaderProgram
|
val shaderBlendGlow: ShaderProgram
|
||||||
val shaderAlphaDither: ShaderProgram
|
val shaderForActors: ShaderProgram
|
||||||
|
|
||||||
private val WIDTH = App.scr.width
|
private val WIDTH = App.scr.width
|
||||||
private val HEIGHT = App.scr.height
|
private val HEIGHT = App.scr.height
|
||||||
@@ -120,7 +119,7 @@ object IngameRenderer : Disposable {
|
|||||||
shaderAtoGrey = App.loadShaderFromClasspath("shaders/default.vert", "shaders/aonly.frag")
|
shaderAtoGrey = App.loadShaderFromClasspath("shaders/default.vert", "shaders/aonly.frag")
|
||||||
|
|
||||||
|
|
||||||
shaderAlphaDither = App.loadShaderFromClasspath("shaders/default.vert", "shaders/alphadither.frag")
|
shaderForActors = App.loadShaderFromClasspath("shaders/default.vert", "shaders/actors.frag")
|
||||||
shaderBlendGlow = App.loadShaderFromClasspath("shaders/blendGlow.vert", "shaders/blendGlow.frag")
|
shaderBlendGlow = App.loadShaderFromClasspath("shaders/blendGlow.vert", "shaders/blendGlow.frag")
|
||||||
|
|
||||||
|
|
||||||
@@ -426,28 +425,24 @@ object IngameRenderer : Disposable {
|
|||||||
|
|
||||||
fboRGB.inAction(camera, batch) {
|
fboRGB.inAction(camera, batch) {
|
||||||
|
|
||||||
batch.inUse {
|
|
||||||
batch.shader = shaderAlphaDither
|
|
||||||
batch.color = Color.WHITE
|
|
||||||
}
|
|
||||||
|
|
||||||
setCameraPosition(0f, 0f)
|
setCameraPosition(0f, 0f)
|
||||||
BlocksDrawer.drawWall(batch.projectionMatrix, false)
|
BlocksDrawer.drawWall(batch.projectionMatrix, false)
|
||||||
|
|
||||||
batch.inUse {
|
batch.inUse {
|
||||||
|
batch.shader = shaderForActors
|
||||||
|
batch.color = Color.WHITE
|
||||||
moveCameraToWorldCoord()
|
moveCameraToWorldCoord()
|
||||||
actorsRenderBehind?.forEach { it.drawBody(batch) }
|
actorsRenderBehind?.forEach { it.drawBody(batch) }
|
||||||
}
|
|
||||||
batch.shader = shaderAlphaDither
|
|
||||||
batch.inUse {
|
|
||||||
particlesContainer?.forEach { it.drawBody(batch) }
|
particlesContainer?.forEach { it.drawBody(batch) }
|
||||||
}
|
}
|
||||||
|
|
||||||
setCameraPosition(0f, 0f)
|
setCameraPosition(0f, 0f)
|
||||||
BlocksDrawer.drawTerrain(batch.projectionMatrix, false)
|
BlocksDrawer.drawTerrain(batch.projectionMatrix, false)
|
||||||
|
|
||||||
batch.shader = shaderAlphaDither
|
batch.shader = shaderForActors
|
||||||
batch.inUse {
|
batch.inUse {
|
||||||
|
batch.shader = shaderForActors
|
||||||
|
batch.color = Color.WHITE
|
||||||
/////////////////
|
/////////////////
|
||||||
// draw actors //
|
// draw actors //
|
||||||
/////////////////
|
/////////////////
|
||||||
@@ -464,6 +459,8 @@ object IngameRenderer : Disposable {
|
|||||||
|
|
||||||
batch.shader = null
|
batch.shader = null
|
||||||
batch.inUse {
|
batch.inUse {
|
||||||
|
batch.shader = shaderForActors
|
||||||
|
batch.color = Color.WHITE
|
||||||
FeaturesDrawer.drawEnvOverlay(batch)
|
FeaturesDrawer.drawEnvOverlay(batch)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -502,6 +499,12 @@ object IngameRenderer : Disposable {
|
|||||||
lightTex.regionWidth * lightmapDownsample,
|
lightTex.regionWidth * lightmapDownsample,
|
||||||
lightTex.regionHeight * lightmapDownsample
|
lightTex.regionHeight * lightmapDownsample
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// if right texture coord for lightTex and fboRGB are obtainable, you can try this:
|
||||||
|
/*
|
||||||
|
vec4 skyboxColour = ...
|
||||||
|
gl_FragCoord = alphablend skyboxColour with (fboRGB * lightTex)
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -529,15 +532,13 @@ object IngameRenderer : Disposable {
|
|||||||
|
|
||||||
fboA.inAction(camera, batch) {
|
fboA.inAction(camera, batch) {
|
||||||
|
|
||||||
batch.inUse {
|
|
||||||
batch.shader = shaderAlphaDither
|
|
||||||
batch.color = Color.WHITE
|
|
||||||
}
|
|
||||||
|
|
||||||
setCameraPosition(0f, 0f)
|
setCameraPosition(0f, 0f)
|
||||||
BlocksDrawer.drawWall(batch.projectionMatrix, true)
|
BlocksDrawer.drawWall(batch.projectionMatrix, true)
|
||||||
|
|
||||||
batch.inUse {
|
batch.inUse {
|
||||||
|
batch.shader = shaderForActors
|
||||||
|
batch.color = Color.WHITE
|
||||||
|
|
||||||
moveCameraToWorldCoord()
|
moveCameraToWorldCoord()
|
||||||
actorsRenderBehind?.forEach { it.drawGlow(batch) }
|
actorsRenderBehind?.forEach { it.drawGlow(batch) }
|
||||||
particlesContainer?.forEach { it.drawGlow(batch) }
|
particlesContainer?.forEach { it.drawGlow(batch) }
|
||||||
@@ -569,6 +570,9 @@ object IngameRenderer : Disposable {
|
|||||||
Gdx.gl.glActiveTexture(GL20.GL_TEXTURE0) // so that batch that comes next will bind any tex to it
|
Gdx.gl.glActiveTexture(GL20.GL_TEXTURE0) // so that batch that comes next will bind any tex to it
|
||||||
|
|
||||||
batch.inUse {
|
batch.inUse {
|
||||||
|
batch.shader = null
|
||||||
|
batch.color = Color.WHITE
|
||||||
|
|
||||||
// draw world
|
// draw world
|
||||||
batch.draw(fboA.colorBufferTexture, 0f, 0f)
|
batch.draw(fboA.colorBufferTexture, 0f, 0f)
|
||||||
batch.flush()
|
batch.flush()
|
||||||
@@ -604,15 +608,13 @@ object IngameRenderer : Disposable {
|
|||||||
private fun drawOverlayActors(actors: List<ActorWithBody>?) {
|
private fun drawOverlayActors(actors: List<ActorWithBody>?) {
|
||||||
fboRGB_lightMixed.inActionF(camera, batch) {
|
fboRGB_lightMixed.inActionF(camera, batch) {
|
||||||
|
|
||||||
batch.inUse {
|
|
||||||
batch.shader = shaderAlphaDither
|
|
||||||
batch.color = Color.WHITE
|
|
||||||
}
|
|
||||||
|
|
||||||
setCameraPosition(0f, 0f)
|
setCameraPosition(0f, 0f)
|
||||||
// BlocksDrawer.renderWhateverGlow_WALL
|
// BlocksDrawer.renderWhateverGlow_WALL
|
||||||
|
|
||||||
batch.inUse {
|
batch.inUse {
|
||||||
|
batch.shader = shaderForActors
|
||||||
|
batch.color = Color.WHITE
|
||||||
|
|
||||||
moveCameraToWorldCoord()
|
moveCameraToWorldCoord()
|
||||||
actors?.forEach {
|
actors?.forEach {
|
||||||
it.drawBody(batch)
|
it.drawBody(batch)
|
||||||
@@ -867,7 +869,7 @@ object IngameRenderer : Disposable {
|
|||||||
shaderKawaseUp.dispose()
|
shaderKawaseUp.dispose()
|
||||||
|
|
||||||
shaderBlendGlow.dispose()
|
shaderBlendGlow.dispose()
|
||||||
shaderAlphaDither.dispose()
|
shaderForActors.dispose()
|
||||||
|
|
||||||
try { fboRGBexport.dispose() }
|
try { fboRGBexport.dispose() }
|
||||||
catch (e: GdxRuntimeException) {}
|
catch (e: GdxRuntimeException) {}
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ internal object BlocksDrawer {
|
|||||||
|
|
||||||
|
|
||||||
private lateinit var tilesQuad: Mesh
|
private lateinit var tilesQuad: Mesh
|
||||||
private val shader = App.loadShaderFromClasspath("shaders/default.vert", "shaders/tiling_dither.frag")
|
private val shader = App.loadShaderFromClasspath("shaders/default.vert", "shaders/tiling.frag")
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
|
||||||
|
|||||||
@@ -30,5 +30,4 @@ void main() {
|
|||||||
vec4 selvec = vec4(0.0, 0.0, 0.0, (alpha > bayerThreshold) ? 1.0 : 0.0);
|
vec4 selvec = vec4(0.0, 0.0, 0.0, (alpha > bayerThreshold) ? 1.0 : 0.0);
|
||||||
|
|
||||||
gl_FragColor = inColor * boolean.yyyx + selvec;
|
gl_FragColor = inColor * boolean.yyyx + selvec;
|
||||||
// gl_FragColor = inColor;
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user