mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-18 03:44:54 -04:00
far improved lightmap updater
This commit is contained in:
parent
33d9804581
commit
2085878cf3
@ -245,7 +245,7 @@ class SkyboxRenderer(
|
|||||||
return RGBColor(red / count, green / count, blue / count)
|
return RGBColor(red / count, green / count, blue / count)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun calculateLightingStrike(original: Vec3): Vec3 {
|
fun calculateLightingStrike(original: Vec3): Vec3 {
|
||||||
val duration = this.strikeDuration
|
val duration = this.strikeDuration
|
||||||
val delta = millis() - lastStrike
|
val delta = millis() - lastStrike
|
||||||
if (delta > duration) {
|
if (delta > duration) {
|
||||||
|
@ -35,8 +35,8 @@ class Lightmap(private val light: RenderLight) {
|
|||||||
private lateinit var defaultUpdater: LightmapUpdater
|
private lateinit var defaultUpdater: LightmapUpdater
|
||||||
|
|
||||||
fun init() {
|
fun init() {
|
||||||
// defaultUpdater = NormalLightmapUpdater(light.renderWindow.connection, light.renderWindow.renderer[SkyRenderer])
|
defaultUpdater = NormalLightmapUpdater(light.renderWindow.connection, light.renderWindow.renderer[SkyRenderer])
|
||||||
defaultUpdater = LegacyLightmapUpdater(light.renderWindow.connection)
|
// defaultUpdater = LegacyLightmapUpdater(light.renderWindow.connection)
|
||||||
buffer.init()
|
buffer.init()
|
||||||
profile.light::fullbright.profileWatch(this, profile = profile) { setLightmapUpdater() }
|
profile.light::fullbright.profileWatch(this, profile = profile) { setLightmapUpdater() }
|
||||||
setLightmapUpdater()
|
setLightmapUpdater()
|
||||||
|
@ -0,0 +1,156 @@
|
|||||||
|
/*
|
||||||
|
* 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.world.light.updater.normal
|
||||||
|
|
||||||
|
import de.bixilon.kotlinglm.vec3.Vec3
|
||||||
|
import de.bixilon.kutil.watcher.DataWatcher.Companion.observe
|
||||||
|
import de.bixilon.minosoft.data.registries.dimension.DimensionProperties
|
||||||
|
import de.bixilon.minosoft.data.world.time.DayPhases
|
||||||
|
import de.bixilon.minosoft.data.world.time.WorldTime
|
||||||
|
import de.bixilon.minosoft.data.world.weather.WorldWeather
|
||||||
|
import de.bixilon.minosoft.gui.rendering.sky.SkyRenderer
|
||||||
|
import de.bixilon.minosoft.gui.rendering.util.VecUtil.clamp
|
||||||
|
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.interpolateLinear
|
||||||
|
import de.bixilon.minosoft.gui.rendering.world.light.LightmapBuffer
|
||||||
|
import de.bixilon.minosoft.gui.rendering.world.light.updater.LightmapUpdater
|
||||||
|
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
|
||||||
|
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
|
||||||
|
import kotlin.math.abs
|
||||||
|
|
||||||
|
class NormalLightmapUpdater(
|
||||||
|
private val connection: PlayConnection,
|
||||||
|
private val skyRenderer: SkyRenderer?,
|
||||||
|
) : LightmapUpdater {
|
||||||
|
private val profile = connection.profiles.rendering.light
|
||||||
|
private var force = true
|
||||||
|
|
||||||
|
init {
|
||||||
|
connection.world::dimension.observe(this) { force = true }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun update(force: Boolean, buffer: LightmapBuffer) {
|
||||||
|
val dimension = connection.world.dimension ?: return
|
||||||
|
val skylight = dimension.hasSkyLight && dimension.effects.daylightCycle
|
||||||
|
|
||||||
|
if (!force || !this.force) {
|
||||||
|
if (!skylight) {
|
||||||
|
// do not recalculate if skylight does not change (e.g. nether or end)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (skylight) {
|
||||||
|
updateBlockSky(dimension, buffer)
|
||||||
|
} else {
|
||||||
|
updateBlock(dimension, buffer)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.force = false
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateBlock(dimension: DimensionProperties, buffer: LightmapBuffer) {
|
||||||
|
for (block in 0 until ProtocolDefinition.LIGHT_LEVELS) {
|
||||||
|
buffer[0, block] = calculateBlock(dimension.brightness[block])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateBlockSky(dimension: DimensionProperties, buffer: LightmapBuffer) {
|
||||||
|
val time = connection.world.time
|
||||||
|
val weather = connection.world.weather
|
||||||
|
val skyColors = Array(ProtocolDefinition.LIGHT_LEVELS.toInt()) { calculateSky(dimension.brightness[it], weather, time) }
|
||||||
|
val blockColors = Array(ProtocolDefinition.LIGHT_LEVELS.toInt()) { calculateBlock(dimension.brightness[it]) }
|
||||||
|
|
||||||
|
for (sky in 0 until ProtocolDefinition.LIGHT_LEVELS) {
|
||||||
|
for (block in 0 until ProtocolDefinition.LIGHT_LEVELS) {
|
||||||
|
buffer[sky, block] = combine(skyColors[sky], blockColors[block])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun calculateBlock(brightness: Float): Vec3 {
|
||||||
|
val base = Vec3(brightness, brightness * ((brightness * 0.6f + 0.4f) * 0.6f + 0.4f), brightness * (brightness * brightness * 0.6f + 0.4f))
|
||||||
|
return base
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun calculateDayBase(brightness: Float, progress: Float): Vec3 {
|
||||||
|
val base = Vec3(0.98f)
|
||||||
|
|
||||||
|
return interpolateLinear((abs(progress - 0.5f) * 2.0f), base, base * 0.9f) * brightness
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun calculateSunset(brightness: Float, progress: Float, time: WorldTime): Vec3 {
|
||||||
|
val day = calculateDayBase(brightness, 1.0f)
|
||||||
|
val night = calculateNightBase(brightness, 0.0f, time)
|
||||||
|
|
||||||
|
return interpolateLinear(progress, day, night)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun calculateNightBase(brightness: Float, progress: Float, time: WorldTime): Vec3 {
|
||||||
|
val max = Vec3(0.10f, 0.10f, 0.30f)
|
||||||
|
|
||||||
|
return interpolateLinear((abs(progress - 0.6f) + 0.4f), max * 0.1f, max) * brightness * time.moonPhase.light
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun calculateSunrise(brightness: Float, progress: Float, time: WorldTime): Vec3 {
|
||||||
|
val night = calculateNightBase(brightness, 1.0f, time)
|
||||||
|
val day = calculateDayBase(brightness, 0.0f)
|
||||||
|
|
||||||
|
return interpolateLinear(progress, night, day)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun calculateThunder(base: Vec3, brightness: Float, thunder: Float): Vec3 {
|
||||||
|
val baseBrightness = base.length()
|
||||||
|
|
||||||
|
var color = interpolateLinear(baseBrightness, Vec3(0.55f, 0.35f, 0.58f), Vec3(0.65f, 0.4f, 0.7f)) * baseBrightness * brightness * 0.3f
|
||||||
|
|
||||||
|
skyRenderer?.let { color = interpolateLinear(brightness * 5.0f + 0.5f, color, it.box.calculateLightingStrike(color)) }
|
||||||
|
return interpolateLinear(thunder, base, color)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun calculateRain(base: Vec3, brightness: Float, rain: Float): Vec3 {
|
||||||
|
val baseBrightness = base.length()
|
||||||
|
|
||||||
|
val color = interpolateLinear(baseBrightness, Vec3(0.4f, 0.4f, 0.8f), Vec3(0.5f, 0.5f, 0.9f)) * baseBrightness * brightness * 0.4f
|
||||||
|
|
||||||
|
return interpolateLinear(rain, base, color)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun calculateSky(brightness: Float, weather: WorldWeather, time: WorldTime): Vec3 {
|
||||||
|
var color = when (time.phase) {
|
||||||
|
DayPhases.DAY -> calculateDayBase(brightness, time.progress)
|
||||||
|
DayPhases.NIGHT -> calculateNightBase(brightness, time.progress, time)
|
||||||
|
DayPhases.SUNRISE -> calculateSunrise(brightness, time.progress, time)
|
||||||
|
DayPhases.SUNSET -> calculateSunset(brightness, time.progress, time)
|
||||||
|
}
|
||||||
|
if (weather.thunder > 0.0f) {
|
||||||
|
color = calculateThunder(color, brightness, weather.thunder)
|
||||||
|
} else if (weather.rain > 0.0f) {
|
||||||
|
color = calculateRain(color, brightness, weather.rain)
|
||||||
|
}
|
||||||
|
|
||||||
|
return color.brighten(0.05f)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun combine(sky: Vec3, block: Vec3): Vec3 {
|
||||||
|
var color = sky + block
|
||||||
|
|
||||||
|
color = color.clamp(0.0f, 1.0f)
|
||||||
|
|
||||||
|
return color
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Vec3.brighten(value: Float): Vec3 {
|
||||||
|
return this * (1.0f - value) + value
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user