mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-15 18:34:56 -04:00
skeletal: shade lighting
This adds (and transforms as needed) a normal into the shader. Maybe interpolation will be done in the future
This commit is contained in:
parent
3eac315d62
commit
e4a5cb597b
@ -24,8 +24,7 @@ import de.bixilon.minosoft.gui.rendering.skeletal.instance.SkeletalInstance
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.mesh.SkeletalMesh
|
||||
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.EMPTY
|
||||
import de.bixilon.minosoft.test.IT
|
||||
import org.testng.Assert.assertEquals
|
||||
import org.testng.Assert.assertTrue
|
||||
import org.testng.Assert.*
|
||||
import org.testng.annotations.Test
|
||||
|
||||
@Test(groups = ["skeletal", "block_entity_rendering"])
|
||||
@ -46,12 +45,13 @@ class OpenCloseAnimationTest {
|
||||
|
||||
fun `correct playing and over state`() {
|
||||
val animation = create()
|
||||
// TODO: assert not playing
|
||||
assertFalse(animation.getInstance().animation.isPlaying(animation))
|
||||
animation.open()
|
||||
// TODO: assert playing
|
||||
assertTrue(animation.getInstance().animation.isPlaying(animation))
|
||||
animation.close()
|
||||
// TODO: assert playing
|
||||
assertTrue(animation.getInstance().animation.isPlaying(animation))
|
||||
assertEquals(animation.draw(0.3f), OVER)
|
||||
// assertFalse(animation.getInstance().animation.isPlaying(animation)) // animation is drawn directly, that is part of the animation manager
|
||||
}
|
||||
|
||||
fun animation() {
|
||||
@ -97,5 +97,8 @@ class OpenCloseAnimationTest {
|
||||
|
||||
@JvmName("getProgress2")
|
||||
fun getProgress() = this.progress
|
||||
|
||||
@JvmName("getInstance2")
|
||||
fun getInstance() = this.instance
|
||||
}
|
||||
}
|
||||
|
@ -72,4 +72,7 @@ class AnimationManager(val instance: SkeletalInstance) {
|
||||
}
|
||||
lock.unlock()
|
||||
}
|
||||
|
||||
fun isPlaying(animation: AbstractAnimation) = animation.name in playing
|
||||
fun isPlaying(name: String) = name in playing
|
||||
}
|
||||
|
@ -13,10 +13,11 @@
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.skeletal.mesh
|
||||
|
||||
import de.bixilon.kotlinglm.vec3.Vec3
|
||||
import de.bixilon.minosoft.gui.rendering.models.block.element.FaceVertexData
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.shader.ShaderTexture
|
||||
|
||||
interface SkeletalConsumer {
|
||||
|
||||
fun addQuad(positions: FaceVertexData, uv: FaceVertexData, transform: Int, texture: ShaderTexture)
|
||||
fun addQuad(positions: FaceVertexData, uv: FaceVertexData, transform: Int, normal: Vec3, texture: ShaderTexture)
|
||||
}
|
||||
|
@ -25,20 +25,35 @@ import de.bixilon.minosoft.gui.rendering.util.mesh.MeshStruct
|
||||
class SkeletalMesh(context: RenderContext, initialCacheSize: Int) : Mesh(context, SkeletalMeshStruct, initialCacheSize = initialCacheSize), SkeletalConsumer {
|
||||
override val order = context.system.quadOrder
|
||||
|
||||
private fun addVertex(position: FaceVertexData, positionOffset: Int, uv: FaceVertexData, uvOffset: Int, transform: Float, textureShaderId: Float) {
|
||||
private fun addVertex(position: FaceVertexData, positionOffset: Int, uv: FaceVertexData, uvOffset: Int, transform: Float, normal: Float, textureShaderId: Float) {
|
||||
data.add(
|
||||
position[positionOffset + 0], position[positionOffset + 1], position[positionOffset + 2],
|
||||
uv[uvOffset + 0], uv[uvOffset + 1],
|
||||
transform, textureShaderId
|
||||
transform, normal,
|
||||
)
|
||||
data.add(textureShaderId)
|
||||
}
|
||||
|
||||
override fun addQuad(positions: FaceVertexData, uv: FaceVertexData, transform: Int, texture: ShaderTexture) {
|
||||
private fun encodePart(part: Float): Int {
|
||||
val unsigned = (part + 1.0f) / 2.0f // remove negative sign
|
||||
return (unsigned * 15.0f).toInt() and 0x0F
|
||||
}
|
||||
|
||||
private fun encodeNormal(normal: Vec3): Int {
|
||||
val x = encodePart(normal.x)
|
||||
val y = encodePart(normal.y)
|
||||
val z = encodePart(normal.z)
|
||||
|
||||
return (y shl 8) or (z shl 4) or (x)
|
||||
}
|
||||
|
||||
override fun addQuad(positions: FaceVertexData, uv: FaceVertexData, transform: Int, normal: Vec3, texture: ShaderTexture) {
|
||||
val transform = transform.buffer()
|
||||
val textureShaderId = texture.shaderId.buffer()
|
||||
val normal = encodeNormal(normal).buffer()
|
||||
|
||||
order.iterate { position, uvIndex ->
|
||||
addVertex(positions, position * Vec3.length, uv, uvIndex * Vec2.length, transform, textureShaderId)
|
||||
addVertex(positions, position * Vec3.length, uv, uvIndex * Vec2.length, transform, normal, textureShaderId)
|
||||
}
|
||||
}
|
||||
|
||||
@ -47,6 +62,7 @@ class SkeletalMesh(context: RenderContext, initialCacheSize: Int) : Mesh(context
|
||||
val position: Vec3,
|
||||
val uv: Vec2,
|
||||
val transform: Int,
|
||||
val normal: Int,
|
||||
val indexLayerAnimation: Int,
|
||||
) {
|
||||
companion object : MeshStruct(SkeletalMeshStruct::class)
|
||||
|
@ -16,7 +16,6 @@ package de.bixilon.minosoft.gui.rendering.skeletal.model.elements
|
||||
import de.bixilon.kotlinglm.GLM
|
||||
import de.bixilon.kotlinglm.vec2.Vec2
|
||||
import de.bixilon.kotlinglm.vec3.Vec3
|
||||
import de.bixilon.minosoft.data.Axes
|
||||
import de.bixilon.minosoft.data.direction.Directions
|
||||
import de.bixilon.minosoft.data.registries.identified.ResourceLocation
|
||||
import de.bixilon.minosoft.gui.rendering.models.block.element.ModelElement.Companion.BLOCK_SIZE
|
||||
@ -47,19 +46,24 @@ data class SkeletalFace(
|
||||
).toArray(direction, 0)
|
||||
|
||||
|
||||
val normal = Vec3(direction.vector)
|
||||
|
||||
for (rotation in context.rotations) {
|
||||
val origin = rotation.origin!! / BLOCK_SIZE
|
||||
|
||||
val rad = -GLM.radians(rotation.value)
|
||||
val vec = Vec3(0, positions)
|
||||
normal.rotateAssign(rad)
|
||||
|
||||
for (i in 0 until 4) {
|
||||
vec.ofs = i * Vec3.length
|
||||
vec.rotateAssign(rad[0], Axes.X, origin, false)
|
||||
vec.rotateAssign(rad[1], Axes.Y, origin, false)
|
||||
vec.rotateAssign(rad[2], Axes.Z, origin, false)
|
||||
vec.rotateAssign(rad, origin, false)
|
||||
}
|
||||
}
|
||||
|
||||
context.consumer.addQuad(positions, uvData, transform, texture.texture)
|
||||
normal.normalizeAssign()
|
||||
|
||||
|
||||
context.consumer.addQuad(positions, uvData, transform, normal, texture.texture)
|
||||
}
|
||||
}
|
||||
|
@ -91,6 +91,20 @@ object Vec3Util {
|
||||
this += origin
|
||||
}
|
||||
|
||||
fun Vec3.rotateAssign(rad: Vec3, origin: Vec3, rescale: Boolean) {
|
||||
this -= origin
|
||||
rotateAssign(rad.x, Axes.X, rescale)
|
||||
rotateAssign(rad.y, Axes.Y, rescale)
|
||||
rotateAssign(rad.z, Axes.Z, rescale)
|
||||
this += origin
|
||||
}
|
||||
|
||||
fun Vec3.rotateAssign(rad: Vec3) {
|
||||
rotateAssign(rad.x, Axes.X, false)
|
||||
rotateAssign(rad.y, Axes.Y, false)
|
||||
rotateAssign(rad.z, Axes.Z, false)
|
||||
}
|
||||
|
||||
operator fun Vec3.get(axis: Axes): Float {
|
||||
return when (axis) {
|
||||
Axes.X -> x
|
||||
|
@ -16,7 +16,8 @@
|
||||
layout (location = 0) in vec3 vinPosition;
|
||||
layout (location = 1) in vec2 vinUV;
|
||||
layout (location = 2) in float vinTransform;
|
||||
layout (location = 3) in float vinIndexLayerAnimation;// texture index (0xF0000000), texture layer (0x0FFFF000), animation index (0x00000FFF)
|
||||
layout (location = 3) in float vinNormal;
|
||||
layout (location = 4) in float vinIndexLayerAnimation;// texture index (0xF0000000), texture layer (0x0FFFF000), animation index (0x00000FFF)
|
||||
|
||||
#include "minosoft:animation/header_vertex"
|
||||
|
||||
@ -35,10 +36,39 @@ uniform uint uLight;
|
||||
|
||||
#include "minosoft:animation/main_vertex"
|
||||
|
||||
float decodeNormal(uint data) {
|
||||
return (data / 15.0f) * 2.0f - 1.0f;
|
||||
}
|
||||
|
||||
vec3 decodeNormal() {
|
||||
uint combined = floatBitsToUint(vinNormal);
|
||||
uint x = combined & 0x0Fu;
|
||||
uint y = combined >> 8u & 0x0Fu;
|
||||
uint z = combined >> 4u & 0x0Fu;
|
||||
return vec3(decodeNormal(x), decodeNormal(y), decodeNormal(z));
|
||||
}
|
||||
|
||||
vec3 transformNormal(vec3 normal, mat4 transform) {
|
||||
// return normalize(mat3(transpose(inverse(transform))) * normal);
|
||||
return mat3(transform) * normal;
|
||||
}
|
||||
|
||||
float getShade(vec3 normal) {
|
||||
if (normal.y < -0.5f) return 0.5f;
|
||||
if (normal.y > 0.5f) return 1.0f;
|
||||
if (normal.x < -0.5f || normal.x > 0.5f) return 0.6f;
|
||||
if (normal.z < -0.5f || normal.z > 0.5f) return 0.8f;
|
||||
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec4 position = uSkeletalTransforms[floatBitsToUint(vinTransform)] * vec4(vinPosition, 1.0f);
|
||||
mat4 transform = uSkeletalTransforms[floatBitsToUint(vinTransform)];
|
||||
vec4 position = transform * vec4(vinPosition, 1.0f);
|
||||
gl_Position = uViewProjectionMatrix * position;
|
||||
finTintColor = getLight(uLight & 0xFFu);
|
||||
vec3 normal = transformNormal(decodeNormal(), transform);
|
||||
|
||||
finTintColor = getLight(uLight & 0xFFu) * vec4(vec3(getShade(normal)), 1.0f);
|
||||
finFragmentPosition = position.xyz;
|
||||
|
||||
run_animation();
|
||||
|
Loading…
x
Reference in New Issue
Block a user