From b8140dbe4e2997606a1d952093713593540da79e Mon Sep 17 00:00:00 2001 From: Moritz Zwerger Date: Sun, 22 Oct 2023 21:20:51 +0200 Subject: [PATCH] render system, skeletal performance improvements --- doc/rendering/Entities.md | 23 ++++++++-- .../gui/rendering/skeletal/SkeletalManager.kt | 2 +- .../skeletal/instance/AnimationManager.kt | 1 + .../skeletal/instance/TransformInstance.kt | 12 +++--- .../gui/rendering/system/base/RenderSystem.kt | 2 +- .../system/opengl/OpenGLRenderSystem.kt | 4 +- .../gui/rendering/util/mat/mat4/Mat4Util.kt | 8 ++++ .../models/entities/player/wide.smodel | 42 +++++++++++++++++++ 8 files changed, 80 insertions(+), 14 deletions(-) create mode 100644 src/main/resources/assets/minecraft/models/entities/player/wide.smodel diff --git a/doc/rendering/Entities.md b/doc/rendering/Entities.md index 2b60a3f7d..0bb1884fb 100644 --- a/doc/rendering/Entities.md +++ b/doc/rendering/Entities.md @@ -19,10 +19,25 @@ Entity rendering is a quite hard topic. ## Model designing -### Block entities - -Block entity models (e.g. chests) are always `facing`=`north` by default. - ### Entities Entities are always designed without any rotation (i.e. `yaw`=`0`) + +## Things to consider + +- name rendering (without culling and visible through walls) (and scoreboard objective) +- hitbox rendering +- entity model itself + - player with arms, legs, ... + - has animations, ... + - different poses (sneaking, etc) +- yaw vs head yaw +- "features" + - armor (and armor trims) + - elytra + - stuck arrows (and bee stingers) + - cape + - shoulder entities (parrots) + - held item +- light (shade and lightmap) +- diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/SkeletalManager.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/SkeletalManager.kt index 24eeb3b72..45c736ea0 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/SkeletalManager.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/SkeletalManager.kt @@ -36,7 +36,7 @@ class SkeletalManager( } fun upload(instance: SkeletalInstance) { - instance.transform.pack(uniformBuffer.buffer, instance.position) + instance.transform.pack(uniformBuffer.buffer, instance.position, Mat4()) uniformBuffer.upload(0 until instance.model.transformCount * Mat4.length) } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/instance/AnimationManager.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/instance/AnimationManager.kt index 68aaf43f8..f688bf60c 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/instance/AnimationManager.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/instance/AnimationManager.kt @@ -61,6 +61,7 @@ class AnimationManager(val instance: SkeletalInstance) { } fun draw(delta: Float) { + if (playing.isEmpty()) return lock.lock() val iterator = playing.iterator() diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/instance/TransformInstance.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/instance/TransformInstance.kt index 222a0567b..764505429 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/instance/TransformInstance.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/instance/TransformInstance.kt @@ -15,7 +15,7 @@ package de.bixilon.minosoft.gui.rendering.skeletal.instance import de.bixilon.kotlinglm.mat4x4.Mat4 import de.bixilon.kotlinglm.vec3.Vec3 -import de.bixilon.minosoft.gui.rendering.util.mat.mat4.Mat4Util.EMPTY_INSTANCE +import de.bixilon.minosoft.gui.rendering.util.mat.mat4.Mat4Util.reset import java.nio.FloatBuffer class TransformInstance( @@ -27,21 +27,21 @@ class TransformInstance( fun reset() { - this.value(Mat4.EMPTY_INSTANCE) + this.value.reset() for ((name, child) in children) { child.reset() } } - fun pack(buffer: FloatBuffer, parent: Mat4) { - val value = parent * value + fun pack(buffer: FloatBuffer, parent: Mat4, temp: Mat4) { + parent.times(value, temp) val offset = this.id * Mat4.length for (index in 0 until Mat4.length) { - buffer.put(offset + index, value.array[index]) + buffer.put(offset + index, temp.array[index]) } for ((name, child) in children) { - child.pack(buffer, value) + child.pack(buffer, temp, temp) } } } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/RenderSystem.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/RenderSystem.kt index d85017cf4..9d82d712c 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/RenderSystem.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/system/base/RenderSystem.kt @@ -72,7 +72,7 @@ interface RenderSystem { this.depth = settings.depth this.depthMask = settings.depthMask this.clearColor = settings.clearColor - shader = null + // shader = null polygonOffset(settings.polygonOffsetFactor, settings.polygonOffsetUnit) } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/system/opengl/OpenGLRenderSystem.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/system/opengl/OpenGLRenderSystem.kt index ec258860d..05061a08b 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/system/opengl/OpenGLRenderSystem.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/system/opengl/OpenGLRenderSystem.kt @@ -14,7 +14,6 @@ package de.bixilon.minosoft.gui.rendering.system.opengl import de.bixilon.kotlinglm.vec2.Vec2i -import de.bixilon.kutil.collections.CollectionUtil.synchronizedSetOf import de.bixilon.kutil.concurrent.lock.thread.ThreadMissmatchException import de.bixilon.minosoft.data.registries.identified.ResourceLocation import de.bixilon.minosoft.data.text.formatting.color.Colors @@ -47,6 +46,7 @@ import org.lwjgl.opengl.GL43.GL_DEBUG_OUTPUT import org.lwjgl.opengl.GL43.glDebugMessageCallback import java.nio.ByteBuffer import java.nio.FloatBuffer +import java.util.* class OpenGLRenderSystem( private val context: RenderContext, @@ -54,7 +54,7 @@ class OpenGLRenderSystem( private var thread: Thread? = null override val nativeShaders: MutableSet = mutableSetOf() override val shaders: MutableSet = mutableSetOf() - private val capabilities: MutableSet = synchronizedSetOf() + private val capabilities: EnumSet = EnumSet.noneOf(RenderingCapabilities::class.java) override lateinit var vendor: OpenGLVendor private set override var active: Boolean = false diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/util/mat/mat4/Mat4Util.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/util/mat/mat4/Mat4Util.kt index 1d894f33d..dbe84bb7d 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/util/mat/mat4/Mat4Util.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/util/mat/mat4/Mat4Util.kt @@ -50,4 +50,12 @@ object Mat4Util { res[2] = this[0, 2] * array[0] + this[1, 2] * array[1] + this[2, 2] * array[2] + this[3, 2] return res } + + fun Mat4.reset() { + val array = this.array + array[0] = 1.0f; array[1] = 0.0f;array[2] = 0.0f;array[3] = 0.0f + array[4] = 0.0f; array[5] = 1.0f;array[6] = 0.0f;array[7] = 0.0f + array[8] = 0.0f; array[9] = 0.0f;array[10] = 1.0f;array[11] = 0.0f + array[12] = 0.0f; array[13] = 0.0f;array[14] = 0.0f;array[15] = 1.0f + } } diff --git a/src/main/resources/assets/minecraft/models/entities/player/wide.smodel b/src/main/resources/assets/minecraft/models/entities/player/wide.smodel new file mode 100644 index 000000000..f88dafedf --- /dev/null +++ b/src/main/resources/assets/minecraft/models/entities/player/wide.smodel @@ -0,0 +1,42 @@ +{ + "elements": { + "body": { + "from": [-4, 12, -2], + "to": [4, 24, 2], + "texture": "minecraft:skin", + "uv": [16, 16], + "faces": "all", + "children": { + "head": { + "offset": [0, 24, 0], + "from": [-4, 0, -4], + "to": [4, 8, 4], + "uv": [0, 0], + "transform": "head", + "faces": "all", + "children": { + "hat": { + "from": [-4, 0, -4], + "to": [4, 8, 4], + "inflate": 0.5, + "uv": [32, 0], + "faces": "all" + } + } + } + } + } + }, + "transforms": { + "head": {}, + "right_arm": {}, + "left_arm": {}, + "right_leg": {}, + "left_leg": {} + }, + "textures": { + "minecraft:skin": { + "resolution": [64, 64] + } + } +}