Page 1 of 1

normalmap for animate models

Posted: Sun May 04, 2008 10:16 am
by _TamerLAN_
Hi, I am from Ukraina. I like irrlicht and i have some questions:
recently, I read some about normalmap for animate models, and this code

#include <irrlicht.h>

// --------------------------------------------------------------------------

using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;



IrrlichtDevice *device;


const stringc vertBumpShader =
"uniform vec3 fvLightPosition1;"
"uniform vec3 fvLightPosition2;"
"uniform vec3 fvLightPosition3;"
"uniform vec3 fvLightPosition4;"
""
"uniform float fLightStrength1;"
"uniform float fLightStrength2;"
"uniform float fLightStrength3;"
"uniform float fLightStrength4;"
""
"uniform mat4 matWorldInverse;"
""
"varying vec2 Texcoord;"
"varying vec3 ViewDirection;"
"varying vec3 LightDirection1;"
"varying vec3 LightDirection2;"
"varying vec3 LightDirection3;"
"varying vec3 LightDirection4;"
"varying vec4 LightDistMultiplier;"
""
"float getLengthSQR (vec3 vec)"
"{"
"return(vec.x*vec.x+vec.y*vec.y+vec.z*vec.z);"
"}"
""
"void main( void )"
"{"
""
" mat4 LightTransform= gl_ModelViewMatrix;"
" LightTransform=LightTransform*matWorldInverse;"
""
" gl_Position = ftransform();"
" Texcoord = gl_MultiTexCoord0.xy;"
""
" vec4 fvObjectPosition = gl_ModelViewMatrix * gl_Vertex;"
" vec4 fvLightPos1 = LightTransform * vec4(fvLightPosition1,1.0);"
" vec4 fvLightPos2 = LightTransform * vec4(fvLightPosition2,1.0);"
" vec4 fvLightPos3 = LightTransform * vec4(fvLightPosition3,1.0);"
" vec4 fvLightPos4 = LightTransform * vec4(fvLightPosition4,1.0);"
""
" vec3 fvViewDirection = - fvObjectPosition.xyz;"
""
" vec3 fvLightDirection1 = (fvLightPos1.xyz - fvObjectPosition.xyz);"
" vec3 fvLightDirection2 = (fvLightPos2.xyz - fvObjectPosition.xyz);"
" vec3 fvLightDirection3 = (fvLightPos3.xyz - fvObjectPosition.xyz);"
" vec3 fvLightDirection4 = (fvLightPos4.xyz - fvObjectPosition.xyz);"
""
" LightDistMultiplier[0]=1.0/(getLengthSQR (fvLightDirection1)/(fLightStrength1*10000.0));"
" LightDistMultiplier[1]=1.0/(getLengthSQR (fvLightDirection2)/(fLightStrength2*10000.0));"
" LightDistMultiplier[2]=1.0/(getLengthSQR (fvLightDirection3)/(fLightStrength3*10000.0));"
" LightDistMultiplier[3]=1.0/(getLengthSQR (fvLightDirection4)/(fLightStrength4*10000.0));"
""
" vec3 fvNormal = gl_NormalMatrix * gl_Normal;"
""
" vec3 fvTangent = -vec3(abs(gl_Normal.y) + abs(gl_Normal.z), abs(gl_Normal.x), 0);"
" vec3 fvBinormal =cross(fvTangent,gl_Normal); "
" fvTangent=gl_NormalMatrix*cross(fvBinormal,gl_Normal);"
" fvBinormal=gl_NormalMatrix*fvBinormal;"
""
""
" ViewDirection.x = dot( fvTangent, fvViewDirection );"
" ViewDirection.y = dot( fvBinormal, fvViewDirection );"
" ViewDirection.z = dot( fvNormal, fvViewDirection );"
""
" LightDirection1.x = dot( fvTangent, fvLightDirection1.xyz );"
" LightDirection1.y = dot( fvBinormal, fvLightDirection1.xyz );"
" LightDirection1.z = dot( fvNormal, fvLightDirection1.xyz );"
""
" LightDirection2.x = dot( fvTangent, fvLightDirection2.xyz );"
" LightDirection2.y = dot( fvBinormal, fvLightDirection2.xyz );"
" LightDirection2.z = dot( fvNormal, fvLightDirection2.xyz );"
""
" LightDirection3.x = dot( fvTangent, fvLightDirection3.xyz );"
" LightDirection3.y = dot( fvBinormal, fvLightDirection3.xyz );"
" LightDirection3.z = dot( fvNormal, fvLightDirection3.xyz );"
""
" LightDirection4.x = dot( fvTangent, fvLightDirection4.xyz );"
" LightDirection4.y = dot( fvBinormal, fvLightDirection4.xyz );"
" LightDirection4.z = dot( fvNormal, fvLightDirection4.xyz );"
""
"}";
// --------------------------------------------------------------------------

