pre calculate alpha mipmap clipping

Thats actually 2 improvements:
 - reducing of drawcalls, there is no distinction between opaque and transparent anymore
 - reducing checks in shader
This commit is contained in:
Moritz Zwerger 2023-12-15 08:08:22 +01:00
parent 01573c4ace
commit 2f052ff198
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
24 changed files with 58 additions and 140 deletions

View File

@ -34,7 +34,6 @@ import de.bixilon.minosoft.gui.rendering.system.base.PolygonModes
import de.bixilon.minosoft.gui.rendering.system.base.layer.OpaqueLayer
import de.bixilon.minosoft.gui.rendering.system.base.layer.RenderLayer
import de.bixilon.minosoft.gui.rendering.system.base.layer.TranslucentLayer
import de.bixilon.minosoft.gui.rendering.system.base.layer.TransparentLayer
import de.bixilon.minosoft.gui.rendering.system.base.settings.RenderSettings
import de.bixilon.minosoft.gui.rendering.system.dummy.DummyRenderSystem
import de.bixilon.minosoft.gui.rendering.system.dummy.texture.DummyTexture
@ -227,4 +226,9 @@ class WorldRendererPipelineTest {
override val settings = RenderSettings.DEFAULT
override val priority = priority
}
private object TransparentLayer : RenderLayer {
override val settings = OpaqueLayer.settings
override val priority get() = 2000
}
}

View File

