Bump mapping for Animated meshes

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!
robmar
Posts: 1125
Joined: Sun Aug 14, 2011 11:30 pm

Re: Bump mapping for Animated meshes

Post by robmar »

Nadro, all what you say, and what Blindside said, does is just skip adding tangents to all the frames, so none of them show bump mapping.

The default meshes get tangents, but when they are morphed or whatever after bone movement they need tangents adding again.

There is no documentation, or at least none that I have found so far.

Do you or anyone actually know how to do this?
robmar
Posts: 1125
Joined: Sun Aug 14, 2011 11:30 pm

Re: Bump mapping for Animated meshes

Post by robmar »

Tested it further and although it does skip converting the frames.. somehow everything gets bump mapped; I owe you a beer Nadro!

All that stuff with converting all those frames, for nothing!

So how does it do that, and so fast?
Nadro
Posts: 1648
Joined: Sun Feb 19, 2006 9:08 am
Location: Warsaw, Poland

Re: Bump mapping for Animated meshes

Post by Nadro »

Good to know, that this problem is solved ;)
Library helping with network requests, tasks management, logger etc in desktop and mobile apps: https://github.com/GrupaPracuj/hermes
robmar
Posts: 1125
Joined: Sun Aug 14, 2011 11:30 pm

Re: Bump mapping for Animated meshes

Post by robmar »

:) Yep, maybe I'll do a sample...
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Re: Bump mapping for Animated meshes

Post by hybrid »

You can interpolate tangents just as all the other vectors. If any of that data is available, it gets animated just as the bones are. That's why this works almost automatically. However, adding tangents in the first place (i.e. for the poses) is still not perfectly working IIRC.
mongoose7
Posts: 1227
Joined: Wed Apr 06, 2011 12:13 pm

Re: Bump mapping for Animated meshes

Post by mongoose7 »

I had a quick look at the code to verify that normals were transformed, but I didn't see any reference to tangents.
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Bump mapping for Animated meshes

Post by Vectrotek »

It would have been nice if IRRLICHT could update the Tangents / Binormals like it does with Normals when it animates a Skinned Model like "*.b3d" or "*.X"..

This shader works fine but Normals "Deviate" during animation.. (Caused by IRR not updating Tangents/Binormals like Normals).. My question is.. "HOW DO WE UPDATE TANGENTS AND BINORMALS LIKE GL_NORMALS IN SKINNED ANIMATION?"

Code: Select all

 //  VERTEX PROGRAM  Jacques. Pretorius 2015 
 
 uniform mat4 mWorld;    
 
 varying vec3 Tangent;
 varying vec3 Binormal;
 varying vec2 UVCoordsXY;
 varying vec3 VNormal;
 varying vec3 VertexGLPosition;
 varying vec3 NormalBB;
 varying vec3 TangentBB;
 varying vec3 BinormalBB;
 
 void main()
  {UVCoordsXY        = gl_MultiTexCoord0.xy;          // Just what it says! 
   Tangent           = normalize(gl_MultiTexCoord1);  // Acuired here and  passed on to the FRAGMENT SHADER
   Binormal          = normalize(gl_MultiTexCoord2);
   VNormal           = gl_Normal; // Must happen here..
   VNormal           = normalize(vec3(mWorld * vec4(VNormal.xyz, 0 )).xyz);  // ???????
 
   // WHAT DO WE DO WITH THESE TO HAVE THEM UPDATED DURING SKINNED DEFORMATION ?!?!?! 
   Tangent           = normalize(vec3(mWorld * vec4(Tangent.xyz, 0 )).xyz);
   Binormal          = normalize(vec3(mWorld * vec4(Binormal.xyz,0)).xyz);
 
 
 
   gl_Position       = gl_ModelViewProjectionMatrix * gl_Vertex;    // UNSEEN, This ensures that OBJECT TRANSLATION is considered..
   VertexGLPosition  = vec3(mWorld * vec4(gl_Vertex.xyz,1)).xyz;  // This ensures that OBJECT TRANSLATION is considered..
  }
 
Fragment..