// OpenGL Fragment Program 1.1
const stringc fragBumpShader =
"uniform vec4 fvAmbient;"
"uniform vec4 fvLight1Color;"
"uniform vec4 fvLight2Color;"
"uniform vec4 fvLight3Color;"
"uniform vec4 fvLight4Color;"

"uniform float fSpecularPower;"
"uniform float fSpecularStrength;"
"uniform float fBumpStrength;"

"uniform sampler2D baseMap;"
"uniform sampler2D bumpMap;"

"varying vec2 Texcoord;"
"varying vec3 ViewDirection;"
"varying vec3 LightDirection1;"
"varying vec3 LightDirection2;"
"varying vec3 LightDirection3;"
"varying vec3 LightDirection4;"
"varying vec4 LightDistMultiplier;"

"void main( void )"
"{"

" vec3 fvLightDirection1 = normalize( LightDirection1 );"
" vec3 fvLightDirection2 = normalize( LightDirection2 );"
" vec3 fvLightDirection3 = normalize( LightDirection3 );"
" vec3 fvLightDirection4 = normalize( LightDirection4 );"

" vec3 fvNormal = texture2D( bumpMap, Texcoord ).yxz;"
" fvNormal.xy*=2.0;"
" fvNormal.xy-=1.0;"

" fvNormal=(vec3(0.0,0.0,1.0)-fvNormal)*fBumpStrength+fvNormal;"

" fvNormal=normalize(fvNormal);"

" float fNDotL1 = max(dot(fvNormal, fvLightDirection1),0.0)-0.1; "
" float fNDotL2 = max(dot(fvNormal, fvLightDirection2),0.0)-0.1; "
" float fNDotL3 = max(dot(fvNormal, fvLightDirection3),0.0)-0.1; "
" float fNDotL4 = max(dot(fvNormal, fvLightDirection4),0.0)-0.1; "

" vec3 fvReflection1 = normalize( ( ( 2.0 * fvNormal ) ) - fvLightDirection1 ); "
" vec3 fvReflection2 = normalize( ( ( 2.0 * fvNormal ) ) - fvLightDirection2 ); "
" vec3 fvReflection3 = normalize( ( ( 2.0 * fvNormal ) ) - fvLightDirection3 ); "
" vec3 fvReflection4 = normalize( ( ( 2.0 * fvNormal ) ) - fvLightDirection4 ); "

" vec3 fvViewDirection = normalize( ViewDirection );"

" float fRDotV1 = max( 0.0, dot( fvReflection1, fvViewDirection ) );"
" float fRDotV2 = max( 0.0, dot( fvReflection2, fvViewDirection ) );"
" float fRDotV3 = max( 0.0, dot( fvReflection3, fvViewDirection ) );"
" float fRDotV4 = max( 0.0, dot( fvReflection4, fvViewDirection ) );"

" vec4 fvBaseColor = texture2D( baseMap, Texcoord );"

" vec4 fvTotalAmbient = fvAmbient * fvBaseColor; "

" vec4 fvTotalDiffuse = fvLight1Color * fNDotL1* fvBaseColor*LightDistMultiplier[0]; "
" vec4 fvTotalSpecular = fNDotL1*fvLight1Color * ( pow( fRDotV1, fSpecularPower ) )*LightDistMultiplier[0];"

" fvTotalDiffuse += fvLight2Color * fNDotL2* fvBaseColor*LightDistMultiplier[1]; "
" fvTotalSpecular += fNDotL2*fvLight2Color * ( pow( fRDotV2, fSpecularPower ) )*LightDistMultiplier[1]; "

