Question about normal mapping

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
socceroos
Posts: 4
Joined: Tue Oct 25, 2011 8:54 am

Question about normal mapping

Post by socceroos »

I wrote a shader about relief mapping. When I use Render Monkey to load it, the effect is very well, but when I switch to Irrlicht,there are no bumps.
I'v heard that Irrlicht didn't import binormals and tangents from models,is it true or not?
In my shader,I calculate tangent space like this:

Code: Select all

 
struct VS_INPUT
{
       float4 Pos:POSITION;
       float2 Tex:TEXCOORD;
       float3 Normal:NORMAL0;
       float3 Binormal:BINORMAL0;
       float3 Tangent:TANGENT0;
};
 
VS_OUTPUT vs_main(VS_INPUT In)
{
        ...
        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);
        ...
}
So, thank you very much for your help.
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Re: I got a shader problem

Post by hybrid »

You can use or convert to a model with tangent space calculated on the CPU. But when calculating it in the shaders, there's no need to support the data on the CPU as well. In your case you seem to expect the data being pre-calculated, though. So maybe check example 11 (and maybe 10 as well) for how shader data is to be used.
Mel
Competition winner
Posts: 2292
Joined: Wed May 07, 2008 11:40 am
Location: Granada, Spain

Re: I got a shader problem

Post by Mel »

To use relief mapping, you have to do 2 things.

First, you have to use a model with the tangent space calculated, Irrlicht can do this for you. using the mesh manipulator.

Second, the Binormal and Tangent data aren't on TANGENT0 nor BINORMAL0 but in TEXCOORD1 and TEXCOORD2 respectively. You have to change that in the shader too
"There is nothing truly useless, it always serves as a bad example". Arthur A. Schmitt
socceroos
Posts: 4
Joined: Tue Oct 25, 2011 8:54 am

Re: I got a shader problem

Post by socceroos »

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;
}
 
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Re: I got a shader problem

Post by hybrid »

Please read example 11 once more. You have one diffuse map and one normal map for normal mapping. In case the color values of your texture are not yet prepared, you need to convert the texture as well. All shown in example 11.
Lonesome Ducky
Competition winner
Posts: 1123
Joined: Sun Jun 10, 2007 11:14 pm

Re: Question about normal mapping

Post by Lonesome Ducky »

On a related note, will we ever get support for tangents on an animated mesh? They could be updated just like the normals after animation, right?
trivtn
Posts: 132
Joined: Tue Jan 17, 2006 12:30 pm
Location: Viet Nam
Contact:

Re: Question about normal mapping

Post by trivtn »

Thanks Mel ! Work perfect now !
Here my HLSL code to Show Tangent In Object Space !

Code: Select all

float4x4 view_proj_matrix;
struct VS_INPUT 
{
   float4 Position: POSITION0;
   float3 Normal:   NORMAL0;
   float4 Color :   COLOR0;
   float2 TexCoord: TEXCOORD0;
   float3 Tangent:  TEXCOORD1;
   float3 Binormal: TEXCOORD2;
};
struct VS_OUTPUT 
{
   float4 Pos:     POSITION;
   float3 Tangent:  TEXCOORD0;
};
VS_OUTPUT vs_main(VS_INPUT Input)
{
   VS_OUTPUT Out;
 
   Out.Pos     = mul(Input.Position,view_proj_matrix);
   Out.Tangent = Input.Tangent;
   return Out;
}
//
float4 ps_main( float4 inDiffuse: COLOR0, float3 Tangent: TEXCOORD0 ) : COLOR0
{
   return float4( normalize( Tangent ) * 0.5 + 0.5, 1.0 );
}
 
There's something is fantastic, there's nothing is absolute.
mongoose7
Posts: 1227
Joined: Wed Apr 06, 2011 12:13 pm

Re: Question about normal mapping

Post by mongoose7 »

Lonesome Ducky wrote:On a related note, will we ever get support for tangents on an animated mesh? They could be updated just like the normals after animation, right?
Are normals updated? This would require another set of matrices. (The transpose of the inverse of the rotation matrix, I think.) Tangents would be easier, not requiring different transformations. Not much point without the normals, though, I guess.
Post Reply