Hardware skinning by shader-pipeline branch

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
Post Reply
penguin03
Posts: 25
Joined: Fri Apr 19, 2013 9:52 am

Hardware skinning by shader-pipeline branch

Post by penguin03 »

@Nadro

I remember you said, it's easy to do hardware skinning by shader-pipeline branch, is there any sample about it?

Or please give me some hints, I'll try it.
Nadro
Posts: 1648
Joined: Sun Feb 19, 2006 9:08 am
Location: Warsaw, Poland

Re: Hardware skinning by shader-pipeline branch

Post by Nadro »

In shader-pipeline branch you can submit bones weights and indices to shaders via vertex attributes, so it's true that it's easy to do hardware skinning in this branch, anyway we still didn't prepare any example for it. I'll back to shader-pipeline development, when tasks related to ogl-es branch will be finished.
Library helping with network requests, tasks management, logger etc in desktop and mobile apps: https://github.com/GrupaPracuj/hermes
RdR
Competition winner
Posts: 273
Joined: Tue Mar 29, 2011 2:58 pm
Contact:

Re: Hardware skinning by shader-pipeline branch

Post by RdR »

I used the shader-pipeline branch as renderer for my custom character animation system.
Simple patch which adds an extra vertex type you can use and pass to your shader.

http://pastebin.com/j1ErCwPq

Code: Select all

 
Index: include/CVertexBuffer.h
===================================================================
--- include/CVertexBuffer.h (revision 4533)
+++ include/CVertexBuffer.h (working copy)
@@ -169,6 +169,8 @@
                return video::EVT_2TCOORDS;     
            case sizeof(video::S3DVertexTangents):
                return video::EVT_TANGENTS;
+           case sizeof(video::S3DVertexBlended):
+               return video::EVT_BLENDED;
            default:
                return (video::E_VERTEX_TYPE)-1;
            }
@@ -187,6 +189,7 @@
    typedef CVertexBuffer<video::S3DVertex> SVertexBuffer;
    typedef CVertexBuffer<video::S3DVertex2TCoords> SVertexBufferLightMap;
    typedef CVertexBuffer<video::S3DVertexTangents> SVertexBufferTangents;
+   typedef CVertexBuffer<video::S3DVertexBlended> SVertexBufferBlended;
 }
 }
 
Index: include/S3DVertex.h
===================================================================
--- include/S3DVertex.h (revision 4533)
+++ include/S3DVertex.h (working copy)
@@ -26,7 +26,11 @@
 
    //! Vertex with a tangent and binormal vector, video::S3DVertexTangents.
    /** Usually used for tangent space normal mapping. */
-   EVT_TANGENTS
+   EVT_TANGENTS,
+
+   //! Vertex with a blend indices and wieghts, video::S3DVertexBlend.
+   /** Usually used for tangent space normal mapping. */
+   EVT_BLENDED
 };
 
 //! Array holding the built in vertex type names
@@ -35,6 +39,7 @@
    "standard",
    "2tcoords",
    "tangents",
+   "blended",
    0
 };
 
@@ -251,8 +256,71 @@
    }
 };
 