" fvTotalDiffuse += fvLight3Color * fNDotL3* fvBaseColor*LightDistMultiplier[2]; "
" fvTotalSpecular += fNDotL3*fvLight3Color * ( pow( fRDotV3, fSpecularPower ) )*LightDistMultiplier[2]; "

" fvTotalDiffuse += fvLight4Color * fNDotL4* fvBaseColor*LightDistMultiplier[3]; "
" fvTotalSpecular += fNDotL4*fvLight4Color * ( pow( fRDotV4, fSpecularPower ) )*LightDistMultiplier[3]; "

" vec4 color=( fvTotalAmbient + fvTotalDiffuse+ (fvTotalSpecular*fSpecularStrength));"
" if(color.r>1.0){color.gb+=color.r-1.0;}"
" if(color.g>1.0){color.rb+=color.g-1.0;}"
" if(color.b>1.0){color.rg+=color.b-1.0;}"
" gl_FragColor = color;"

"}"
;

class Shader_Bump_callback: public video::IShaderConstantSetCallBack
{
public:
float fLightStrength[4]; //you know I=1/r??? i changed it to I=1/(r?/fLightStrength) for better results
vector3df fvLightPosition[4]; //the light positions
SColorf fvLightColor[4];
SColorf fvAmbient;
float fSpecularPower; // S=pow(fDiffuseIntensity,fSpecularPower)*fSpecularStrength;
float fSpecularStrength;// will result in less glossing surfaces
float fBumpStrength; //strength of the bumpmapping.. higher values will result in more "bumpy" surfaces

virtual void OnSetConstants(video::IMaterialRendererServices* services, s32 userData)
{

int var0=0;
services->setPixelShaderConstant("baseMap", (float*)(&var0), 1); //the colormap
int var1=1;
services->setPixelShaderConstant("bumpMap", (float*)(&var1), 1); //the normalmap

core::matrix4 invWorld = services->getVideoDriver()->getTransform(video::ETS_WORLD);
invWorld.makeInverse();
services->setPixelShaderConstant("matWorldInverse", (float*)(&invWorld), 16);

services->setPixelShaderConstant("fLightStrength1", (float*)(&fLightStrength[0]), 1);
services->setPixelShaderConstant("fLightStrength2", (float*)(&fLightStrength[1]), 1);
services->setPixelShaderConstant("fLightStrength3", (float*)(&fLightStrength[2]), 1);
services->setPixelShaderConstant("fLightStrength4", (float*)(&fLightStrength[3]), 1);

services->setPixelShaderConstant("fvLightPosition1", (float*)(&fvLightPosition[0]), 3);
services->setPixelShaderConstant("fvLightPosition2", (float*)(&fvLightPosition[1]), 3);
services->setPixelShaderConstant("fvLightPosition3", (float*)(&fvLightPosition[2]), 3);
services->setPixelShaderConstant("fvLightPosition4", (float*)(&fvLightPosition[3]), 3);

services->setPixelShaderConstant("fvAmbient", (float*)(&fvAmbient), 4);
services->setPixelShaderConstant("fvLight1Color", (float*)(&fvLightColor[0]), 4);
services->setPixelShaderConstant("fvLight2Color", (float*)(&fvLightColor[1]), 4);
services->setPixelShaderConstant("fvLight3Color", (float*)(&fvLightColor[2]), 4);
services->setPixelShaderConstant("fvLight4Color", (float*)(&fvLightColor[3]), 4);

services->setPixelShaderConstant("fSpecularPower", (float*)(&fSpecularPower), 1);
services->setPixelShaderConstant("fSpecularStrength", (float*)(&fSpecularStrength), 1);
services->setPixelShaderConstant("fBumpStrength", (float*)(&fBumpStrength), 1);


}
};




// --------------------------------------------------------------------------

#pragma comment(lib, "Irrlicht.lib")


