We use a Dynamic Material Instance, where we can load a Texture and modify a Material Parameter on a mesh. The Texture which modifies the parameter is loaded using a specific disk path location, (It’s not located in Project Content)
While this works just fine, and we can modify Normal Maps and or create Animation Normals, could it be possible, by having a sequence of 60 Frames, to load multiple Normals (e.g. 60 different normal map textures) and render each one of them per frame, to modify the material parameter?
As I’ve been researching this, creating an array of Textures and then dynamically fill in each slot, taken from the Disk Location might work?
Yes, that’s the plan, to create an animation using each different texture per frame, under the Normal map channel.
Using a flipBook came to mind indeed and thank you for pointing it out, as 2D Sprites are similar, but the only concern is that we load the 2DTexture dynamically, from a disk location, outside of project content directory.
Sprites do require tiling them up properly first, unless there’s any workarounds I’m not aware of?
Hmm, unsure I might be able to provide a solution.
Making a texture-array is certainly possible, you can swap out parameters in the material-instance/instance-dynamic a you need to.
I’d just be worried about performance.
If the textures need to be determined before you change them, eg: something is based on the state of the critter, then I don’t supposed you can predict the order you need them?
If the order is static, like a movie, can you use a media-texture?
While I can’t see any technical reason this wouldn’t work, keep in mind that normal maps rely quite a lot on being high resolution and sometimes high bit depth to offer good quality shading. Loading 60 into memory all at once for a single object is not great. Most games with animated normals have a small number that they cheaply lerp between (such as the clothing in GTA).
You can also achieve rotation with some math, and panning is trivial. A mask could be made to apply each of these effects in different spots to create pretty advanced looking animations without needing multiple frames.
Make sure to preload all of the normal map so that they are able to run properly. It will of course take up a lot of VRAM using that many normal maps. Packing them into a single or multiple textures could be helpful. You might want to reconsider your approach to whatever it is you are trying to solve, especially if this is for a game.
Indeed this looks possible, my only concern and the part which I’m skeptical is that, the Textures are being loaded from a location outside of the project content folder.
I’ve never used a similar approach before, which is why I’m trying to first make sure this is possible, at a reasonable cost of course.
Modifying the rotation and lerp between less materials, instead of using 1 per frame sounds promising, I will have a look on that and thank you for suggesting it!
@EliasWick
Packing sounds good indeed as it could make it less expensive. It is not for a game, therefore we can make use of a bit more expensive approaches, within a reasonable limit of course.
Thank you for your response, and providing these links.
I checked Media Texture and in theory, that’s exactly the approach, loading a set of textures and animating them using the Normal Map channel, on a mesh.
I haven’t found a way to use textures located “Outside of Content”, as with Editor Only it’s
possible and that would be a solution, but the project will be packed, which based on the tooltip description, it will lose the reference to the location, outside of content folder.
Maybe a workaround can solve this, but most likely it’s going to require Engine modification.
Look into DeriveNormalZ to use XY and calc Z on the fly. Can save you a channel, and across 60 textures…
If you pack XYXY into the RGBA of a texture, you could cut the texture-count in half, but memory would be the same as using the alpha channel doubles-up on memory so 1/2 and the double cancel.
Otherwise if you stick with RGB, you can still cut down to 40 textures overall, but you will have to juggle/coordinate as you go.
Normal maps don’t use the same compression as RGB Or RGBA and in fact by default throw away the B channel and do a higher quality compression on just the RG. I would not recommend packing them, especially if you’re using arrays they will share a single sample anyway. If you’re not saving memory or samples there’s no point.
Frankly there’s no good way to load 60 normal maps into memory all at once. You can really only reduce the number of frames, the resolution or the depth and all will likely adversely effect the quality of the animation.
Normal maps are meant to cheaply add lighting detail, if they stop being cheap it begs the question of why are we using them.
Without knowing the exact nature of an animation it’s hard to recommend an alternative. But for example vertex animation can cheaply animate real geometry via math or textures.