fix leaf block & leaf particle colors
This commit is contained in:
@@ -70,6 +70,8 @@ data class Color(val alpha: Int, val red: Int, val green: Int, val blue: Int) {
|
||||
)
|
||||
|
||||
val asInt get() = (alpha shl 24) or (red shl 16) or (green shl 8) or blue
|
||||
val asHSB get() = HSB.fromColor(this)
|
||||
|
||||
operator fun times(f: Float) = Color(
|
||||
alpha,
|
||||
(f * red.toFloat()).toInt().coerceIn(0 until 256),
|
||||
@@ -93,6 +95,10 @@ data class HSB(var hue: Float, var saturation: Float, var brightness: Float) {
|
||||
val hsbVals = java.awt.Color.RGBtoHSB((color shr 16) and 255, (color shr 8) and 255, color and 255, null)
|
||||
return HSB(hsbVals[0], hsbVals[1], hsbVals[2])
|
||||
}
|
||||
fun fromColor(color: Color): HSB {
|
||||
val hsbVals = java.awt.Color.RGBtoHSB(color.red, color.green, color.blue, null)
|
||||
return HSB(hsbVals[0], hsbVals[1], hsbVals[2])
|
||||
}
|
||||
}
|
||||
val asInt: Int get() = java.awt.Color.HSBtoRGB(hue, saturation, brightness)
|
||||
val asColor: Color get() = Color(asInt)
|
||||
|
||||
@@ -84,20 +84,20 @@ fun crossModelsRaw(num: Int, size: Double, hOffset: Double, vOffset: Double): Li
|
||||
}
|
||||
}
|
||||
|
||||
fun crossModelSingle(base: List<Quad>, sprite: TextureAtlasSprite, tintIndex: Int,scrambleUV: Boolean) =
|
||||
fun crossModelSingle(base: List<Quad>, sprite: TextureAtlasSprite, color: Color, tint: Int, scrambleUV: Boolean) =
|
||||
base.map { if (scrambleUV) it.scrambleUV(random, canFlipU = true, canFlipV = true, canRotate = true) else it }
|
||||
.map { it.colorIndex(tintIndex) }
|
||||
.map { it.color(color).colorIndex(tint) }
|
||||
.mapIndexed { idx, quad -> quad.sprite(sprite) }
|
||||
.withOpposites()
|
||||
.bake(false)
|
||||
|
||||
fun crossModelsTextured(
|
||||
leafBase: Iterable<List<Quad>>,
|
||||
tintIndex: Int,
|
||||
color: Color, tint: Int,
|
||||
scrambleUV: Boolean,
|
||||
spriteGetter: (Int) -> ResourceLocation
|
||||
) = leafBase.mapIndexed { idx, leaf ->
|
||||
crossModelSingle(leaf, Atlas.BLOCKS[spriteGetter(idx)], tintIndex, scrambleUV)
|
||||
crossModelSingle(leaf, Atlas.BLOCKS[spriteGetter(idx)], color, tint, scrambleUV)
|
||||
}.toTypedArray()
|
||||
|
||||
fun Iterable<Quad>.withOpposites() = flatMap { listOf(it, it.flipped) }
|
||||
|
||||
@@ -87,7 +87,7 @@ class StandardCactusModel(
|
||||
crossModelsRaw(64, config.size, 0.0, 0.0)
|
||||
.transform { rotateZ(randomD(-config.sizeVariation, config.sizeVariation)) }
|
||||
}
|
||||
crossModelsTextured(models, -1, true) { cactusCrossSprite }
|
||||
crossModelsTextured(models, Color.white, -1, true) { cactusCrossSprite }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -28,19 +28,24 @@ import mods.betterfoliage.util.averageHSB
|
||||
import mods.betterfoliage.util.idxOrNull
|
||||
import mods.betterfoliage.util.lazy
|
||||
import mods.betterfoliage.util.lazyMap
|
||||
import mods.betterfoliage.util.lighten
|
||||
import mods.betterfoliage.util.brighten
|
||||
import mods.betterfoliage.util.logTextureColor
|
||||
import mods.betterfoliage.util.randomI
|
||||
import net.minecraft.client.renderer.RenderType
|
||||
import net.minecraft.util.Direction.DOWN
|
||||
import net.minecraft.util.Direction.UP
|
||||
import net.minecraft.util.ResourceLocation
|
||||
import org.apache.logging.log4j.Level.INFO
|
||||
import java.util.Random
|
||||
|
||||
object StandardGrassDiscovery : ParametrizedModelDiscovery() {
|
||||
override fun processModel(ctx: ModelDiscoveryContext, params: Map<String, String>) {
|
||||
val texture = params.location("texture") ?: return
|
||||
val tint = params.int("tint") ?: -1
|
||||
val color = Atlas.BLOCKS.file(texture).averageHSB.lighten()
|
||||
val color = Atlas.BLOCKS.file(texture).averageHSB.let {
|
||||
detailLogger.logTextureColor(INFO, "grass texture \"$texture\"", it)
|
||||
it.brighten().asColor
|
||||
}
|
||||
ctx.addReplacement(StandardGrassKey(texture, tint, color))
|
||||
BetterFoliage.blockTypes.grass.add(ctx.blockState)
|
||||
ctx.blockState.block.extendLayers()
|
||||
|
||||
@@ -22,8 +22,12 @@ import mods.betterfoliage.resource.discovery.ModelDiscoveryContext
|
||||
import mods.betterfoliage.resource.discovery.ParametrizedModelDiscovery
|
||||
import mods.betterfoliage.resource.generated.GeneratedLeafSprite
|
||||
import mods.betterfoliage.util.Atlas
|
||||
import mods.betterfoliage.util.averageHSB
|
||||
import mods.betterfoliage.util.lazy
|
||||
import mods.betterfoliage.util.lazyMap
|
||||
import mods.betterfoliage.util.logColorOverride
|
||||
import mods.betterfoliage.util.brighten
|
||||
import mods.betterfoliage.util.logTextureColor
|
||||
import mods.betterfoliage.util.saturate
|
||||
import net.minecraft.client.renderer.RenderType
|
||||
import net.minecraft.util.Direction.UP
|
||||
import net.minecraft.util.ResourceLocation
|
||||
@@ -31,14 +35,19 @@ import org.apache.logging.log4j.Level.INFO
|
||||
|
||||
object StandardLeafDiscovery : ParametrizedModelDiscovery() {
|
||||
override fun processModel(ctx: ModelDiscoveryContext, params: Map<String, String>) {
|
||||
val leafSprite = params.location("texture-leaf") ?: return
|
||||
val leafType = LeafParticleRegistry.typeMappings.getType(leafSprite) ?: "default"
|
||||
val generated = GeneratedLeafSprite(leafSprite, leafType)
|
||||
val texture = params.location("texture") ?: return
|
||||
val tint = params.int("tint") ?: -1
|
||||
val color = Atlas.BLOCKS.file(texture).averageHSB.let {
|
||||
detailLogger.logTextureColor(INFO, "leaf texture \"$texture\"", it)
|
||||
it.brighten().asColor
|
||||
}
|
||||
val leafType = LeafParticleRegistry.typeMappings.getType(texture) ?: "default"
|
||||
val generated = GeneratedLeafSprite(texture, leafType)
|
||||
.register(BetterFoliage.generatedPack)
|
||||
.apply { ctx.sprites.add(this) }
|
||||
|
||||
detailLogger.log(INFO, " particle $leafType")
|
||||
ctx.addReplacement(StandardLeafKey(generated, leafType, null))
|
||||
ctx.addReplacement(StandardLeafKey(generated, leafType, tint, color))
|
||||
BetterFoliage.blockTypes.leaf.add(ctx.blockState)
|
||||
}
|
||||
}
|
||||
@@ -46,10 +55,9 @@ object StandardLeafDiscovery : ParametrizedModelDiscovery() {
|
||||
data class StandardLeafKey(
|
||||
val roundLeafTexture: ResourceLocation,
|
||||
override val leafType: String,
|
||||
override val overrideColor: Color?
|
||||
override val tintIndex: Int,
|
||||
override val avgColor: Color
|
||||
) : HalfBakedWrapperKey(), LeafParticleKey {
|
||||
val tintIndex: Int get() = if (overrideColor == null) 0 else -1
|
||||
|
||||
override fun bake(ctx: ModelBakingContext, wrapped: SpecialRenderModel): SpecialRenderModel {
|
||||
return StandardLeafModel(wrapped, this)
|
||||
}
|
||||
@@ -78,14 +86,16 @@ class StandardLeafModel(
|
||||
val leafSpritesSnowed by SpriteSetDelegate(Atlas.BLOCKS) { idx ->
|
||||
ResourceLocation(BetterFoliageMod.MOD_ID, "blocks/better_leaves_snowed_$idx")
|
||||
}
|
||||
val leafModelsBase = BetterFoliage.modelManager.lazyMap { key: StandardLeafKey ->
|
||||
val leafModelsBase by BetterFoliage.modelManager.lazy {
|
||||
Config.leaves.let { crossModelsRaw(64, it.size, it.hOffset, it.vOffset) }
|
||||
}
|
||||
val leafModelsNormal = BetterFoliage.modelManager.lazyMap { key: StandardLeafKey ->
|
||||
crossModelsTextured(leafModelsBase[key], key.tintIndex, true) { key.roundLeafTexture }
|
||||
// generated leaf textures naturally carry the color of their source textures
|
||||
// no need to color the quad a second time
|
||||
crossModelsTextured(leafModelsBase, Color.white, key.tintIndex, true) { key.roundLeafTexture }
|
||||
}
|
||||
val leafModelsSnowed = BetterFoliage.modelManager.lazyMap { key: StandardLeafKey ->
|
||||
crossModelsTextured(leafModelsBase[key], -1, false) { leafSpritesSnowed[it].name }
|
||||
crossModelsTextured(leafModelsBase, Color.white, -1, false) { leafSpritesSnowed[it].name }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -25,7 +25,7 @@ import mods.betterfoliage.util.averageHSB
|
||||
import mods.betterfoliage.util.idxOrNull
|
||||
import mods.betterfoliage.util.lazy
|
||||
import mods.betterfoliage.util.lazyMap
|
||||
import mods.betterfoliage.util.lighten
|
||||
import mods.betterfoliage.util.brighten
|
||||
import mods.betterfoliage.util.randomI
|
||||
import net.minecraft.client.renderer.RenderType
|
||||
import net.minecraft.util.Direction
|
||||
@@ -36,7 +36,7 @@ object StandardMyceliumDiscovery : ParametrizedModelDiscovery() {
|
||||
override fun processModel(ctx: ModelDiscoveryContext, params: Map<String, String>) {
|
||||
val texture = params.location("texture") ?: return
|
||||
val tint = params.int("tint") ?: -1
|
||||
val color = Atlas.BLOCKS.file(texture).averageHSB.lighten(multiplier = 1.5f)
|
||||
val color = Atlas.BLOCKS.file(texture).averageHSB.brighten(multiplier = 1.5f).asColor
|
||||
ctx.addReplacement(StandardMyceliumKey(texture, tint, color))
|
||||
ctx.blockState.block.extendLayers()
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package mods.betterfoliage.render.particle
|
||||
|
||||
import com.mojang.blaze3d.vertex.IVertexBuilder
|
||||
import mods.betterfoliage.model.Color
|
||||
import mods.betterfoliage.model.HSB
|
||||
import mods.betterfoliage.util.Double3
|
||||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.client.particle.SpriteTexturedParticle
|
||||
@@ -92,10 +94,16 @@ abstract class AbstractParticle(world: ClientWorld, x: Double, y: Double, z: Dou
|
||||
renderVertex(coords[3], sprite.u0, sprite.v1)
|
||||
}
|
||||
|
||||
fun setColor(color: Int) {
|
||||
bCol = (color and 255) / 256.0f
|
||||
gCol = ((color shr 8) and 255) / 256.0f
|
||||
rCol = ((color shr 16) and 255) / 256.0f
|
||||
fun setColor(color: Color) {
|
||||
rCol = color.red / 256.0f
|
||||
gCol = color.green / 256.0f
|
||||
bCol = color.blue / 256.0f
|
||||
}
|
||||
|
||||
/**
|
||||
* Set particle color to the "stronger" of the given colors, determined by higher color saturation
|
||||
*/
|
||||
fun setColor(color1: Color, color2: Color) =
|
||||
setColor(if (color1.asHSB.saturation > color2.asHSB.saturation) color1 else color2)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package mods.betterfoliage.render.particle
|
||||
|
||||
import mods.betterfoliage.config.Config
|
||||
import mods.betterfoliage.model.Color
|
||||
import mods.betterfoliage.util.Double3
|
||||
import mods.betterfoliage.util.PI2
|
||||
import mods.betterfoliage.util.minmax
|
||||
@@ -44,7 +45,7 @@ class FallingLeafParticle(
|
||||
yd = -Config.fallingLeaves.speed
|
||||
|
||||
quadSize = Config.fallingLeaves.size.toFloat() * 0.1f
|
||||
setColor(leaf.overrideColor?.asInt ?: blockColor)
|
||||
if (leaf.tintIndex == -1) setColor(leaf.avgColor) else setColor(leaf.avgColor, Color(blockColor))
|
||||
sprite = LeafParticleRegistry[leaf.leafType][randomI(max = 1024)]
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,8 @@ interface LeafBlockModel {
|
||||
|
||||
interface LeafParticleKey {
|
||||
val leafType: String
|
||||
val overrideColor: Color?
|
||||
val tintIndex: Int
|
||||
val avgColor: Color
|
||||
}
|
||||
|
||||
object LeafParticleRegistry : HasLogger(), VeryEarlyReloadListener {
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
package mods.betterfoliage.util
|
||||
|
||||
import mods.betterfoliage.BetterFoliageMod
|
||||
import mods.betterfoliage.model.HSB
|
||||
import net.minecraft.block.BlockState
|
||||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.util.ResourceLocation
|
||||
@@ -65,6 +66,11 @@ abstract class HasLogger {
|
||||
val detailLogger = BetterFoliageMod.detailLogger(this)
|
||||
}
|
||||
|
||||
fun Logger.logTextureColor(level: Level, description: String, avgColor: HSB) {
|
||||
val rgb = avgColor.asColor
|
||||
log(level, "$description average color RGB[${rgb.red},${rgb.green},${rgb.blue}], HSB[${avgColor.hue},${avgColor.saturation},${avgColor.brightness}]")
|
||||
}
|
||||
|
||||
fun getBlockModel(state: BlockState) = Minecraft.getInstance().blockRenderer.blockModelShaper.getBlockModel(state)
|
||||
/**
|
||||
* Check if the Chunk containing the given [BlockPos] is loaded.
|
||||
|
||||
@@ -16,6 +16,8 @@ import java.io.IOException
|
||||
import javax.imageio.ImageIO
|
||||
import kotlin.math.atan2
|
||||
import kotlin.math.cos
|
||||
import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
import kotlin.math.sin
|
||||
|
||||
enum class Atlas(val resourceId: ResourceLocation) {
|
||||
@@ -107,8 +109,10 @@ val ResourceLocation.averageHSB: HSB get() = resourceManager.loadSprite(this).le
|
||||
return HSB(avgHue, sumSaturation / numOpaque.toFloat(), sumBrightness / numOpaque.toFloat())
|
||||
}
|
||||
|
||||
fun HSB.lighten(multiplier: Float = 2.0f, ceiling: Float = 0.9f) =
|
||||
copy(brightness = (brightness * multiplier).coerceAtMost(ceiling)).asColor
|
||||
fun HSB.brighten(multiplier: Float = 1.5f, floor: Float = 0.1f, ceiling: Float = 0.9f) =
|
||||
copy(brightness = (brightness * multiplier).coerceAtMost(max(ceiling, brightness)).coerceAtLeast(min(floor, brightness)))
|
||||
fun HSB.saturate(multiplier: Float = 1.5f, floor: Float = 0.1f, ceiling: Float = 0.9f) =
|
||||
copy(saturation = (saturation * multiplier).coerceAtMost(max(ceiling, saturation)).coerceAtLeast(min(floor, saturation)))
|
||||
|
||||
/** Weighted blend of 2 packed RGB colors */
|
||||
fun blendRGB(rgb1: Int, rgb2: Int, weight1: Int, weight2: Int): Int {
|
||||
|
||||
@@ -3,8 +3,8 @@ match block.class.extends(classOf("minecraft:oak_leaves")) setParam("type", "lea
|
||||
|
||||
match isParam("type", "leaf")
|
||||
model.extends("minecraft:block/leaves", "minecraft:block/cube_all")
|
||||
setParam("texture-leaf", model.texture("all"))
|
||||
setParam("tint-leaf", model.tint("all"))
|
||||
setParam("texture", model.texture("all"))
|
||||
setParam("tint", model.tint("all"))
|
||||
end
|
||||
|
||||
// Podzol
|
||||
|
||||
Reference in New Issue
Block a user