diff --git a/src/main/java/de/bixilon/minosoft/data/world/chunk/Chunk.kt b/src/main/java/de/bixilon/minosoft/data/world/chunk/Chunk.kt index 93bba4ecf..cb8888992 100644 --- a/src/main/java/de/bixilon/minosoft/data/world/chunk/Chunk.kt +++ b/src/main/java/de/bixilon/minosoft/data/world/chunk/Chunk.kt @@ -311,30 +311,34 @@ class Chunk( return traceBlock(blockPosition.inChunkPosition, deltaChunkPosition) } - private fun traceBlock(inChunkSectionPosition: Vec3i, chunkOffset: Vec2i): BlockState? { - if (chunkOffset.x == 0 && chunkOffset.y == 0) { - return this[inChunkSectionPosition] + fun traceChunk(offset: Vec2i): Chunk? { + if (offset.x == 0 && offset.y == 0) { + return this } val neighbours = this.neighbours ?: return null - if (chunkOffset.x > 0) { - chunkOffset.x-- - return neighbours[6].traceBlock(inChunkSectionPosition, chunkOffset) + if (offset.x > 0) { + offset.x-- + return neighbours[6].traceChunk(offset) } - if (chunkOffset.x < 0) { - chunkOffset.x++ - return neighbours[1].traceBlock(inChunkSectionPosition, chunkOffset) + if (offset.x < 0) { + offset.x++ + return neighbours[1].traceChunk(offset) } - if (chunkOffset.y > 0) { - chunkOffset.y-- - return neighbours[4].traceBlock(inChunkSectionPosition, chunkOffset) + if (offset.y > 0) { + offset.y-- + return neighbours[4].traceChunk(offset) } - if (chunkOffset.y < 0) { - chunkOffset.y++ - return neighbours[3].traceBlock(inChunkSectionPosition, chunkOffset) + if (offset.y < 0) { + offset.y++ + return neighbours[3].traceChunk(offset) } - Broken("Can not get chunk from offset: $chunkOffset") + Broken("Can not get chunk from offset: $offset") + } + + private fun traceBlock(inChunkPosition: Vec3i, chunkOffset: Vec2i): BlockState? { + return traceChunk(chunkOffset)?.get(inChunkPosition) } } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/particle/ParticleMesh.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/particle/ParticleMesh.kt index 9d25b0638..7fbb8d1a4 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/particle/ParticleMesh.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/particle/ParticleMesh.kt @@ -27,7 +27,7 @@ import de.bixilon.minosoft.util.collections.floats.DirectArrayFloatList class ParticleMesh(renderWindow: RenderWindow, data: DirectArrayFloatList) : Mesh(renderWindow, ParticleMeshStruct, PrimitiveTypes.POINT, -1, clearOnLoad = false, data = data) { - fun addVertex(position: Vec3d, scale: Float, texture: AbstractTexture, tintColor: RGBColor, uvMin: FloatArray? = null, uvMax: FloatArray? = null) { + fun addVertex(position: Vec3d, scale: Float, texture: AbstractTexture, tintColor: RGBColor, uvMin: FloatArray? = null, uvMax: FloatArray? = null, light: Int) { val minTransformedUV = if (uvMin == null) { EMPTY_UV_ARRAY } else { @@ -43,6 +43,7 @@ class ParticleMesh(renderWindow: RenderWindow, data: DirectArrayFloatList) : Mes data.add(texture.renderData.shaderTextureId.buffer()) data.add(scale) data.add(tintColor.rgba.buffer()) + data.add(light.buffer()) } @@ -57,6 +58,7 @@ class ParticleMesh(renderWindow: RenderWindow, data: DirectArrayFloatList) : Mes val indexLayerAnimation: Int, val scale: Float, val tintColor: RGBColor, + val light: Int, ) { companion object : MeshStruct(ParticleMeshStruct::class) } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/particle/ParticleRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/particle/ParticleRenderer.kt index c40ca811e..96f50e2ef 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/particle/ParticleRenderer.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/particle/ParticleRenderer.kt @@ -35,6 +35,7 @@ import de.bixilon.minosoft.gui.rendering.system.base.phases.SkipAll import de.bixilon.minosoft.gui.rendering.system.base.phases.TranslucentDrawable import de.bixilon.minosoft.gui.rendering.system.base.phases.TransparentDrawable import de.bixilon.minosoft.gui.rendering.system.base.shader.Shader +import de.bixilon.minosoft.gui.rendering.system.base.shader.Shader.Companion.loadAnimated import de.bixilon.minosoft.gui.rendering.system.base.shader.ShaderUniforms import de.bixilon.minosoft.modding.event.invoker.CallbackEventInvoker import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection @@ -137,14 +138,8 @@ class ParticleRenderer( override fun postInit(latch: CountUpAndDownLatch) { transparentShader.defines[Shader.TRANSPARENT_DEFINE] = "" - transparentShader.load() - renderWindow.textureManager.staticTextures.use(transparentShader) - renderWindow.textureManager.staticTextures.animator.use(transparentShader) - - translucentShader.load() - renderWindow.textureManager.staticTextures.use(translucentShader) - renderWindow.textureManager.staticTextures.animator.use(translucentShader) - + transparentShader.loadAnimated(light = true) + translucentShader.loadAnimated(light = true) connection.world.particleRenderer = this diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/Particle.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/Particle.kt index 990d0bba3..1f98a21cc 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/Particle.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/Particle.kt @@ -103,14 +103,13 @@ abstract class Particle( return interpolateLinear((time - lastTickTime) / ProtocolDefinition.TICK_TIMEd, previousPosition, position) } - fun forceMove(delta: Vec3d) { + open fun forceMove(delta: Vec3d) { this.previousPosition = Vec3d(position) position += delta } fun forceMove(move: () -> Double) { - this.previousPosition = Vec3d(position) - position += move + forceMove(Vec3d(move())) } open fun move(velocity: Vec3d) { diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/render/RenderParticle.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/render/RenderParticle.kt index 0efe6c1de..c80a6879f 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/render/RenderParticle.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/render/RenderParticle.kt @@ -17,10 +17,40 @@ import de.bixilon.kotlinglm.vec3.Vec3d import de.bixilon.minosoft.data.registries.particle.data.ParticleData import de.bixilon.minosoft.data.text.formatting.color.ChatColors import de.bixilon.minosoft.data.text.formatting.color.RGBColor +import de.bixilon.minosoft.data.world.chunk.light.SectionLight +import de.bixilon.minosoft.data.world.positions.ChunkPositionUtil.chunkPosition +import de.bixilon.minosoft.data.world.positions.ChunkPositionUtil.inChunkPosition import de.bixilon.minosoft.gui.rendering.particle.types.Particle +import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3dUtil.blockPosition import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection abstract class RenderParticle(connection: PlayConnection, position: Vec3d, velocity: Vec3d, data: ParticleData? = null) : Particle(connection, position, velocity, data) { protected open var scale: Float = 0.1f * (random.nextFloat() * 0.5f + 0.5f) * 2.0f protected var color: RGBColor = ChatColors.WHITE + + var light = 0 + open val emittingLight = 0 + + override fun forceMove(delta: Vec3d) { + super.forceMove(delta) + val aabb = aabb + position + var maxBlockLight = 0 + var maxSkyLight = 0 + + val chunkPosition = position.blockPosition.chunkPosition + val chunk = connection.world[chunkPosition] ?: return + + for (position in aabb.blockPositions) { + val light = chunk.traceChunk(position.chunkPosition - chunkPosition)?.light?.get(position.inChunkPosition) ?: SectionLight.SKY_LIGHT_MASK + if (light and SectionLight.BLOCK_LIGHT_MASK > maxBlockLight) { + maxBlockLight = light and SectionLight.BLOCK_LIGHT_MASK + } + if (light and SectionLight.SKY_LIGHT_MASK > maxSkyLight) { + maxSkyLight = light and SectionLight.SKY_LIGHT_MASK + } + } + + this.light = maxBlockLight or maxSkyLight + } + } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/render/texture/TextureParticle.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/render/texture/TextureParticle.kt index 17a09febc..0d78102fc 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/render/texture/TextureParticle.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/render/texture/TextureParticle.kt @@ -15,6 +15,7 @@ package de.bixilon.minosoft.gui.rendering.particle.types.render.texture import de.bixilon.kotlinglm.vec3.Vec3d import de.bixilon.minosoft.data.registries.particle.data.ParticleData +import de.bixilon.minosoft.data.world.chunk.light.SectionLight import de.bixilon.minosoft.gui.rendering.particle.ParticleMesh import de.bixilon.minosoft.gui.rendering.particle.types.render.RenderParticle import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureTransparencies @@ -26,10 +27,11 @@ abstract class TextureParticle(connection: PlayConnection, position: Vec3d, velo override fun addVertex(transparentMesh: ParticleMesh, particleMesh: ParticleMesh, time: Long) { + val light = light and SectionLight.SKY_LIGHT_MASK or emittingLight val texture = texture ?: return when { texture.transparency == TextureTransparencies.TRANSLUCENT || color.alpha != 255 -> particleMesh else -> transparentMesh - }.addVertex(getCameraPosition(time), scale, texture, color) + }.addVertex(getCameraPosition(time), scale, texture, color, light = light) } } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/render/texture/advanced/AdvancedTextureParticle.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/render/texture/advanced/AdvancedTextureParticle.kt index dd272ad69..899b3d4be 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/render/texture/advanced/AdvancedTextureParticle.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/render/texture/advanced/AdvancedTextureParticle.kt @@ -16,6 +16,7 @@ package de.bixilon.minosoft.gui.rendering.particle.types.render.texture.advanced import de.bixilon.kotlinglm.vec2.Vec2 import de.bixilon.kotlinglm.vec3.Vec3d import de.bixilon.minosoft.data.registries.particle.data.ParticleData +import de.bixilon.minosoft.data.world.chunk.light.SectionLight import de.bixilon.minosoft.gui.rendering.particle.ParticleMesh import de.bixilon.minosoft.gui.rendering.particle.types.render.texture.simple.SimpleTextureParticle import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureTransparencies @@ -26,10 +27,12 @@ abstract class AdvancedTextureParticle(connection: PlayConnection, position: Vec var maxUV: Vec2 = Vec2(1.0f, 1.0f) override fun addVertex(transparentMesh: ParticleMesh, particleMesh: ParticleMesh, time: Long) { + val light = light and SectionLight.SKY_LIGHT_MASK or emittingLight + val texture = texture ?: return when { texture.transparency == TextureTransparencies.TRANSLUCENT || color.alpha != 255 -> particleMesh else -> transparentMesh - }.addVertex(getCameraPosition(time), scale, texture, color, minUV.array, maxUV.array) + }.addVertex(getCameraPosition(time), scale, texture, color, minUV.array, maxUV.array, light) } } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/render/texture/simple/slowing/FlameParticle.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/render/texture/simple/slowing/FlameParticle.kt index 3e56862e7..25e0f3a38 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/render/texture/simple/slowing/FlameParticle.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/particle/types/render/texture/simple/slowing/FlameParticle.kt @@ -23,6 +23,8 @@ import kotlin.math.pow open class FlameParticle(connection: PlayConnection, position: Vec3d, velocity: Vec3d, data: ParticleData? = null) : SlowingParticle(connection, position, velocity, data) { + override val emittingLight: Int get() = 14 // non vanilla + override var scale: Float get() = super.scale * (1.0f - (floatAge / maxAge).pow(2) * 0.5f) set(value) { diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/shader/Shader.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/shader/Shader.kt index 79ae4fc82..fd91812aa 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/shader/Shader.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/shader/Shader.kt @@ -93,10 +93,14 @@ interface Shader { return ResourceLocation(namespace, "rendering/shader/${path.replace("(\\w+)\\.\\w+".toRegex(), "$1")}/${path.split("/").last()}") } - fun Shader.loadAnimated() { + fun Shader.loadAnimated(light: Boolean = false) { load() renderWindow.textureManager.staticTextures.use(this) renderWindow.textureManager.staticTextures.animator.use(this) + + if (light) { + renderWindow.lightMap.use(this) + } } } } diff --git a/src/main/resources/assets/minosoft/rendering/shader/particle/particle.vsh b/src/main/resources/assets/minosoft/rendering/shader/particle/particle.vsh index 5acd854f7..43470a2f5 100644 --- a/src/main/resources/assets/minosoft/rendering/shader/particle/particle.vsh +++ b/src/main/resources/assets/minosoft/rendering/shader/particle/particle.vsh @@ -20,10 +20,14 @@ layout (location = 3) in uint vinIndexLayerAnimation; layout (location = 4) in float vinScale; layout (location = 5) in uint vinTintColor; +layout (location = 6) in uint vinLight; #include "minosoft:animation/buffer" +#include "minosoft:light" + + out Vertex { uint textureIndex1; @@ -47,7 +51,7 @@ void main() { ginVertex.minUVCoordinates = vinMinUVCoordinates; ginVertex.scale = vinScale; - ginVertex.tintColor = getRGBAColor(vinTintColor); + ginVertex.tintColor = getRGBAColor(vinTintColor) * getLight(vinLight & 0xFFu); uint animationIndex = vinIndexLayerAnimation & 0xFFFu;