mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-17 03:15:35 -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)
|
||||
}
|
||||
|
||||
private fun calculateLightingStrike(original: Vec3): Vec3 {
|
||||
fun calculateLightingStrike(original: Vec3): Vec3 {
|
||||
val duration = this.strikeDuration
|
||||
val delta = millis() - lastStrike
|
||||
if (delta > duration) {
|
||||
|
@ -35,8 +35,8 @@ class Lightmap(private val light: RenderLight) {
|
||||
private lateinit var defaultUpdater: LightmapUpdater
|
||||
|
||||
fun init() {
|
||||
// defaultUpdater = NormalLightmapUpdater(light.renderWindow.connection, light.renderWindow.renderer[SkyRenderer])
|
||||
defaultUpdater = LegacyLightmapUpdater(light.renderWindow.connection)
|
||||
defaultUpdater = NormalLightmapUpdater(light.renderWindow.connection, light.renderWindow.renderer[SkyRenderer])
|
||||
// defaultUpdater = LegacyLightmapUpdater(light.renderWindow.connection)
|
||||
buffer.init()
|
||||
profile.light::fullbright.profileWatch(this, profile = profile) { 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