int main()
{
// Create device
video::E_DRIVER_TYPE driverType = video::EDT_OPENGL;

device = createDevice(driverType, dimension2di(800, 600), 32, false, false, false, 0);
if (!device) {
printf("Error creating Irrlicht device\n");
return 0;
}

// Obtain device internals
IVideoDriver* driver = device->getVideoDriver();
ISceneManager* smgr = device->getSceneManager();
// Set a window caption
device->setWindowCaption(L"NormalMapShader - Irrlicht Engine Demo");

// Create GLSL shaders
video::IGPUProgrammingServices* gpu = driver->getGPUProgrammingServices();
s32 mtlToonShader = video::EMT_SOLID; // Fallback material type
bool bCanDoGLSL_1_1 = false;
if (gpu && (driverType == video::EDT_OPENGL)) {
bCanDoGLSL_1_1 = true; // provisionally accept
if (!driver->queryFeature(video::EVDF_ARB_FRAGMENT_PROGRAM_1)) {
printf("queryFeature(video::EVDF_ARB_FRAGMENT_PROGRAM_1) failed\n");
bCanDoGLSL_1_1 = false;
}
if (!driver->queryFeature(video::EVDF_ARB_VERTEX_PROGRAM_1)) {
printf("queryFeature(video::EVDF_ARB_VERTEX_PROGRAM_1) failed\n");
bCanDoGLSL_1_1 = false;
}
}

if (bCanDoGLSL_1_1) {
Shader_Bump_callback *callback= new Shader_Bump_callback;

callback->fBumpStrength=4;
callback->fSpecularStrength=0.9;
callback->fSpecularPower=20;

callback->fvAmbient=SColorf(0.02,0.02,0.02);

callback->fLightStrength[0]=1;
callback->fvLightColor[0]=SColorf(1.00,0.52,0.31);
callback->fvLightPosition[0]=vector3df(100,-10,0);

callback->fLightStrength[1]=1;
callback->fvLightColor[1]=SColorf(0.31,0.55,1.0);
callback->fvLightPosition[1]=vector3df(-100,10,0);


mtlToonShader = gpu->addHighLevelShaderMaterial(
vertBumpShader.c_str(), "main", video::EVST_VS_1_1,
fragBumpShader.c_str(), "main", video::EPST_PS_1_1,
callback, video::EMT_SOLID);
} else {
// This demo is for OpenGL!
printf("This demo requires OpenGL with GLSL High-Level shaders\n");
mtlToonShader = video::EMT_SOLID;
}

// Add an animated mesh
IAnimatedMesh* mesh = smgr->getMesh("dwarf.x");


ISceneNode* node = smgr->addAnimatedMeshSceneNode(mesh);
if (node)
{
node->setMaterialFlag(EMF_LIGHTING, false);
node->setMaterialTexture( 0, driver->getTexture("Fieldstone.tga") );
node->setMaterialTexture( 1, driver->getTexture("Fieldstonebumpdot3.tga") );
node->setMaterialType((video::E_MATERIAL_TYPE)mtlToonShader); // Override material type
}

// Add a viewing camera
smgr->addCameraSceneNodeFPS();

// Main rendering loop
while(device->run())
{
vector3df rot=node->getRotation();
rot.Y+=0.1;
node->setRotation(rot);
driver->beginScene(true, true, SColor(0,0,0,0));
smgr->drawAll();
driver->endScene();
}

device->drop();

// Done
return 0;
}


this code is very good work, but I want do this in video::E_DRIVER_TYPE driverType = video::EDT_DIRECT3D9 ;, because my project use DirectX9...
If anybody knows how do this in DirectX9 mode, write me please...

Posted: Tue May 06, 2008 1:53 pm
by TheGameMaker
you have to convert the GLSL shader to a HLSL shader..
GLSL ist the shaderlanguage of openGL.. hence you only can use it with opengl... :wink: so what you have to do is learning HLSL shader language and convert it..

Posted: Wed May 07, 2008 1:42 am
by BlindSide
It's possible to use ordinary Irrlicht normal mapping on animated meshes ever since SkinnedMesh was introduced in version 1.4. You just have to convert the mesh to tangents using "irr::scene::ISkinnedMesh::convertMeshToTangents()". (First you must load an animated mesh and cast it to a skinned mesh eg.:

Code: Select all

IAnimatedMesh* mesh = smgr->getMesh("mymesh.x");
((ISkinnedMesh*)mesh)->convertMeshToTangents();
Cheers