Painting in-game

I want to provide players with an in-game painting feature. I need this to allow them to customize their avatars, which are primitives at the moment; later I hope to allow them to deform the meshes in a similar way to how they paint colors to them.

I’ve found so many resources, and the first one happened to waste a lot of my time. I used blueprints shared in a whiteboard tutorial, which were derived from a live training video on render targets which showed a method for painting height maps in real time. The problem I’m having with this current solution of mine, is one I can’t paint black, and two I can’t replace colours. If I paint with (200,50,50) for example I end up with white unless I paint for a very short time.

So I’m hoping to the community can help point me on the right development path.

I need an implementation that can allow me to:

  1. paint any color
  2. paint on meshes
  3. save changes, for subsequent play sessions
    – I was thinking I will need to effectively paint to textures or some intermediate in order to save the work

My resources thus far:

  1. whiteboard tutorial - Unreal Engine 4 Tutorial - Making a Usable Whiteboard - YouTube
    I adapted this by splitting my input color into three channels, and reading from three render targets (one for each channel)
    It works, but I get white as a result see picture:

    This happens because I need it set to additive. In addition to this problem I cannot paint the color black.

  2. Blueprint Drawing to Render Targets Overview | Live Training | Unreal Engine
    This is basically the basis for the whiteboard, they start to talk about painting height maps around 8-9 minutes in.

    This seems to be almost exactly what I need, and I only found it about an hour ago. I still need to dig in a bit more to his bread crumbs as there is no source code shared. I suspect that, although this seems to work well. I am not sure it is suitable since there are several other resources I’ve come across which state you can’t do vertex painting in-game, only in-editor. Furthermore I suspect I wouldn’t be able to save the output.

Thanks for anybody who even took the time to read this, but I’m really hoping someone can help here. I’ve spent too much development time trying to get this to work already.

Hi. This is doable. I recently did an android app where the user can draw on meshes with different color, brushes, opacity, sizes etc. Also, you can save the work and load back later. I implemented this with projection painting using blueprints and drawing to rendertargets only. What specificly are you wondering about?

My goal is to have an interface to change the color, size, and softness of the brush. Right now I’m trying to work off of this resource on the subject, it seems pretty good. I’ve tried it out with a translucent textured material to see how it works with overwriting colors, and it seems to work perfectly. The only problem now is I need a way to get a circular brush, with adjustable properties. I really suck at all this arty side stuff, so I could be missing something, but I think I’ve got to make myself a brush class, and write some C++ code to procedurally generate and/or update the properties of the brush; wooo cos and sin time =( The circle part is easy, but I’m not totally sure on the region within the circle yet. This link seems to be helpful for writing custom runtime textures, but I haven’t written anything yet. ( A new, community-hosted Unreal Engine Wiki - Announcements - Epic Developer Community Forums )

I don’t have any specific ponderings, only pretty general ones. I’ve sprinted down a few dead ends already, and I’m just trying to avoid it. Seems like I have a solid development path right now though, so long as I can generate these textures without problems. If there is a better solution I’d absolutely love to hear it though!

Okay so I got it working, with this:…render-targets
Then a bit of custom code to dynamically create a brush texture for me (during runtime).

void UPaintBrush::UpdateBrush( UTexture2D* &texture )
    texture = m_BrushTexture;
    static const uint8 w = RADIUS * 2, h = w;
    static FUpdateTextureRegion2D region = FUpdateTextureRegion2D( 0, 0, 0, 0, w, h );
    auto cleanupFunc = ]( uint8 *SrcData, const FUpdateTextureRegion2D *Regions ) {};

    //Create circular brush
    for( uint8 x = 0; x < w; ++x )
        for( uint8 y = 0; y < h; ++y )
            int8 rx = x - RADIUS;
            int8 ry = y - RADIUS;
            double hyp = FMath::Sqrt( rx*rx + ry*ry );
            double coord_radius = hyp / RADIUS;
            FColor pixel;
            if( coord_radius <= 1.0 )
                pixel = FColor( m_BrushColour );
                pixel.A *= (1-coord_radius) * m_BrushSoftness;
                pixel = FColor( 0, 0, 0, 0 );
            m_BrushPixels.Add( pixel );
    m_BrushTexture->UpdateTextureRegions( 0, 1, &region, 4 * w, 4, (uint8*)m_BrushPixels.GetData(), cleanupFunc );