wip sun rendering

This commit is contained in:
Bixilon 2022-11-03 18:10:33 +01:00
parent 7f1f4779bb
commit cd1a8a126a
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
13 changed files with 270 additions and 18 deletions

View File

@ -26,5 +26,4 @@ class WeatherC {
* Enables snow overlay
*/
var snow by delegate(true)
}

View File

@ -35,7 +35,7 @@ class WorldTime(
val phase = DayPhases.of(time)
val progress = phase.getProgress(time)
val day = this.age / ProtocolDefinition.TICKS_PER_DAY
val day = (this.age + 6000) / ProtocolDefinition.TICKS_PER_DAY - 1 // day changes at midnight (18k)
val skyAngle: Float

View File

@ -14,7 +14,7 @@
package de.bixilon.minosoft.data.world.weather
data class WorldWeather(
val rain: Float = 1.0f,
val rain: Float = 0.0f,
val thunder: Float = 0.0f,
) {
val raining: Boolean get() = rain > 0.0f

View File

@ -52,13 +52,11 @@ import de.bixilon.minosoft.gui.rendering.world.WorldRenderer
import de.bixilon.minosoft.modding.event.listener.CallbackEventListener.Companion.listen
import de.bixilon.minosoft.properties.MinosoftProperties
import de.bixilon.minosoft.properties.MinosoftPropertiesLoader
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
import de.bixilon.minosoft.terminal.RunConfiguration
import de.bixilon.minosoft.util.KUtil.format
import de.bixilon.minosoft.util.KUtil.toResourceLocation
import de.bixilon.minosoft.util.Reference
import de.bixilon.minosoft.util.SystemInformation
import kotlin.math.abs
class DebugHUDElement(guiRenderer: GUIRenderer) : Element(guiRenderer), LayoutedElement, Initializable {
private val connection = renderWindow.connection
@ -177,7 +175,7 @@ class DebugHUDElement(guiRenderer: GUIRenderer) : Element(guiRenderer), Layouted
connection.world::time.observe(this) { // ToDo: Kutil 1.18: Allow instant fire
text = BaseComponent(
"Time ", it.time, " (", it.phase, ")", ", cycling=", it.cycling, "\n",
"Date ", "day=", abs(it.age) / ProtocolDefinition.TICKS_PER_DAY, " (", it.moonPhase, ")"
"Date ", "day=", it.day, " (", it.moonPhase, ")"
)
}
}

View File

@ -24,6 +24,7 @@ import de.bixilon.minosoft.gui.rendering.renderer.renderer.Renderer
import de.bixilon.minosoft.gui.rendering.renderer.renderer.RendererBuilder
import de.bixilon.minosoft.gui.rendering.sky.box.SkyboxRenderer
import de.bixilon.minosoft.gui.rendering.sky.properties.OverworldSkyProperties
import de.bixilon.minosoft.gui.rendering.sky.sun.SunRenderer
import de.bixilon.minosoft.gui.rendering.system.base.DepthFunctions
import de.bixilon.minosoft.gui.rendering.system.base.PolygonModes
import de.bixilon.minosoft.gui.rendering.system.base.RenderSystem
@ -44,6 +45,7 @@ class SkyRenderer(
var matrix by watched(Mat4())
val profile = connection.profiles.rendering.sky
private val box = SkyboxRenderer(this).register()
private val sun = SunRenderer(this).register()
override fun init(latch: CountUpAndDownLatch) {
for (renderer in renderer) {

View File

@ -43,6 +43,7 @@ import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.interpolateLinea
import de.bixilon.minosoft.modding.event.events.blocks.chunk.ChunkDataChangeEvent
import de.bixilon.minosoft.modding.event.listener.CallbackEventListener.Companion.listen
import de.bixilon.minosoft.util.KUtil.minosoft
import de.bixilon.minosoft.util.KUtil.murmur64
import java.util.*
import kotlin.math.PI
import kotlin.math.abs
@ -120,17 +121,6 @@ class SkyboxRenderer(
}
}
@Deprecated("Kutil 1.18")
fun Long.murmur64(): Long {
var value = this
value = value xor (value ushr 33)
value *= -0xae502812aa7333L
value = value xor (value ushr 33)
value *= -0x3b314601e57a13adL
value = value xor (value ushr 33)
return value
}
override fun init() {
colorShader.load()

View File

@ -0,0 +1,44 @@
/*
* 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.sky.sun
import de.bixilon.kotlinglm.vec2.Vec2
import de.bixilon.kotlinglm.vec3.Vec3
import de.bixilon.minosoft.gui.rendering.RenderWindow
import de.bixilon.minosoft.gui.rendering.system.base.MeshUtil.buffer
import de.bixilon.minosoft.gui.rendering.system.base.buffer.vertex.PrimitiveTypes
import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.AbstractTexture
import de.bixilon.minosoft.gui.rendering.util.mesh.Mesh
import de.bixilon.minosoft.gui.rendering.util.mesh.MeshStruct
open class SunMesh(renderWindow: RenderWindow, primitiveType: PrimitiveTypes = renderWindow.renderSystem.preferredPrimitiveType) : Mesh(renderWindow, SunMeshStruct, primitiveType, initialCacheSize = 2 * 3 * SunMeshStruct.FLOATS_PER_VERTEX) {
fun addVertex(position: Vec3, texture: AbstractTexture, uv: Vec2) {
data.add(position.x)
data.add(position.y)
data.add(position.z)
data.add(uv.x)
data.add(uv.y)
data.add(texture.renderData.shaderTextureId.buffer())
}
data class SunMeshStruct(
val position: Vec3,
val uv: Vec2,
val indexLayerAnimation: Int,
) {
companion object : MeshStruct(SunMeshStruct::class)
}
}

View File

@ -0,0 +1,136 @@
/*
* 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.sky.sun
import de.bixilon.kotlinglm.func.rad
import de.bixilon.kotlinglm.mat4x4.Mat4
import de.bixilon.kotlinglm.vec2.Vec2
import de.bixilon.kotlinglm.vec3.Vec3
import de.bixilon.kotlinglm.vec4.Vec4
import de.bixilon.minosoft.data.world.time.DayPhases
import de.bixilon.minosoft.data.world.time.WorldTime
import de.bixilon.minosoft.gui.rendering.events.CameraMatrixChangeEvent
import de.bixilon.minosoft.gui.rendering.sky.SkyChildRenderer
import de.bixilon.minosoft.gui.rendering.sky.SkyRenderer
import de.bixilon.minosoft.gui.rendering.system.base.RenderingCapabilities
import de.bixilon.minosoft.gui.rendering.textures.TextureUtil.texture
import de.bixilon.minosoft.modding.event.listener.CallbackEventListener.Companion.listen
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
import de.bixilon.minosoft.util.KUtil.minecraft
import de.bixilon.minosoft.util.KUtil.minosoft
import de.bixilon.minosoft.util.KUtil.murmur64
import java.util.*
import kotlin.math.pow
class SunRenderer(
private val sky: SkyRenderer,
) : SkyChildRenderer {
private val texture = sky.renderWindow.textureManager.staticTextures.createTexture(SUN)
private val shader = sky.renderWindow.renderSystem.createShader(minosoft("weather/sun"))
private var mesh = SunMesh(sky.renderWindow)
private var day = -1L
private var matrix = Mat4()
private var matrixUpdate = true
private var sunModifier = 0.0f
override fun init() {
shader.load()
}
private fun prepareMesh() {
mesh.addYQuad(
start = Vec2(-0.15f, -0.15f),
y = 1f,
end = Vec2(+0.15f, +0.15f),
vertexConsumer = { position, uv ->
mesh.addVertex(
position = position,
texture = texture,
uv = uv,
)
}
)
mesh.load()
}
override fun postInit() {
prepareMesh()
// sky.renderWindow.textureManager.staticTextures.use(shader)
sky.renderWindow.connection.events.listen<CameraMatrixChangeEvent> { calculateMatrix(it.projectionMatrix, it.viewMatrix) }
}
private fun getSunAngle(): Float {
val time = sky.renderWindow.connection.world.time
// 270: sunrise (23k-0k)
// 0: day (0-12k)
// 90: sunset (12k-13k)
// 180: night (13k-23k)
return ((time.time / ProtocolDefinition.TICKS_PER_DAYf) - 0.25f) * 360.0f
}
private fun calculateSunIntensity(): Float {
val time = sky.renderWindow.connection.world.time
return when (time.phase) {
DayPhases.NIGHT -> 0.0f
DayPhases.DAY -> 1.0f
DayPhases.SUNSET -> (1.0f - time.progress).pow(2)
DayPhases.SUNRISE -> time.progress.pow(2)
}
}
private fun calculateMatrix(projection: Mat4 = sky.renderWindow.camera.matrixHandler.projectionMatrix, view: Mat4 = sky.renderWindow.camera.matrixHandler.viewMatrix) {
val matrix = projection * view.toMat3().toMat4()
matrix.rotateAssign(getSunAngle().rad, Vec3(0, 0, -1))
matrix.translateAssign(Vec3(0.0f, -0.01f, 0.0f)) // prevents face fighting
matrix.translateAssign(Vec3(0.0f, -sunModifier, 0.0f)) // moves the sun closer to the player based on the day (sun appears bigger)
this.matrix = matrix
this.matrixUpdate = true
}
override fun onTimeUpdate(time: WorldTime) {
if (this.day != time.day) {
this.day = time.day
sunModifier = Random(day.murmur64()).nextFloat(0.0f, 0.2f)
}
}
override fun draw() {
shader.use()
calculateMatrix()
if (matrixUpdate) {
shader.setMat4("uSunMatrix", matrix)
shader.setVec4("uTintColor", Vec4(1.0f, 1.0f, 1.0f, calculateSunIntensity()))
this.matrixUpdate = false
}
sky.renderSystem.enable(RenderingCapabilities.BLENDING)
mesh.unload()
mesh = SunMesh(sky.renderWindow)
prepareMesh()
mesh.draw()
sky.renderSystem.disable(RenderingCapabilities.BLENDING)
}
companion object {
private val SUN = minecraft("environment/sun").texture()
}
}

View File

@ -85,13 +85,16 @@ abstract class Mesh(
addQuad(positions, uvStart, uvEnd, vertexConsumer)
}
fun addYQuad(start: Vec2, y: Float, end: Vec2, uvStart: Vec2 = Vec2(0.0f, 0.0f), uvEnd: Vec2 = Vec2(1.0f, 1.0f), vertexConsumer: (position: Vec3, uv: Vec2) -> Unit) {
fun addYQuad(start: Vec2, y: Float, end: Vec2, uvStart: Vec2 = Vec2(0.0f, 0.0f), uvEnd: Vec2 = Vec2(1.0f, 1.0f), reversed: Boolean = false, vertexConsumer: (position: Vec3, uv: Vec2) -> Unit) {
val positions = arrayOf(
Vec3(start.x, y, start.y),
Vec3(start.x, y, end.y),
Vec3(end.x, y, end.y),
Vec3(end.x, y, start.y),
)
if (reversed) {
positions.reverse()
}
addQuad(positions, uvStart, uvEnd, vertexConsumer)
}

View File

@ -25,6 +25,8 @@ import de.bixilon.minosoft.data.entities.entities.player.local.HealthCondition
import de.bixilon.minosoft.data.text.BaseComponent
import de.bixilon.minosoft.data.text.ChatComponent
import de.bixilon.minosoft.data.text.formatting.color.ChatColors
import de.bixilon.minosoft.data.world.time.WorldTime
import de.bixilon.minosoft.data.world.weather.WorldWeather
import de.bixilon.minosoft.gui.rendering.RenderConstants
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3dUtil.EMPTY
import de.bixilon.minosoft.modding.event.events.InternalMessageReceiveEvent
@ -128,5 +130,7 @@ class ConnectionUtil(
connection.fire(ContainerCloseEvent(connection, it.id ?: -1, it))
}
connection.player.healthCondition = HealthCondition()
connection.world.time = WorldTime(connection.world)
connection.world.weather = WorldWeather()
}
}

View File

@ -318,4 +318,15 @@ object KUtil {
if (this is CharSequence) return this.length
return toString().length
}
@Deprecated("Kutil 1.18")
fun Long.murmur64(): Long {
var value = this
value = value xor (value ushr 33)
value *= -0xae502812aa7333L
value = value xor (value ushr 33)
value *= -0x3b314601e57a13adL
value = value xor (value ushr 33)
return value
}
}

View File

@ -0,0 +1,33 @@
/*
* 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.
*/
#version 330 core
out vec4 foutColor;
flat in uint finTextureIndex;
in vec3 finTextureCoordinates;
uniform vec4 uTintColor;
// #include "minosoft:texture"
void main() {
// vec4 texelColor = getTexture(finTextureIndex, finTextureCoordinates);
foutColor = vec4(1.0f, 0.5f, 0.5f, 1.0f) * uTintColor;
if (foutColor.a == 0.0f) {
discard;
}
}

View File

@ -0,0 +1,32 @@
/*
* 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.
*/
#version 330 core
layout (location = 0) in vec3 vinPosition;
layout (location = 1) in vec2 vinUV;
layout (location = 2) in uint vinIndexLayerAnimation;
//flat out uint finTextureIndex;
//out vec3 finTextureCoordinates;
uniform mat4 uSunMatrix;
#include "minosoft:color"
void main() {
gl_Position = uSunMatrix * vec4(vinPosition, 1.0f);
// finTextureIndex = vinIndexLayerAnimation >> 28u;
// finTextureCoordinates = vec3(vinUV, ((vinIndexLayerAnimation >> 12) & 0xFFFFu));
}