From 30e0a1a8a07d76fc565dae3a7e6750d7bc685d67 Mon Sep 17 00:00:00 2001 From: Bixilon Date: Wed, 30 Jun 2021 20:42:50 +0200 Subject: [PATCH] wip lightmap --- .../data/world/light/WorldLightAccessor.kt | 3 + .../minosoft/gui/rendering/RenderConstants.kt | 2 +- .../minosoft/gui/rendering/block/LightMap.kt | 58 +++++++++++++++++++ .../gui/rendering/block/WorldRenderer.kt | 8 ++- .../block/mesh/ChunkSectionArrayMesh.kt | 10 ++-- .../block/renderable/block/ElementRenderer.kt | 7 ++- .../block/renderable/fluid/FluidRenderer.kt | 2 +- .../system/opengl/FloatUniformBuffer.kt | 36 ++++++++++++ .../system/opengl/IntUniformBuffer.kt | 2 +- .../rendering/system/opengl/UniformBuffer.kt | 8 +-- .../rendering/shader/includes/light.glsl | 22 +++++++ .../{chunk/chunk.fsh => world/world.fsh} | 0 .../{chunk/chunk.vsh => world/world.vsh} | 5 +- 13 files changed, 145 insertions(+), 18 deletions(-) create mode 100644 src/main/java/de/bixilon/minosoft/gui/rendering/block/LightMap.kt create mode 100644 src/main/java/de/bixilon/minosoft/gui/rendering/system/opengl/FloatUniformBuffer.kt create mode 100644 src/main/resources/assets/minosoft/rendering/shader/includes/light.glsl rename src/main/resources/assets/minosoft/rendering/shader/{chunk/chunk.fsh => world/world.fsh} (100%) rename src/main/resources/assets/minosoft/rendering/shader/{chunk/chunk.vsh => world/world.vsh} (93%) diff --git a/src/main/java/de/bixilon/minosoft/data/world/light/WorldLightAccessor.kt b/src/main/java/de/bixilon/minosoft/data/world/light/WorldLightAccessor.kt index d4c892aa8..6c9ddc258 100644 --- a/src/main/java/de/bixilon/minosoft/data/world/light/WorldLightAccessor.kt +++ b/src/main/java/de/bixilon/minosoft/data/world/light/WorldLightAccessor.kt @@ -30,6 +30,9 @@ class WorldLightAccessor( } override fun getBlockLight(blockPosition: Vec3i): Int { + if (RenderConstants.DISABLE_LIGHTING) { + return 15 + } return world.chunks[blockPosition.chunkPosition]?.lightAccessor?.getBlockLight(blockPosition) ?: 0 } } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/RenderConstants.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/RenderConstants.kt index d473f0388..a7933685f 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/RenderConstants.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/RenderConstants.kt @@ -57,7 +57,7 @@ object RenderConstants { const val MAXIMUM_QUEUE_TIME_PER_FRAME = 100L - const val DISABLE_LIGHTING = true + const val DISABLE_LIGHTING = false const val RENDER_BLOCKS = true const val RENDER_FLUIDS = true diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/block/LightMap.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/block/LightMap.kt new file mode 100644 index 000000000..ad9b47db3 --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/block/LightMap.kt @@ -0,0 +1,58 @@ +/* + * Minosoft + * Copyright (C) 2021 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 . + * + * This software is not affiliated with Mojang AB, the original developer of Minecraft. + */ + +package de.bixilon.minosoft.gui.rendering.block + +import de.bixilon.minosoft.data.text.RGBColor.Companion.asGray +import de.bixilon.minosoft.gui.rendering.shader.Shader +import de.bixilon.minosoft.gui.rendering.system.opengl.FloatUniformBuffer +import de.bixilon.minosoft.protocol.network.connection.PlayConnection +import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition + + +class LightMap(private val connection: PlayConnection) { + private val uniformBuffer = FloatUniformBuffer(1, FloatArray(16 * 16 * 4) { 1.0f }) + private var lastUpdate = -1L + + + fun init() { + uniformBuffer.init() + + } + + fun use(shader: Shader, bufferName: String = "uLightMapBuffer") { + uniformBuffer.use(shader, bufferName) + } + + fun update() { + val currentTime = System.currentTimeMillis() + if (currentTime - lastUpdate < ProtocolDefinition.TICK_TIME * 10) { + return + } + lastUpdate = currentTime + + // ToDo + for (skyLight in 0 until 16) { + for (blockLight in 0 until 16) { + val index = ((skyLight shl 4) or blockLight) * 4 + + val color = ((blockLight + skyLight) / 30.0f).asGray() + + uniformBuffer.data[index + 0] = color.floatRed + uniformBuffer.data[index + 1] = color.floatRed + uniformBuffer.data[index + 2] = color.floatGreen + } + } + uniformBuffer.upload() + } +} diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/block/WorldRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/block/WorldRenderer.kt index 5e91b76d2..9cb52b7da 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/block/WorldRenderer.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/block/WorldRenderer.kt @@ -63,6 +63,7 @@ class WorldRenderer( private val waterBlock = connection.registries.blockRegistry[ResourceLocation("minecraft:water")]?.nullCast() lateinit var chunkShader: Shader + private val lightMap = LightMap(connection) val allChunkSections: SynchronizedMap> = synchronizedMapOf() val visibleChunks: SynchronizedMap> = synchronizedMapOf() @@ -182,12 +183,14 @@ class WorldRenderer( check(renderWindow.textures.animator.animatedTextures.size < TextureArray.MAX_ANIMATED_TEXTURES) { "Can not have more than ${TextureArray.MAX_ANIMATED_TEXTURES} animated textures!" } chunkShader = Shader( renderWindow = renderWindow, - resourceLocation = ResourceLocation(ProtocolDefinition.MINOSOFT_NAMESPACE, "chunk"), + resourceLocation = ResourceLocation(ProtocolDefinition.MINOSOFT_NAMESPACE, "world"), ) chunkShader.load() + lightMap.init() renderWindow.textures.use(chunkShader) - renderWindow.textures.animator.use(chunkShader, "uAnimationBuffer") + renderWindow.textures.animator.use(chunkShader) + lightMap.use(chunkShader) for (blockState in allBlocks!!) { for (model in blockState.renderers) { @@ -199,6 +202,7 @@ class WorldRenderer( override fun update() { lastVisibleChunks = visibleChunks.toSynchronizedMap() + lightMap.update() } override fun draw() { diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/block/mesh/ChunkSectionArrayMesh.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/block/mesh/ChunkSectionArrayMesh.kt index a822bcd64..abd3c566a 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/block/mesh/ChunkSectionArrayMesh.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/block/mesh/ChunkSectionArrayMesh.kt @@ -24,13 +24,9 @@ import glm_.vec3.Vec3 class ChunkSectionArrayMesh : Mesh(SectionArrayMeshStruct::class, initialCacheSize = 100000) { - fun addVertex(position: Vec3, textureCoordinates: Vec2, texture: Texture, tintColor: RGBColor?, lightLevel: Int = 14) { + fun addVertex(position: Vec3, textureCoordinates: Vec2, texture: Texture, tintColor: RGBColor?, light: Int) { val color = tintColor ?: ChatColors.WHITE - val lightFactor = (lightLevel + 1) / MAX_LIGHT_LEVEL_FLOAT - - val lightColor = RGBColor((color.red * lightFactor).toInt(), (color.green * lightFactor).toInt(), (color.blue * lightFactor).toInt()) - val textureLayer = if (RenderConstants.FORCE_DEBUG_TEXTURE) { RenderConstants.DEBUG_TEXTURE_ID } else { @@ -44,7 +40,8 @@ class ChunkSectionArrayMesh : Mesh(SectionArrayMeshStruct::class, initialCacheSi textureCoordinates.y * texture.uvEnd.y, Float.fromBits(textureLayer), Float.fromBits(texture.properties.animation?.animationId ?: -1), - Float.fromBits(lightColor.rgb), + Float.fromBits(color.rgb), + Float.fromBits(light) )) } @@ -61,6 +58,7 @@ class ChunkSectionArrayMesh : Mesh(SectionArrayMeshStruct::class, initialCacheSi val textureLayer: Int, val animationId: Int, val tintColor: RGBColor, + val light: Int, ) { companion object : MeshStruct(SectionArrayMeshStruct::class) } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/block/renderable/block/ElementRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/block/renderable/block/ElementRenderer.kt index 875ed2103..050560146 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/block/renderable/block/ElementRenderer.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/block/renderable/block/ElementRenderer.kt @@ -94,8 +94,11 @@ class ElementRenderer( finalColor = finalColor.with(finalColor.floatRed * shadeLevel, finalColor.floatGreen * shadeLevel, finalColor.floatBlue * shadeLevel) - val lightLevel = context.lightAccessor.getLightLevel(context.blockPosition + face.cullFace?.let { directionMapping[it] }) // ToDo: rotate cullface + val lightPosition = context.blockPosition + face.cullFace?.let { directionMapping[it] }// ToDo: rotate cullface + val blockLight = context.lightAccessor.getBlockLight(lightPosition) + val skyLight = context.lightAccessor.getSkyLight(lightPosition) + val light = (skyLight shl 4) or blockLight val drawPositions = mutableListOf() for (position in positionTemplate) { drawPositions += transformedPositions[position] @@ -113,7 +116,7 @@ class ElementRenderer( textureCoordinates = texturePositions[texturePositionIndex]!!, texture = texture, tintColor = finalColor, - lightLevel = lightLevel, + light = light, ) } } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/block/renderable/fluid/FluidRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/block/renderable/fluid/FluidRenderer.kt index 60dec5340..03fe20736 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/block/renderable/fluid/FluidRenderer.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/block/renderable/fluid/FluidRenderer.kt @@ -143,7 +143,7 @@ class FluidRenderer( textureCoordinates = texturePositions[vertex.second]!!, texture = texture, tintColor = tintColor, - lightLevel = lightLevel, + light = lightLevel, ) } } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/system/opengl/FloatUniformBuffer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/system/opengl/FloatUniformBuffer.kt new file mode 100644 index 000000000..312e0de3c --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/system/opengl/FloatUniformBuffer.kt @@ -0,0 +1,36 @@ +/* + * Minosoft + * Copyright (C) 2021 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 . + * + * This software is not affiliated with Mojang AB, the original developer of Minecraft. + */ + +package de.bixilon.minosoft.gui.rendering.system.opengl + +import org.lwjgl.opengl.ARBUniformBufferObject.GL_UNIFORM_BUFFER +import org.lwjgl.opengl.GL15.* + +class FloatUniformBuffer(bindingIndex: Int = 0, var data: FloatArray = FloatArray(0)) : UniformBuffer(bindingIndex) { + override val size: Int + get() = data.size + + override fun initialUpload() { + bind() + glBufferData(GL_UNIFORM_BUFFER, data, GL_DYNAMIC_DRAW) + unbind() + } + + override fun upload() { + check(initialSize == size) { "Can not change buffer size!" } + bind() + glBufferSubData(GL_UNIFORM_BUFFER, 0, data) + unbind() + } + +} diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/system/opengl/IntUniformBuffer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/system/opengl/IntUniformBuffer.kt index 0ee9142aa..f57d38054 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/system/opengl/IntUniformBuffer.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/system/opengl/IntUniformBuffer.kt @@ -16,7 +16,7 @@ package de.bixilon.minosoft.gui.rendering.system.opengl import org.lwjgl.opengl.ARBUniformBufferObject.GL_UNIFORM_BUFFER import org.lwjgl.opengl.GL15.* -class IntUniformBuffer(var data: IntArray = IntArray(0)) : UniformBuffer() { +class IntUniformBuffer(bindingIndex: Int = 0, var data: IntArray = IntArray(0)) : UniformBuffer(bindingIndex) { override val size: Int get() = data.size diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/system/opengl/UniformBuffer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/system/opengl/UniformBuffer.kt index 8046fda8d..8bdf7fc51 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/system/opengl/UniformBuffer.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/system/opengl/UniformBuffer.kt @@ -18,7 +18,7 @@ import org.lwjgl.opengl.ARBUniformBufferObject.* import org.lwjgl.opengl.GL15.glBindBuffer import org.lwjgl.opengl.GL15.glGenBuffers -abstract class UniformBuffer { +abstract class UniformBuffer(private val bindingIndex: Int) { private var id = -1 protected abstract val size: Int protected var initialSize = -1 @@ -27,7 +27,7 @@ abstract class UniformBuffer { fun init() { id = glGenBuffers() initialUpload() - glBindBufferRange(GL_UNIFORM_BUFFER, 0, id, 0, size.toLong()) + glBindBufferRange(GL_UNIFORM_BUFFER, bindingIndex, id, 0, size.toLong()) initialSize = size } @@ -43,8 +43,8 @@ abstract class UniformBuffer { fun use(shader: Shader, bufferName: String) { shader.use() - shader.setUniformBuffer(bufferName, 0) - glBindBufferBase(GL_UNIFORM_BUFFER, 0, id) + shader.setUniformBuffer(bufferName, bindingIndex) + glBindBufferBase(GL_UNIFORM_BUFFER, bindingIndex, id) } protected abstract fun initialUpload() diff --git a/src/main/resources/assets/minosoft/rendering/shader/includes/light.glsl b/src/main/resources/assets/minosoft/rendering/shader/includes/light.glsl new file mode 100644 index 000000000..d4d270937 --- /dev/null +++ b/src/main/resources/assets/minosoft/rendering/shader/includes/light.glsl @@ -0,0 +1,22 @@ +/* + * Minosoft + * Copyright (C) 2020 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 . + * + * This software is not affiliated with Mojang AB, the original developer of Minecraft. + */ + +layout(std140) uniform uLightMapBuffer +{ + vec4 uLightMap[16 * 16];// ToDo: uint[256] should work without padding, but it seems there is padding. Using vec4 for now. +}; + + +vec4 getLight(uint light) { + return uLightMap[light]; +} diff --git a/src/main/resources/assets/minosoft/rendering/shader/chunk/chunk.fsh b/src/main/resources/assets/minosoft/rendering/shader/world/world.fsh similarity index 100% rename from src/main/resources/assets/minosoft/rendering/shader/chunk/chunk.fsh rename to src/main/resources/assets/minosoft/rendering/shader/world/world.fsh diff --git a/src/main/resources/assets/minosoft/rendering/shader/chunk/chunk.vsh b/src/main/resources/assets/minosoft/rendering/shader/world/world.vsh similarity index 93% rename from src/main/resources/assets/minosoft/rendering/shader/chunk/chunk.vsh rename to src/main/resources/assets/minosoft/rendering/shader/world/world.vsh index ecc623637..886dd5e35 100644 --- a/src/main/resources/assets/minosoft/rendering/shader/chunk/chunk.vsh +++ b/src/main/resources/assets/minosoft/rendering/shader/world/world.vsh @@ -19,6 +19,7 @@ layout (location = 2) in uint vinTextureLayer; layout (location = 3) in int vinAnimationIndex; layout (location = 4) in uint vinTintColor; +layout (location = 5) in uint vinLight; flat out uint finTextureIndex1; out vec3 finTextureCoordinates1; @@ -35,9 +36,11 @@ uniform mat4 uViewProjectionMatrix; #include "minosoft:color" +#include "minosoft:light" + void main() { gl_Position = uViewProjectionMatrix * vec4(vinPosition, 1.0f); - finTintColor = getRGBColor(vinTintColor); + finTintColor = getRGBColor(vinTintColor) * getLight(vinLight); if (vinAnimationIndex == -1) {