8 bone influence

This commit is contained in:
Asval 2024-04-30 02:54:40 +02:00
parent 21cfa0781f
commit 071d32b2da
7 changed files with 103 additions and 61 deletions

@ -1 +1 @@
Subproject commit 462e5efd764e97256d123685f37be621f5787fcc
Subproject commit 39ba4c7fcd9e058dbe33d8fec7cddb00763ace33

View File

@ -8,7 +8,7 @@ in vec3 fPos;
in vec3 fNormal;
in vec3 fTangent;
in vec2 fTexCoords;
in float fTexLayer;
flat in int fTexLayer;
in vec4 fColor;
struct Texture
@ -98,7 +98,7 @@ out vec4 FragColor;
int LayerToIndex()
{
return clamp(int(fTexLayer), 0, uUvCount - 1);
return clamp(fTexLayer, 0, uUvCount - 1);
}
vec4 SamplerToVector(sampler2D s, vec2 coords)

View File

@ -4,10 +4,10 @@ layout (location = 1) in vec3 vPos;
layout (location = 2) in vec3 vNormal;
layout (location = 3) in vec3 vTangent;
layout (location = 4) in vec2 vTexCoords;
layout (location = 5) in float vTexLayer;
layout (location = 6) in vec4 vColor;
layout (location = 7) in vec4 vBoneIds;
layout (location = 8) in vec4 vBoneWeights;
layout (location = 5) in int vTexLayer;
layout (location = 6) in float vColor;
layout (location = 7) in vec4 vBoneInfluence;
layout (location = 8) in vec4 vBoneInfluenceExtra;
layout (location = 9) in mat4 vInstanceMatrix;
layout (location = 13) in vec3 vMorphTargetPos;
layout (location = 14) in vec3 vMorphTargetTangent;
@ -30,9 +30,23 @@ out vec3 fPos;
out vec3 fNormal;
out vec3 fTangent;
out vec2 fTexCoords;
out float fTexLayer;
flat out int fTexLayer;
out vec4 fColor;
vec4 unpackARGB(int color)
{
float a = float((color >> 24) & 0xFF);
float r = float((color >> 16) & 0xFF);
float g = float((color >> 8) & 0xFF);
float b = float((color >> 0) & 0xFF);
return vec4(r, g, b, a);
}
vec2 unpackBoneIDsAndWeights(int packedData)
{
return vec2(float((packedData >> 16) & 0xFFFF), float(packedData & 0xFFFF));
}
void main()
{
vec4 bindPos = vec4(mix(vPos, vMorphTargetPos, uMorphTime), 1.0);
@ -44,18 +58,24 @@ void main()
vec4 finalTangent = vec4(0.0);
if (uIsAnimated)
{
for(int i = 0 ; i < 4; i++)
vec4 boneInfluences[2];
boneInfluences[0] = vBoneInfluence;
boneInfluences[1] = vBoneInfluenceExtra;
for (int i = 0; i < 2; i++)
{
int boneIndex = int(vBoneIds[i]);
if(boneIndex < 0) break;
for(int j = 0 ; j < 4; j++)
{
vec2 boneInfluence = unpackBoneIDsAndWeights(int(boneInfluences[i][j]));
int boneIndex = int(boneInfluence.x);
float weight = boneInfluence.y;
mat4 boneMatrix = uFinalBonesMatrix[boneIndex] * inverse(uRestBonesMatrix[boneIndex]);
mat4 inverseBoneMatrix = transpose(inverse(boneMatrix));
float weight = vBoneWeights[i];
mat4 boneMatrix = uFinalBonesMatrix[boneIndex] * inverse(uRestBonesMatrix[boneIndex]);
mat4 inverseBoneMatrix = transpose(inverse(boneMatrix));
finalPos += boneMatrix * bindPos * weight;
finalNormal += inverseBoneMatrix * bindNormal * weight;
finalTangent += inverseBoneMatrix * bindTangent * weight;
finalPos += boneMatrix * bindPos * weight;
finalNormal += inverseBoneMatrix * bindNormal * weight;
finalTangent += inverseBoneMatrix * bindTangent * weight;
}
}
}
else
@ -72,5 +92,5 @@ void main()
fTangent = vec3(transpose(inverse(vInstanceMatrix)) * finalTangent);
fTexCoords = vTexCoords;
fTexLayer = vTexLayer;
fColor = vColor;
fColor = unpackARGB(int(vColor));
}

View File

