Digital Painting Program

Traditional artists have often pointed out the ways in which digital painting softwares fall short in comparison to the experience of using real, physical paint. For instance, programs like Adobe Photoshop mix colors inaccurately and do not capture the appearance of paint thickness.

For my thesis project, I wanted to draw upon my experience painting both traditionally and digitally to create a lightweight, artist-friendly program that incorporates the “feel” of painting in real life. My key priorities were implementing satisfying paint mixing and brush behavior, a textured 3D appearance with lighting, and general usability and versatility for the artist.

I coded the program using WebGL and Javascript over the course of 12 weeks.

Program Structure

The user paints by pressing and moving the mouse across the screen. As the mouse is pressed, color appears accordingly at the position of the mouse. A panel is displayed that allows the user to modify brush, paint, and lighting properties.

The program’s implementation depends on three OpenGL textures: a canvas texture, a “snapshot” texture, and the final display texture that includes normals and lighting calculations. For each brushstroke the user paints, a new “snapshot” texture is created that essentially screenshots and briefly preserves the old canvas, ensuring that the current brushstroke does not over-blend by mixing with itself.

Paintbrush Representation

The “brush” is represented as a collection of bristles, a series of points that each contain a unique color and position relative to the center of the brush. Bristle positions are scattered using Voronoi noise and regenerated randomly with each brushstroke.

Along the path of a brushstroke, the location of the current step along two lines is calculated: one is a line from the last mouse position to the current mouse position, and the other is a line from a recent position of the brush to the current position of the brush. By stepping along the latter line, the impression of the bristles “dragging” across the canvas is produced, creating a more realistic brush-like appearance.

The user can change the brush’s size, shape (square or circle), flatness, rotation, and bristle density.

Paint Mixing

A vital property of oil and acrylic paint is the ability for it to not only be deposited from the brush to the canvas, but also be picked up from the canvas to the brush at the same time. To replicate this behavior, the program interpolates three colors for each bristle at each step: the color from the color picker, the color of the paint on the canvas underneath the brush, and the color of the paint that is already on the bristle. The resulting color is deposited to the canvas and the bristle.

The user can adjust a slider to control the degree of paint blending, simulating the effect of painting on wet or dry paint. Each bristle blends paint to a slightly different degree, producing realistic color variation.

By including the library Mixbox, I was able to incorporate painterly color mixing into the program, in contrast to the standard additive RGB compositing formula that programs like Photoshop use. Users have the option to switch to RGB mixing if desired.

Thickness and Lighting

A notable part of the experience of physical painting is the thickness of the paint, also known as the impasto technique, which gives paintings a three-dimensional element when viewed in person. To simulate this appearance, I first generated random height values for each bristle in a brushstroke that I passed into the display shader. I then calculated normal values for each fragment by finding the average slope of the heights across its neighboring fragments, and finally combined these values with Blinn-Phong shading and a light vector.

The user is able to dynamically interact with sliders controlling the direction, intensity, and attenuation of the lighting, allowing them to see the effects on their painting in real-time.

Additional Features

In prioritizing the artist-friendly experience, I also added the following features:

  • Pen pressure support

  • A brush cursor

  • An eyedropper tool

  • Adjustable color noise

  • Options for a chalky/grainy brush

  • Keyboard shortcuts

Below is a copy I painted of Van Gogh’s Wheat Field with Cypresses, made in one hour in the program, along with the original.

Below is a comparison of mixing red and yellow in my program (left) with Photoshop (right). Since Photoshop uses one simple 2D bitmap texture per brush instead of a per-bristle paintbrush representation, it results in less realistic painting behavior.