Wolfram Research

Function Repository Resource:

ImageRayTraceBump (1.0.0) current version: 1.1.0 »

Source Notebook

Add bump and highlights to an image with ray tracing

Contributed by: Mark Greenberg

ResourceFunction["ImageRayTraceBump"][img]

uses ray tracing to simulate bump shading and specular highlights based on the brightness channel of img.

ResourceFunction["ImageRayTraceBump"][img1,img2]

simulates bump shading and specular highlights in img1 based on the brightness channel of img2.

Details and Options

ResourceFunction["ImageRayTraceBump"] locates the camera at the center of img (or img1) 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 img2).
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"10how 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"5how reflective the surface of img appears to be

Examples

Basic Examples (2) 

Add bump to an image:

In[1]:=
(* Evaluate this cell to get the example input *) CloudGet["https://www.wolframcloud.com/obj/02f6cf79-7001-4017-a6d2-cf7d97fc8618"]
Out[1]=

Add bump from one image to another:

In[2]:=
(* Evaluate this cell to get the example input *) CloudGet["https://www.wolframcloud.com/obj/e72fa38b-69af-4188-a536-9b2bfa3c149d"]
Out[2]=

Scope (2) 

In ImageRayTraceBump[img1,img2], the two images need not be the same size. If either dimension of img2 is smaller than that of img1, it reflects and tiles:

In[3]:=
(* Evaluate this cell to get the example input *) CloudGet["https://www.wolframcloud.com/obj/908de4b9-1c06-498a-9d71-67f61354cba1"]
Out[3]=

If a dimension of img2 is larger, it covers img1 starting in the top left corner:

In[4]:=
(* Evaluate this cell to get the example input *) CloudGet["https://www.wolframcloud.com/obj/e5d561e1-7461-4340-aa7a-a07036fa06e8"]
Out[4]=

Options (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]:=
(* Evaluate this cell to get the example input *) CloudGet["https://www.wolframcloud.com/obj/c1a08eac-bcba-4a05-a036-6bf862313093"]
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]:=
(* Evaluate this cell to get the example input *) CloudGet["https://www.wolframcloud.com/obj/268b068b-be08-461d-aa6d-fb948a9b46cf"]
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]:=
(* Evaluate this cell to get the example input *) CloudGet["https://www.wolframcloud.com/obj/466c4d83-ce90-4047-b2d3-c6a213e55477"]
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]:=
(* Evaluate this cell to get the example input *) CloudGet["https://www.wolframcloud.com/obj/c6c59cba-9ec5-42ac-8c4b-64b9324af453"]
Out[8]=

Applications (2) 

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

In[9]:=
(* Evaluate this cell to get the example input *) CloudGet["https://www.wolframcloud.com/obj/673d5d9a-9fe8-4bb0-8498-d5f1c3179dfc"]
Out[9]=

Use ImageRayTraceBump as an artistic filter:

In[10]:=
(* Evaluate this cell to get the example input *) CloudGet["https://www.wolframcloud.com/obj/46c2a811-3ad1-4dd2-b47d-a035e2fb661a"]
Out[10]=

Neat Examples (2) 

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

In[11]:=
(* Evaluate this cell to get the example input *) CloudGet["https://www.wolframcloud.com/obj/2ae434cd-9c41-42e5-9007-12a6f89b643b"]
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]:=
(* Evaluate this cell to get the example input *) CloudGet["https://www.wolframcloud.com/obj/e25bd2ed-4d50-455c-9180-b5f2b2099814"]
Out[12]=

Publisher

Mark Greenberg

Version History

  • 1.1.0 – 30 October 2023
  • 1.0.0 – 21 May 2020

Related Resources

Author Notes

A similar but simpler effect to ImageRayTraceBump[img] can be achieved with the built-in symbol ImageEffect[img,{"Embossing",x,a}]. A function in the Wolfram Function Repository called ImageBump also provides similar functionality through filtering. The ray tracing of ImageRayTraceBump allows for more control of the finished image and the addition of specular highlights.
ImageRayTraceBump tends to darken some images, so post-processing might be needed to achieve the desired output.
The output of ImageRayTraceBump can be grainy at times. If this happens, try enlarging img first, then applying ImageRayTraceBump, and finally shrinking the output back to original size.
A reflection point exists halfway between the (x,y)-coordinates of the light and the center of the image. If the light is too close to the image, a glare will wash out part of the bump effect and distort the colors. The solution to this is to move the light further from {0,0} in the image plane.
Ray tracing is slow; be patient. ImageRayTraceBump does work on larger images. I tested it on images up to 10,000 pixels square, and it works as expected. However, larger images can take several hours to render.
Ray tracing is a technique used in other visual effects not included in ImageRayTraceBump. Refraction, reflection, and radiosity pertain more to scenes with multiple 3D objects. Self-shadowing and ambient occlusion could possibly be added to the effects simulated in ImageRayTraceBump. They would slow down the function considerably and add only slight benefit.

License Information