Cabochon Lights in Unreal 4

s-l500.jpg

Hey guys!

For my Uni project I am creating a classic fun fair environment and for it I plan to have Cabochon Lights (seen in image above) which are commonly used on rides flashing along to the music.

My question is how would you go about creating the prism-like refracting the plastic does to the light? Would it be a simple case of just putting light inside a translucent gem shape, or would the physics not work like that?

Another option I’ve considered are IES lighting profiles, but I can’t find any related to amusement parks. Would I have to make one myself, if so how would I go about doing it?

Also, because of the environment I will probably have about 100 or more of these. How many lights can I add before lag becomes an issue? I know I can bake some of the lighting but a lot will turn on and off so the lighting needs to change real time so what other options could I use to help with performance?

Any help would be appreciated, thanks!

In answer to the first part of your question - no, you won’t get this effect by putting a light inside a translucent mesh. The beautiful light patterns in your reference image are a ‘caustic’ effect, caused by refraction in the material. It’s ridiculously expensive to compute, even in an offline renderer - and a real-time renderer definitely doesn’t support it.

You probably could put in 100 or so static (not stationary) lights, but it’s probably overkill - especially if the lights are small. Baking won’t help you if there are more than 5 overlapping lights on the same objects.

Like almost everything else in computer graphics, you’ll have to cheat - and there are lots of ways you could go about it. I think I would probably start by creating a strip of these lights in a DCC package, and bake out a ‘lit’ and ‘unlit’ texture for the whole strip. You could try rendering the caustics, and the bounce light on nearby objects, but painting them in is probably more efficient if you have some usable reference.

I’d then set up a material with an animated mask that ‘reveals’ the lit texture (turns the lights on) in the correct sequence.

This will give you the look, but won’t actually emit any light into your scene. For this you could use a much smaller number of lights (long and thin) arranged so that they represent the combined contribution of many more smaller ones. Adding an animated light function (gobo) could sell the ‘flashing light’ idea - my guess is that it doesn’t have to be particularly accurate to look good.

That’s one method. You could use decals. You could bake out two texture sets for the area just around your lights (if the lights followed a two step alternating pattern) and switch between them. If it’s dark, and we never get that close, you could rely on glow alone to ‘sell’ the effect.

Hope that gives you some ideas.

I have been experimenting with methods for creating stuff like this in UE4. Scribbler is definitely correct that this is an offline type effect.

That said, there is actually a way to preview a version of this using a crazy expensive technique using the Scatter method and procedural mesh. I will be giving a GDC talk that mentions this specifically, so that will be shared next month or so.

The basic idea is:

  1. Create a generic polygon cache using procmesh. I encode 512x512 grid of quads which is 262k quads or 524k tris. Each quad needs to have its 1d index encoded. I use the UVs for this (and then the UVs have to be reconstructed manaully in the material).

  2. You’d need to store a layout of your mesh unwrapped, storing the normal and another texture storing the positions.

  3. Then, you create a bunch of instances of the procmesh (first I convert it to a regular static mesh since the procmesh will be very slow to move around). To get a decent result, you will need at least 16 million photons, which means you need 16 instances of the 512x512 grid mesh (remember 2 tris per photon).

  4. Then you do some 1d to 2d space conversion math, you position the photons to start on the positional texture in the world, and then you give them a trajectory formed using the light origin, and then use Snell’s law to calculate correct refraction (http://shaderbits.com/blog/optimized-snell-s-law-refraction

5). Now all you have to do, is get the Z distance from each photon from the ground, and you push each photon along its normalized trajectory, times the Z distance, and divided by the Z component of the normalized direction vector.

The last step ONLY works if you know you are projecting ONLY on to flat ground.

This is ‘realtime’ in the sense that you could change the normal map and instantly see it move, or you could move the virutal light location and alter the caustic pattern instantly.

To project onto something that isn’t an analytical shape (like a flat ground is a plane, or a box or cylinder would also be fairly easy), would require a totally different method called photon gathering, which has to be computed offline using render targets.

You can also make fake caustics by just using the normal map. In this example, the tiling caustics are just from a pre-made texture, but the caustics from the ripples are just using the blue channel from the fluid sim normal. Then the fluid sim normal XY adds some distortion to the UVs of the tiling caustic texture, which sort of integrates them. You could do something similar for glass, but keep in mind it won’t allow for overlapping shapes like true caustics.

While this can look cool, compared to real caustics it is nowhere near as interesting or complex.

Wouldn’t a Light Function do the trick, too?

Yes. but I am more talking about methods to author the light function texture itself in a way that matches some normal map shape you have. you can of course just try random textures or radial mapping methods. sometimes a pure nonsense texture works.

Here is a quick example of a 2d radial projection of some random noise:

c86a07c64df30a87c03426f08e71888f07338586.jpeg

noise node was set to NoiseFunction = Gradient_Texture, Turbulence=False., Tiling=True, RepeatSize=4 (hence 6 equal repeats like a hexagon, based on the 24 input radial tiling).

Vary the Y or Z params to get different randomized patterns. Can use lightvector.R there too.

edit IES profiles would not be able to create this effect using a single light, because they map a 1d gradient around radially, such that it looks like concentric rings. You would need a few lights rotated outwards to get that effect.

For example, one IES profile light would create things that are like this if projected down on the ground:
03.JPG

But if the light is at a grazing angle, it will make more of a parabolic or streaking effect. but you would need a light for each streak direction. here I rotated 4 at grazing angles:
04.JPG