3D surface BRDF plotsΒΆ

This example demonstrates how to make 3D surface plots of sampled material BRDF functions.


import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits import mplot3d

from raysect.core import Point3D, Vector3D
from raysect.optical.library.metal import RoughAluminium


plt.ion()

origin = Point3D(0, 0, 0)

aluminium = RoughAluminium(0.25)

def calculate_brdf_surface(light_vector):

    thetas = np.arange(0, 91, step=5)
    num_thetas = len(thetas)
    phis = np.arange(0, 361, step=10)
    num_phis = len(phis)
    thetas, phis = np.meshgrid(thetas, phis)

    X = np.zeros((num_phis, num_thetas))
    Y = np.zeros((num_phis, num_thetas))
    Z = np.zeros((num_phis, num_thetas))

    for i in range(num_phis):
        for j in range(num_thetas):

            theta = np.deg2rad(thetas[i, j])
            phi = np.deg2rad(phis[i, j])
            outgoing = Vector3D(np.cos(phi)*np.sin(theta), np.sin(phi)*np.sin(theta), np.cos(theta))

            radius = aluminium.bsdf(light_vector, outgoing, 500)
            X[i, j] = radius * np.cos(phi) * np.sin(theta)
            Y[i, j] = radius * np.sin(phi) * np.sin(theta)
            Z[i, j] = radius * np.cos(theta)

    return X, Y, Z


light_angle = 0
light_position = Point3D(np.sin(np.deg2rad(light_angle)), 0, np.cos(np.deg2rad(light_angle)))
light_direction = origin.vector_to(light_position).normalise()
X, Y, Z = calculate_brdf_surface(light_direction)

plt.figure()
ax = plt.axes(projection='3d')
ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap='viridis', edgecolor='none')
ax.set_xlim(-1, 1)
ax.set_ylim(-1, 1)
plt.title("Light angle {} degrees".format(light_angle))


light_angle = -10
light_position = Point3D(np.sin(np.deg2rad(light_angle)), 0, np.cos(np.deg2rad(light_angle)))
light_direction = origin.vector_to(light_position).normalise()
X, Y, Z = calculate_brdf_surface(light_direction)

plt.figure()
ax = plt.axes(projection='3d')
ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap='viridis', edgecolor='none')
ax.set_xlim(-1, 1)
ax.set_ylim(-1, 1)
plt.title("Light angle {} degrees".format(light_angle))


light_angle = -25
light_position = Point3D(np.sin(np.deg2rad(light_angle)), 0, np.cos(np.deg2rad(light_angle)))
light_direction = origin.vector_to(light_position).normalise()
X, Y, Z = calculate_brdf_surface(light_direction)

plt.figure()
ax = plt.axes(projection='3d')
ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap='viridis', edgecolor='none')
ax.set_xlim(-1, 1)
ax.set_ylim(-1, 1)
plt.title("Light angle {} degrees".format(light_angle))


light_angle = -45
light_position = Point3D(np.sin(np.deg2rad(light_angle)), 0, np.cos(np.deg2rad(light_angle)))
light_direction = origin.vector_to(light_position).normalise()
X, Y, Z = calculate_brdf_surface(light_direction)

plt.figure()
ax = plt.axes(projection='3d')
ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap='viridis', edgecolor='none')
ax.set_xlim(-1, 1)
ax.set_ylim(-1, 1)
plt.title("Light angle {} degrees".format(light_angle))

plt.show()
../../_images/brdf_surface3d_plots.png