Code: Select all

 
 //   FRAGMENT SHADER written by Jacques Pretorius 2015..
 
 
 // Used IRRLICHT 1.8.1..
 
 // We are limited to 4 maps so use the alpha and RGB channels with inititive..
 uniform sampler2D DiffuseMap;        // The "ClipMap" is determined in the Diffuse ALPHA Channel..
 uniform sampler2D NormalMap;         // The "Droplet" Effect MASK is in the "NormalMap" ALPHA Channel..
 uniform sampler2D SpecularMap;       // We could have Further functionality in the R, G or B channels if needed..
 uniform sampler2D GlossMap;          // We could have had Gloss as the alpha channel in the specular map..
                                      // Should we need the FOURTH Texture, well change Glossmap to be Specular ALPHA..
 uniform int       FShaderCommand;    // An Integer that is controlled from the program used to alter the operation of this Fragment Shader (press buttons 1 to 0..)
                                      // We also could have a "VProgramCommand" for the Vertex Program..
 uniform vec4      CamPosTEST;
 uniform vec3      LightPos001;       // This would become an array when it comes to many lights..
 uniform mat4      mWorld;            // Fed from IRRLICHT via Vetrex Shader.. ENSURES CORRECT LIGHTING after SCALE TRANSLATE and ROTATE.... 
                                      // MWORLD ensures that we have physically correct lighting on a normal map 
                                      // no mater what the SCALE, ROTATION or TRANSLATION is..
 varying vec2      UVCoordsXY;        // Passed through the Vertex Program..
 varying vec3      VNormal;           // Effectively Fragment Normal after passing through the Vertex Progam.
 varying vec3      Tangent;           // What is the feasibility of a "RGB pre-rendered Tangent Map"? 
 varying vec3      Binormal;          // BiNormal and NOT BiTangent.. (no specific reason) 
 varying vec4      CameraPosition;    // We have alight hooked to the camera for demonstrative prposes.
 varying vec3      VertexGLPosition;  // As needed.. 
 // varying vec3      LightPosition;     // As needed.. 
 varying vec3      LightColour;       // MUST IMPLEMENT THIS !!! 
                                      // We need an array of lights from the scene which is either processed 
                                      // for importance by the CPU in the code or in here by the GPU.. 
 #define MAX_LIGHTS 32                // The Maxcimum amount of lights supported by the shader..
 
 // =============================================================================
 vec4 Interpolate(float Slider, vec4 ArgA, vec4 ArgB) 
  {vec4 OutputVal = ArgB * Slider + ArgA * (1 - Slider);
   return OutputVal;
  }
 // =  M A I N  = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = 
 void main()
  {//   VNormal           = normalize(vec3(mWorld * vec4(VNormal.xyz, 0 )).xyz);  // ???????
   // AGAIN.. HOW DO WE UPDATE THESE TO CHANGE WITH ETHE SKINNED ANIMATION ? 
   //   Tangent           = normalize(vec3(mWorld * vec4(Tangent.xyz, 0 )).xyz);
   //   Binormal          = normalize(vec3(mWorld * vec4(Binormal.xyz,0)).xyz);
   // vec3 VNormalORIG = VNormal;
 
   // -- IMAGE MAPS -- (get them first) 
   vec4 DiffuseMAPPEDCol  = texture2D(DiffuseMap,UVCoordsXY.xy); // ALPHA is "Clipmap"..
   vec4 NormalMAPPEDCol    = texture2D(NormalMap,UVCoordsXY.xy); // ALPHA is "Droplet Shader Mask"..
   vec3 SpecularMAPPEDCol  = texture2D(SpecularMap,UVCoordsXY.xy);
   vec3 GlossMAPEDCol      = texture2D(GlossMap,UVCoordsXY.xy);
 
   // - UN-RANGECOMPRESSED NORMALS - 
   vec3 UnCompressedNormal = (NormalMAPPEDCol -0.5) * 2.0;  
 
   // - LIGHTS - 
        LightPos001     = CamPosTEST.xyz;
   vec3 LightPos002 = vec3( 0.0 , -100.0 , 0.0);
   vec3 LightCol001 = vec3( 0.9 , 0.9 , 1.0 ); LightCol001.xyz *= 0.90; // Global Intensity Scale.
   vec3 LightCol002 = vec3( 1.0 , 0.1 , 0.0 ); LightCol002.xyz *= 0.90; // Global Intensity Scale.
 
 
   // - NORMALISED DIRECTIONS -
//   vec3 ViewDir     = normalize(CamPosTEST - VertexGLPosition);
//   vec3 LightDir001 = normalize(LightPos001 - VertexGLPosition); // Fragment Position??
//   vec3 LightDir002 = normalize(LightPos002 - VertexGLPosition);
 
  
 
   normalize(UnCompressedNormal); // Didnt really help our case..
   vec3 FinalNormal;
   // !!!!!!!!!!!!!!!!!!
   // FinalNormal = normalize( (UnCompressedNormal.x * Tangent)
   //            +  (UnCompressedNormal.y * Binormal)
   //            + (UnCompressedNormal.z * VNormal));
   // !!!!!!!!!!!!!!!!!!!!
   // What follows is a "Broken Down" version of the above for us to see how it works..
 
   // HOW DO WE GET SKIN DEFORMATION TO RESULT IN CORRECT LIGHTING? 
   // Look at existing code (which there isn't much of) 
   // HOW DO WE USE THE DYNAMIC NORMAL TO ANIMATE THE TANGENT..(Bitangent merely a cross between trhe other two)
 
   // Ramblings..
   // It is either "OBJECT SPACE" for Skinned Meshes (NON SPACE SAVING MIRRORRED UVS MANDATORY) or it is "REALTIME TANGENT GENERATION" by the CPU / GPU.... (onto something here)..
   // If it is "Realtime Tangent Generation" then we must CROSS the Tangent with the Normal to get Binormal in order to save CPU time..
 
   // OBJECT SPACE FOR SMINNED MODELS LOOK VERY PROMISING INDEED..
   // There may be a problem when converting form TAN to OBJECT for examples in X-Normal..
   // one could rightly state: "USE OBJECT NORMALS FOR SKINNED OBJECTS AND TANGENT NORMALS FOR STATIC OBJECTS."..
   
   
   
   
   // If we choose to have "Object Normals" and "UNIQUE UVS" for "SKINNED Models" then we should remember that "Tangent Normals" are still available for
   // "NON-SKINNED WORLD OBJECTS" which we can still Rotate, Translate and Scale successfully..
 
    // BE AWARE OF THIS IN IRR ENGINE CODE.. (not hat it help us with LIVE TANGENTS)..
    // #define USE_NVIDIA_GLH_VERSION // use version used by nvidia in glh headers
    // #define USE_IRR_VERSION
 
   // It could be a MIRACULOUS EQUATION that can UPDATE THE TANGENTS or something with what weve got in the shader which is not really much..(does not look lightly)..
   // There could be some way to PRESERVE THE ORIGINAL PRE-DEFORMED GEOMETRY and get it into the shader as a MAP OF SOME SORT.. (approximations?)   
   // We could make peace with our problem and keep things in mind when we animate the model.. (Skinning versus GL Rotation etc..)..
   // Can we MATCH UP A UV COORD WITH A VERTEX?  
   // If we, after exasperating trials, finally make peace with the fact that tangent influenced normals
   // cannot be perfected for skinned models, then we can at least know that the Z direction of the final normal is what we want it to be..
   // We could get away with these deviations because moving models during action may not be "disturbingly" apparent..
   // However, we shall keep searching for a mathematical solution..
 
   // HOW DO WE GET VALUES "FROM" THE GPU? We know how to SEND values to it..
 
   // HOW DOES COMPOSER HANDLE THIS PROBLEM ? 
   // COMPOSER SEEMS TO HAVE ANIMATED TANGENTS AND BINORMALS!!
   // THE QUESTION HOWEVER IS.. "ARE THE TANGENTS ANIMATED IN THE SHADER OR UNSEEN IN CPU CODE!!"
   // LETS HOPE IT IS IN THE SHADER..
   // WE WILL HAVE TO DISECT THE CGFX CODE PROPERLY TO UNDERSTAND THIS..
   // Ive done a lot of work on the CGFX shader, so lets hope it pays off..
   // Well..
   // We have learned that the animated tangents come fom CPU code i.e. NOT DONE IN THE SHADERS..
   // IT IS BECOMING CLEAR THAT WE HAVE TO GET IRRLICHT TO ANIMATE THESE ATNGENTS FROM THE CPU SIDE (CODE)..
   // Now.. Im a bit apprehensive to mess with the ENGINE CODE, so what Ill do now is to try find a way
   // to somehow bypass the engine from our code and then incorporate some kind of TANGENT / BINORMAL ANIMATION
   // from our code sothat if it proves successful then some "brainiacs" can incorporate the
   // code into the next release of IRRLICHT with what is found in the CPU code of mine..
 
 
   vec3 AddA;  vec3 AddB;  vec3 AddC;
   // - T A N G E N T - 
   AddA.x = UnCompressedNormal.x * Tangent.x; // STATIC !!
   AddA.y = UnCompressedNormal.x * Tangent.y;
   AddA.z = UnCompressedNormal.x * Tangent.z;
   // - B I N O R M A L - 
   AddB.x = UnCompressedNormal.y * Binormal.x; // STATIC !!
   AddB.y = UnCompressedNormal.y * Binormal.y;
   AddB.z = UnCompressedNormal.y * Binormal.z;
   
   
   // - V E R T E X   N O R M A L - (updated with skinned deformation) 
   AddC.x = UnCompressedNormal.z * VNormal.x; // DYNAMIC !!
   AddC.y = UnCompressedNormal.z * VNormal.y;
   AddC.z = UnCompressedNormal.z * VNormal.z;
 
   vec3 AddFin;
   AddFin.x = AddA.x + AddB.x + AddC.x;
   AddFin.y = AddA.y + AddB.y + AddC.y;
   AddFin.z = AddA.z + AddB.z + AddC.z;
   FinalNormal =  normalize (AddFin);  
 
                             // WE NEED TO CORRECT THIS TO WORK WITH "SKINNED DEFORMATION"!!!..
 
 
 
   // - NORMALISED DIRECTIONS - (used for Diffuse and Specularity) 
   vec3 ViewDir     = normalize(CamPosTEST - VertexGLPosition);
   vec3 LightDir001 = normalize(LightPos001 - VertexGLPosition); // Fragment Position??
   vec3 LightDir002 = normalize(LightPos002 - VertexGLPosition);
   // DIFFUSE BASE FOR ALL LIGHTS..
   float DiffBASE001 = max(dot(FinalNormal, (LightDir001)),0.0);
   float DiffBASE002 = max(dot(FinalNormal, (LightDir002)),0.0);
   // ADD INDIVIDUAL LIGHT COLOURS..
   vec3 DiffColByLight001 = DiffBASE001 * LightCol001; // All xyz..
   vec3 DiffColByLight002 = DiffBASE002 * LightCol002;
   // FINAL COLOURED DIFFUSE MIX..
   vec3 FinalDiffLightsColed = DiffColByLight001 + DiffColByLight002; // Combine the diffuse results of different lights..
 
   // S P E C U L A R I T Y   versus   G L O S S..
   // The equation below could perhaps be simplified..
   // Youll note that it looks somewhat strange in that uses a Power of a Power which is something I've never encountered before..
   // The reaon for using this "Extension" of Phong's method is to Standardise the concept of gloss for the artist when it comes to 
   // mapping Gloss for Specularity..
   // Look in the example Gloss/Specular map (which may be mixed into a R, G, B or A channel in the Gloss/Specular map) for a little Gloss palette (if there was space)..
   // I seems very few if any shader implementations out there truly understands that Specularity IS NOT Gloss..
   // Specularity is the amount of Light reflected or intensity of the Specular highlight (mathematically similar to reflection),
   // where Gloss is the Size of that Highlight..(Unpolished Metal Gloss has a "bigger" highlight and lower Specularity whereas
   // a shiny Apple would have a "smaller" highlight and higher specularity)..
   // What I tried here is to Standardise the Level of GREY SCALE as related to the sharpness of the highlight..
 
   // DONT REMOVE THE CLAMPS..
   float SpecBASE001 = clamp(pow(clamp(dot(normalize((ViewDir + LightDir001)),FinalNormal),0.0,1.0),  pow(2, (GlossMAPEDCol * 10.0)) ), 0.0 , 1.0 );
   float SpecBASE002 = clamp(pow(clamp(dot(normalize((ViewDir + LightDir002)),FinalNormal),0.0,1.0),  pow(2, (GlossMAPEDCol * 10.0)) ), 0.0 , 1.0 );
 
   vec3 SpecBasColled001 = LightCol001.xyz * SpecBASE001 ;
   vec3 SpecBasColled002 = LightCol002.xyz * SpecBASE002 ;
   vec3 SpecColledFINAL = (SpecBasColled001  +  SpecBasColled002); // Will be in loop..
 
   vec3 SpecularColour =  SpecularMAPPEDCol.xyz * SpecColledFINAL.xyz ; // SPECULAR is mathematically based on REFLECTION thus should reflect LIGHT COLOUR..
   // keep in mind that this (above) would eventually be a loop of some sort to handle
   // all the lights once we have more lights and a good system to feed the lights from the main program..
   // I am considering a "lights pool" from which we select the important ones and perhaps
   // combine or average , say, two lights in terms of position and colour into one light in the shader..
   // We dont really want to have each light in the program reflected verbatim in the shader..
   // Anyhow, this is future stuff..
 
 
   // -- DROPLET SHADER EFFECT -- 
   // " D R O P L E  T   S H A D E R "   P A R T   1   o f   3 ..   
   // Droplet Shading simulates the effect created when a light shines on, for instance,
   // a red round glassy gem in a ring where we have a Specular Highlight and then also a
   // reversed-bigger sort of highlight that is the same colour as the 
   // material which the gem is made of..
   // This effect is useful for, well, gems and particularly the irisses in eyes..
 
   float GlobalDropConcavity = -1.0; // Think of the "Convexity" of the "Lens" of an eye then of the "Concavity" of the "Iris"..
   vec3 AlteredUCN = UnCompressedNormal;
   // Invert the X and Y normals to simulate the Concavity of an Iris or back of a gem..
   AlteredUCN.x *= GlobalDropConcavity;    // Tweakable value.. Was originally -1.
   AlteredUCN.y *= GlobalDropConcavity;    // It is not a mathematically perfect thing so tweaking is O.K..
   vec3 DropletNormal = normalize((AlteredUCN.y * Binormal)  // The "Altered Normal" is an Inverse of the X and Y of the
                                 +(AlteredUCN.x * Tangent)   
                                 +(AlteredUCN.z * VNormal)); // "Original Normal" with the Z of the Normal UNTOUCHED..
                                 // Remember to change these once we get Skinned Deformation right..
   float GlobalDropFact = 0.75;
   float GlobalDropPhong = 8.0;
   vec3 DropletColled001 = LightCol001;   
   float DropletEffect001 = clamp(dot(normalize((ViewDir + LightDir001)),DropletNormal),0.0,1.0);  // Correct..
   DropletEffect001 = clamp(pow(DropletEffect001,  GlobalDropPhong ), 0.0 , 1.0 );
   // Phong 8.0 is good..(here we dont use the Standardising 
   // POW of POW as we manually controll the Sharpness of the "Inner Hhighlight")
   DropletEffect001 *= GlobalDropFact;
   DropletColled001.xyz *= DropletEffect001;
   vec3 DropletColled002 = LightCol002;   
   float DropletEffect002 = clamp(dot(normalize((ViewDir + LightDir002)),DropletNormal),0.0,1.0);  // Correct.. 
   DropletEffect002 = clamp(pow(DropletEffect002,  GlobalDropPhong ), 0.0 , 1.0 );
   DropletEffect002 *= GlobalDropFact;
   DropletColled002.xyz *= DropletEffect002;
   vec3 DropletFINAL = DropletColled001  +  DropletColled002;
   // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
   // " D R O P L E T   S H A D E R "    P A R T    3   o f   3  . .
   vec4 PreDropletDiffuse = DiffuseMAPPEDCol; // DO THIS BEFORE OTHER CALCULATIONS..
   // We DONT want to use "already shaded" diffuse here as it will negate the effect..
   // Here we use the "Alpha hannel" of the "Mormal Map" to BLOCK OUT ANY MAPPED DIFFUSE..
   // It also serves as a "Mask" for the effect.. (steer clear of "if ()" as borders become visible)
   DiffuseMAPPEDCol.xyz *= (1.0 - NormalMAPPEDCol.w);
   gl_FragColor = DiffuseMAPPEDCol; // Re-apply the MASKED mapped diffuse to Gl_Col before further diffuse shading.. 
   gl_FragColor.xyz *= FinalDiffLightsColed.xyz;
   
 
   // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 
   // This is now added to the masked area.. Multiplication instead of "if ()" ensures smooth transition..
   gl_FragColor.x += DropletFINAL.x * PreDropletDiffuse.x * NormalMAPPEDCol.w;
   gl_FragColor.y += DropletFINAL.y * PreDropletDiffuse.y * NormalMAPPEDCol.w;
   gl_FragColor.z += DropletFINAL.z * PreDropletDiffuse.z * NormalMAPPEDCol.w;   
   gl_FragColor.w = DiffuseMAPPEDCol.w;
 
 
 
   // ADD THE SPECULAR HIGHLIGHT.. 
   gl_FragColor.x += SpecularColour.x;
   gl_FragColor.y += SpecularColour.y;
   gl_FragColor.z += SpecularColour.z;
   
 
   if (FShaderCommand == 0)  // -- DEFAULT FULL FUNCTION RENDER -- 
    {// INTERPOLATE BETWEEN THE RAW MAPPED DIFFUSE COLOUR AND THE SHADED COLOUR AS A WAY OF CONTROLLING AMBIENT LIGHTING..
     // Often Misunderstood, the "AMBIENT" value for a scene is merely how much of the ORIGINAL MAPPED DIFFUSE COLOUR is rendered..
     // "Ambience" in my understanding is NOT REALLY a "Material Specific" attribute but rather a "Scene Specific" attribute..
     // "Ambience" could even be expressed as the render PLUS Original Mapped Colour..
     // For this wed need to KEEP SPECULAR UNTOUCHED.. The concept is debatable...
     // Keep pressing 1, 2 and 0 on the keyboard during runtime to understand the concept..
     // You may notice a Framerate Change during these keypresses which is simply
     // because different remdermodes use different sections of this GPU code and returns from different places..
     float AmbientSlider = 0.6;  // 0 is pure MAPPED values and 1 is pure SHADED values.. 0.85 is a good balance when considering "Droplet Shading"..
     gl_FragColor = Interpolate(AmbientSlider, PreDropletDiffuse, gl_FragColor  );
    }
   // gl_FragColor = mix(gl_FragColor,PreDropletDiffuse , AmbientSlider) // cant ge mix to work??
 
   //|||  SHADER COMMANDS  ||||||
   if (FShaderCommand == 2) {gl_FragColor = DiffuseMAPPEDCol; return;}  // And skip everything else..
   if (FShaderCommand == 3) // Show FINAL NORMALS..
    {gl_FragColor.x = (FinalNormal.x / 2.0) + 0.5; // Our vanilla Range Compression representation.
     gl_FragColor.y = (FinalNormal.y / 2.0) + 0.5;
     gl_FragColor.z = (FinalNormal.z / 2.0) + 0.5;
     gl_FragColor.w = DiffuseMAPPEDCol.w;
     return;
    }
 
   if (FShaderCommand == 4)  // Show Diffuse by LIGHT_001 only..
   {// gl_FragColor.xyz = FinalDiffLightsColed.xyz * 0.6; // uncomment if you want both lights.. (slightly subdued)..
     gl_FragColor.xyz = DiffColByLight001.xyz * 0.7;    // if you want Diffuse for Light 001 only..
    gl_FragColor.w = DiffuseMAPPEDCol.w;
    return;
   }
 
   if (FShaderCommand == 5) // Show DIFFUSE and SPECULAR (altered for better viewing) 
    {float DiffSub = 0.3;
     float SpecSub = 1.25;
     gl_FragColor.x = FinalDiffLightsColed.x * DiffSub;
     gl_FragColor.x += (SpecularColour.x * SpecSub);
     gl_FragColor.y = FinalDiffLightsColed.y * DiffSub;
     gl_FragColor.y += (SpecularColour.y * SpecSub);
     gl_FragColor.z = FinalDiffLightsColed.z * DiffSub;
     gl_FragColor.z += (SpecularColour.z * SpecSub);
     float GreyDiff = ( FinalDiffLightsColed.x +  FinalDiffLightsColed.y +  FinalDiffLightsColed.z ) / 3.0;
 
     gl_FragColor.w = DiffuseMAPPEDCol.w;
     return; } 
 
   if (FShaderCommand == 6) // Show TANGENTS..
    {gl_FragColor.x = (Tangent.x / 2.0) + 0.5;
     gl_FragColor.y = (Tangent.y / 2.0) + 0.5;
     gl_FragColor.z = (Tangent.z / 2.0) + 0.5;
     gl_FragColor.w = DiffuseMAPPEDCol.w;
     return; 
    } 
   if (FShaderCommand == 7) 
    {gl_FragColor.x =(Binormal.x/2.0)+0.5; gl_FragColor.y =(Binormal.y/2.0)+0.5; gl_FragColor.z =(Binormal.z/2.0)+0.5;
     gl_FragColor.w = DiffuseMAPPEDCol.w;
     return; 
    } 
   if (FShaderCommand == 8) // UNCOMPRESSED MAP NORMALS..
    {// gl_FragColor.x = NormalMAPPEDCol.x; gl_FragColor.y = NormalMAPPEDCol.y; gl_FragColor.z = NormalMAPPEDCol.z;
     gl_FragColor.x =  (UnCompressedNormal .x / 2.0) + 0.5; 
     gl_FragColor.y =  (UnCompressedNormal .y / 2.0) + 0.5;
     gl_FragColor.z =  (UnCompressedNormal .z / 2.0) + 0.5;
     gl_FragColor.w = DiffuseMAPPEDCol.w;
     return;
    } 
   if (FShaderCommand == 9) // Vertex Normals..
    {gl_FragColor.x =  (VNormal .x / 2.0) + 0.5; 
     gl_FragColor.y =  (VNormal .y / 2.0) + 0.5;
     gl_FragColor.z =  (VNormal .z / 2.0) + 0.5;
     gl_FragColor.w = DiffuseMAPPEDCol.w; // So we can have clipmapping..
     return; 
    } 
 
   //     - F R E S N E L -     (many uses)!!
   /*  // Uncomment this for an interesting effect!..
    float Fresnel = dot(VNormal, ViewDir);
   //float Fresnel = dot(FinalNormal * 1, ViewDir);  // DropletNormal
   // float Fresnel = dot(DropletNormal, ViewDir);  // DropletNormal
    // Fresnel = clamp((Fresnel - 0.2) * 1000.0, 0.0, 1.0);
    Fresnel *= 2.5;
    //if ((1.0 - Fresnel) > 0.7)
     // {
       // gl_FragColor.x += (1.0 - Fresnel);
        float InvFresnel = (1.0 - Fresnel);
       // InvFresnel *= 1.0;
      if (InvFresnel > 0.0) { gl_FragColor.x += InvFresnel;}
     // }
    //gl_FragColor.y = Fresnel;
    //gl_FragColor.z = Fresnel;
      gl_FragColor.w =  0 + (1.0 - Fresnel);
   //gl_FragColor.x = InvFresnel;
   //gl_FragColor.y = InvFresnel;
   //gl_FragColor.z = InvFresnel;
 
   //*/
 
  }// -- END -- 
 
 
 
 
 
 
 