@ -2,8 +2,8 @@
layout (location = 1) in vec3 vPos;
layout (location = 2) in vec3 vNormal;
layout (location = 7) in vec4 vBoneIds;
layout (location = 8) in vec4 vBoneWeights;
layout (location = 7) in vec4 vBoneInfluence;
layout (location = 8) in vec4 vBoneInfluenceExtra;
layout (location = 9) in mat4 vInstanceMatrix;
layout (location = 13) in vec3 vMorphTargetPos;
@ -22,6 +22,11 @@ uniform mat4 uProjection;
uniform float uMorphTime;
uniform bool uIsAnimated;
vec2 unpackBoneIDsAndWeights(int packedData)
{
return vec2(float((packedData >> 16) & 0xFFFF), float(packedData & 0xFFFF));
}
void main()
{
vec4 bindPos = vec4(mix(vPos, vMorphTargetPos, uMorphTime), 1.0);
@ -31,16 +36,22 @@ void main()
vec4 finalNormal = vec4(0.0);
if (uIsAnimated)
{
for(int i = 0 ; i < 4; i++)
vec4 boneInfluences[2];
boneInfluences[0] = vBoneInfluence;
boneInfluences[1] = vBoneInfluenceExtra;
for(int i = 0 ; i < 2; i++)
{
int boneIndex = int(vBoneIds[i]);
if(boneIndex < 0) break;
for(int j = 0; j < 4; j++)
{
vec2 boneInfluence = unpackBoneIDsAndWeights(int(boneInfluences[i][j]));
int boneIndex = int(boneInfluence.x);
float weight = boneInfluence.y;
mat4 boneMatrix = uFinalBonesMatrix[boneIndex] * inverse(uRestBonesMatrix[boneIndex]);
float weight = vBoneWeights[i];
mat4 boneMatrix = uFinalBonesMatrix[boneIndex] * inverse(uRestBonesMatrix[boneIndex]);
finalPos += boneMatrix * bindPos * weight;
finalNormal += transpose(inverse(boneMatrix)) * bindNormal * weight;
finalPos += boneMatrix * bindPos * weight;
finalNormal += transpose(inverse(boneMatrix)) * bindNormal * weight;
}
}
}
else

View File

@ -1,8 +1,8 @@
#version 460 core
layout (location = 1) in vec3 vPos;
layout (location = 7) in vec4 vBoneIds;
layout (location = 8) in vec4 vBoneWeights;
layout (location = 7) in vec4 vBoneInfluence;
layout (location = 8) in vec4 vBoneInfluenceExtra;
layout (location = 9) in mat4 vInstanceMatrix;
layout (location = 13) in vec3 vMorphTargetPos;
@ -20,6 +20,11 @@ uniform mat4 uProjection;
uniform float uMorphTime;
uniform bool uIsAnimated;
vec2 unpackBoneIDsAndWeights(int packedData)
{
return vec2(float((packedData >> 16) & 0xFFFF), float(packedData & 0xFFFF));
}
void main()
{
vec4 bindPos = vec4(mix(vPos, vMorphTargetPos, uMorphTime), 1.0);
@ -27,12 +32,19 @@ void main()
vec4 finalPos = vec4(0.0);
if (uIsAnimated)
{
for(int i = 0 ; i < 4; i++)
vec4 boneInfluences[2];
boneInfluences[0] = vBoneInfluence;
boneInfluences[1] = vBoneInfluenceExtra;
for(int i = 0 ; i < 2; i++)
{
int boneIndex = int(vBoneIds[i]);
if(boneIndex < 0) break;
for(int j = 0; j < 4; j++)
{
vec2 boneInfluence = unpackBoneIDsAndWeights(int(boneInfluences[i][j]));
int boneIndex = int(boneInfluence.x);
float weight = boneInfluence.y;
finalPos += uFinalBonesMatrix[boneIndex] * inverse(uRestBonesMatrix[boneIndex]) * bindPos * vBoneWeights[i];
finalPos += uFinalBonesMatrix[boneIndex] * inverse(uRestBonesMatrix[boneIndex]) * bindPos * weight;
}
}
}
else finalPos = bindPos;

View File

@ -26,7 +26,8 @@ public class VertexArrayObject<TVertexType, TIndexType> : IDisposable where TVer
switch (type)
{
case VertexAttribPointerType.Int:
GL.VertexAttribIPointer(index, count, VertexAttribIntegerType.Int, vertexSize * _sizeOfVertex, (IntPtr) (offset * _sizeOfVertex));
case VertexAttribPointerType.UnsignedInt:
GL.VertexAttribIPointer(index, count, (VertexAttribIntegerType) type, vertexSize * _sizeOfVertex, offset * _sizeOfVertex);
break;
default:
GL.VertexAttribPointer(index, count, type, false, vertexSize * _sizeOfVertex, offset * _sizeOfVertex);

View File

@ -20,6 +20,7 @@ namespace FModel.Views.Snooper.Models;
public class VertexAttribute
{
public int Size;
public VertexAttribPointerType Type;
public bool Enabled;
}
@ -28,18 +29,18 @@ public abstract class UModel : IRenderableModel
protected const int LodLevel = 0;
private readonly UObject _export;
private readonly List<VertexAttribute> _vertexAttributes = new()
{
new VertexAttribute { Size = 1, Enabled = false }, // VertexIndex
new VertexAttribute { Size = 3, Enabled = true }, // Position
new VertexAttribute { Size = 3, Enabled = false }, // Normal
new VertexAttribute { Size = 3, Enabled = false }, // Tangent
new VertexAttribute { Size = 2, Enabled = false }, // UV
new VertexAttribute { Size = 1, Enabled = false }, // TextureLayer
new VertexAttribute { Size = 4, Enabled = false }, // Colors
new VertexAttribute { Size = 4, Enabled = false }, // BoneIds
new VertexAttribute { Size = 4, Enabled = false } // BoneWeights
};
private readonly List<VertexAttribute> _vertexAttributes =
[
new VertexAttribute { Size = 1, Type = VertexAttribPointerType.Int, Enabled = false }, // VertexIndex
new VertexAttribute { Size = 3, Type = VertexAttribPointerType.Float, Enabled = true }, // Position
new VertexAttribute { Size = 3, Type = VertexAttribPointerType.Float, Enabled = false }, // Normal
new VertexAttribute { Size = 3, Type = VertexAttribPointerType.Float, Enabled = false }, // Tangent
new VertexAttribute { Size = 2, Type = VertexAttribPointerType.Float, Enabled = false }, // UV
new VertexAttribute { Size = 1, Type = VertexAttribPointerType.Float, Enabled = false }, // TextureLayer
new VertexAttribute { Size = 1, Type = VertexAttribPointerType.Float, Enabled = false }, // Colors
new VertexAttribute { Size = 4, Type = VertexAttribPointerType.Float, Enabled = false }, // BoneIds
new VertexAttribute { Size = 4, Type = VertexAttribPointerType.Float, Enabled = false } // BoneWeights
];
public int Handle { get; set; }
public BufferObject<uint> Ebo { get; set; }
@ -149,24 +150,20 @@ public abstract class UModel : IRenderableModel
if (HasVertexColors)
{
var color = lod.VertexColors[i];
Vertices[baseIndex + count++] = color.R;
Vertices[baseIndex + count++] = color.G;
Vertices[baseIndex + count++] = color.B;
Vertices[baseIndex + count++] = color.A;
Vertices[baseIndex + count++] = lod.VertexColors[i].ToPackedARGB();
}
if (vert is CSkelMeshVertex skelVert)
{
var weightsHash = skelVert.UnpackWeights();
Vertices[baseIndex + count++] = skelVert.Bone[0];
Vertices[baseIndex + count++] = skelVert.Bone[1];
Vertices[baseIndex + count++] = skelVert.Bone[2];
Vertices[baseIndex + count++] = skelVert.Bone[3];
Vertices[baseIndex + count++] = weightsHash[0];
Vertices[baseIndex + count++] = weightsHash[1];
Vertices[baseIndex + count++] = weightsHash[2];
Vertices[baseIndex + count++] = weightsHash[3];
int max = skelVert.Influences.Count;
for (int j = 0; j < 8; j++)
{
var boneID = j < max ? skelVert.Influences[j].Bone : (short) 0;
var weight = j < max ? skelVert.Influences[j].RawWeight : (byte) 0;
// Pack bone ID and weight
Vertices[baseIndex + count++] = (boneID << 16) | weight;
}
}
}
@ -197,8 +194,9 @@ public abstract class UModel : IRenderableModel
if (i != 5 || !broken)
{
Vao.VertexAttributePointer((uint) i, attribute.Size, i == 0 ? VertexAttribPointerType.Int : VertexAttribPointerType.Float, VertexSize, offset);
Vao.VertexAttributePointer((uint) i, attribute.Size, attribute.Type, VertexSize, offset);
}
offset += attribute.Size;
}