Recently implemented a real-time mesh vertex animation in UE4, with a large number of vertices (hundreds of thousands of levels)
The first is to create the dynamic Vertex Buffer, then each frame to update the vertex data, found that the efficiency is lower
The bottleneck of efficiency is in the calculation of vertex coordinates, after all, there is a lot of
Then changed to be based on vertex Texture (material in the World Position Offset) Implementation, then VB will not update, only need to update each frame Texture
In this way, although the amount of data transmitted is consistent, it is possible to calculate a portion of the vertex coordinates into the GPU side, which greatly reduces the CPU pressure
The actual measurement found that the gamethread time consumption is still very high, the further optimization is to throw this part of the operation into the background thread [CPP] view plain copy void Adynamictexturetestcharacter:: Updateingamethread () {ftexture2dmipmap& Mip = dynamictexture->platformdata->mips[0]; fvector4* Dest = (fvector4*) Mip.BulkData.Lock (lock_read_write); Writetexturedata (Dest); Mip.BulkData.Unlock (); Dynamictexture->updateresource (); }
After a test, crash, carefully see, the original is Ftexture2d::updateresource () will re-create the D3D texture object, the correlation function must be gamethread call in order to
The way that the data update itself is problematic, can not be directly updated to the corresponding D3D texture it. Search UE4 code, found that Ftwitchlivestreaming::updatewebcamtexture () has more efficient implementation, the general idea is to send the data to Renderthread to update directly, The call is Rhiupdatetexture2d[CPP] View plain Copy void adynamictexturetestcharacter::updateinrenderthread () { fvector4* dest = databuffer.getdata (); Writetexturedata (Dest); struct FUpdateTextureContext { uint8* sourcebuffer; // render thread assumes ownership uint32 BufferPitch; FTexture2DResource* DestTextureResource; } updatetexturecontext = { (uint8*) dest, sizeof (FVECTOR4) * dynamictExture->getsizex (), (ftexture2dresource*) dynamictexture->resource }; enqueue_unique_render_command_oneparameter ( updatedynamictexture, FUpdateTextureContext, context, updatetexturecontext, { const fupdatetextureregion2d updateregion ( 0, 0, // Dest X, Y 0, 0, // Source X, Y context.desttExtureresource->getsizex (), // width Context.desttextureresource->getsizey ()); // height rhiupdatetexture2d ( context.desttextureresource->gettexture2drhi (), // Destination GPU texture 0, // mip map index UpdateRegion, // Update region Context.BufferPitch, // Source buffer pitch context.sourcebuffer); // source buffer pointer }); }
This practice is no longer authorized to run Gamethread, so the performance impact is relatively small. The actual test of the call thread execution time is about 1ms faster than the previous one, which is still quite large for the FPS effect
Resources
Https://wiki.unrealengine.com/Dynamic_Textures
From: http://blog.csdn.net/xoyojank/article/details/49232841