This is my first post.. Hope it helps..
Last edited by Vectrotek on Thu May 14, 2015 11:40 pm, edited 3 times in total.
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Bump mapping for Animated meshes

Post by Vectrotek »

This is the code that calls these shaders..

Code: Select all

 
 // Jacques Pretorius 2015..
 // Thanks to all the CPU and GPU code-sharing Irrlicht guys out there!!
 // Note: This may not be the fastest or most cohesive code, but it should suffice to
 // demonstrate the use of the GLSL code..
 
 // = = = = = = = = = = = = = = = = = = = = = = 
 // #include <IRRLICHT_1_8_1/irrlicht.h> // Change this to suit your implementation..
  #include <irrlicht.h>             // Like this perhaps..
 #include <vector>
 // = = = = = = = = = = = = = = = = = = = = = = 
 //#pragma comment(lib,"irrlicht.lib") // IF WE DONT HAVE A "Libraries" directory in our IDE project tree..
 // = = = = = = = = = = = = = = = = = = = = = = 
 using namespace irr;
 using namespace core;
 using namespace scene;
 using namespace video;
 // = = = = = = = = = = = = = = = = = = = = = = 
 
 #define DIFFUSE  0
 #define NORMAL   1
 #define SPECULAR 2
 #define GLOSS    3
 
 // = = = = = = = = = = = = = = = = = = = = = = 
 // Variables and Objects..(I like them here as it gives an "overview" of matters) 
 video::E_DRIVER_TYPE            TheDriverType;
 core::dimension2d<u32>          DeskResolution;
 IrrlichtDevice*                 TheIRRNullDevice;  // Used to determine the desktop resolution..
 ICameraSceneNode*               TheCameraSceneNode;
 //---------------------------------------------------------------------------
 
 //                                    - ANIMATED MODELS (DirectX or BLITZ BASIC) -                                         
 scene::IAnimatedMesh*              AniMesh0001;  
 scene::IAnimatedMeshSceneNode*  AniMeshNode0001; 
 //                                                                                                                  
 scene::IAnimatedMesh*              AniMesh0002;  
 scene::IAnimatedMeshSceneNode*  AniMeshNode0002; 
 //                                                                                                                  
 
 // NOTE THE SLIGHT DIFFERENCE BETWEEN SKINNED AND STATIC OBJECTS!
 
 //                                    - STATIC MODELS (WAVEFRONT OBJ - disable *.mtl) -                                         
 scene::IMesh*                       IMesh0003;
 scene::IAnimatedMesh*             AniMesh0003;  
 scene::ISceneNode*                 ISceneNode0003 ;
 //                                                                                                                  
 scene::IMesh*                       IMesh0004;
 scene::IAnimatedMesh*             AniMesh0004;  
 scene::ISceneNode*                 ISceneNode0004 ;
 //                                                                                                                  
 
 
 
 //---------------------------------------------------------------------------
 video::IGPUProgrammingServices* TheGraphicsProcessorGPU;
 s32                             IDFIRSTShader;
 s32                             IDSECONDShader;
 int                             FragShadeCommand;    // Used to swich between render methods in the shader..
 int                             VertShadeCommand; 
 IrrlichtDevice*                 PrivateDevice;
 IVideoDriver*                   PrivateDriver;
 ISceneManager*                  PrivateSceneManager;  
 float                           GlossynessIN;        // Now we use maps for gloss..
 scene::ISceneNodeAnimator*      TheRotationAnimator ;
 vector3df                       LightPosition001;
 
 bool                            PlayPause;           // 1 = Play ; 0 = Pause..
 bool                            PrevPlayPause;       // Do things only when change occured..
 float                           AniPlaySpeed;        // Playing Speed..
 
 
 
 matrix4                         TheWorldMatrix; // CAN WE HANDLE CG WITH THIS??
 
 // WITH THIS SHADER IMPLEMENTATION WE FORGET ABOUT ALL THESE!!
 // matrix4                         TheViewMatrix;
 // matrix4                         TheProjectionMatrix;
 // matrix4                         TheInverseViewMatrix;
 //---------------------------------------------------------------------------
 // = = = = = = = = = = = = = = = = = = = = = = 
 class VECTROTEKAPP : public irr::IEventReceiver, irr::video::IShaderConstantSetCallBack
  {public:
   VECTROTEKAPP()
    {//  - INITIALISATION - 
     // Create the Irrlicht PrivateDevice.
     //                                 - INITIATION - 
     TheIRRNullDevice = createDevice(video::EDT_NULL);  // EDT = Enumerator Display Type.. Just so we know :) 
     DeskResolution   = TheIRRNullDevice->getVideoModeList()->getDesktopResolution();  // Mine..
     TheIRRNullDevice->drop();
 
 
     // PrivateDevice = createDevice(EDT_OPENGL,core::dimension2d<u32>( 1024 , 768 ), 32 ); // OLD METHOD..
     // PrivateDevice = createDevice(EDT_DIRECT3D9,DeskResolution,32); // For this use HLSL which resembles Nvidia CG..
     PrivateDevice    = createDevice(EDT_OPENGL,DeskResolution,32);
 
     PrivateDevice->setEventReceiver(this);
     PrivateSceneManager = PrivateDevice->getSceneManager();
     PrivateDriver = PrivateDevice->getVideoDriver();
     PrivateDevice ->getCursorControl()->setVisible(false);
 
     FragShadeCommand = 1; // Default Normal Shader Operation..
     VertShadeCommand = 1; // Default Normal Shader Operation..
     PlayPause = 1;        // Playing by default..
 
 
 
     SKeyMap keyMap[8];
     keyMap[0].Action  = EKA_MOVE_FORWARD;  keyMap[0].KeyCode = KEY_UP;
     keyMap[1].Action  = EKA_MOVE_FORWARD;  keyMap[1].KeyCode = KEY_KEY_W;
     keyMap[2].Action  = EKA_MOVE_BACKWARD; keyMap[2].KeyCode = KEY_DOWN;
     keyMap[3].Action  = EKA_MOVE_BACKWARD; keyMap[3].KeyCode = KEY_KEY_S;
     keyMap[4].Action  = EKA_STRAFE_LEFT;   keyMap[4].KeyCode = KEY_LEFT;
     keyMap[5].Action  = EKA_STRAFE_LEFT;   keyMap[5].KeyCode = KEY_KEY_A;
     keyMap[6].Action  = EKA_STRAFE_RIGHT;  keyMap[6].KeyCode = KEY_RIGHT;
     keyMap[7].Action  = EKA_STRAFE_RIGHT;  keyMap[7].KeyCode = KEY_KEY_D;
 
        TheCameraSceneNode = PrivateSceneManager -> addCameraSceneNodeFPS(0,        // ISceneNode* parent = 0   
                                                                          200,      // f32 rotateSpeed = 100.0f 
                                                                          0.0095,  // f32 moveSpeed = 0.5f     
                                                                          -1,       // s32 id                   
                                                                          keyMap,  // SKeyMap* keyMapArray     
                                                                          8);       // s32 keyMapSize           
 
 
 
//     TheCameraSceneNode = PrivateSceneManager->addCameraSceneNodeFPS();
     // FOR SPEED CONTROLL YOU MUST HAVE THE KEY CONTROLL SYSTEM INVOKED..
 
     
 
 
     TheCameraSceneNode->setPosition(core::vector3df( 0.0 , 20.0 ,20.0 ));
     TheCameraSceneNode->setTarget(core::vector3df( 0.0 , 10.0 , 0.0 ));
     TheCameraSceneNode->setFarValue(12000.0f);
     PrivateDriver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, true);
 
 
     // PrivateSceneManager->addSkyDomeSceneNode(PrivateDriver->getTexture("media/000_SKYDOME/SkyDome.jpg"),16,16,1.0,1.5);
 
 
 //* 
 ISceneNode* TheSKYBOXIscenenode
   = PrivateSceneManager
   ->addSkyBoxSceneNode(PrivateDriver->getTexture("media/0000_SKY_BOXES/0002_OFFICE_JACK/OFFICE_TOP.png"),
                        PrivateDriver->getTexture("media/0000_SKY_BOXES/0002_OFFICE_JACK/OFFICE_DOWN.png"),
                        PrivateDriver->getTexture("media/0000_SKY_BOXES/0002_OFFICE_JACK/OFFICE_FRONT.png"),
                        PrivateDriver->getTexture("media/0000_SKY_BOXES/0002_OFFICE_JACK/OFFICE_BACK.png"),
                        PrivateDriver->getTexture("media/0000_SKY_BOXES/0002_OFFICE_JACK/OFFICE_LEFT.png"),
                        PrivateDriver->getTexture("media/0000_SKY_BOXES/0002_OFFICE_JACK/OFFICE_RIGHT.png")); 
 
 //*/ 
 
 
 
 
     PrivateDriver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, true);
     GlossynessIN = 128.0;
     TheRotationAnimator = PrivateSceneManager->createRotationAnimator(core::vector3df( 0.3,0.2f,0.4 ));
     TheGraphicsProcessorGPU = PrivateDriver->getGPUProgrammingServices();
     // I create the shader material for the glass pane. 
     IDFIRSTShader = TheGraphicsProcessorGPU
                          ->addHighLevelShaderMaterialFromFiles(
                                                                "SHADERS/GLSL_002_VERTEX_PROGRAM.vert",  // Vertex Program Filename 
 
                                                                "main",            // Main Vertex Function Name 
                                                                EVST_VS_2_0,       // Vertex Program Profile 
                                                                "SHADERS/GLSL_001_FRAGMENT_SHADER.frag",  // Fragment Shader Filename 
 
                                                                "main",            // Main Fragment function name 
                                                                EPST_PS_2_0,       // Fragment Shader Profile 
                                                           this,
                                                                EMT_TRANSPARENT_ALPHA_CHANNEL_REF,
                                                                0, // ??
                                                                EGSL_DEFAULT
                                                               );
 
 
 
 
 
    // OUR NEW TEST SHADER!!
     IDSECONDShader = TheGraphicsProcessorGPU
                          ->addHighLevelShaderMaterialFromFiles(
                                                                "SHADERS/TEST_VERT.vert",  // Vertex Program Filename 
 
                                                                "main",            // Main Vertex Function Name 
                                                                EVST_VS_2_0,       // Vertex Program Profile 
                                                                "SHADERS/TEST_FRAG.frag",  // Fragment Shader Filename 
 
                                                                "main",            // Main Fragment function name 
                                                                EPST_PS_2_0,       // Fragment Shader Profile 
                                                                this               // 
                                                               );
 
     /* EVST_VS_1_1 EVST_VS_2_0 EVST_VS_2_a EVST_VS_3_0 EVST_VS_4_0 EVST_VS_4_1 EVST_VS_5_0 */
     /* EPST_PS_1_1 EPST_PS_1_2 EPST_PS_1_3 EPST_PS_1_4 EPST_PS_2_0 EPST_PS_2_a EPST_PS_2_b EPST_PS_3_0 EPST_PS_4_0 EPST_PS_4_1 EPST_PS_5_0 */
 
 
 
 
 
 
 
 
 
 //* 
 //                                  - FIRST ITEM - (ANIMATED)                                       
     AniMesh0001 = PrivateSceneManager ->getMesh("Media/0002_FALMER_IK_BAKE/X_001.x"); 
  // Yes! We can open "*.ms3d" from Blender 2.74..
 
     ((ISkinnedMesh*)AniMesh0001)->convertMeshToTangents();     // CONVERT A SKINNED MESH TO A SKINNED-TANGENT-MESH!!
     AniMeshNode0001 = 0;
     AniMeshNode0001 = PrivateSceneManager->addAnimatedMeshSceneNode(AniMesh0001);
 
     // USE THE *.MTL file for an alias object to simplify multitextures..
 
     //  We have to automate texture loading!! 
 
     // We need a method of naming maps like ID Tech 4 which uses the last letter of the name as a clue to whether it is diffuse, specular or local etc..
 
     // Some kind of string manipulation so that we dont have to do this every time..
     // Multiple textures on a model would also allow for more effects..
 
     AniMeshNode0001 -> getMaterial( 0 ).setTexture(DIFFUSE,  PrivateDriver->getTexture("Media/0002_FALMER_IK_BAKE/DIFFUSE_MAP.tga"));
     AniMeshNode0001 -> getMaterial( 0 ).setTexture(NORMAL,   PrivateDriver->getTexture("Media/0002_FALMER_IK_BAKE/NORMAL_MAP.tga"));
     AniMeshNode0001 -> getMaterial( 0 ).setTexture(SPECULAR, PrivateDriver->getTexture("Media/0002_FALMER_IK_BAKE/SPECULAR_MAP.tga"));
     AniMeshNode0001 -> getMaterial( 0 ).setTexture(GLOSS,    PrivateDriver->getTexture("Media/0002_FALMER_IK_BAKE/GLOSS_MAP.tga"));
     AniMeshNode0001 -> setMaterialType(E_MATERIAL_TYPE(IDFIRSTShader));
     AniMeshNode0001 -> setScale(vector3df( 1.0 , 1.0 , 1.0 ));   // Please be sure about why everyone likes BIG Scales!!
     AniMeshNode0001 -> setRotation(core::vector3df( 0.0 , 45.0 , 0.0 ));
     AniMeshNode0001 -> setPosition(vector3df( -20.0 , 12.0 , 0.0 ));
 
     AniPlaySpeed =  5.0 ;
 
 
 
     AniMeshNode0001 -> setAnimationSpeed  (AniPlaySpeed) ;   // Get this into command..
