Light direction vector in Cycles


I’m working on a shader that relies on the angle between the camera and the light that is incident on the object. I get the impression I can’t get the vector direction for a ray that is triggering the shader calculation - I didn’t see anything in the Blender wiki that looked like it, anyway. This might be only something I can do in Unity / UE…

Can anyone confirm? Specifically, I’m looking for a “light vector” which points to / from the light source - much like the view vector does for the camera.


Blender Internal Render, the OpenGL render and the BGE allow access to the light vector. In Cycles, and particularly for cycles shaders (SVM and OSL), all vectors are light vectors! It’s just that some vectors contribute with more light than others to a particular direction (the incoming vector).

Right. I figured how to optimize it in Cycles by testing for certain kinds of rays… but getting a vector for the triggering ray was eluding me. Anyway, seems you’ve confirmed my suspicions - it can’t be done.

Well… Cycles is open source, and it’s possible to include new closures, even if just for personal use. But you need to generalize your shader in some other way. In renderers like Cycles, closures are generic for their local hemisphere… so you need to describe your shader not with the light vector in mind but how much energy from the whole hemisphere is reflected/transmitted to the incoming ray. There’s lots of papers about this, just do a simple search for ‘bidirectional distribution function’.

Unfortunately, I need a light vector because I’m trying to port an old UE4 shader I built that reproduces retroreflective light behaviors (like you see in highway signing). The use case typically involves one overpowering light source, so as an optimization, the direct rays from that single source are all that’s needed for the calculation, though other light rays certainly do affect the behavior of the sign. But because retroreflective surfaces are designed to return 60%+ of the light which is incident upon them in the same direction (along the path of incidence), then I need to know what that path is from the start.

That said, I can probably mock up some user-defined values in the shader which specify a light source position from the camera and use vector math to do the rest of the work.

there was some thread on retro reflector
does not mean it is 100 % valid

see these

retro are difficult to do in blender anyway
so good luck and let us know fi you come up with better way to do it

have fun

happy cl

The latter two links didn’t work, but I did check out the blendswap shader. The author assumed the light source to be in line with the camera. It’s a good visual effect, but, of course, lacks accuracy.

I can picture the solution assuming the light is always in a fixed position with respect to the viewer (even if it’s not directly inline), which covers the most common use case - a driver in a car / truck. But of course, there’s incidental light that creates interesting artifact “flashes” in the signing (you can see this on a sunny day as you drive past a retroreflective highway sign), as well as the use case of lights which are positioned independently of the observer…

I didn’t assume anything - that is exactly the effect I was going for.

A retro-reflective material bounces light back in the direction it came from - and as such only shows the retro-reflective effect when the light source is in line with the camera (e.g. retro-reflective tape, cat’s eyes , bike reflectors etc)


@graffy there are some particularities to some retro-reflective materials that may be a bit difficult to recreate precisely, and others that have a slight angular shift from the incoming and outgoing rays, but generally speaking moony is right on this one.

looks like forum has lost some of the older threads !

search on blender nation forum might find some retro stuff too!

happy cl

That is true, but there is some room in that. The angle between the eye of the observer and the light source, for example, can range as much as a degree before the effect starts to really cut out. Given a distant object, that means a light several feet from the observer could still create the effect.

Also, the reflecting surface could be angled as much as 50 degrees from normal before the retroreflective effect is lost completely - in transportation engineering, this allows for signs which may not be quite facing the driver, but tends to avoid signs that are intended for another direction of travel, for example.

So, really, there are three effects to account for - the angle between the viewer and the light source (which may be fixed, but is not necessarily zero), the angle at which the light source strikes the retroreflective surface (which varies as the light source move), and the rate at which the effect falls off given the light source’s incidence angle on the surface. On the falloff point, 3M’s diamond grade specs suggest it’s generally linear, but it didn’t seem right when I tested it in UDK - a 2nd or 3rd order curve seemed better.

Just thinking a bit more… I don’t suppose I could pass a scalar value in the alpha channel of the light source color and decode that in the retroreflective material? That would probably give me enough information to get it done. I remember doing stuff like that when I was playing with GLSL shaders…

@graffy, but for most of what you’re talking, simply playing with reflections, roughness and normals is enough.

