节点材质系统初步搭建完毕
我的节点材质系统已经基本搭建完毕,ShaderFX和虚幻UDK给于了极大的启发与支持,感谢感谢
以下效果图是骨骼动画的各通道效果图
Specular Map
节点暂时还是用C++构造的,之后会改为二进制存储
MaterialCompiler Compiler;
MaterialNodeTextureSampler SamplerNode(&Compiler);
/*MaterialNodeVector VectorNode(&Compiler);
VectorNode.mData = Vector4( 1,1,0,0);*/
MaterialNodeAdd AddNode(&Compiler);
MaterialNodePointLight PointLightNode(&Compiler);
//VectorNode.mRGB.LinkTo( &AddNode.mDataX );
//SamplerNode.mRGB.LinkTo( &AddNode.mDataY );
SamplerNode.mRGB.LinkTo( &PointLightNode.mAmbient );
//AddNode.mResult.LinkTo( &PointLightNode.mDiffuse );
if ( Compiler.GetErrorCount() == 0 )
{
PointLightNode.Compile();
Compiler.SaveCode( StringConverter().AnsiToUnicode( mShaderFile.c_str() ) );
}
生成的代码格式和虚幻的shader模板一摸一样,不过我的利用了点不定参数列表的小技巧,代码更漂亮的,呵呵
MaterialNodePointLight::MaterialNodePointLight(MaterialCompiler* Compiler)
: MaterialNode( Compiler )
{
mAmbient .BindSlot( L"Ambient", this, MVT_Float3, "float3(0.0f,0.0f,0.0f)" );
mDiffuse .BindSlot( L"Diffuse", this, MVT_Float3, "float3(0.0f,0.0f,0.0f)" );
mNormal .BindSlot( L"Normal", this, MVT_Float3, "Parameters.VertexNormal" );
mSpecular .BindSlot( L"Specular", this, MVT_Float3, "float3(0.0f,0.0f,0.0f)");
mSpecularPow.BindSlot( L"SpecularPow", this, MVT_Float, "16.0f");
mOpacity .BindSlot( L"Opacity", this, MVT_Float, "1.0f");
}
typedef std::vector<void*> FormatParameterArray;
void MaterialNodePointLight::Compile( )
{
dword CodeGenLength = 0;
FormatParameterArray tFormatParameterArray;
// 编译代码,并构建格式化数组
for ( SlotList::iterator it = mSlotList.begin();
it != mSlotList.end();
++it )
{
MaterialSlot* Slot = *it;
Slot->Compile();
CodeGenLength += StringHelperA::Length( Slot->GetResultCode() );
CodeGenLength += StringHelperA::Length( Slot->GetCaculateCode() );
tFormatParameterArray.push_back( (void*)Slot->GetCaculateCode() );
tFormatParameterArray.push_back( (void*)Slot->GetResultCode() );
}
// 读取模板文件
FileStream ShaderFile;
if ( !ShaderFile.Open(L"shader/MaterialTemplatePixelShader.usf", FAM_Read ) )
{
Assert( false );
}
dword ShaderFileSize = ShaderFile.GetSize();
AString ShaderTemplateCode;
ShaderTemplateCode.resize( ShaderFileSize + 1);
ShaderFile.ReadBuffer( (void*)ShaderTemplateCode.data(), ShaderFileSize * sizeof( char ) );
ShaderTemplateCode[ShaderFileSize] = 0;
mCompiler->WriteFinalCode( ShaderFileSize + CodeGenLength , ShaderTemplateCode.c_str(), &tFormatParameterArray[0] );
}