I wonder if the model I used contains the tangents and binormals info, it need not to call IMeshManipulator::createMeshWithTangents()?
I've searched the CD3D9Driver.cpp,and found the following words:
D3DFVF_TEXCOORDSIZE2(0) | // real texture coord
D3DFVF_TEXCOORDSIZE3(1) | // misuse texture coord 2 for tangent
D3DFVF_TEXCOORDSIZE3(2) // misuse texture coord 3 for binormal
so I switched the TANGENT0 and BINORMAL0 to TEXCOORD2 and TEXCOORD3,but it doesn't work.Also no bumps.
Following is all my codes:
//main.cpp
Code: Select all
#include <irrlicht.h>
using namespace irr;
#pragma comment(lib,"Irrlicht.lib")
IrrlichtDevice* device=0;
class MyShaderCallBack : public video::IShaderConstantSetCallBack
{
public:
virtual void OnSetConstants(video::IMaterialRendererServices* services, s32 userData)
{
video::IVideoDriver *driver=services->getVideoDriver();
core::matrix4 worldViewProj=driver->getTransform(video::ETS_PROJECTION)*driver->getTransform(video::ETS_VIEW)*driver->getTransform(video::ETS_WORLD);
core::matrix4 worldView=driver->getTransform(video::ETS_VIEW)*driver->getTransform(video::ETS_WORLD);
core::matrix4 view=driver->getTransform(video::ETS_VIEW);
services->setVertexShaderConstant("worldviewproj_matrix",worldViewProj.pointer(),16);
services->setVertexShaderConstant("view_matrix",view.pointer(),16);
services->setVertexShaderConstant("worldview_matrix",worldView.pointer(),16);
core::vector3df ambient(0.2,0.2,0.2);
services->setPixelShaderConstant("ambient",reinterpret_cast<f32*>(&ambient),3);
core::vector3df diffuse(1,1,1);
services->setPixelShaderConstant("diffuse",reinterpret_cast<f32*>(&diffuse),3);
core::vector3df specular(0.75,0.75,0.75);
services->setPixelShaderConstant("specular",reinterpret_cast<f32*>(&specular),3);
f32 tileX=14.0;
services->setVertexShaderConstant("tileX",&tileX,1);
f32 tileY=10.0;
services->setVertexShaderConstant("tileY",&tileY,1);
float tile=8.0;
services->setVertexShaderConstant("tile",&tile,1);
f32 shine=128.0;
services->setPixelShaderConstant("shine",&shine,1);
f32 depth=0.1;
services->setPixelShaderConstant("depth",&depth,1);
core::vector3df light(100.0,300.0,50.0);
services->setVertexShaderConstant("lightpos",reinterpret_cast<f32*>(&light),3);
}
};
int main()
{
device=createDevice(video::EDT_DIRECT3D9,core::dimension2d<s32>(640,480),16,false,false,false);
scene::ISceneManager* smgr=device->getSceneManager();
video::IVideoDriver* driver=device->getVideoDriver();
c8* vsFileName="sample.hlsl";
c8* psFileName="sample.hlsl";
video::IGPUProgrammingServices* gpu=driver->getGPUProgrammingServices();
s32 matType=0;
if(gpu)
{
MyShaderCallBack* mc=new MyShaderCallBack();
matType=gpu->addHighLevelShaderMaterialFromFiles(vsFileName,"vs_main",video::EVST_VS_2_0,psFileName,"ps_main",video::EPST_PS_2_a,mc);
mc->drop();
}
scene::IAnimatedMesh* mesh=smgr->getMesh("sample.3ds");
scene::IMesh* tangentMesh=smgr->getMeshManipulator()->createMeshWithTangents(mesh->getMesh(0));
scene::ISceneNode* node=smgr->addMeshSceneNode(tangentMesh);
video::ITexture* colormap=driver->getTexture("laco.jpg");
video::ITexture* depthmap=driver->getTexture("laco.tga");
video::ITexture* normalXmap=driver->getTexture("laco_n1.tga");
video::ITexture* normalYmap=driver->getTexture("laco_n2.tga");
node->setMaterialTexture(0,colormap);
node->setMaterialTexture(1,depthmap);
node->setMaterialTexture(2,normalXmap);
node->setMaterialTexture(3,normalYmap);
node->setMaterialFlag(video::EMF_LIGHTING,false);
node->setMaterialType((video::E_MATERIAL_TYPE)matType);
scene::ICameraSceneNode* cam=smgr->addCameraSceneNodeFPS(0,15,15);
cam->setName("camera");
while(device->run())
{
if (device->isWindowActive())
{
driver->beginScene(true,true,video::SColor(255,100,0,0));
smgr->drawAll();
driver->endScene();
}
}
device->drop();
return 0;
}
//vs_main in shader
Code: Select all
struct VS_INPUT
{
float4 Pos:POSITION;
float2 Tex:TEXCOORD0;
float3 Normal:NORMAL;
float3 Binormal:TEXCOORD3;
float3 Tangent:TEXCOORD2;
};
struct VS_OUTPUT
{
float4 Pos:POSITION;
float2 Tex:TEXCOORD0;
float3 viewVecTS:TEXCOORD1;
float3 lightVecTS:TEXCOORD2;
};
VS_OUTPUT vs_main(VS_INPUT In)
{
VS_OUTPUT Out;
float4 pos=float4(In.Pos.x,In.Pos.y,In.Pos.z,1.0);
Out.Pos=mul(pos,worldviewproj_matrix);
Out.Tex.x=In.Tex.x*tileX;
Out.Tex.y=In.Tex.y*tileY;
float3x3 worldviewrot;
worldviewrot[0]=worldview_matrix[0].xyz;
worldviewrot[1]=worldview_matrix[1].xyz;
worldviewrot[2]=worldview_matrix[2].xyz;
float3 tangent=mul(In.Tangent,worldviewrot);
float3 binormal=mul(In.Binormal,worldviewrot);
float3 normal=mul(In.Normal,worldviewrot);
float3x3 tangentspace=float3x3(tangent,binormal,normal);
float3 vpos=mul(pos,worldview_matrix).xyz;
float3 eye=mul(vpos,tangentspace);
eye.z=-eye.z;
Out.viewVecTS=eye;
float4 light=float4(lightpos.x,lightpos.y,lightpos.z,1);
light=mul(light,view_matrix);
light.xyz=mul(light.xyz-vpos,tangentspace);
Out.lightVecTS=light.xyz;
return Out;
}