Insert Subtexture into a Texture
Hello dear community.
I am struggling for more than a week already to accomplish next task: I have a texture (buffer initially, but it's no trouble to create UTexture2D from it). I need it to be rendered on top of some part of an object. Like a sticker on the wall, or logo on a shirt. What would be the right approach? Things i tried: Edit the texture of an object directly by using
UMaterialInterface* OriginalMaterial = GetStaticMeshComponent()->GetMaterial(targetMaterialElementIndexWhichIKnow);
OriginalMaterial->GetUsedTextures(OUT_OriginalTexturesArray, EMaterialQualityLevel::Type::Num, true, ERHIFeatureLevel::Type::Num, true);
No good. As soon as you merely try to read from the original texture buffer, like written here: https://wiki.unrealengine.com/Dynamic_Textures at the second option, you get Access Violation exception. Apparently UE lets you to tinker only with buffers of the textures you created YOURSELF through CreateTransient. I am very confused here, since this seems to be the right approach IMHO.
Another thing i tried was going through UTextureRenderTarget2D API. No luck here either. Apparently there is no way to designate to UTextureRenderTarget2D to override only part of the texture. It is good for applying sort of mask on all of the texture, but there seems to be no way to designate some texture as part of the UTextureRenderTarget2D or make UTextureRenderTarget2D itself cover only a sub-region.
My current attempt involves Decals. The problems are:
1). I inherited from ADecalActor, but my class ACustomDecalActor doesn't appear in blueprints no matter what i do.
2). Contrary to StaticMeshActor where you can apply dynamic material easily to it, Decals are not so nice. If anyone knows how to override Decal base texture from c++ please share your knowledge.
3). AFAIK Decals are not that cheap to render, since they are not really integrated into the texture, but rather render thread does extra work of rendering something on top of something already rendered. No?
4). Decals won't perform great under any angle. There are certain light angle issues.
5). There apparently is no way to attach my custom Decal to the moving object. "Spawn Decal Attached" returns stock Decal, and blueprint attach methods don't do the job (either due to my missuse, or due to missinterpretation of my custom Decal).
Please help. I will be glad to have at least some direction.
Thank you in advance.
Found the solution!
Of course the approach of direct buffer edit is the right one. What i was missing is getter.
Apparently, (correct me if i am wrong) one working with native texture should use two integral tricks:
1) You can not just go [Texture]->PlatformData->Mips[Level]; like in manual. The PlatformData you have to get from it's respective getter, like so: [Texture]->GetRunningPlatformData()->Mips[Level]; Otherwise you will run into Access Violation exceptions on lock/unlock.
2) You really have to be quick between lock and unlock. I know that it is obvious, but what is not obvious, is that you don't have 1/60 of a second, but significantly less. So, i know you probably encountered out there some sample projects where the developer does lock(LOCK_READ_WRITE) , then edits the texture buffer in some nested "for" loop, then does unlock(). Completely disregard those examples. You literally have time only for FMemory::Memcpy ! the explanation here(https://wiki.unrealengine.com/Dynamic_Textures) might be a little missguiding. The second example is what you should literally do! No more.
P.S. UTextureRenderTarget2D API is wrong approach AFAIK. Don't go this way. Decals i managed to make work, but they are really performance taxing.
P.P.S. Be advised, that if you mutilate some texture in the native level, all instances of this same texture will be mutilated. I mean if you have five same cars in the game, edit one, HW accelerator edits them all. This is because HW accelerator shares the pointer to the texture between the instances to increase performance. And this is by design!
P.P.P.S. Write me here if you would like some code snippets or more explanations. So far it seems i am the only one that is interested in such a thing.
Follow this question
Once you sign in you will be able to subscribe for any updates here