I'm working on a live wallpaper that shows a pure metallic object. Since it's a live wallpaper, I can make a ton of approximations...this isn't a full blown scene in a game world. My shader only has to support this one material. People won't expect extreme detail, etc. So, for example, I don't even bother with diffuse since a pure conductive material barely has any.

So I'm trying to implement a reflective conductive surface that pulls the reflection from a cubemap representing the lighting environment. On a very basic level it looks like this:

vec3 fresnelSchlick (vec3 f0, float cosTheta)
    return mix(f0, vec3(1.0), pow(1.0 - cosTheta, 5.0));

float NdV = dot(normal, viewDir);
vec2 brdf = texture2D(u_brdf, vec2(u_roughness, NdV)).rg; // from a LUT

vec3 reflection = textureCube(u_cubemap, reflect(viewDir, normal));
gl_FragColor = reflection * (fresnelSchlick(materialColor, NdV) * brdf.x + brdf.y);

The problem with my simple math here is that the range of possible final pixel colors does not produce a proper-looking range of hues. Suppose my material color is #0050ff and the environment is monochrome white. Then all of the possible colors that could be seen are:

enter image description here

This doesn't allow for bright looking reflections at the light sources in the envmap. I found this example material render for comparison. The cubemap in the example here is close to monochrome white. But at the bright areas of the reflection, there is a lot of red component in the color.

With my limited range of colors, my object looks dull and lifeless. Can anyone point out what I'm missing in my equation?

enter image description here


1 Answer 1


This is a dirty little secret for metallic lighting: it's all about the reflections. Every good looking metallic render is actually reflecting from a complex environment. This goes for other reflective materials too, like glass and water.

reflective spheres

From http://www.pauldebevec.com/Probes/

Take for example the above scene. The reflective spheres all use the same environment map (shown inset above-left), which is a room with natural lighting coming through large windows, which can be plainly seen in the reflections. The environment can be most clearly seen in the fully-reflective sphere in the back.

This makes sense if you think about it; a perfectly reflective object would have its appearance almost entirely determined by its environment (and its shape). So of course, if you have a simple, monochrome environment, your reflective object will look similarly boring.

This is why most reflective materials are showcased in a certain environment. It could be an outdoor or indoor scene or an artificial one but with distinctive lighting sources.

  • \$\begingroup\$ That partially gets me there, but I feel like there is something missing in my shader equations. With my above shader and specular color, no matter how fancy the envmap is, there will never be any red content whatsoever in the render, unlike the example pic I showed. In that example, the specular color supposedly has no red component, but the highlights are whiter than cyan...There is red in the render. \$\endgroup\$
    – TenFour04
    Aug 28, 2017 at 5:20
  • \$\begingroup\$ @TenFour04 I see; I misunderstood your example and thought that it was yours. I think they are using a HDR environment map where values can be above 100%, that's how they're getting very bright highlights. \$\endgroup\$ Aug 28, 2017 at 5:48
  • \$\begingroup\$ Gotcha. But even then there is something wrong with my math. Suppose I simulate an HDR envmap by adding *16 to my reflection line. The 0 in the R channel of the specular color will still zero out the final value. \$\endgroup\$
    – TenFour04
    Aug 28, 2017 at 19:04
  • \$\begingroup\$ @TenFour04 You don't want no red, you want no more red than blue. There's a key difference. \$\endgroup\$ Dec 8, 2017 at 17:02

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .