wip lightmap

This commit is contained in:
Bixilon 2021-06-30 20:42:50 +02:00
parent 96e80b909c
commit 30e0a1a8a0
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
13 changed files with 145 additions and 18 deletions

View File

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

View File

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

View File

@ -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 <https://www.gnu.org/licenses/>.
*
* 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()
}
}

View File

@ -63,6 +63,7 @@ class WorldRenderer(
private val waterBlock = connection.registries.blockRegistry[ResourceLocation("minecraft:water")]?.nullCast<FluidBlock>()
lateinit var chunkShader: Shader
private val lightMap = LightMap(connection)
val allChunkSections: SynchronizedMap<Vec2i, SynchronizedMap<Int, ChunkSectionMeshCollection>> = synchronizedMapOf()
val visibleChunks: SynchronizedMap<Vec2i, SynchronizedMap<Int, ChunkSectionMeshCollection>> = 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() {

View File

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

View File

@ -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<Vec3>()
for (position in positionTemplate) {
drawPositions += transformedPositions[position]
@ -113,7 +116,7 @@ class ElementRenderer(
textureCoordinates = texturePositions[texturePositionIndex]!!,
texture = texture,
tintColor = finalColor,
lightLevel = lightLevel,
light = light,
)
}
}

View File

@ -143,7 +143,7 @@ class FluidRenderer(
textureCoordinates = texturePositions[vertex.second]!!,
texture = texture,
tintColor = tintColor,
lightLevel = lightLevel,
light = lightLevel,
)
}
}

View File

@ -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 <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.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()
}
}

View File

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

View File

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

View File

@ -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 <https://www.gnu.org/licenses/>.
*
* 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];
}

View File

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