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

View File

@ -34,7 +34,6 @@ class ChunkMeshes(
val center: Vec3 = Vec3(Vec3i.of(chunkPosition, sectionHeight, Vec3i(8, 8, 8))) val center: Vec3 = Vec3(Vec3i.of(chunkPosition, sectionHeight, Vec3i(8, 8, 8)))
var opaqueMesh: ChunkMesh? = ChunkMesh(context, if (smallMesh) 3000 else 100000) var opaqueMesh: ChunkMesh? = ChunkMesh(context, if (smallMesh) 3000 else 100000)
var translucentMesh: ChunkMesh? = ChunkMesh(context, if (smallMesh) 3000 else 10000, onDemand = true) 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 textMesh: ChunkMesh? = ChunkMesh(context, if (smallMesh) 5000 else 50000, onDemand = true)
var blockEntities: ArrayList<BlockEntityRenderer<*>>? = null var blockEntities: ArrayList<BlockEntityRenderer<*>>? = null
@ -45,7 +44,6 @@ class ChunkMeshes(
fun finish() { fun finish() {
this.opaqueMesh?.finish() this.opaqueMesh?.finish()
this.translucentMesh?.finish() this.translucentMesh?.finish()
this.transparentMesh?.finish()
this.textMesh?.finish() this.textMesh?.finish()
} }
@ -53,7 +51,6 @@ class ChunkMeshes(
fun load() { fun load() {
this.opaqueMesh?.load() this.opaqueMesh?.load()
this.translucentMesh?.load() this.translucentMesh?.load()
this.transparentMesh?.load()
this.textMesh?.load() this.textMesh?.load()
val blockEntities = this.blockEntities val blockEntities = this.blockEntities
if (blockEntities != null) { if (blockEntities != null) {
@ -84,7 +81,6 @@ class ChunkMeshes(
if (processMesh(opaqueMesh)) opaqueMesh = null if (processMesh(opaqueMesh)) opaqueMesh = null
if (processMesh(translucentMesh)) translucentMesh = null if (processMesh(translucentMesh)) translucentMesh = null
if (processMesh(transparentMesh)) transparentMesh = null
if (processMesh(textMesh)) textMesh = null if (processMesh(textMesh)) textMesh = null
@ -102,7 +98,6 @@ class ChunkMeshes(
fun unload() { fun unload() {
opaqueMesh?.unload() opaqueMesh?.unload()
translucentMesh?.unload() translucentMesh?.unload()
transparentMesh?.unload()
textMesh?.unload() textMesh?.unload()
val blockEntities = blockEntities 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 addVertex(x: Float, y: Float, z: Float, u: Float, v: Float, textureId: Float, lightTint: Float) = Broken()
override fun get(transparency: TextureTransparencies) = when (transparency) { override fun get(transparency: TextureTransparencies) = when (transparency) {
TextureTransparencies.OPAQUE -> opaqueMesh
TextureTransparencies.TRANSPARENT -> transparentMesh
TextureTransparencies.TRANSLUCENT -> translucentMesh 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) { class VisibleMeshes(val cameraPosition: Vec3 = Vec3.EMPTY, previous: VisibleMeshes? = null) {
val opaque: ArrayList<ChunkMesh> = ArrayList(previous?.opaque?.size ?: 128) val opaque: ArrayList<ChunkMesh> = ArrayList(previous?.opaque?.size ?: 128)
val translucent: ArrayList<ChunkMesh> = ArrayList(previous?.translucent?.size ?: 16) 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 text: ArrayList<ChunkMesh> = ArrayList(previous?.text?.size ?: 16)
val blockEntities: ArrayList<BlockEntityRenderer<*>> = ArrayList(previous?.blockEntities?.size ?: 128) val blockEntities: ArrayList<BlockEntityRenderer<*>> = ArrayList(previous?.blockEntities?.size ?: 128)
val sizeString: String 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) { fun addMesh(mesh: ChunkMeshes) {
@ -42,10 +41,6 @@ class VisibleMeshes(val cameraPosition: Vec3 = Vec3.EMPTY, previous: VisibleMesh
it.distance = -distance it.distance = -distance
translucent += it translucent += it
} }
mesh.transparentMesh?.let {
it.distance = distance
transparent += it
}
mesh.textMesh?.let { mesh.textMesh?.let {
it.distance = distance it.distance = distance
text += it text += it
@ -60,7 +55,6 @@ class VisibleMeshes(val cameraPosition: Vec3 = Vec3.EMPTY, previous: VisibleMesh
val worker = UnconditionalWorker() val worker = UnconditionalWorker()
worker += UnconditionalTask(ThreadPool.Priorities.HIGHER) { opaque.sort() } worker += UnconditionalTask(ThreadPool.Priorities.HIGHER) { opaque.sort() }
worker += UnconditionalTask(ThreadPool.Priorities.HIGHER) { translucent.sort() } worker += UnconditionalTask(ThreadPool.Priorities.HIGHER) { translucent.sort() }
worker += UnconditionalTask(ThreadPool.Priorities.HIGHER) { transparent.sort() }
worker += UnconditionalTask(ThreadPool.Priorities.HIGHER) { text.sort() } worker += UnconditionalTask(ThreadPool.Priorities.HIGHER) { text.sort() }
worker.work() worker.work()
} }
@ -69,7 +63,6 @@ class VisibleMeshes(val cameraPosition: Vec3 = Vec3.EMPTY, previous: VisibleMesh
fun removeMesh(mesh: ChunkMeshes) { fun removeMesh(mesh: ChunkMeshes) {
mesh.opaqueMesh?.let { opaque -= it } mesh.opaqueMesh?.let { opaque -= it }
mesh.translucentMesh?.let { translucent -= it } mesh.translucentMesh?.let { translucent -= it }
mesh.transparentMesh?.let { transparent -= it }
mesh.textMesh?.let { text -= it } mesh.textMesh?.let { text -= it }
mesh.blockEntities?.let { blockEntities -= it } mesh.blockEntities?.let { blockEntities -= it }
} }
@ -77,7 +70,6 @@ class VisibleMeshes(val cameraPosition: Vec3 = Vec3.EMPTY, previous: VisibleMesh
fun clear() { fun clear() {
opaque.clear() opaque.clear()
translucent.clear() translucent.clear()
transparent.clear()
text.clear() text.clear()
blockEntities.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.chunk.mesh.ChunkMeshes
import de.bixilon.minosoft.gui.rendering.models.block.state.baked.cull.FaceCulling 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.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.VecUtil.plus
import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2Util.EMPTY import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2Util.EMPTY
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.rotate 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( val positions = arrayOf(
Vec3(offsetPosition.x, offsetPosition.y + cornerHeights[0], offsetPosition.z), Vec3(offsetPosition.x, offsetPosition.y + cornerHeights[0], offsetPosition.z),
@ -222,7 +221,7 @@ class FluidSectionMesher(
Vec2(0.5f, (1 - v2) / 2), 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] val fluidLight = chunk.light[x, offsetY + y, z]
addFluidVertices(meshToUse, positions, texturePositions, model.flowing, tint, fluidLight) addFluidVertices(meshToUse, positions, texturePositions, model.flowing, tint, fluidLight)
rendered = true rendered = true

View File

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

View File

@ -17,15 +17,17 @@ import de.bixilon.kotlinglm.mat4x4.Mat4
import de.bixilon.kotlinglm.vec3.Vec3 import de.bixilon.kotlinglm.vec3.Vec3
import de.bixilon.minosoft.gui.rendering.light.LightmapBuffer import de.bixilon.minosoft.gui.rendering.light.LightmapBuffer
import de.bixilon.minosoft.gui.rendering.shader.Shader 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.NativeShader
import de.bixilon.minosoft.gui.rendering.system.base.shader.ShaderUniforms import de.bixilon.minosoft.gui.rendering.system.base.shader.ShaderUniforms
import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureManager import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureManager
class ParticleShader( class ParticleShader(
override val native: NativeShader, override val native: NativeShader,
override val transparent: Boolean, ) : Shader(), TextureShader, AnimatedShader, LightShader, ViewProjectionShader {
) : Shader(), TextureShader, AnimatedShader, LightShader, TransparentShader, ViewProjectionShader {
override var textures: TextureManager by textureManager() override var textures: TextureManager by textureManager()
override val lightmap: LightmapBuffer by lightmap() override val lightmap: LightmapBuffer by lightmap()
override var viewProjectionMatrix: Mat4 by viewProjectionMatrix() 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 { companion object {
private const val MAGIC_VELOCITY_CONSTANT = 0.4 private const val MAGIC_VELOCITY_CONSTANT = 0.4

View File

@ -1,6 +1,6 @@
/* /*
* Minosoft * 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. * 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) { 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 * 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. * 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? 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 light = light
val texture = texture ?: return val texture = texture ?: return
when { when {
texture.transparency == TextureTransparencies.TRANSLUCENT || color.alpha != 255 -> particleMesh texture.transparency == TextureTransparencies.TRANSLUCENT || color.alpha != 255 -> translucentMesh
else -> transparentMesh else -> mesh
}.addVertex(getCameraPosition(time), scale, texture, color, light = light) }.addVertex(getCameraPosition(time), scale, texture, color, light = light)
} }
} }

View File

@ -1,6 +1,6 @@
/* /*
* Minosoft * 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. * 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 minUV: Vec2 = Vec2(0.0f, 0.0f)
var maxUV: Vec2 = Vec2(1.0f, 1.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 light = light
val texture = texture ?: return val texture = texture ?: return
when { when {
texture.transparency == TextureTransparencies.TRANSLUCENT || color.alpha != 255 -> particleMesh texture.transparency == TextureTransparencies.TRANSLUCENT || color.alpha != 255 -> translucentMesh
else -> transparentMesh else -> mesh
}.addVertex(getCameraPosition(time), scale, texture, color, minUV.array, maxUV.array, light) }.addVertex(getCameraPosition(time), scale, texture, color, minUV.array, maxUV.array, light)
} }
} }

View File

@ -13,9 +13,7 @@
package de.bixilon.minosoft.gui.rendering.shader 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.shader.uniform.ShaderUniform
import de.bixilon.minosoft.gui.rendering.system.base.shader.NativeShader
abstract class Shader : AbstractShader { abstract class Shader : AbstractShader {
private val uniforms: MutableMap<String, ShaderUniform<*>> = mutableMapOf() private val uniforms: MutableMap<String, ShaderUniform<*>> = mutableMapOf()
@ -26,9 +24,6 @@ abstract class Shader : AbstractShader {
} }
fun load() { fun load() {
if (this is TransparentShader && this.transparent) {
native.defines["TRANSPARENT"] = " "
}
native.load() native.load()
native.context.system.shaders += this native.context.system.shaders += this
for (uniform in uniforms.values) { 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 { object DefaultSettings {
val OPAQUE = RenderSettings.DEFAULT val OPAQUE = RenderSettings.DEFAULT
val TRANSPARENT = RenderSettings(blending = true)
val TRANSLUCENT = RenderSettings( val TRANSLUCENT = RenderSettings(
blending = true, blending = true,
sourceRGB = BlendingFunctions.SOURCE_ALPHA, 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.kutil.file.FileUtil.createParent
import de.bixilon.minosoft.data.registries.identified.ResourceLocation import de.bixilon.minosoft.data.registries.identified.ResourceLocation
import de.bixilon.minosoft.data.registries.identified.ResourceLocationUtil.extend 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.RGB8Buffer
import de.bixilon.minosoft.gui.rendering.system.base.texture.data.buffer.RGBA8Buffer import de.bixilon.minosoft.gui.rendering.system.base.texture.data.buffer.RGBA8Buffer
import de.bixilon.minosoft.gui.rendering.system.base.texture.data.buffer.TextureBuffer 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") 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 { private fun InputStream.readTexture1(factory: TextureBufferFactory<*>?): TextureBuffer {
val decoder = PNGDecoder(this) val decoder = PNGDecoder(this)
val size = Vec2i(decoder.width, decoder.height) val size = Vec2i(decoder.width, decoder.height)

View File

@ -19,6 +19,9 @@ package example.jonathan2520;
public class SRGBAverager { public class SRGBAverager {
private static final SRGBTable SRGB = new SRGBTable(); 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) { public static int average(int c0, int c1, int c2, int c3) {
if ((((c0 | c1 | c2 | c3) ^ (c0 & c1 & c2 & c3)) & 0xff000000) == 0) { if ((((c0 | c1 | c2 | c3) ^ (c0 & c1 & c2 & c3)) & 0xff000000) == 0) {
@ -61,6 +64,17 @@ public class SRGBAverager {
float a2 = c2 & 0xff; float a2 = c2 & 0xff;
float a3 = c3 & 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) float r = a0 * SRGB.decode(c0 >> 24 & 0xff)
+ a1 * SRGB.decode(c1 >> 24 & 0xff) + a1 * SRGB.decode(c1 >> 24 & 0xff)
+ a2 * SRGB.decode(c2 >> 24 & 0xff) + a2 * SRGB.decode(c2 >> 24 & 0xff)
@ -76,12 +90,11 @@ public class SRGBAverager {
+ a2 * SRGB.decode(c2 >> 8 & 0xff) + a2 * SRGB.decode(c2 >> 8 & 0xff)
+ a3 * SRGB.decode(c3 >> 8 & 0xff); + a3 * SRGB.decode(c3 >> 8 & 0xff);
float a = a0 + a1 + a2 + a3;
return SRGB.encode(r / a) << 24 return SRGB.encode(r / a) << 24
| SRGB.encode(g / a) << 16 | SRGB.encode(g / a) << 16
| SRGB.encode(b / a) << 8 | SRGB.encode(b / a) << 8
| (int) (0.25F * a + 0.5F); | ai;
} }
} }
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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