In this post I’ll be going over how you can use UV Offsetting to create a dynamic, runtime editable Oscilloscope for the UDK with a single material. Oscilloscopes are used to measure constantly varying signals.
Oscilloscopes are great for creating a retro scifi look. The one we’ll be creating will show a sine wave. We’ll be able to change it’s frequency, amplitude, and the speed at which is moves across the material. We’ll also be able to do a few cosmetic things like adjust the colour and adding a vignette effect.
Sine Waves – A Quick Breakdown
A Typical Sine Wave
So that we’re all on the same page I’m just going to quickly go over some of the terms involved in sine waves. Frequency refers to the space between the valleys or peaks of the curve. A frequency of one will give you a single peak and a single valley. More than one will give you more, less than one will give you only part of the sine curve. The amplitude refers to the height and depth of the valleys and peaks. More will give you more extreme peaks and valleys, less will give you very shallow peaks and valleys.
Technically you really dont need any textures at all for this, but for cosmetic reasons I’m using a single channel-packed image. I’ve included it below, feel free to grab it.
A channel packed texture that I will be using.
The Material – An Overview
Ocilloscope Material Overview - Click to Enlarge
There are several parts to this material. “Grid”, “Glow” and “Line” are all cosmetic. They take the images from the channels of the channel packed material and combine them into something that resembles an oscilloscope.
“Sine Wave” creates the sine wave pattern. “Inject Into UV” combines the sine wave pattern with the UV’s for the green channel (the one containing the flat line) to create the appearance of a sine wave. “Vignette Blend” and “Vignette Generation” can be used to reduce the amplitude of the sine wave towards the edges of the material (cosmetic, just for a stylised retro look).
Grid, Line and Glow
Let’s get the simple stuff out of the way here. If you aren’t familiar with parameters I suggest you read the first part of this series.
Oscilloscope Grid Section
Oscilloscope Glow Section
Oscilloscope Line Section
Each of the above sections take the appropriate image from the appropriate channel and colourises it according to the “Colour” parameter and then changes it’s intesity to make it darker or brighter. Straight forward stuff. The Line section is already accepting the offset UVs that we’ll be digging into in a moment.
Creating the Sine Wave
To create the sine wave we’re going to take advantage of a useful material node called, appropriately, “Sine”. It can be found in the Math section. When given a range of values from 0 to 1 it produces the iconic “sine wave”:
A Typical Sine Wave
So we need to give the sine node a range of number ranging from 0 to 1. Now picture in your mind what that would like as an image. You know that a constant value of 0 will give you black and that a constant of 1 will give you white. So a series that ranges from 0 to 1 will give you a black and white gradient. This might seem obvious, but it really helps to see all the images show in the nodes as representations of series of numbers, rather than just images.
Now, we could simply create a gradient image in Photoshop and import that. The problem with that, however, is that it’s not a true gradient. It’s made up of pixels. If the nodes end up asking for a value that’s between pixels we’re going to get distortion. Luckily for us theres an “algorithmic” way of doing this. The UV Coords node is actually a combination of two perfect, algorithmic gradients. We can extract this gradient with a Component Mask and use it instead of an image, giving us the same result but with no distortion and using less texture memory.
- Sine Wave Generation – Section 1
Above is a breakdown of the first section (in red) of the sine wave generation section. Remember that this is all going to be fed back into a UV Coord node at some point. We also want our sine wave to scroll across the material. We could use a panner but we also want to be able to control the speed with a parameter. We can mimic the behaviour of panning by multiplying our speed parameter with a time node.
The second section (in blue) is where we extract the gradient from the UV Coord node. Make sure you get the red channel. If you’re not familiar with component masks, I reccomend that you read the first part of this series.
The third part of this section (in green) is where we add in our frequency paramter. All this does is take the gradient (which represents 0-1, remember) and makes it represent 0 – 4, or whatever the frequency is set at.
Sine Wave Generation - Section 2
This is the most important part. The first step here is to add the fraction node. What this does is to look at each value and discard the part that comes before the decimal place, replacing it with zero. This gives the striped appearance seen in the nodes preview.
Next we pass this on to the Sine node which turns the series of 0-1 values into individual sine curves (represented here in black and white columns of pixels, of course).
Finally the output of the Sine node is multiplied by out Amplitude parameter.
Vignetting – Generation
You sometimes see oscilloscopes in movies and comics, especially retro scifi stuff, where the amplitude tapers off to the edges. We can mimic this by multiplying in a vignette on the left and right edge of the material.
Vignette Generation - Click to Enlarge
We’re doing basically the same thing we did to get a gradient for the sine node. The multiplication node makes the black part of the gradient smaller. By doing this once, reversing the gradient, doing it again and multiplying the two together we get the vignette effect we’re after. The parameter here influences the amount of multiplication and can be used to change the smoothness of the tapering effect the vignette will cause.
Vignetting – Blend
The simplest way to create a blend from “no vignette” to “full vignette” is to use a Linear Interpolate node. Just plug stuff in like you see below:
Okay, we now have all the setup we need to finally be able to inject our sine wave data into the UV Coords that will be distorting our line.
UV Injection - Click to Enlarge
What we’re doing here is seperating out the red and green channels of the UV Coord and adding the sine data to the green channel. We then recombine the red and modified green channel with a Vector Append node. Finally we plug the modified UV Coords into the Line texture.
You should now create an instanced material from the material we just made. If you’re not sure how to do that, check out part 1 of this series. You should end up with something like this: