Built in IVertexType with tangent and binormal?

I couldn’t find any built in vertex type for normal mapping, eg vertex with tangent and binormal.

Does it exist in MonoGame, or do I have to create one myself?
Thanks,

I did it myself, i’m not sure there is a built-in one
Its just a generic struct we have to feed

Thanks,
Care to post your definition code?

I tried this declaration:

namespace Microsoft.Xna.Framework.Graphics
{
    /// <summary>
    /// Texture type for normal mapping
    /// </summary>
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct VertexPositionNormalTangentTexture : IVertexType
    {

        /// <summary>
        /// Position.
        /// </summary>
        public Vector3 Position;

        /// <summary>
        /// Normal.
        /// </summary>
        public Vector3 Normal;

        /// <summary>
        /// Tangent.
        /// </summary>
        public Vector3 Tangent;

        /// <summary>
        /// Binormal.
        /// </summary>
        public Vector3 Binormal;

        /// <summary>
        /// Texture coords.
        /// </summary>
        public Vector2 TextureCoordinate;

        /// <summary>
        /// Vertex declaration object.
        /// </summary>
        public static readonly VertexDeclaration VertexDeclaration;

        /// <summary>
        /// Vertex declaration.
        /// </summary>
        VertexDeclaration IVertexType.VertexDeclaration
        {
            get
            {
                return VertexDeclaration;
            }
        }

        /// <summary>
        /// Static constructor to init vertex declaration.
        /// </summary>
        static VertexPositionNormalTangentTexture()
        {
            VertexElement[] elements = new VertexElement[] {
                new VertexElement(0, VertexElementFormat.Vector4, VertexElementUsage.Position, 0),
                new VertexElement(12, VertexElementFormat.Vector3, VertexElementUsage.Normal, 0),
                new VertexElement(24, VertexElementFormat.Vector3, VertexElementUsage.Tangent, 0),
                new VertexElement(36, VertexElementFormat.Vector3, VertexElementUsage.Binormal, 0),
                new VertexElement(48, VertexElementFormat.Vector2, VertexElementUsage.TextureCoordinate, 0)
            };
            VertexDeclaration declaration = new VertexDeclaration(elements);
            VertexDeclaration = declaration;
        }


        /// <summary>
        /// Create the vertex.
        /// </summary>
        /// <param name="position">Vertex position.</param>
        /// <param name="normal">Vertex normal.</param>
        /// <param name="textureCoordinate">Texture coordinates.</param>
        /// <param name="tangent">Vertex tangent.</param>
        /// <param name="binormal">Vertex binormal.</param>
        public VertexPositionNormalTangentTexture(Vector3 position, Vector3 normal, Vector2 textureCoordinate, Vector3 tangent, Vector3 binormal)
        {
            Normal = normal;
            Position = position;
            TextureCoordinate = textureCoordinate;
            Tangent = tangent;
            Binormal = binormal;
        }

        /// <summary>
        /// Get if equals another object.
        /// </summary>
        /// <param name="obj">Object to compare to.</param>
        /// <returns>If objects are equal.</returns>
        public override bool Equals(object obj)
        {
            if (obj == null)
            {
                return false;
            }
            if (obj.GetType() != base.GetType())
            {
                return false;
            }
            return (this == ((VertexPositionNormalTangentTexture)obj));
        }

        /// <summary>
        /// Get the hash code of this vertex.
        /// </summary>
        /// <returns></returns>
        public override int GetHashCode()
        {
            unchecked
            {
                var hashCode = Position.GetHashCode();
                hashCode = (hashCode * 397) ^ Normal.GetHashCode();
                hashCode = (hashCode * 397) ^ TextureCoordinate.GetHashCode();
                hashCode = (hashCode * 397) ^ Tangent.GetHashCode();
                hashCode = (hashCode * 397) ^ Binormal.GetHashCode();
                return hashCode;
            }
        }

        /// <summary>
        /// Return string representation of this vertex.
        /// </summary>
        /// <returns>String representation of the vertex.</returns>
        public override string ToString()
        {
            return "{{Position:" + this.Position + " Normal:" + this.Normal + " TextureCoordinate:" + this.TextureCoordinate + " Tangent " + this.Tangent + "}}";
        }

        /// <summary>
        /// Return if two vertices are equal.
        /// </summary>
        /// <param name="left">Left side to compare.</param>
        /// <param name="right">Right side to compare.</param>
        /// <returns>If equal.</returns>
        public static bool operator ==(VertexPositionNormalTangentTexture left, VertexPositionNormalTangentTexture right)
        {
            return (((left.Position == right.Position) && (left.Normal == right.Normal)) && (left.TextureCoordinate == right.TextureCoordinate) && left.Binormal == right.Binormal && left.Tangent == right.Tangent);
        }

        /// <summary>
        /// Return if two vertices are not equal.
        /// </summary>
        /// <param name="left">Left side to compare.</param>
        /// <param name="right">Right side to compare.</param>
        /// <returns>If not equal.</returns>
        public static bool operator !=(VertexPositionNormalTangentTexture left, VertexPositionNormalTangentTexture right)
        {
            return !(left == right);
        }
    }
}

with this effect input:

// vertex shader input
struct VertexShaderInput
{
	float4 Position : POSITION0;
	float3 Normal : NORMAL0;
	float3 Tangent : TANGENT0;
	float3 Binormal : BINORMAL0;
	float2 TextureCoordinate : TEXCOORD0;
};

But it doesn’t seem to work (I don’t see anything on screen).

VertexElement(0, VertexElementFormat.Vector4, VertexElementUsage.Position, 0),

new VertexElement(16, VertexElementFormat.Vector3, VertexElementUsage.Normal, 0),

VertexElement(0, VertexElementFormat.Vector3, VertexElementUsage.Position, 0),

new VertexElement(12, VertexElementFormat.Vector3, VertexElementUsage.Normal, 0),

2 Likes

Yeah I tried that too, still doesn’t work :confused:

VertexElement[] elements = new VertexElement[] {
                new VertexElement(0, VertexElementFormat.Vector4, VertexElementUsage.Position, 0),
                new VertexElement(16, VertexElementFormat.Vector3, VertexElementUsage.Normal, 0),
                new VertexElement(28, VertexElementFormat.Vector3, VertexElementUsage.Tangent, 0),
                new VertexElement(40, VertexElementFormat.Vector3, VertexElementUsage.Binormal, 0),
                new VertexElement(52, VertexElementFormat.Vector2, VertexElementUsage.TextureCoordinate, 0)
            };
            VertexDeclaration declaration = new VertexDeclaration(elements);
            VertexDeclaration = declaration;

ack… use vector3 and 12 cuz your position is vector3

edit:
sorry for the post above

i mean
> VertexElement(0, VertexElementFormat.Vector4, VertexElementUsage.Position, 0),

        new VertexElement(16, VertexElementFormat.Vector3, VertexElementUsage.Normal, 0),

for vector4

and

VertexElement(0, VertexElementFormat.Vector3, VertexElementUsage.Position, 0),
new VertexElement(12, VertexElementFormat.Vector3, VertexElementUsage.Normal, 0),

for vector3

Edit: Nevermind the problem was somewhere else in the code (culling optimization, I changed my vertex type and forgot to update bounding box).

Thanks a lot :slight_smile:

oh…

edit: remove…

1 Like