mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-17 11:24:56 -04:00
world-rendering: fix some transparent rendering
This commit is contained in:
parent
831fd25444
commit
95c4898f4a
@ -15,7 +15,6 @@ package de.bixilon.minosoft.data.direction
|
||||
import de.bixilon.minosoft.data.Axes
|
||||
import de.bixilon.minosoft.data.registries.blocks.properties.serializer.BlockPropertiesSerializer
|
||||
import de.bixilon.minosoft.data.text.ChatColors
|
||||
import de.bixilon.minosoft.gui.rendering.models.FaceSize
|
||||
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.get
|
||||
import de.bixilon.minosoft.util.KUtil
|
||||
import de.bixilon.minosoft.util.enum.ValuesEnum
|
||||
@ -82,11 +81,11 @@ enum class Directions(
|
||||
}
|
||||
}
|
||||
|
||||
fun getSize(from: Vec3, to: Vec3): FaceSize {
|
||||
fun getSize(from: Vec3, to: Vec3): Pair<Vec2, Vec2> {
|
||||
return when (this) {
|
||||
DOWN, UP -> FaceSize(from.xz, to.xz)
|
||||
NORTH, SOUTH -> FaceSize(from.xy, to.xy)
|
||||
WEST, EAST -> FaceSize(from.yz, to.yz)
|
||||
DOWN, UP -> Pair(from.xz, to.xz)
|
||||
NORTH, SOUTH -> Pair(from.xy, to.xy)
|
||||
WEST, EAST -> Pair(from.yz, to.yz)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,6 +14,7 @@ import java.util.*
|
||||
class CullSectionPreparer(
|
||||
val renderWindow: RenderWindow,
|
||||
) : AbstractSectionPreparer {
|
||||
private val ambientLight = floatArrayOf(1.0f, 1.0f, 1.0f, 1.0f)
|
||||
|
||||
override fun prepare(chunkPosition: Vec2i, sectionHeight: Int, section: ChunkSection, neighbours: Array<ChunkSection?>): ChunkSectionMeshes {
|
||||
val mesh = ChunkSectionMeshes(renderWindow, chunkPosition, sectionHeight)
|
||||
@ -69,7 +70,7 @@ class CullSectionPreparer(
|
||||
|
||||
val position = Vec3i(offsetX + x, offsetY + y, offsetZ + z)
|
||||
random.setSeed(VecUtil.generatePositionHash(position.x, position.y, position.z))
|
||||
val rendered = model.singleRender(position, mesh, random, neighbourBlocks, 0xFF, floatArrayOf(1.0f, 1.0f, 1.0f, 1.0f))
|
||||
val rendered = model.singleRender(position, mesh, random, block, neighbourBlocks, 0xFF, ambientLight)
|
||||
if (rendered) {
|
||||
mesh.addBlock(x, y, z)
|
||||
}
|
||||
|
@ -1,14 +1,18 @@
|
||||
package de.bixilon.minosoft.gui.rendering.models
|
||||
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureTransparencies
|
||||
|
||||
object CullUtil {
|
||||
|
||||
fun Array<FaceSize>.canCull(size: FaceSize): Boolean {
|
||||
for (faceSize in this) {
|
||||
fun Array<FaceProperties>.canCull(properties: FaceProperties, sameBlock: Boolean): Boolean {
|
||||
for (property in this) {
|
||||
if (
|
||||
faceSize.start.x <= size.start.x
|
||||
&& faceSize.start.y <= size.start.y
|
||||
&& faceSize.end.x >= size.end.x
|
||||
&& faceSize.end.y >= size.end.y
|
||||
property.sizeStart.x <= properties.sizeStart.x
|
||||
&& property.sizeStart.y <= properties.sizeStart.y
|
||||
&& property.sizeEnd.x >= properties.sizeEnd.x
|
||||
&& property.sizeEnd.y >= properties.sizeEnd.y
|
||||
&& !((properties.transparency == TextureTransparencies.OPAQUE && property.transparency != TextureTransparencies.OPAQUE)
|
||||
|| (properties.transparency != TextureTransparencies.OPAQUE && property.transparency == properties.transparency && !sameBlock))
|
||||
) {
|
||||
return true
|
||||
}
|
||||
|
@ -13,9 +13,11 @@
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.models
|
||||
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureTransparencies
|
||||
import glm_.vec2.Vec2
|
||||
|
||||
class FaceSize(
|
||||
val start: Vec2,
|
||||
val end: Vec2,
|
||||
)
|
||||
interface FaceProperties {
|
||||
val sizeStart: Vec2
|
||||
val sizeEnd: Vec2
|
||||
val transparency: TextureTransparencies
|
||||
}
|
@ -17,17 +17,17 @@ import de.bixilon.minosoft.data.direction.Directions
|
||||
import de.bixilon.minosoft.data.registries.blocks.BlockState
|
||||
import de.bixilon.minosoft.data.world.light.LightAccessor
|
||||
import de.bixilon.minosoft.gui.rendering.block.mesh.ChunkSectionMeshes
|
||||
import de.bixilon.minosoft.gui.rendering.models.FaceSize
|
||||
import de.bixilon.minosoft.gui.rendering.models.FaceProperties
|
||||
import de.bixilon.minosoft.gui.rendering.models.baked.block.BakedBlockModel
|
||||
import glm_.vec3.Vec3i
|
||||
import java.util.*
|
||||
|
||||
class MultipartBakedModel(
|
||||
val models: Array<BakedBlockModel>,
|
||||
val sizes: Array<Array<FaceSize>>,
|
||||
val sizes: Array<Array<FaceProperties>>,
|
||||
) : BakedBlockModel {
|
||||
|
||||
override fun getSize(random: Random, direction: Directions): Array<FaceSize> {
|
||||
override fun getTouchingFaceProperties(random: Random, direction: Directions): Array<FaceProperties> {
|
||||
return sizes[direction.ordinal]
|
||||
}
|
||||
|
||||
@ -35,10 +35,10 @@ class MultipartBakedModel(
|
||||
return 0xFF
|
||||
}
|
||||
|
||||
override fun singleRender(position: Vec3i, mesh: ChunkSectionMeshes, random: Random, neighbours: Array<BlockState?>, light: Int, ambientLight: FloatArray): Boolean {
|
||||
override fun singleRender(position: Vec3i, mesh: ChunkSectionMeshes, random: Random, blockState: BlockState, neighbours: Array<BlockState?>, light: Int, ambientLight: FloatArray): Boolean {
|
||||
var rendered = false
|
||||
for (model in models) {
|
||||
if (model.singleRender(position, mesh, random, neighbours, light, ambientLight) && !rendered) {
|
||||
if (model.singleRender(position, mesh, random, blockState, neighbours, light, ambientLight) && !rendered) {
|
||||
rendered = true
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ import de.bixilon.minosoft.data.direction.Directions
|
||||
import de.bixilon.minosoft.data.registries.blocks.BlockState
|
||||
import de.bixilon.minosoft.data.world.light.LightAccessor
|
||||
import de.bixilon.minosoft.gui.rendering.block.mesh.ChunkSectionMeshes
|
||||
import de.bixilon.minosoft.gui.rendering.models.FaceSize
|
||||
import de.bixilon.minosoft.gui.rendering.models.FaceProperties
|
||||
import de.bixilon.minosoft.gui.rendering.models.baked.block.BakedBlockModel
|
||||
import glm_.vec3.Vec3i
|
||||
import java.util.*
|
||||
@ -37,8 +37,8 @@ class WeightedBakedModel(
|
||||
this.totalWeight = totalWeight
|
||||
}
|
||||
|
||||
override fun getSize(random: Random, direction: Directions): Array<FaceSize> {
|
||||
return getModel(random).getSize(random, direction)
|
||||
override fun getTouchingFaceProperties(random: Random, direction: Directions): Array<FaceProperties> {
|
||||
return getModel(random).getTouchingFaceProperties(random, direction)
|
||||
}
|
||||
|
||||
private fun getModel(random: Random): BakedBlockModel {
|
||||
@ -60,8 +60,8 @@ class WeightedBakedModel(
|
||||
return getModel(random).getLight(position, random, side, lightAccessor)
|
||||
}
|
||||
|
||||
override fun singleRender(position: Vec3i, mesh: ChunkSectionMeshes, random: Random, neighbours: Array<BlockState?>, light: Int, ambientLight: FloatArray): Boolean {
|
||||
return getModel(random).singleRender(position, mesh, random, neighbours, light, ambientLight)
|
||||
override fun singleRender(position: Vec3i, mesh: ChunkSectionMeshes, random: Random, blockState: BlockState, neighbours: Array<BlockState?>, light: Int, ambientLight: FloatArray): Boolean {
|
||||
return getModel(random).singleRender(position, mesh, random, blockState, neighbours, light, ambientLight)
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -17,17 +17,17 @@ import de.bixilon.minosoft.data.direction.Directions
|
||||
import de.bixilon.minosoft.data.registries.blocks.BlockState
|
||||
import de.bixilon.minosoft.data.world.light.LightAccessor
|
||||
import de.bixilon.minosoft.gui.rendering.block.mesh.ChunkSectionMeshes
|
||||
import de.bixilon.minosoft.gui.rendering.models.FaceSize
|
||||
import de.bixilon.minosoft.gui.rendering.models.FaceProperties
|
||||
import de.bixilon.minosoft.gui.rendering.models.baked.BakedModel
|
||||
import glm_.vec3.Vec3i
|
||||
import java.util.*
|
||||
|
||||
interface BakedBlockModel : BakedModel {
|
||||
|
||||
fun getSize(random: Random, direction: Directions): Array<FaceSize>
|
||||
fun getTouchingFaceProperties(random: Random, direction: Directions): Array<FaceProperties>
|
||||
|
||||
// ToDo: Tint
|
||||
fun singleRender(position: Vec3i, mesh: ChunkSectionMeshes, random: Random, neighbours: Array<BlockState?>, light: Int, ambientLight: FloatArray): Boolean
|
||||
fun singleRender(position: Vec3i, mesh: ChunkSectionMeshes, random: Random, blockState: BlockState, neighbours: Array<BlockState?>, light: Int, ambientLight: FloatArray): Boolean
|
||||
|
||||
// ToDo: Get ambient light
|
||||
fun getLight(position: Vec3i, random: Random, side: Directions, lightAccessor: LightAccessor): Int
|
||||
|
@ -19,35 +19,36 @@ import de.bixilon.minosoft.data.world.light.LightAccessor
|
||||
import de.bixilon.minosoft.gui.rendering.block.mesh.ChunkSectionMesh
|
||||
import de.bixilon.minosoft.gui.rendering.block.mesh.ChunkSectionMeshes
|
||||
import de.bixilon.minosoft.gui.rendering.models.CullUtil.canCull
|
||||
import de.bixilon.minosoft.gui.rendering.models.FaceSize
|
||||
import de.bixilon.minosoft.gui.rendering.models.FaceProperties
|
||||
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3iUtil.toVec3
|
||||
import glm_.vec3.Vec3i
|
||||
import java.util.*
|
||||
|
||||
class BakedBlockStateModel(
|
||||
val faces: Array<Array<BakedFace>>,
|
||||
val sizes: Array<Array<FaceSize>>,
|
||||
private val faces: Array<Array<BakedFace>>,
|
||||
private val touchingFaceProperties: Array<Array<FaceProperties>>,
|
||||
) : BakedBlockModel, GreedyBakedBlockModel { // ToDo: Greedy meshable
|
||||
override val canGreedyMesh: Boolean = true
|
||||
override val greedyMeshableFaces: BooleanArray = booleanArrayOf(true, false, true, true, true, true)
|
||||
|
||||
override fun getSize(random: Random, direction: Directions): Array<FaceSize> {
|
||||
return sizes[direction.ordinal]
|
||||
override fun getTouchingFaceProperties(random: Random, direction: Directions): Array<FaceProperties> {
|
||||
return touchingFaceProperties[direction.ordinal]
|
||||
}
|
||||
|
||||
override fun singleRender(position: Vec3i, mesh: ChunkSectionMeshes, random: Random, neighbours: Array<BlockState?>, light: Int, ambientLight: FloatArray): Boolean {
|
||||
override fun singleRender(position: Vec3i, mesh: ChunkSectionMeshes, random: Random, blockState: BlockState, neighbours: Array<BlockState?>, light: Int, ambientLight: FloatArray): Boolean {
|
||||
val floatPosition = position.toVec3().array
|
||||
var rendered = false
|
||||
for ((index, faces) in faces.withIndex()) {
|
||||
val direction = Directions.VALUES[index]
|
||||
val neighbour = neighbours[index]?.model
|
||||
var neighbourSize: Array<FaceSize>? = null
|
||||
if (neighbour != null) {
|
||||
val neighbour = neighbours[index]
|
||||
val neighboursModel = neighbour?.model
|
||||
var neighbourProperties: Array<FaceProperties>? = null
|
||||
if (neighboursModel != null) {
|
||||
random.setSeed(0L) // ToDo
|
||||
neighbourSize = neighbour.getSize(random, direction.inverted)
|
||||
neighbourProperties = neighboursModel.getTouchingFaceProperties(random, direction.inverted)
|
||||
}
|
||||
for (face in faces) {
|
||||
if (face.touching && neighbourSize != null && neighbourSize.isNotEmpty() && neighbourSize.canCull(face.faceSize)) {
|
||||
if (face.touching && neighbourProperties != null && neighbourProperties.isNotEmpty() && neighbourProperties.canCull(face, blockState == neighbour)) {
|
||||
continue
|
||||
}
|
||||
face.singleRender(floatPosition, mesh, light, ambientLight)
|
||||
|
@ -17,7 +17,7 @@ import de.bixilon.minosoft.data.Axes
|
||||
import de.bixilon.minosoft.data.direction.Directions
|
||||
import de.bixilon.minosoft.gui.rendering.block.mesh.ChunkSectionMesh
|
||||
import de.bixilon.minosoft.gui.rendering.block.mesh.ChunkSectionMeshes
|
||||
import de.bixilon.minosoft.gui.rendering.models.FaceSize
|
||||
import de.bixilon.minosoft.gui.rendering.models.FaceProperties
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureTransparencies
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.AbstractTexture
|
||||
import de.bixilon.minosoft.gui.rendering.util.mesh.Mesh
|
||||
@ -27,7 +27,8 @@ import glm_.vec2.Vec2
|
||||
import glm_.vec3.Vec3
|
||||
|
||||
class BakedFace(
|
||||
val faceSize: FaceSize,
|
||||
override val sizeStart: Vec2,
|
||||
override val sizeEnd: Vec2,
|
||||
val positions: Array<Vec3>,
|
||||
val uv: Array<Vec2>,
|
||||
val shade: Float,
|
||||
@ -35,7 +36,10 @@ class BakedFace(
|
||||
val cullFace: Directions?,
|
||||
val texture: AbstractTexture,
|
||||
val touching: Boolean,
|
||||
) {
|
||||
) : FaceProperties {
|
||||
override val transparency: TextureTransparencies
|
||||
get() = texture.transparency // ToDo
|
||||
|
||||
fun singleRender(position: FloatArray, mesh: ChunkSectionMeshes, light: Int, ambientLight: FloatArray) {
|
||||
val meshToUse = when (texture.transparency) {
|
||||
TextureTransparencies.OPAQUE -> mesh.opaqueMesh
|
||||
|
@ -17,7 +17,7 @@ import de.bixilon.minosoft.data.Axes
|
||||
import de.bixilon.minosoft.data.direction.Directions
|
||||
import de.bixilon.minosoft.data.registries.ResourceLocation
|
||||
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
||||
import de.bixilon.minosoft.gui.rendering.models.FaceSize
|
||||
import de.bixilon.minosoft.gui.rendering.models.FaceProperties
|
||||
import de.bixilon.minosoft.gui.rendering.models.baked.block.BakedBlockModel
|
||||
import de.bixilon.minosoft.gui.rendering.models.baked.block.BakedBlockStateModel
|
||||
import de.bixilon.minosoft.gui.rendering.models.baked.block.BakedFace
|
||||
@ -84,7 +84,7 @@ data class UnbakedBlockStateModel(
|
||||
|
||||
|
||||
val faces: Array<MutableList<BakedFace>> = Array(Directions.SIZE) { mutableListOf() }
|
||||
val sizes: Array<MutableList<FaceSize>> = Array(Directions.SIZE) { mutableListOf() }
|
||||
val touchingFaceProperties: Array<MutableList<FaceProperties>> = Array(Directions.SIZE) { mutableListOf() }
|
||||
|
||||
for (element in model.elements) {
|
||||
val rescale = element.rotation?.rescale ?: false
|
||||
@ -129,11 +129,8 @@ data class UnbakedBlockStateModel(
|
||||
}
|
||||
}
|
||||
|
||||
val size = face.direction.getSize(element.from, element.to)
|
||||
val (sizeStart, sizeEnd) = face.direction.getSize(element.from, element.to)
|
||||
val touching = (if (face.direction.negative) element.from[face.direction.axis] else element.to[face.direction.axis] - 1.0f) == 0.0f
|
||||
if (touching) {
|
||||
sizes[direction.ordinal] += size
|
||||
}
|
||||
var shade = 1.0f
|
||||
if (element.shade) {
|
||||
shade = when (direction) {
|
||||
@ -143,8 +140,9 @@ data class UnbakedBlockStateModel(
|
||||
Directions.WEST, Directions.EAST -> 0.6f
|
||||
}
|
||||
}
|
||||
faces[direction.ordinal] += BakedFace(
|
||||
faceSize = size,
|
||||
val bakedFace = BakedFace(
|
||||
sizeStart = sizeStart,
|
||||
sizeEnd = sizeEnd,
|
||||
positions = positions,
|
||||
uv = texturePositions,
|
||||
shade = shade,
|
||||
@ -153,21 +151,25 @@ data class UnbakedBlockStateModel(
|
||||
texture = texture,
|
||||
touching = touching,
|
||||
)
|
||||
|
||||
faces[direction.ordinal] += bakedFace
|
||||
if (touching) {
|
||||
touchingFaceProperties[direction.ordinal] += bakedFace
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val finalFaces: Array<Array<BakedFace>?> = arrayOfNulls(faces.size)
|
||||
|
||||
for ((index, faceArray) in faces.withIndex()) {
|
||||
finalFaces[index] = faceArray.toTypedArray()
|
||||
}
|
||||
val finalSizes: Array<Array<FaceSize>?> = arrayOfNulls(faces.size)
|
||||
|
||||
for ((index, sizeArray) in sizes.withIndex()) {
|
||||
finalSizes[index] = sizeArray.toTypedArray()
|
||||
val finalTouchingProperties: Array<Array<FaceProperties>?> = arrayOfNulls(faces.size)
|
||||
for ((index, sizeArray) in touchingFaceProperties.withIndex()) {
|
||||
finalTouchingProperties[index] = sizeArray.toTypedArray()
|
||||
}
|
||||
|
||||
val baked = BakedBlockStateModel(finalFaces.unsafeCast(), finalSizes.unsafeCast())
|
||||
val baked = BakedBlockStateModel(finalFaces.unsafeCast(), finalTouchingProperties.unsafeCast())
|
||||
this.baked = baked
|
||||
return baked
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ package de.bixilon.minosoft.gui.rendering.models.unbaked.block
|
||||
|
||||
import de.bixilon.minosoft.data.direction.Directions
|
||||
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
||||
import de.bixilon.minosoft.gui.rendering.models.FaceSize
|
||||
import de.bixilon.minosoft.gui.rendering.models.FaceProperties
|
||||
import de.bixilon.minosoft.gui.rendering.models.baked.BakedModel
|
||||
import de.bixilon.minosoft.gui.rendering.models.baked.MultipartBakedModel
|
||||
import de.bixilon.minosoft.gui.rendering.models.baked.block.BakedBlockModel
|
||||
@ -16,16 +16,16 @@ class UnbakedMultipartModel(
|
||||
|
||||
override fun bake(renderWindow: RenderWindow): BakedModel {
|
||||
val baked: Array<BakedBlockModel?> = arrayOfNulls(this.models.size)
|
||||
val sizes: Array<MutableList<FaceSize>> = Array(Directions.SIZE) { mutableListOf() }
|
||||
val sizes: Array<MutableList<FaceProperties>> = Array(Directions.SIZE) { mutableListOf() }
|
||||
|
||||
for ((index, model) in this.models.withIndex()) {
|
||||
val bakedModel = model.bake(renderWindow)
|
||||
for (direction in Directions.VALUES) {
|
||||
sizes[direction.ordinal] += bakedModel.getSize(RANDOM, direction) // There is no random here!
|
||||
sizes[direction.ordinal] += bakedModel.getTouchingFaceProperties(RANDOM, direction) // There is no random here!
|
||||
}
|
||||
baked[index] = bakedModel
|
||||
}
|
||||
val finalFaces: Array<Array<FaceSize>?> = arrayOfNulls(Directions.SIZE)
|
||||
val finalFaces: Array<Array<FaceProperties>?> = arrayOfNulls(Directions.SIZE)
|
||||
for (index in 0 until Directions.SIZE) {
|
||||
finalFaces[index] = sizes[index].toTypedArray()
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user