tried to tackle the alpha blending issue but it seems the problem is on somewhere far far away

This commit is contained in:
minjaesong
2022-04-20 17:53:47 +09:00
parent cfcdb9c998
commit b3a27bb428
6 changed files with 36 additions and 51 deletions

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -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) {}

View File

@@ -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 {

View File

@@ -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;
} }