Things that are difficult to implement in cycles when it comes to some retroreflective materials, are dued to secondary phenomena that happens in the structures the materials are made off. Things like diffraction, interference and inversion are the ones that you woun’t find a good solution… anything else it’s quite easy to produce.

And so it is with my shader. The light source doesnt have to be exactly in line with the camera - but the further away it is - the effect diminishes until eventually you get to the stage where you cannot see the effect at all - just like for a real material.

An effect you can also see in my retro-reflective material. The rolls still displays the retro-reflective effect even as the roll normals curve away from the camera. I chose to model the ‘tape’ material on the roll - rather than simply on a flat plane specifically to show exactly this effect.

You can’t simulate the linearity of the falloff since we can’t shape the highlight tail. The only thing you can do is modify the roughness and the model. For stuff like inversion you’d have to model it using opened up 3 faced cubes in an array, no way to accomplish that modifying normals.

Btw, how come we don’t have access to sun light vector? Seems like a natural thing to have.

Since last version Lukas has implemented texture coordinates for lamps - if that is what you mean ?

No. Those coords are anyway only available to the light itself, which of course are very usable for IES and other light texturing stuff. In a regular object material, the only external reference we have are camera data and object coordinates for an external object. I.e. I could change a sun lamps strength and color based on orientation - strong and white overhead suns automatically change into dimmer and redder sunsets - without any messy driver setup. The sky texture is supposed to get an automatic align, probably to a dropdown list of sun lamps, I’d like to see something similar for nodes, as referencing external objects now are limited to object texture coords. Maybe it’s possible to calculate with some vector math magic?

I presume you’re referring to my attempt to create a response curve to control falloff. If so, I didn’t modify normals - I simply calculated the intensity given the incident light vector w.r.t the surface normal. Then, I used a curve to model the falloff. In the end, it was a guess, and it killed the performance of the shader - in other words, it was more effort than it was worth. :slight_smile: But, being an engineer with a professional interest in modelling retroreflective light behavior, I had to try to implement the actual physics as much as I could…

That said, for most, if not all cases, I’d say Moony’s shader is probably more than adequate. It looks really good, IMHO.

FWIW, here’s a link to two videos demo’ing my UDK shader:

(explanation of the shader - Length: 5:56)

(demo highway lane closure with barricades - Length 1:41)

Saw the first video, and noticed those two images about incidence and divergence… Are the materials from 3M so specially anisotropic, or the incident and divergence angles are basically the same?

This is just because most retroreflective materials i’ve seen are isotropic. And the few speciallized anisotropic retroreflectors I encounter in my life were so expensive to make and install that weren’t suitable for most applications.

But even so, anisotropic retroreflection is not difficult, thought it must be mapped (read as: one must define anisotropic directions on the tangent plane).

The incidence angle determines the intensity of light reflected, the divergence angle determines the intensity of light viewed. They’re properties of every retroreflective surface, I think. For example, if the angle of incidence exceeds 50 degrees or so, the retroreflectors cut out - the surface will not reflect the light. if the angle of divergence exceeds maybe two degrees (hard to say, since one degree is the usual maximum), the observer doesn’t get to see the light which is reflected. I guess that’s anisotropic behavior technically, but I wouldn’t consider it as such, because those angles really define what retroreflection is… ?

However, you’ll notice at the end I included the “bias” striping in the sign surface - which indicates to the sign fabricator which way the sheeting has to be oriented to maximize performance. The difference, though, isn’t greatly significant - at least I don’t remember thinking that it was when I explored the issue.

If that’s the case, then for the incidence angle you just need to shift the incident normal in the parallel plane to the road level. The divergence comes for free with the roughness value, and the difference from both can be set by changing the anisotropic value. Note that it’s possible to stack multiple reflections in order to adjust the divergence distribution curve.

And knowing now for what you need the light vector, i can tell this:
In cycles, materials are light independent. They should perform equally in any light conditions, and therefore the user should only define how the distribution occurs. This is very different from materials used in UDK, or other ‘canvas painting’ shaders, where is up to the artist to set the material’s final color.
If you have the specs for the light scattering of the surface, I don’t mind to help you to get the material to look as close as possible to them.