@ -44,7 +44,6 @@ import de.bixilon.minosoft.gui.rendering.system.base.RenderSystem
import de.bixilon.minosoft.gui.rendering.system.base.layer.OpaqueLayer
import de.bixilon.minosoft.gui.rendering.system.base.layer.RenderLayer
import de.bixilon.minosoft.gui.rendering.system.base.layer.TranslucentLayer
import de.bixilon.minosoft.gui.rendering.system.base.layer.TransparentLayer
import de.bixilon.minosoft.gui.rendering.system.base.settings.RenderSettings
import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2iUtil.EMPTY
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.EMPTY
@ -62,9 +61,8 @@ class ChunkRenderer(
private val profile = connection.profiles.block
override val renderSystem: RenderSystem = context.system
val visibilityGraph = context.camera.visibilityGraph
private val shader = renderSystem.createShader(minosoft("chunk")) { ChunkShader(it, false) }
private val transparentShader = renderSystem.createShader(minosoft("chunk")) { ChunkShader(it, true) }
private val textShader = renderSystem.createShader(minosoft("chunk")) { ChunkShader(it, true) }
private val shader = renderSystem.createShader(minosoft("chunk")) { ChunkShader(it) }
private val textShader = renderSystem.createShader(minosoft("chunk")) { ChunkShader(it) }
val lock = SimpleLock()
val world: World = connection.world
@ -93,7 +91,6 @@ class ChunkRenderer(
override fun registerLayers() {
layers.register(OpaqueLayer, shader, this::drawBlocksOpaque) { visible.opaque.isEmpty() }
layers.register(TransparentLayer, transparentShader, this::drawBlocksTransparent) { visible.transparent.isEmpty() }
layers.register(TranslucentLayer, shader, this::drawBlocksTranslucent) { visible.translucent.isEmpty() }
layers.register(TextLayer, textShader, this::drawText) { visible.text.isEmpty() }
layers.register(BlockEntitiesLayer, shader, this::drawBlockEntities) { visible.blockEntities.isEmpty() }
@ -101,7 +98,6 @@ class ChunkRenderer(
override fun postInit(latch: AbstractLatch) {
shader.load()
transparentShader.load()
textShader.native.defines["FIXED_MIPMAP_LEVEL"] = 0
textShader.load()
@ -231,12 +227,6 @@ class ChunkRenderer(
}
}
private fun drawBlocksTransparent() {
for (mesh in visible.transparent) {
mesh.draw()
}
}
private fun drawBlocksTranslucent() {
for (mesh in visible.translucent) {
mesh.draw()

View File

@ -34,7 +34,6 @@ class ChunkMeshes(
val center: Vec3 = Vec3(Vec3i.of(chunkPosition, sectionHeight, Vec3i(8, 8, 8)))
var opaqueMesh: ChunkMesh? = ChunkMesh(context, if (smallMesh) 3000 else 100000)
var translucentMesh: ChunkMesh? = ChunkMesh(context, if (smallMesh) 3000 else 10000, onDemand = true)
var transparentMesh: ChunkMesh? = ChunkMesh(context, if (smallMesh) 3000 else 20000, onDemand = true)
var textMesh: ChunkMesh? = ChunkMesh(context, if (smallMesh) 5000 else 50000, onDemand = true)
var blockEntities: ArrayList<BlockEntityRenderer<*>>? = null
@ -45,7 +44,6 @@ class ChunkMeshes(
fun finish() {
this.opaqueMesh?.finish()
this.translucentMesh?.finish()
this.transparentMesh?.finish()
this.textMesh?.finish()
}
@ -53,7 +51,6 @@ class ChunkMeshes(
fun load() {
this.opaqueMesh?.load()
this.translucentMesh?.load()
this.transparentMesh?.load()
this.textMesh?.load()
val blockEntities = this.blockEntities
if (blockEntities != null) {
@ -84,7 +81,6 @@ class ChunkMeshes(
if (processMesh(opaqueMesh)) opaqueMesh = null
if (processMesh(translucentMesh)) translucentMesh = null
if (processMesh(transparentMesh)) transparentMesh = null
if (processMesh(textMesh)) textMesh = null
@ -102,7 +98,6 @@ class ChunkMeshes(
fun unload() {
opaqueMesh?.unload()
translucentMesh?.unload()
transparentMesh?.unload()
textMesh?.unload()
val blockEntities = blockEntities
@ -141,8 +136,7 @@ class ChunkMeshes(
override fun addVertex(x: Float, y: Float, z: Float, u: Float, v: Float, textureId: Float, lightTint: Float) = Broken()
override fun get(transparency: TextureTransparencies) = when (transparency) {
TextureTransparencies.OPAQUE -> opaqueMesh
TextureTransparencies.TRANSPARENT -> transparentMesh
TextureTransparencies.TRANSLUCENT -> translucentMesh
else -> opaqueMesh
}!!
}

View File

@ -24,12 +24,11 @@ import de.bixilon.minosoft.util.KUtil.format
class VisibleMeshes(val cameraPosition: Vec3 = Vec3.EMPTY, previous: VisibleMeshes? = null) {
val opaque: ArrayList<ChunkMesh> = ArrayList(previous?.opaque?.size ?: 128)
val translucent: ArrayList<ChunkMesh> = ArrayList(previous?.translucent?.size ?: 16)
val transparent: ArrayList<ChunkMesh> = ArrayList(previous?.transparent?.size ?: 128)
val text: ArrayList<ChunkMesh> = ArrayList(previous?.text?.size ?: 16)
val blockEntities: ArrayList<BlockEntityRenderer<*>> = ArrayList(previous?.blockEntities?.size ?: 128)
val sizeString: String
get() = "${opaque.size.format()}|${translucent.size.format()}|${transparent.size.format()}|${text.size.format()}|${blockEntities.size.format()}"
get() = "${opaque.size.format()}|${translucent.size.format()}|${text.size.format()}|${blockEntities.size.format()}"
fun addMesh(mesh: ChunkMeshes) {
@ -42,10 +41,6 @@ class VisibleMeshes(val cameraPosition: Vec3 = Vec3.EMPTY, previous: VisibleMesh
it.distance = -distance
translucent += it
}
mesh.transparentMesh?.let {
it.distance = distance
transparent += it
}
mesh.textMesh?.let {
it.distance = distance
text += it
@ -60,7 +55,6 @@ class VisibleMeshes(val cameraPosition: Vec3 = Vec3.EMPTY, previous: VisibleMesh
val worker = UnconditionalWorker()
worker += UnconditionalTask(ThreadPool.Priorities.HIGHER) { opaque.sort() }
worker += UnconditionalTask(ThreadPool.Priorities.HIGHER) { translucent.sort() }
worker += UnconditionalTask(ThreadPool.Priorities.HIGHER) { transparent.sort() }
worker += UnconditionalTask(ThreadPool.Priorities.HIGHER) { text.sort() }
worker.work()
}
@ -69,7 +63,6 @@ class VisibleMeshes(val cameraPosition: Vec3 = Vec3.EMPTY, previous: VisibleMesh
fun removeMesh(mesh: ChunkMeshes) {
mesh.opaqueMesh?.let { opaque -= it }
mesh.translucentMesh?.let { translucent -= it }
mesh.transparentMesh?.let { transparent -= it }
mesh.textMesh?.let { text -= it }
mesh.blockEntities?.let { blockEntities -= it }
}
@ -77,7 +70,6 @@ class VisibleMeshes(val cameraPosition: Vec3 = Vec3.EMPTY, previous: VisibleMesh
fun clear() {
opaque.clear()
translucent.clear()
transparent.clear()
text.clear()
blockEntities.clear()
}

View File

@ -36,7 +36,6 @@ import de.bixilon.minosoft.gui.rendering.chunk.mesh.ChunkMesh
import de.bixilon.minosoft.gui.rendering.chunk.mesh.ChunkMeshes
import de.bixilon.minosoft.gui.rendering.models.block.state.baked.cull.FaceCulling
import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.Texture
import de.bixilon.minosoft.gui.rendering.textures.TextureUtil.getMesh
import de.bixilon.minosoft.gui.rendering.util.VecUtil.plus
import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2Util.EMPTY
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.rotate
@ -149,7 +148,7 @@ class FluidSectionMesher(
}
}
val meshToUse = texture.transparency.getMesh(mesh)
val meshToUse = mesh[texture.transparency]
val positions = arrayOf(
Vec3(offsetPosition.x, offsetPosition.y + cornerHeights[0], offsetPosition.z),
@ -222,7 +221,7 @@ class FluidSectionMesher(
Vec2(0.5f, (1 - v2) / 2),
)
val meshToUse = model.flowing.transparency.getMesh(mesh)
val meshToUse = mesh[model.flowing.transparency]
val fluidLight = chunk.light[x, offsetY + y, z]
addFluidVertices(meshToUse, positions, texturePositions, model.flowing, tint, fluidLight)
rendered = true

View File

@ -24,8 +24,7 @@ import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureManager
class ChunkShader(
override val native: NativeShader,
override val transparent: Boolean,
) : Shader(), TextureShader, AnimatedShader, LightShader, TransparentShader, ViewProjectionShader, FogShader {
) : Shader(), TextureShader, AnimatedShader, LightShader, ViewProjectionShader, FogShader {
override var textures: TextureManager by textureManager()
override val lightmap: LightmapBuffer by lightmap()
override var viewProjectionMatrix: Mat4 by viewProjectionMatrix()

View File

@ -30,8 +30,8 @@ import de.bixilon.minosoft.gui.rendering.renderer.renderer.RendererBuilder
import de.bixilon.minosoft.gui.rendering.renderer.renderer.world.LayerSettings
import de.bixilon.minosoft.gui.rendering.renderer.renderer.world.WorldRenderer
import de.bixilon.minosoft.gui.rendering.system.base.RenderSystem
import de.bixilon.minosoft.gui.rendering.system.base.layer.OpaqueLayer
import de.bixilon.minosoft.gui.rendering.system.base.layer.TranslucentLayer
import de.bixilon.minosoft.gui.rendering.system.base.layer.TransparentLayer
import de.bixilon.minosoft.gui.rendering.system.base.phases.SkipAll
import de.bixilon.minosoft.modding.event.listener.CallbackEventListener.Companion.listen
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
@ -49,11 +49,11 @@ class ParticleRenderer(
override val layers = LayerSettings()
override val renderSystem: RenderSystem = context.system
private val profile = connection.profiles.particle
private val transparentShader = renderSystem.createShader(minosoft("particle")) { ParticleShader(it, true) }
private val translucentShader = renderSystem.createShader(minosoft("particle")) { ParticleShader(it, false) }
private val shader = renderSystem.createShader(minosoft("particle")) { ParticleShader(it) }
private val translucentShader = renderSystem.createShader(minosoft("particle")) { ParticleShader(it) }
// There is no opaque mesh because it is simply not needed (every particle has transparency)
private var transparentMesh = ParticleMesh(context, BufferedArrayFloatList(MAXIMUM_AMOUNT * ParticleMesh.ParticleMeshStruct.FLOATS_PER_VERTEX))
private var mesh = ParticleMesh(context, BufferedArrayFloatList(MAXIMUM_AMOUNT * ParticleMesh.ParticleMeshStruct.FLOATS_PER_VERTEX))
private var translucentMesh = ParticleMesh(context, BufferedArrayFloatList(MAXIMUM_AMOUNT * ParticleMesh.ParticleMeshStruct.FLOATS_PER_VERTEX))
private val particlesLock = SimpleLock()
@ -103,7 +103,7 @@ class ParticleRenderer(
get() = particles.size
override fun registerLayers() {
layers.register(TransparentLayer, transparentShader, this::drawTransparent)
layers.register(OpaqueLayer, shader, this::drawTransparent)
layers.register(TranslucentLayer, translucentShader, this::drawTranslucent)
}
@ -115,7 +115,7 @@ class ParticleRenderer(
matrixUpdate = true
}
transparentMesh.load()
mesh.load()
translucentMesh.load()
for (particle in connection.registries.particleType) {
for (resourceLocation in particle.textures) {
@ -127,7 +127,7 @@ class ParticleRenderer(
}
override fun postInit(latch: AbstractLatch) {
transparentShader.load()
shader.load()
translucentShader.load()
connection.world.particle = this
@ -198,8 +198,8 @@ class ParticleRenderer(
val cameraRight = Vec3(matrix[0][0], matrix[1][0], matrix[2][0])
val cameraUp = Vec3(matrix[0][1], matrix[1][1], matrix[2][1])
transparentShader.cameraRight = cameraRight
transparentShader.cameraUp = cameraUp
shader.cameraRight = cameraRight
shader.cameraUp = cameraUp
translucentShader.cameraRight = cameraRight
translucentShader.cameraUp = cameraUp
@ -210,14 +210,14 @@ class ParticleRenderer(
updateShaders()
matrixUpdate = false
}
transparentMesh.unload()
mesh.unload()
translucentMesh.unload()
}
override fun prepareDrawAsync() {
transparentMesh.data.clear()
mesh.data.clear()
translucentMesh.data.clear()
transparentMesh = ParticleMesh(context, transparentMesh.data)
mesh = ParticleMesh(context, mesh.data)
translucentMesh = ParticleMesh(context, translucentMesh.data)
particlesLock.acquire()
@ -229,7 +229,7 @@ class ParticleRenderer(
if (particle.dead) {
continue
}
particle.addVertex(transparentMesh, translucentMesh, time)
particle.addVertex(mesh, translucentMesh, time)
if (index % 1000 == 0) {
time = millis()
@ -245,12 +245,12 @@ class ParticleRenderer(
}
override fun postPrepareDraw() {
transparentMesh.load()
mesh.load()
translucentMesh.load()
}
private fun drawTransparent() {
transparentMesh.draw()
mesh.draw()
}
private fun drawTranslucent() {

View File

@ -17,15 +17,17 @@ import de.bixilon.kotlinglm.mat4x4.Mat4
import de.bixilon.kotlinglm.vec3.Vec3
import de.bixilon.minosoft.gui.rendering.light.LightmapBuffer
import de.bixilon.minosoft.gui.rendering.shader.Shader
import de.bixilon.minosoft.gui.rendering.shader.types.*
import de.bixilon.minosoft.gui.rendering.shader.types.AnimatedShader
import de.bixilon.minosoft.gui.rendering.shader.types.LightShader
import de.bixilon.minosoft.gui.rendering.shader.types.TextureShader
import de.bixilon.minosoft.gui.rendering.shader.types.ViewProjectionShader
import de.bixilon.minosoft.gui.rendering.system.base.shader.NativeShader
import de.bixilon.minosoft.gui.rendering.system.base.shader.ShaderUniforms
import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureManager
class ParticleShader(
override val native: NativeShader,
override val transparent: Boolean,
) : Shader(), TextureShader, AnimatedShader, LightShader, TransparentShader, ViewProjectionShader {
) : Shader(), TextureShader, AnimatedShader, LightShader, ViewProjectionShader {
override var textures: TextureManager by textureManager()
override val lightmap: LightmapBuffer by lightmap()
override var viewProjectionMatrix: Mat4 by viewProjectionMatrix()

View File

@ -236,7 +236,7 @@ abstract class Particle(
}
}
abstract fun addVertex(transparentMesh: ParticleMesh, particleMesh: ParticleMesh, time: Long)
abstract fun addVertex(mesh: ParticleMesh, translucentMesh: ParticleMesh, time: Long)
companion object {
private const val MAGIC_VELOCITY_CONSTANT = 0.4

View File

@ -1,6 +1,6 @@
/*
* Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger
* Copyright (C) 2020-2023 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
@ -21,5 +21,5 @@ import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
abstract class NoRenderParticle(connection: PlayConnection, position: Vec3d, velocity: Vec3d, data: ParticleData?) : Particle(connection, position, velocity, data) {
override fun addVertex(transparentMesh: ParticleMesh, particleMesh: ParticleMesh, time: Long) = Unit
override fun addVertex(mesh: ParticleMesh, translucentMesh: ParticleMesh, time: Long) = Unit
}

View File

@ -1,6 +1,6 @@
/*
* Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger
* Copyright (C) 2020-2023 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
@ -25,13 +25,13 @@ abstract class TextureParticle(connection: PlayConnection, position: Vec3d, velo
abstract val texture: Texture?
override fun addVertex(transparentMesh: ParticleMesh, particleMesh: ParticleMesh, time: Long) {
override fun addVertex(mesh: ParticleMesh, translucentMesh: ParticleMesh, time: Long) {
val light = light
val texture = texture ?: return
when {
texture.transparency == TextureTransparencies.TRANSLUCENT || color.alpha != 255 -> particleMesh
else -> transparentMesh
texture.transparency == TextureTransparencies.TRANSLUCENT || color.alpha != 255 -> translucentMesh
else -> mesh
}.addVertex(getCameraPosition(time), scale, texture, color, light = light)
}
}

View File

@ -1,6 +1,6 @@
/*
* Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger
* Copyright (C) 2020-2023 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
@ -25,13 +25,13 @@ abstract class AdvancedTextureParticle(connection: PlayConnection, position: Vec
var minUV: Vec2 = Vec2(0.0f, 0.0f)
var maxUV: Vec2 = Vec2(1.0f, 1.0f)
override fun addVertex(transparentMesh: ParticleMesh, particleMesh: ParticleMesh, time: Long) {
override fun addVertex(mesh: ParticleMesh, translucentMesh: ParticleMesh, time: Long) {
val light = light
val texture = texture ?: return
when {
texture.transparency == TextureTransparencies.TRANSLUCENT || color.alpha != 255 -> particleMesh
else -> transparentMesh
texture.transparency == TextureTransparencies.TRANSLUCENT || color.alpha != 255 -> translucentMesh
else -> mesh
}.addVertex(getCameraPosition(time), scale, texture, color, minUV.array, maxUV.array, light)
}
}

View File

@ -13,9 +13,7 @@
package de.bixilon.minosoft.gui.rendering.shader
import de.bixilon.minosoft.gui.rendering.shader.types.TransparentShader
import de.bixilon.minosoft.gui.rendering.shader.uniform.ShaderUniform
import de.bixilon.minosoft.gui.rendering.system.base.shader.NativeShader
abstract class Shader : AbstractShader {
private val uniforms: MutableMap<String, ShaderUniform<*>> = mutableMapOf()
@ -26,9 +24,6 @@ abstract class Shader : AbstractShader {
}
fun load() {
if (this is TransparentShader && this.transparent) {
native.defines["TRANSPARENT"] = " "
}
native.load()
native.context.system.shaders += this
for (uniform in uniforms.values) {

View File

@ -1,18 +0,0 @@
/*
* Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.gui.rendering.shader.types
interface TransparentShader {
val transparent: Boolean
}

View File

@ -1,21 +0,0 @@
/*
* Minosoft
* Copyright (C) 2020-2023 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.gui.rendering.system.base.layer
import de.bixilon.minosoft.gui.rendering.system.base.settings.DefaultSettings
object TransparentLayer : RenderLayer {
override val settings get() = DefaultSettings.TRANSPARENT
override val priority: Int get() = 1000
}

View File

@ -17,7 +17,6 @@ import de.bixilon.minosoft.gui.rendering.system.base.BlendingFunctions
object DefaultSettings {
val OPAQUE = RenderSettings.DEFAULT
val TRANSPARENT = RenderSettings(blending = true)
val TRANSLUCENT = RenderSettings(
blending = true,
sourceRGB = BlendingFunctions.SOURCE_ALPHA,

View File

@ -18,9 +18,6 @@ import de.bixilon.kutil.exception.Broken
import de.bixilon.kutil.file.FileUtil.createParent
import de.bixilon.minosoft.data.registries.identified.ResourceLocation
import de.bixilon.minosoft.data.registries.identified.ResourceLocationUtil.extend
import de.bixilon.minosoft.gui.rendering.chunk.mesh.ChunkMesh
import de.bixilon.minosoft.gui.rendering.chunk.mesh.ChunkMeshes
import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureTransparencies
import de.bixilon.minosoft.gui.rendering.system.base.texture.data.buffer.RGB8Buffer
import de.bixilon.minosoft.gui.rendering.system.base.texture.data.buffer.RGBA8Buffer
import de.bixilon.minosoft.gui.rendering.system.base.texture.data.buffer.TextureBuffer
@ -40,14 +37,6 @@ object TextureUtil {
return this.extend(prefix = "textures/", suffix = ".png")
}
fun TextureTransparencies.getMesh(mesh: ChunkMeshes): ChunkMesh {
return when (this) {
TextureTransparencies.OPAQUE -> mesh.opaqueMesh
TextureTransparencies.TRANSLUCENT -> mesh.translucentMesh
TextureTransparencies.TRANSPARENT -> mesh.transparentMesh
}!!
}
private fun InputStream.readTexture1(factory: TextureBufferFactory<*>?): TextureBuffer {
val decoder = PNGDecoder(this)
val size = Vec2i(decoder.width, decoder.height)

View File

@ -19,6 +19,9 @@ package example.jonathan2520;
public class SRGBAverager {
private static final SRGBTable SRGB = new SRGBTable();
private static final float ALPHA_THRESHOLD = 0.6f;
private static final int ALPHA_THRESHOLD_INT = (int) (0xFF * ALPHA_THRESHOLD);
public static int average(int c0, int c1, int c2, int c3) {
if ((((c0 | c1 | c2 | c3) ^ (c0 & c1 & c2 & c3)) & 0xff000000) == 0) {
@ -61,6 +64,17 @@ public class SRGBAverager {
float a2 = c2 & 0xff;
float a3 = c3 & 0xff;
float a = a0 + a1 + a2 + a3;
int ai = (int) (0.25F * a + 0.5F);
// check if opaque and transparent are mixed, if so check if target alpha is above specific threshold to keep it
if ((a == 0) && (a0 == 0xff || a1 == 0xff || a2 == 0xff || a3 == 0xff)) {
if (a1 < ALPHA_THRESHOLD_INT) {
return 0;
}
ai = 0xff;
}
float r = a0 * SRGB.decode(c0 >> 24 & 0xff)
+ a1 * SRGB.decode(c1 >> 24 & 0xff)
+ a2 * SRGB.decode(c2 >> 24 & 0xff)
@ -76,12 +90,11 @@ public class SRGBAverager {
+ a2 * SRGB.decode(c2 >> 8 & 0xff)
+ a3 * SRGB.decode(c3 >> 8 & 0xff);
float a = a0 + a1 + a2 + a3;
return SRGB.encode(r / a) << 24
| SRGB.encode(g / a) << 16
| SRGB.encode(b / a) << 8
| (int) (0.25F * a + 0.5F);
| ai;
}
}
}

View File

@ -13,7 +13,6 @@
#version 330 core
#define TRANSPARENT
out vec4 foutColor;

View File

@ -13,7 +13,6 @@
#version 330 core
#define TRANSPARENT
out vec4 foutColor;

View File

@ -29,15 +29,4 @@ void discard_alpha() {
}
#endif
}
void set_alpha_transparent() {
#ifndef DISABLE_ALPHA_DISCARD
if (foutColor.a < 0.6f) {
discard;
} else {
foutColor.a = 1.0f;
}
#endif
}
#endif

View File

@ -66,10 +66,6 @@ void applyTexel() {
vec4 texel = getAnimationTexture();
foutColor = texel;
#ifdef TRANSPARENT
set_alpha_transparent();
#endif
#ifdef FOG
set_fog();
#endif

View File

@ -14,7 +14,6 @@
#version 330 core
#define FOG
#define TRANSPARENT
out vec4 foutColor;

View File

@ -14,7 +14,6 @@
#version 330 core
#define FOG
#define TRANSPARENT
out vec4 foutColor;