+//! Vertex with blend indices and weights along with a tangent and binormal vector.
+/** Usually used for tangent space normal mapping. */
+struct S3DVertexBlended : public S3DVertexTangents
+{
+   //! default constructor
+   S3DVertexBlended() : S3DVertexTangents() { }
 
+   //! constructor
+   S3DVertexBlended(const core::vector3df& pos,
+       const core::vector3df& normal, SColor c,
+       const core::vector2df& tcoords,
+       const core::vector3df& tangent,
+       const core::vector3df& binormal,
+       const float blendIndices[4],
+       const float blendWeights[4],
+       const core::vector2df& tcoords2)
+       : S3DVertexTangents(pos, normal, c, tcoords, tangent, binormal), TCoords2(tcoords2) { 
+           BlendIndices[0] = blendIndices[0];
+           BlendIndices[1] = blendIndices[1];
+           BlendIndices[2] = blendIndices[2];
+           BlendIndices[3] = blendIndices[3];
 
+           BlendWeights[0] = blendWeights[0];
+           BlendWeights[1] = blendWeights[1];
+           BlendWeights[2] = blendWeights[2];
+           BlendWeights[3] = blendWeights[3];
+   }
+
+   //! Blend indices
+   float BlendIndices[4];
+
+   //! Blend weights
+   float BlendWeights[4];
+
+   //! Second set of texture coordinates
+   core::vector2d<f32> TCoords2;
+
+   //! Equality operator
+   bool operator==(const S3DVertexBlended& other) const
+   {
+       return ((static_cast<S3DVertex>(*this)==other) &&
+           (TCoords2 == other.TCoords2));
+   }
+
+   //! Inequality operator
+   bool operator!=(const S3DVertexBlended& other) const
+   {
+       return ((static_cast<S3DVertex>(*this)!=other) ||
+           (TCoords2 != other.TCoords2));
+   }
+
+   bool operator<(const S3DVertexBlended& other) const
+   {
+       return ((static_cast<S3DVertex>(*this) < other) ||
+               ((static_cast<S3DVertex>(*this) == other) && (TCoords2 < other.TCoords2)));
+   }
+
+   E_VERTEX_TYPE getType() const
+   {
+       return EVT_BLENDED;
+   }
+};
+
+
+
 inline u32 getVertexPitchFromType(E_VERTEX_TYPE vertexType)
 {
    switch (vertexType)
@@ -261,6 +329,8 @@
        return sizeof(video::S3DVertex2TCoords);
    case video::EVT_TANGENTS:
        return sizeof(video::S3DVertexTangents);
+   case video::EVT_BLENDED:
+       return sizeof(video::S3DVertexBlended);
    default:
        return sizeof(video::S3DVertex);
    }
Index: source/Irrlicht/CNullDriver.cpp
===================================================================
--- source/Irrlicht/CNullDriver.cpp (revision 4533)
+++ source/Irrlicht/CNullDriver.cpp (working copy)
@@ -268,7 +268,19 @@
    VertexDescriptor[2]->addAttribute("inTexCoord0", 2, EVAS_TEXCOORD0, EVAT_FLOAT);
    VertexDescriptor[2]->addAttribute("inTangent", 3, EVAS_TANGENT, EVAT_FLOAT);
    VertexDescriptor[2]->addAttribute("inBinormal", 3, EVAS_BINORMAL, EVAT_FLOAT);
+   
+   addVertexDescriptor("blended");
+   VertexDescriptor[3]->addAttribute("inPosition", 3, EVAS_POSITION, EVAT_FLOAT);
+   VertexDescriptor[3]->addAttribute("inNormal", 3, EVAS_NORMAL, EVAT_FLOAT);
+   VertexDescriptor[3]->addAttribute("inColor", 4, EVAS_COLOR, EVAT_UBYTE);
+   VertexDescriptor[3]->addAttribute("inTexCoord0", 2, EVAS_TEXCOORD0, EVAT_FLOAT);
+   VertexDescriptor[3]->addAttribute("inTangent", 3, EVAS_TANGENT, EVAT_FLOAT);
+   VertexDescriptor[3]->addAttribute("inBinormal", 3, EVAS_BINORMAL, EVAT_FLOAT);
+   VertexDescriptor[3]->addAttribute("inBlendIndices", 4, EVAS_BLEND_INDICES, EVAT_FLOAT);
+   VertexDescriptor[3]->addAttribute("inBlendWeights", 4, EVAS_BLEND_WEIGHTS, EVAT_FLOAT);
+   VertexDescriptor[3]->addAttribute("inTexCoord1", 2, EVAS_TEXCOORD1, EVAT_FLOAT);
 
+
    return true;
 }
 
penguin03
Posts: 25
Joined: Fri Apr 19, 2013 9:52 am

Re: Hardware skinning by shader-pipeline branch

Post by penguin03 »

@RdR

Thank you for your implementation.

By the way, which format file are you using for your character animation system? I tried to use OGRE3d exporter to export skeleton mesh from 3DS max, the irrlich3d render output is wrong.

The problem is here:
http://irrlicht.sourceforge.net/forum/v ... =4&t=48676
RdR
Competition winner
Posts: 273
Joined: Tue Mar 29, 2011 2:58 pm
Contact:

Re: Hardware skinning by shader-pipeline branch

Post by RdR »

penguin03 wrote: Thank you for your implementation.

By the way, which format file are you using for your character animation system? I tried to use OGRE3d exporter to export skeleton mesh from 3DS max, the irrlich3d render output is wrong.

The problem is here:
http://irrlicht.sourceforge.net/forum/v ... =4&t=48676
I created my own file format
http://irrlicht.sourceforge.net/forum/v ... =6&t=46513
Post Reply