How do YOU make beautiful plugin gui's?

Hey guys - do you think vector based GUIs look different than jpeg based? My designer uses photoshops with jpegs, etc but it seems like most plugins I see have a more shiny / polished / digital sheen to them and I’m wondering if that’s from vector based graphics. Assuming we didn’t change size at any point.

I really have no clue about this stuff so please bear with me and thanks!

You won’t be able to make skeuomorphic UIs with vector graphics (if anyone has done it, please show it here!) so in the end it depends on what you’re looking for. My advice is: use vector whenever you can, it will look great on any screen out of the box. And if using JPGs make sure you have 2x versions for retina displays.


Using vector based graphics is imho more resilient to resizing (less magic numbers in the code) and makes code less likely to explode in size (e.g sliders)

By vector based I mean:

  • get some svgs in your projucer project (ending up in binarydata)
  • load them as drawables in your custom l&f
  • draw them (eventually with some transform) in your l&f

Note: as far as my tests go, juce plays nice with svgs, except:

  • shadows
  • text (must convert it to outlines in your svg tool to have it printed correctly)

I do not use any images anymore and also try to avoid svg’s where ever possible.

I started to code the UI components. Following UI uses only the paint method and the JUCE graphics operations:

another one:

I miss some blending and gradient options to make photo realistic UI’s, but i’m happy with the result. And scaling works great!

p.s. The fonts in Juce is the main weak point in my optinion, but i think it’s not an issue anymore on retina displays.


@kunz those look amazing! would you be willing to give a bit more information on how you got your knobs and buttons to actually look like knobs and buttons instead of just circles and squares?

1 Like

Hey! I’ve used those plugins before! Mind blowing that you’re doing that all in code. Seriously gorgeous.

My main question is, how are you achieving any sort of acceptable performance? In most cases I struggle with GUI CPU usage for drawing even basic graphics on all renderers, especially if I’m doing anything animated like meters.

While I’d like to hear what @kunz has to share, the answer is light-simulating gradients. Lots of light-simulating gradients. Not just straight shadow gradients, but blended blurred shadows and lines which give depth to a scene. Just like how an artist’s work or a 3D rendering is believably brought to life when lighting/shading is added, you can do with vector graphics.

The easiest technique I’ve found to get off the ground is to use heavily blurred drop shadows to simulate ambient occlusion. You can see this in @kunz’s UI’s as all the shadows around the knobs and sliders. The problem is that in JUCE these are super expensive. (hence my questions about performance)

I made some eye-candy filled controls based on these principles a while back, I’ll have to see if I can dig any up…


The performance could be better. I have noticed this too.

Not sure if it’s possible to do a full animated UI this way. I often overlay, for example meter LED’s, with components that use setOpaque(true) to make sure the background does not re-render while the LED’s changing the colors. I also make sure that i don’t use too much and too big shadows. It needs some tuning and the possibilities are limited at the moment.

It would be nice to have a faster renderer :wink:

1 Like

I used only the linear, radial gradients and shadows directly form the JUCE library. It’s very limited. You can layer those components like you would do it in photoshop.

We did the same thing:

We use to do most prototyping with the old Adobe Fireworks. It has two advantages, first, it’s really fast to use. It’s both bitmap and vector based, with a more object oriented philosophy than photoshop’s focus on pixels and layers. And second, it more or less covers what JUCE is able to recreate.

Once we have a nice looking draft, I jump into implementation by using a mix of bitmaps/bitmap strips/3-slice/9-slice scaling and a lot of vector path acrobatics. This often takes weeks if not months, just to stumble upon a better idea and start over again. :slight_smile:

In my experience the whole subject is quite a challenge! Both artistically and performance wise. I can only approach it in an iterative manner with many evaluation and correction steps. Too much depends on the UI.

1 Like

Small suggestion for the shadows mentioned above (in a rescaling context).

Bitmap based shadows scale easily, because they don’t contain sharp corners or transitions anyway. For knobs, a realistic approach could be a hybrid use of vector trickery for all solid parts, and scaled bitmaps for all soft parts (highlights, glows, shadows, reflections).

1 Like

Indeed. In technical artist speak it’s called “baking” and used to be used a lot in the late 2000s in game engines which couldn’t afford to or simply didn’t have real-time ambient occlusion (like the Source engine, which is my native tongue for game dev). Essentially lighting was computed directly into the bitmap diffuse/color texture and when mapped onto the object looked really nice while having zero performance penalty.

A best-of-both-worlds approach could be paint and cache parts of a component (such as a shadow) to an Image object than only gets invalidated and repainted on resize. I’m currently doing this on some meters where I’m painting the green-yellow gradient once to an Image and just drawing and clipping that image at paint time rather than regenerating the gradient every paint.

1 Like