Wednesday, May 8, 2013

UDK Custom Lighting Model Materials (diffuse/specular reflectance)

This is a collection of diffuse and specular reflectance models rebuilt in the material editor. To keep things easy to follow I'm using default material nodes if possible. There are just a few custom HLSL nodes for those functions that would not be available otherwise, or more expensive.
Please note that I did use constant vectors instead of texture samplers.

Download samples:

I won't go into the basics of custom lighting materials or BDRF's (bidirectional reflectance distribution function), so this is worth a read:

As a reference, here's UDKs default Phong lighting rebuilt as a custom material. Despite its name Phong does only refer to the specular reflectance which is added to the Lambert diffuse term. This same combination of diffuse and specular components (simple add) does apply to the majority of BDRF models.

Blinn Specular
- easy to compute
- elongated specular highlights
- useful for oceans, wet streets

Schlick Specular
- easy to compute
- uses no specular power but a specular multipler
- uniform, less shiny specular highlights

Ward Specular (isotropic)
- slightly advanced model
- more physically accurate than phong
- specular highlight is controled by a roughness parameter (0.00001 - 1 range)
- low roughness results in small and strong specular highlights

Ward Specular (anisotropic)
- anisotropic version of the simple ward model
- required for specific things like hair rendering or brushed metal
- handles anisotropic direction maps
- roughness parameter is a constant2vector,
makes it possible to control the specular highlights x and y dimensions independantly

Cook-Torrance Specular
- advanced model
- designed for metal surfaces
- comprises a fresnel term,
which is controled by the y component of the roughness parameter

Minnaert Diffuse
- easy to compute
- best suited for velvet materials
- view dependant diffuse highlight

Oren-Nayar Diffuse
- advanced model
- designed for rough surfaces
- handels inter-reflections
- roughness=0 equals to default lambert diffuse
- does not require a custom material


  1. Hey dude! Thanks so much for making these breakdowns. They really help a ton.

  2. Thank you very much this has helped a lot, really appreciate it :)

    I've had a go at creating the ward specular model but the result wasn't the same as yours I've followed your setup exactly but I seem to be getting a different specular and a harsh black shadow :S

    Here's a a screenshot...

    Any Ideas?

    Help is greatly appreciated. Thanks


    1. Hi,
      most likely there is a constant clamp missing somewhere (my fault). Causing some values to be <0 and therefore turning the mesh black once you add the specular term to the diffuse. Maybe somewhere on the upper group of nodes including 1/sqrt(dot(N.L)*dot(E.N)). That is guessing from looking at the screenshots, I'd have to check the material in UDK for a precise answer.
      Let me know if you need further help.

    2. I was testing out the ward specular as well, and I was confused with the start of it. Playing aroudn with it in UE4 though, but at the start of the graph the cross product of 0,1,0 & 0,0,1 looks incorrect in your picture? Am I missing something? Shouldn't that equal 1,0,0

  3. Is there some way to create a colorized shading model, for instance the part where light doesn't reach are red, while the other parts are either uncolored or some other color? (To be used as a cheat instead of SSS.) Thanks