//     AniMeshNode0001 -> setFrameLoop  ( 0.0  ,  99.0 );  // Automate this..
     AniMeshNode0001 -> setFrameLoop  ( 0.0  +  1.0  ,  AniMeshNode0001 -> getEndFrame () + 1.0 );  // Automate this..
                                                                                 // We will controll the sequence here once we have the game running..
 
 
  /* // Some thing we csn do eith it..
 
     AniMeshNode0001 -> getMaterialCount();
     AniMeshNode0001 -> clone();
     AniMeshNode0001 -> getAutomaticCulling();
         AniMeshNode0001 -> addChild();
         AniMeshNode0001 -> getEndFrame ();
         AniMeshNode0001 -> setAutomaticCulling ();
         AniMeshNode0001 -> setPosition();
         AniMeshNode0001 ->
 */
 
 
 
 //*/ 
 
 
 
 //                                  - THIRD ITEM - (STATIC)                                       
 //* 
 
     AniMesh0003 = PrivateSceneManager ->getMesh("Media/0001_DROPSHIP_INTERIOR/OBJ_001.obj"); // N  REMEMBER TO DELETE "*.mtl"!! (IRRLICHT does wierd things with it..)
 
     // Dont confuse animesh with skinned mesh..
     IMesh0003 = PrivateSceneManager->getMeshManipulator() ->createMeshWithTangents(AniMesh0003->getMesh(0) ,false,false,false,true );  // RECALC NORMALS..
     ISceneNode0003 = 0;
     ISceneNode0003 = PrivateSceneManager->addMeshSceneNode(IMesh0003);
     ISceneNode0003 -> getMaterial( 0 ).setTexture(DIFFUSE,  PrivateDriver->getTexture("Media/0001_DROPSHIP_INTERIOR/DIFFUSE_MAP.tga"));
     ISceneNode0003 -> getMaterial( 0 ).setTexture(NORMAL,   PrivateDriver->getTexture("Media/0001_DROPSHIP_INTERIOR/NORMAL_MAP.tga"));
     ISceneNode0003 -> getMaterial( 0 ).setTexture(SPECULAR, PrivateDriver->getTexture("Media/0001_DROPSHIP_INTERIOR/SPECULAR_MAP.tga"));
     ISceneNode0003 -> getMaterial( 0 ).setTexture(GLOSS,    PrivateDriver->getTexture("Media/0001_DROPSHIP_INTERIOR/GLOSS_MAP.tga"));
     ISceneNode0003 -> setMaterialType(E_MATERIAL_TYPE(IDFIRSTShader));
 
