上次讲解了3d游戏里武器的粒子效果实现,今天继续讲解武器表面增强(加)一层纹理特效。
先来看下效果
原来武器表面是没有这个七彩图片流动的效果的。
原武器的图片
这个技术用到了hlsl ,高阶着色器语言(High Level Shader Language,简称HLSL)
irrlicht的 10.Shaders 就是hlsl的使用例子。
hlsl又分多种语言,cg hlsl glsl ,我主要使用hlsl的。DIRECT3D9
原理我就不细讲了,直接扔代码实现,基于irrlicht dx9
加载完武器模型后
IAnimatedMeshSceneNode* weaponNode; //武器节点
weaponNode->setMaterialTexture(1,Driver->getTexture("colorful.tga"));//设置武器纹理
colorful.tga 是个七彩的图片
//
s32 getMaterialType(bool istransparent){
device->getVideoDriver();
c8* vsFileName = 0; // filename for the vertex shader
c8* psFileName = 0; // filename for the pixel shader
video::E_DRIVER_TYPE driverType ;
driverType=drv->getDriverType();
switch(driverType)
{
case video::EDT_DIRECT3D9:
psFileName = "weapon.hlsl";
vsFileName = psFileName; // both shaders are in the same file
break;
default:
return NULL;
break;
}
//检查硬件是否支持着色
if (!drv->queryFeature(video::EVDF_PIXEL_SHADER_2_0) &&
!drv->queryFeature(video::EVDF_ARB_FRAGMENT_PROGRAM_1))
{
device->getLogger()->log("WARNING: Pixel shaders disabled "\
"because of missing driver/hardware support.");
psFileName = 0;
}
if (!drv->queryFeature(video::EVDF_VERTEX_SHADER_1_1) &&
!drv->queryFeature(video::EVDF_ARB_VERTEX_PROGRAM_1))
{
device->getLogger()->log("WARNING: Vertex shaders disabled "\
"because of missing driver/hardware support.");
vsFileName = 0;
}
// create materials
video::IGPUProgrammingServices* gpu = drv->getGPUProgrammingServices();
if (gpu)
{
if(istransparent)
{
newMaterialType1 = gpu->addHighLevelShaderMaterialFromFiles(
getWeaponHLSLFile(device->getFileSystem()), "vs_main", video::EVST_VS_1_1,
getWeaponHLSLFile(device->getFileSystem()), "ps_main", video::EPST_PS_2_0,
this, video::EMT_TRANSPARENT_ADD_COLOR ); //EMT_SOLID EMT_TRANSPARENT_ADD_COLOR
}else
{
newMaterialType1 = gpu->addHighLevelShaderMaterialFromFiles(
getWeaponHLSLFile(device->getFileSystem()), "vs_main", video::EVST_VS_1_1,
getWeaponHLSLFile(device->getFileSystem()), "ps_main", video::EPST_PS_2_0,
this, video::EMT_SOLID ); //EMT_SOLID EMT_TRANSPARENT_ADD_COLOR
}
this->drop();
}
return newMaterialType1;
}
getMaterialType函数就是个创建gpu 添加hlsl高级着色语言脚本 weapon.hlsl
addHighLevelShaderMaterialFromFiles方法有个参数需要 video::IShaderConstantSetCallBack的接口实现。写个类继承下 : public video::IShaderConstantSetCallBack 并实现OnSetConstants方法(例子可以看irrlicht的 10.Shaders )。
virtual void OnSetConstants(video::IMaterialRendererServices* services, s32 userData)
{
IVideoDriver* drv=device->getVideoDriver();
core::matrix4 mWorldViewProj;
mWorldViewProj = drv->getTransform(video::ETS_PROJECTION);
mWorldViewProj *= drv->getTransform(video::ETS_VIEW);
mWorldViewProj *= drv->getTransform(video::ETS_WORLD);
services->setVertexShaderConstant("mWorldViewProj", mWorldViewProj.pointer(), 16);
float b=1.0;
services->setPixelShaderConstant("bright", &b, 1);
services->setPixelShaderConstant("fTime", &time, 1);
time+=0.001f;
}
//给武器加上材质
weaponNode->setMaterialType(getMaterialType(0));
weapon.hlsl脚本里代码如下
float4x4 mWorldViewProj;
struct VS_INPUT
{
float4 Position : POSITION0;
float2 Texcoord : TEXCOORD0;
};
struct VS_OUTPUT
{
float4 Position : POSITION0;
float2 Texcoord : TEXCOORD0;
};
VS_OUTPUT vs_main( VS_INPUT Input )
{
VS_OUTPUT Output;
Output.Position = mul( Input.Position, mWorldViewProj );
Output.Texcoord = Input.Texcoord;
return( Output );
}
sampler2D baseMap;
sampler2D flameMap;
float fTime;
float bright;
struct PS_INPUT
{
float2 Texcoord : TEXCOORD0;
};
struct PS_OUTPUT
{
vector color : COLOR0;
};
PS_OUTPUT ps_main( PS_INPUT Input )
{
PS_OUTPUT output;
output.color=float4(0,0,0,0);
PS_OUTPUT blue;
blue.color=float4(0,0,220,0);
float4 base=tex2D( baseMap, Input.Texcoord );
Input.Texcoord.y = Input.Texcoord.y-fTime;
Input.Texcoord.x = Input.Texcoord.x-fTime;
float4 color2=tex2D( flameMap,Input.Texcoord );
output.color=base + color2;
if(output.color.x<150 && output.color.y<150 && output.color.z<150){
}else{
}
output.color*=0.70;
output.color*=bright;
return output;
}
里面的代码就是对colorful.tga 纹理+武器base纹理。顺便增加了流动效果和亮度微调。
如果一切正确,那么运行结果就是武器有了纹理流动的特效了。
3d游戏武器粒子特效的实现2 完。