# Wolfram Function Repository

Instant-use add-on functions for the Wolfram Language

Function Repository Resource:

Add bump and highlights to an image with ray tracing

Contributed by:
Mark Greenberg

ResourceFunction["ImageRayTraceBump"][ uses ray tracing to simulate bump shading and specular highlights based on the brightness channel of | |

ResourceFunction["ImageRayTraceBump"][ simulates bump shading and specular highlights in |

ResourceFunction["ImageRayTraceBump"] locates the camera at the center of *img* (or *img*_{1}) at a height equal to half of the largest pixel dimension.

ResourceFunction["ImageRayTraceBump"] determines the height of each pixel based on the brightness channel of *img* (or *img*_{2}).

ResourceFunction["ImageRayTraceBump"] calculates the surface normal of each pixel from four triangles formed by its eight neighbors:

ResourceFunction["ImageRayTraceBump"] can take the following options:

"BumpHeight" | 10 | how high the bump appears to be |

"LightPosition" | {-2,2,1} | where the light appears to be coming from |

"LightType" | "Directional" | what kind of light is shining on img |

"Shininess" | 5 | how reflective the surface of img appears to be |

Add bump to an image:

In[1]:= |

Out[1]= |

Add bump from one image to another:

In[2]:= |

Out[2]= |

In ImageRayTraceBump[*img*_{1},*img*_{2}], the two images need not be the same size. If either dimension of *img*_{2} is smaller than that of *img*_{1}, it reflects and tiles:

In[3]:= |

Out[3]= |

If a dimension of *img*_{2} is larger, it covers *img*_{1} starting in the top left corner:

In[4]:= |

Out[4]= |

The option "BumpHeight" sets the apparent height or depth of the apparent terrain. Negative values invert the bump. Practical settings are -20 ≤ *n* ≤ 20 where *n* is a real number. The effect of "BumpHeight" is more noticeable when the "LightType" is set to "Point":

In[5]:= |

Out[5]= |

The "LightPosition" option determines where the light appears to be coming from. {0,0,0} is at the center of the image. {1,1,1} is the upper-left corner of the image at a height of 0.5*Min[ImageDimensions[*img*]]. Directional light follows the vector from the "LightPosition" to {0,0,0}. In this model, the light does not attenuate. If you get an unwanted glare, try moving the light further from the center of *img*:

In[6]:= |

Out[6]= |

The "LightType" option determines whether the source is a point of light emanating from the "LightPosition" or directional light with parallel rays like sunlight. Directional light is parallel to the ray from the "LightPosition" to the center of the image. The difference between directional light and point light can be subtle or dramatic depending on the situation:

In[7]:= |

Out[7]= |

The "Shininess" option gives the amount of specularity. Higher values produce sharper highlights making the surface appear smooth or wet. Practical setting values are 1 ≤ *n* ≤ 10 where *n* is a real number:

In[8]:= |

Out[8]= |

Give a photo, like this of an elephant's hide, a subtle 3D realism:

In[9]:= |

Out[9]= |

Use ImageRayTraceBump as an artistic filter:

In[10]:= |

Out[10]= |

Combine two procedural images (here, a density plot and a graphic of overlapping polygons) to create snakeskin:

In[11]:= |

Out[11]= |

Make an animation to highlight the 3D nature of the new output. Warning, this example can take a very long time to evaluate:

In[12]:= |

Out[12]= |

- 1.0.0 – 21 May 2020

This work is licensed under a Creative Commons Attribution 4.0 International License