Category: Programming

  • Texturing Tools for Unity

    Texturing Tools for Unity

    A package that contains a variety of editor tools to allow you to do some basic texture work within Unity. With one (or a few) scripts, you can draw freely on any 3D object in your scene. Features include a layer-based system with customizable brushes with full undo support. Textures can be saved, as well as brush presets for use later.

    Check out the package here: https://github.com/westonwright/texturing-tools-unity


    Features

    Drawing Surface

    The Drawing Surface is a script you can place on any object in a scene to enable texture editing on that object. The object must have a Mesh Filter and a Mesh Collider. The drawing surface has multiple features, explained below.

    Transform/Drawing Mode

    While in Transform Mode, the object behaves as normal, and cannot be drawn on from the scene view.

    While in Drawing Mode all transformation tools (translate, scale, rotate) are disabled, as is selecting other objects in the scene. This allows you to draw on the object unobstructed by clicking and dragging across its geometry.

    Channels

    Each Drawing Surface can have any number of channels that can be swapped between at will. Channels are independent collections of layers with a set resolution and are applied to the correspondingly named texture channel in the object’s material. For example, you could have one channel named _MainTex that will apply to the albedo of the object, and another channel named _EmissionMap that will apply to the emission of the object.

    For most materials, the primary texture channel is named “_MainTex”, so that is the default name of a new channel.

    Layers

    Layers are fairly self-explanatory, although it should be noted that (for now) they are listed in the opposite order you might expect! In the current release, they come in the form of Textures and Layers, although more may be added in the future.

    Layers have a standard set of controls.

    1. This checkbox enables or disables the layer temporarily.
    2. This checkbox locks a layer, which prevents it from being drawn on.
    3. This arrow moves a layer up or down in the list.
    4. This context-sensitive arrow will move a layer in or out of a folder

    Textures

    Textures are layers that store pixel data at the resolution defined by its channel. At least one texture layer is required to enable drawing.

    Folders

    Folders can store other layers and folders for easy organization. A locked or hidden folder will do the same for all of its children.

    Saving

    Your layer data is automatically saved when your unity project is saved.

    If you press “Save Drawing As…”, you can export your final drawing as a PNG to a desired location.

    UV View

    The UV view displays the currently selected Channel and the UV polygon data of the selected drawing surface. It can be drawn on directly, with the added benefit of displaying in RGB when the current channel might not be on the object.

    Drawing Settings

    Displays which tool is currently being used and any associated settings. There are currently two tools: Brush, and Eraser


    How it Works

    Spacing Stroke Points

    One of the main issues that became immediately visible when first designing this system was the appearance of each stroke was directly tied to the frame rate of the engine and the speed of the cursor. The solution was to track the distance traveled since the last point and only draw a new one past a given threshold. This feature is called “Spacing” in the drawing settings and can be tuned to the desired distance or turned off completely.

    This solution was not perfect, however, as when the cursor traveled further than the threshold distance in one frame, it would essentially skip any point that would have been drawn. The solution was to store new points in a queue and add multiple points to the queue if the distance traveled was too great. While not a perfect solution due to the added appearance of hard lines, it was a better solution than allowing gaps in the stroke.

    Surface Drawing

    Drawing on the surface of an object uses raycasts to determine the UV coordinate of the point currently being drawn. Because the basic implementation would simply draw a straight line between any two points in UV space, it would run into issues any time there was a UV break, as demonstrated below:

    To remedy this, the vertex indices of the previous tri drawn on are stored and compared against those of the new stroke. If all of them are the same (meaning it is the same tri) or there are at least two matches (meaning it is a neighboring tri), the stroke can be continued as usual. If there aren’t at least two matches, the stroke interpolation must be halted and resumed at the new location. In future implementations, it is possible that a smoother line could be drawn without having to halt the stroke completely.

    It should be noted that this also introduced potential issues if the distance from the last point drawn happened to skip over more than two tris. The current solution for this is to check every screen-space pixel in the line between two desired points to detect changes in the tri. This could be improved in the future with a quick-search-esque implementation of searching through the pixels or perhaps something more advanced.