Please give the evaluation to me.
DirectX 9 and HLSL only.
Linked Irrlicht1.4.2 and win32.
The model must make outline.
Development Environment.
Windows XP SP2
DirectX 9.0c
NVIDIA GeForce 8600 GT
Global variable.
Code: Select all
//*******************************************
// Global variable.
//*******************************************
IrrlichtDevice* g_device = 0;
Code: Select all
//*******************************************
// Shader call back class.
//*******************************************
class MyShaderCallBack : public IShaderConstantSetCallBack
{
private:
IVideoDriver* m_driver;
matrix4 mtxW;
matrix4 mtxWVP;
// Color of light.
SColorf m_colLitDef;
SColorf m_colLitAmb;
// Vector of light.
vector3df m_vectLitVec;
// U position of shader texture.
f32 m_fShadowU;
public:
MyShaderCallBack()
{
m_colLitDef = SColor(255,255,255,255);
m_colLitAmb = SColor(0,0,0,0);
m_vectLitVec = vector3df( 100.0f, 0.0f, 0.0f );
m_fShadowU = 0.25;
};
// Set U position of shader texture.
void SetMaterialU( s32 f_nMax, s32 f_nNow )
{
f32 oneU = ( 1.0f / (f32)f_nMax );
f32 centerU = oneU / 2.0f;
m_fShadowU = centerU + oneU * (f32)f_nNow;
}
virtual void OnSetConstants(IMaterialRendererServices* services, s32 userData)
{
m_driver = services->getVideoDriver();
// World,View,Projection matrix to HLSL.
mtxWVP = m_driver->getTransform(ETS_PROJECTION);
mtxWVP *= m_driver->getTransform(ETS_VIEW);
mtxWVP *= mtxW = m_driver->getTransform(ETS_WORLD);
services->setVertexShaderConstant("MatrixWVP", mtxWVP.pointer(), 16);
services->setVertexShaderConstant("MatrixW", mtxW.pointer(), 16);
// Color of light to HLSL.
services->setVertexShaderConstant("LightDiffuseColor", (f32*)(&m_colLitDef), 4);
services->setVertexShaderConstant("LightAmbientColor", (f32*)(&m_colLitAmb), 4);
// Vector of light to HLSL.
services->setVertexShaderConstant("LightDirection", (f32*)(&m_vectLitVec), 3);
// U position of shader texture to HLSL.
services->setVertexShaderConstant("ShadowU", (f32*)(&m_fShadowU), 1);
// f32 var0=0;
// services->setPixelShaderConstant("MeshTexture", &var0, 1);
// f32 var1=1;
// services->setPixelShaderConstant("ShadeTexture", &var1, 1);
}
};
Code: Select all
int APIENTRY _tWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow )
{
// Create Irrlicht device.
SIrrlichtCreationParameters param;
param.DriverType = EDT_DIRECT3D9;
param.WindowSize.Width = 1024;
param.WindowSize.Height = 768;
param.AntiAlias = false;
param.Vsync = false;
param.Fullscreen = false;
param.Bits = 32;
g_device = createDeviceEx(param);
if (g_device == 0)
return 1;
g_device->setWindowCaption(L"Toon Shading by Tenko - Irrlicht Engine Demo");
IVideoDriver* driver = g_device->getVideoDriver();
ISceneManager* smgr = g_device->getSceneManager();
IGUIEnvironment* env = g_device->getGUIEnvironment();
driver->setTextureCreationFlag( ETCF_ALWAYS_32_BIT, true );
c8* vsFileName = 0; // Vertex shader file name.
c8* psFileName = 0; // Pixel shader file name.
psFileName = "./media/hlsl.fx";
vsFileName = psFileName; // Copy file name.
//================================
// Check shader version.
//================================
if (!driver->queryFeature(EVDF_PIXEL_SHADER_1_1) &&
!driver->queryFeature(EVDF_ARB_FRAGMENT_PROGRAM_1))
{
g_device->getLogger()->log("WARNING: Pixel shaders disabled "\
"because of missing driver/hardware support.");
psFileName = 0;
}
if (!driver->queryFeature(EVDF_VERTEX_SHADER_1_1) &&
!driver->queryFeature(EVDF_ARB_VERTEX_PROGRAM_1))
{
g_device->getLogger()->log("WARNING: Vertex shaders disabled "\
"because of missing driver/hardware support.");
vsFileName = 0;
}
// Load mesh.
IAnimatedMesh* g_mesh = g_device->getSceneManager()->getMesh( "media/test.x" );
// Add mesh scene node.
IAnimatedMeshSceneNode* g_Model = smgr->addAnimatedMeshSceneNode(g_mesh);
g_Model->setMaterialFlag(EMF_LIGHTING, false);
// Load toon shader texture.
ITexture* pShadeTexture = driver->getTexture( "media/shade.bmp" );
// Set shader texture to mesh.
g_Model->setMaterialTexture( 1, pShadeTexture );
IGPUProgrammingServices* gpu = driver->getGPUProgrammingServices();
for( u32 nMat=0; nMat<g_Model->getMaterialCount(); nMat++ )
{
// Create shader material.
MyShaderCallBack* mc = new MyShaderCallBack();
mc->SetMaterialU( g_Model->getMaterialCount(), nMat );
// Create shader material from HLSL.
s32 newMaterialType = gpu->addHighLevelShaderMaterialFromFiles(
psFileName, "VS_Shade", EVST_VS_1_1,
psFileName, "PS_Shade", EPST_PS_1_1,
mc, EMT_SOLID, nMat);
mc->drop();
// Set shader material.
g_Model->getMaterial(nMat).MaterialType = ((E_MATERIAL_TYPE)newMaterialType);
// Set texture mapping mode to MIRROR.
g_Model->getMaterial(nMat).TextureLayer[1].TextureWrap = ETC_MIRROR;
}
// Set mesh animation parameter.
g_Model->setAnimationSpeed(30);
g_Model->setFrameLoop(0, 3000);
// Set mesh scale.
g_Model->setScale( vector3df(1.0f,1.0f,1.0f) );
g_Model->setPosition( vector3df(0.0f,0.0f,0.0f) );
// Add rotation animator to mesh.
ISceneNodeAnimator* anim2 = smgr->createRotationAnimator(vector3df(0.0f,0.1f,0.0f));
g_Model->addAnimator(anim2);
anim2->drop();
// g_Model->setDebugDataVisible( EDS_MESH_WIRE_OVERLAY );
// Add camera scene node.
ICameraSceneNode* cam = smgr->addCameraSceneNodeMaya( NULL, -300, 20, 15 );
cam->setPosition(vector3df(0,0,-4));
cam->setTarget(vector3df(0,0,0));
cam->setFarValue( 2000.0f );
cam->setNearValue( 0.01f );
//================================
// Draw.
//================================
int lastFPS = -1;
while(g_device->run())
{
driver->beginScene(true, true, SColor(255,100,100,100));
smgr->drawAll();
driver->endScene();
int fps = driver->getFPS();
if (lastFPS != fps)
{
stringw str = L"Toon Shading by Tenko - Irrlicht Engine Demo [";
str += driver->getName();
str += "] FPS:";
str += fps;
g_device->setWindowCaption( str.c_str() );
lastFPS = fps;
}
}
g_device->drop();
return 0;
}
Code: Select all
float4x4 MatrixW;
float4x4 MatrixWVP;
float ShadowU;
float4 LightDiffuseColor;
float4 LightAmbientColor;
float3 LightDirection;
sampler MeshTextureSampler;
sampler ShadeTextureSampler;
//================================
// Vertex shader.
//================================
struct VS_OUTPUT_Shade
{
float4 Pos : POSITION;
float4 Col : COLOR0;
float2 TexUV : TEXCOORD0;
float2 ShadeTexUV : TEXCOORD1;
};
VS_OUTPUT_Shade VS_Shade(
float4 Pos : POSITION,
float3 Normal : NORMAL,
float2 TexCoord0 : TEXCOORD0,
float4 Diffuse : COLOR0
)
{
VS_OUTPUT_Shade Out = (VS_OUTPUT_Shade)0;
Out.Pos = mul( Pos, MatrixWVP );
float3 norm = normalize(Normal);
float3 ligt = normalize(LightDirection);
float dot = dot( mul( norm, (float3x3)MatrixW ), -ligt );
// dot *= 0.01f;
dot += 1.0f;
dot *= 0.5f;
Out.ShadeTexUV.x = dot;
Out.ShadeTexUV.y = ShadowU;
Out.Col = Diffuse * LightDiffuseColor + LightAmbientColor;
Out.TexUV = TexCoord0;
return Out;
}
//================================
// Pixel shader.
//================================
float4 PS_Shade( VS_OUTPUT_Shade In ) : COLOR0
{
return tex2D( MeshTextureSampler, In.TexUV ) * tex2D( ShadeTextureSampler, In.ShadeTexUV ) * In.Col;
}
Please edit it according to your model.
If it is composed of 5 meshes.
If it is composed of 4 meshes.
But it has the problem.
- Cannot change the scale of the model.
- Only Directional Light can be used.
- The light is only one.
- The model must make outline.