Here I have a sphere in Blender Internal using the Reflection coordinate mapping.

classic Blender reflection mapping

The important characteristics of this are:

  • The center of the image is where the surface normal points directly at the camera.
  • There are four "poles" that correspond to the top-middle, bottom-middle, left-middle, and right-middle of the image. No matter the perspective, all four are always visible, and always match the same four points on the image.

I am trying to replicate this in the non-Internal engines. Luckily, I found the source code for how Internal did it, which is basically $ref = (normal \cdot view) \times normal + view$. So I came up with this:

attempt at copying the classic (nodes)

(The result of this goes directly into the texture node.)

attempt at copying the classic (result)

This is certainly progress: the four poles are visible in about the right places, at least. However, the problems are clear, and after trying a bunch of things I can't get past them:

  • The bottom-right corner of the image is where the center should be. I can't seem to get the center in there without breaking the appearance at some other angle (usually backside angles).
  • The poles are not equal to the edge of the image. In fact, they seem to be completely unbound, changing freely with perspective. The center goes with them and can easily be made to scroll completely off the surface.

A lesser problem is that it seems to be completely nonfunctional in orthographic view, in contrast to the Internal version which looks exactly the same. Rendering with an actual camera rather than just the viewport seems to be slightly better, but still pretty far off.

orthographic view


1 Answer 1


The source code is actually doing (note the factor -2)

$$\mathrm{refl} = \mathrm{view} - 2 (\mathrm{view} \cdot \mathrm{normal})\mathrm{normal}$$

which is the reflection of the view vector across the normal. The vector math node has a "Reflect" option that can do this for us.

Since the Blender internal reflection looks basically the same from any direction, it's probably doing this in camera space. So we'll try:

(Btw if you do this in world space instead, you get the same thing as the "Reflection" output of the Texture Coordinate node.)

This looks good, but it's going across the texture twice. The reflected vector components range from -1 to 1, while to go across the texture once we want to go from 0 to 1. We can remap [-1, 1] onto [0, 1] with $x\mapsto 0.5x+0.5$; let's put that on a Mapping node in between the reflection and the texture:

That looks pretty good to me. It still doesn't work the same in ortho mode though.

edit: Here's a version that works in ortho mode. The Geometry node's Incoming socket seems to be better behaved in ortho mode than the Camera Data's View Vector.

Note that the scale factors have picked up a negative sign.

  • $\begingroup$ I guess that's on me for seeing the "dot [product]" comment and not thinking the -2 was suspicious. I did try this mapping but must've not recognised it as correct because the rest was wrong. I'll leave this for a few days to see if someone has an idea for the ortho problem, then accept. $\endgroup$ Oct 20, 2022 at 21:01
  • $\begingroup$ The Geometry's node's Incoming socket seems to work in ortho mode, so you can use that instead. See the edit. $\endgroup$
    – scurest
    Oct 20, 2022 at 21:42
  • $\begingroup$ Excellent. Must be some quirk of the camera data node. $\endgroup$ Oct 20, 2022 at 22:40

You must log in to answer this question.

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