//      ISceneNode0003 -> setScale(vector3df( 1.0 , 1.0 , 1.0 ));
      ISceneNode0003 -> setScale(vector3df( 0.5 , 0.5 , 0.5 ));
     ISceneNode0003 -> setRotation(core::vector3df( 10.0 , 45.0 , 30.0 ));
     ISceneNode0003 -> setPosition(vector3df( 20.0 , 20.0 , 0.0 )); // 
 
     ISceneNode0003->setDebugDataVisible(EDS_NORMALS); // 
 
 //*/ 
 
 
 
 
 
      //  -- MAIN LOOP --   
      int OldFps = 0;
 
 
 
      while(PrivateDevice->run())
       { //                        MAIN LOOP                                   
 
        
 
        if(PrivateDevice->isWindowActive())
         {PrivateDriver->beginScene(true,          // backBuffer 
                                    true,          // zBuffer 
                                    SColor( 255 , 207 , 211 , 192 ) // color 
                                   );
 
          // Then we switch back to the screen and set our glass pane and
          // PrivateDriver->setRenderTarget(0, true, true, SColor( 255 , 207 , 211 , 192 ));  // G B R
          PrivateSceneManager->drawAll();    // Draw the scene.
          PrivateDriver->endScene();
 
 
 
 
 
 
      if (PrevPlayPause != PlayPause)
       {
        if (PlayPause == 0)
         {
          AniMeshNode0001 -> setAnimationSpeed  ( 0 ) ;  
         }
 
        else if (PlayPause == 1)
         {
          AniMeshNode0001 -> setAnimationSpeed  (AniPlaySpeed) ; 
         }
 
       }
      PrevPlayPause = PlayPause;
 
 
 
 
 
 
 
          if(PrivateDriver->getFPS() != OldFps)
           {OldFps = PrivateDriver->getFPS();
            core::stringw WindowCaption = "Animated *.x with GLSL Shader..  FPS: ";
            WindowCaption += OldFps;
            PrivateDevice->setWindowCaption(WindowCaption.c_str());
           }
         }
 
   } //                          END MAIN LOOP                                 
  // -- END MAIN LOOP --                     
  };
 
    ~VECTROTEKAPP()
     {// Drop the PrivateDevice when the app is destroyed.
      PrivateDevice->drop();    
      PrivateDevice = NULL;
     }
    // Here we can change the tint colour based on key input.
    virtual bool OnEvent(const irr::SEvent& event)
     {if(event.EventType == irr::EET_KEY_INPUT_EVENT)
       {if(!event.KeyInput.PressedDown)
         {switch(event.KeyInput.Key) 
           {                      // Here we send a value to the Fragment Shader to show how we can control shader operations from our code..
            case irr::KEY_KEY_1:  FragShadeCommand = 1; break; // Fragemtn Shader " Normal Operation "..
            case irr::KEY_KEY_2:  FragShadeCommand = 2; break; // Fragment Shader " Mapped Unlit Diffuse "..
            case irr::KEY_KEY_3:  FragShadeCommand = 3; break; // Fragment Shader " Final Normals "..
            case irr::KEY_KEY_4:  FragShadeCommand = 4; break; // Fragment Shader " Diffuse Only "..
            case irr::KEY_KEY_5:  FragShadeCommand = 5; break; // Fragment Shader " Subdued Diffuse ans Specular Only "..
            case irr::KEY_KEY_6:  FragShadeCommand = 6; break; // Fragment Shader " Tangents "..
            case irr::KEY_KEY_7:  FragShadeCommand = 7; break; // Fragment Shader " BiNormals "..
            case irr::KEY_KEY_8:  FragShadeCommand = 8; break; // Fragment Shader " Mapped Normals "..
            case irr::KEY_KEY_9:  FragShadeCommand = 9; break; // Fragment Shader " VERTEX NORMALS "..
            case irr::KEY_KEY_0:  FragShadeCommand = 0; break; // Fragment Shader " Special ABmient Interpretation "..
 
            case irr::KEY_KEY_P:  PlayPause = !PlayPause; break; // Fragment Shader "PLAY - PAUSE Toggle"..
 
 
            case irr::KEY_KEY_O:  AniPlaySpeed *= 2.0;     AniMeshNode0001 -> setAnimationSpeed  (AniPlaySpeed) ; break; // "Faster"..
 
            case irr::KEY_KEY_I:  AniPlaySpeed *= 0.5; AniMeshNode0001 -> setAnimationSpeed  (AniPlaySpeed) ; break; // "Slower"..
 
            case irr::KEY_OEM_4: AniMeshNode0001 -> setCurrentFrame  (1) ; break; // 1 is indeed the FIRST FRAME.. "First Frame"..
 
 
 
 
            // AniPlaySpeed;
 
 
 
           }
         }
       }
      return false;
     }
 
 
 
    virtual void OnSetConstants(irr::video::IMaterialRendererServices* PrivateServices, irr::s32 userData) 
    {
     // Here we set the necessary shader constants.
     // Both shaders require the same information, so they share this function.
     vector3df TheTangent;
     vector3df TheBinormal;
     //                                                                                                                                                    
     // MATRICES..
 
    // NEW TESTS TO SEE IF WE CAN GET SKINNED ANIMATED TANGENTS WORKING..
 
    // irr::core::matrix4 matNormal;
    irr::core::matrix4 matWorld;
 
    // matWorld.getInverse(matNormal);
    // matNormal = matNormal.getTransposed();
 
     // FORGET "HALF ANGLES" and all that jazz...
     // This kicks ass!!
 
     TheWorldMatrix = PrivateDriver->getTransform(ETS_WORLD); // THE ONLY ONE!!!!!!
     vector3df TheCameraPosition = PrivateSceneManager->getActiveCamera()->getPosition();
     LightPosition001 = TheCameraPosition;
     PrivateServices->setVertexShaderConstant("mWorld", TheWorldMatrix.pointer(), 16);
     // PrivateServices->setVertexShaderConstant("CamPos", &TheCameraPosition.X, 4);
 
     // This is the shader code so we can see how TANGENT, BINORMAL and UV COORDS are passed from OPENGL to the shader..
     //   UVCoordsXY = gl_MultiTexCoord0.xy;         
     //   Tangent    = normalize(gl_MultiTexCoord1); 
     //   Binormal   = normalize(gl_MultiTexCoord2); 
     // Do NOT uncomment the above..                 
 
     int TexAddress = 0;  int TexAddress2 = 1;  int TexAddress3 = 2;  int TexAddress4 = 3;
     PrivateServices->setPixelShaderConstant("DiffuseMap",  (int*)(&TexAddress), 1);  // Note that this name dont necessarely need to match the name in the shader.. Order does though..
     PrivateServices->setPixelShaderConstant("NormalMap",   (int*)(&TexAddress2), 1);  // AHA!!  Must NOT be float as was in example!!
     PrivateServices->setPixelShaderConstant("SpecularMap", (int*)(&TexAddress3), 1);  // AHA!!  Must NOT be float as was in example!!
     PrivateServices->setPixelShaderConstant("GlossMap",    (int*)(&TexAddress4), 1);  // AHA!!  Must NOT be float as was in example!!
 
     PrivateServices->setPixelShaderConstant("FShaderCommand",  (int*)(&FragShadeCommand), 1);   // AFTER GLOSSMAP..
     // Note that this name dont necessarely need to match the name in the shader.. Order however is important
 
 
     
     // This is what we would have if we opted for RGBA INDIVIDUAL CHANEL UTILISATION..
     // This single map would then cater for SPECULAR and GLOSS, and still have TWO MORE FREE CHANNELS available for other things like a "Tangent MAP"..
     // Another FOUR CHANNELS would then also be available!
     // WE WILL THEN HAVE SPACE FOR AN "EMISSION MAP"!!
 
     // PrivateServices->setPixelShaderConstant("ExtendedEffectsMap",    (int*)(&TexAddress4), 1);  // AHA!!  Must NOT be float as was in example!!
 
 
     PrivateServices->setPixelShaderConstant("CamPosTEST", &TheCameraPosition.X, 4);
 
     // MAX 4 IMAGES IF WE DONT WANT TO CHANGE IRRLICHT CODE..  THIS MAY A GRAPHICS CARD THING AND NOT SPECIFICALLY AN IRRLICHT THING!!
     // SO WE START USING ALPHA CHANNELS OF IMAGES..
     // SO FAR WE USE ALPHA FOR DIFFUSE (CLIPMAP) and ALPHA FOR NORMAL MAP (DROPLET SHADING)..
     // WE COULD SAVE SPACE AND USE ALPHA FOR SPECULAR MAP AS THE GLOSS MAP...
     // THIS WOULD FREE A FOURTH IMAGE THAT WE CAN USE RGB AND ALPHA CHANNELS FOR MORE MAP BASED EFFECTS...
     // ANOTHER POSSIBILITY IS THAT WE USE THE SEPARATE RGBA CHANNELS IN AN IMAGE FOR THINGS
     // THAT USE SINGLE VALUES LIKE SPECULAR (mono) and GLOSS (single value always)..
     // TO DO THIS WE MUST THEN MAKE PEACE WITH THE FACT THAT WE USE SPECULAR (not gloss)
     // AS A MONOCHROME VALLUE WHICH IS ACTUALLY PHYSICALLY CORRECT..(SPECULAR IS IN MATHEMATICAL TERMS ATUALLY REFLECTION)
     // HAVING COLOUR IN THE SPECULAR MAP MAY NOT NECESSARILY BE PHYSICALLY CORRECT, BUT COULD ENHANCE THE FINAL EFFECT (could it?)..
     // THE MORE I THINK ABOUT IT, THE MORE I TEND TOWARD A MONO SPECULAR VALUE BECAUSE A RED, FOR INSTANCE, SPEC COLOUR
     // WOULD BE MEANINGLESS ON A BLUE DIFFUSE SURFACE..
     // FINALLY, IF WE GO SEPARATE RGBA SINGLE ATTRIBUTES THEN OUR ARTISTS MUST UNDERSTAND THE CHANNEL MIXER IN PHOTOSHOP AND ITS
     // COUNTERPART IN OTHER BITMAP EDITORS SUCH AS GIMP..
     // WITH CLEVER MATH WE COULD ALSO CALCULATE THE Z OF THE NORMALS GIVEN X AND Y THUS FREEING UP THE "BLUE" CHANNEL FOR EVEN MORE..
 
 
     // THE FUTURE..
     // Reflop Map (what reflects and what does not) would become possible
     // once we have "Cubemap Reflection" working like in CG!! (a single value that would work under RGBA mixes)
     // PrivateServices->setPixelShaderConstant("PseudoSSSMap", (int*)(&TexAddress4), 1);  // Something Im working on that if works would be cool..
     PrivateServices->setPixelShaderConstant("mWorld", TheWorldMatrix.pointer(), 16); // HOW ABOUT IT.. THE ONLY MATRIX NEEDED!!
 
     // NEW TEST..
 
     // PrivateServices->setPixelShaderConstant("mWorldNormal", matNormal.pointer(), 16); // HOW ABOUT IT.. THE ONLY MATRIX NEEDED!!
 
     // mWorldNormal
 
 
    }               
  };
 // = = = = = = = = = = = = = = = = = = = = = = 
 int main()
  {// constructors/destructors used for running etc..
   VECTROTEKAPP App;
   return 0;
  }
 // This code was written by Jacques Pretorius "VECTROTEK" in 2015 inspired by all the guys on the IRRLICHT FORUM..
 // = = = = = = = = = = = = = = = = = = = = = = 
 
 
 
 
 
 
 
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Bump mapping for Animated meshes

Post by Vectrotek »

How and where to do I upload 3 Megs worth of data in a ZIP file to be downloaded from here?
Last edited by Vectrotek on Thu May 14, 2015 11:22 pm, edited 1 time in total.
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Bump mapping for Animated meshes

Post by Vectrotek »

try this.. http://s000.tinyupload.com/?file_id=431 ... 7932053941
It is the FULL SOURCE CODE AND EXECUTABLE.. (dont worry if the IDE cant find the shaders, they are there..)
CuteAlien
Admin
Posts: 9646
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Bump mapping for Animated meshes

Post by CuteAlien »

Thanks for the code and examples. I think the easiest way to upload sources is to use bitbucket or github (as long as it's not too much you can also put media in there).
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Bump mapping for Animated meshes

Post by Vectrotek »

Thanks!

Did the program in the ZIP from "Tiny Upload" run?
Do you think updating Tangents and Bi-normals like Normals is feasible at all?
i think this could be a solution because in Nvidia's Composer they are updated along with the normals.
I'm trying to do these updates myself in the example code by accessing some Irrlicht functions. I don't know enough to alter Irrlicht code yet..
When I get a chance ill post a better example of the deviation that occurs because of no Tangent and Bi-normal updates..
(maps are in down-scaled and posterised "*.PNG" to save bandwidth)
I have a few nice models in "*.x" and "*.b3d" that I use to experiment with.. Mostly converted from Doom 3 Prey and Quake 4..
I've learned a lot from your posts.. Thanks!

Let me know what you think of the program if you ran it!
thanhle
Posts: 325
Joined: Wed Jun 12, 2013 8:09 am

Re: Bump mapping for Animated meshes

Post by thanhle »

Hi mate,
I've ran your demo.
This is fantastic, I like the vein sticking out of that Alien skin.

Regards
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Bump mapping for Animated meshes

Post by Vectrotek »

Thanks! I wish I could model like that, it is a "Skyrim" model..
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Bump mapping for Animated meshes

Post by Vectrotek »

HI! This is an example to clarify my Tangent/Binormal Problem..

It is 6.5 Megs!! I really tried to get the data as small as possible.

If you run "000_TANGENT_BALL.exe" you will see that Skinned
Animation causes "final" GLSL normals to change in unexpected ways..

Try using keys "3", "6" and "7" to change the rendermode..
You can also Slow, Hasten or Pause the animation with the "I","O","P" Keys..
"[" Brings us to the First Frame i.e. T, or NULL POSE..

Here it is: (slight code change)
Deleted.. Check later posts, all there.


I now know that Updating Tangents and Binormals is the key, but how?
Please share your code if you crack it!
Im looking at how IRRLICHT updates the normals and trying
to get the same for Tangents / Binormals..
I am sure it wouldn't be too much of a "CPU TIME PENALTY" if
we have some kind of an OPTION to do this or not..
We could even have updating done only at every "Nth" frame (again, option would be nice)..

The Normal deviation only becomes really aparent at angles greater than approx 75.0 degrees..

Keep in mind that Static objects can be Translated,
Scaled, even Rotated and the shader will light
it correclty. (Thanks to You, the Forum Members ofcourse!)

Sorry about the large ZIP file, I did everything possible to keep it small..

If You'd like a HIRES Package let me know..

The models come from the Internet and are free for educational purposes
but not for Commercial material..
Last edited by Vectrotek on Sun Sep 27, 2015 9:28 pm, edited 1 time in total.
Post Reply