<jupyter_start><jupyter_text>This tutorial focuses on the fast local shading mode of redner. This mode does not compute shadow or global illumination, but is faster and less noisy. Again, we will import pyredner and tensorflow, download the teapot object, load it, and setup the camera.<jupyter_code>!pip install --upgrade redner-gpu
# Tensorflow by default allocates all GPU memory, leaving very little for rendering.
# We set the environment variable TF_FORCE_GPU_ALLOW_GROWTH to true to enforce on demand
# memory allocation to reduce page faults.
import os
os.environ['TF_FORCE_GPU_ALLOW_GROWTH'] = 'true'
%tensorflow_version 2.x
import tensorflow as tf
tf.compat.v1.enable_eager_execution() # redner only supports eager mode
import pyredner_tensorflow as pyredner
import urllib
import zipfile
# wget
filedata = urllib.request.urlretrieve('https://casual-effects.com/g3d/data10/common/model/teapot/teapot.zip', 'teapot.zip')
# unzip
zip_ref = zipfile.ZipFile('teapot.zip', 'r')
zip_ref.extractall('teapot/')
objects = pyredner.load_obj('teapot/teapot.obj', return_objects=True)
camera = pyredner.automatic_camera_placement(objects, resolution=(480, 640))
scene = pyredner.Scene(camera = camera, objects = objects)<jupyter_output><empty_output><jupyter_text>Now, in contrast to the previous tutorials, we also setup some lightings. In the fast local shading mode, redner supports four kinds of lights: ambient light, point light, directional light, and spot light. We setup a point light with squared distance falloff at between the camera and the teapot this time.<jupyter_code>light = pyredner.PointLight(position = camera.position + tf.constant((0.0, 0.0, 100.0)),
                                                intensity = tf.constant((20000.0, 30000.0, 20000.0)))
img = pyredner.render_deferred(scene = scene, lights = [light])
# Visualize img
from matplotlib.pyplot import imshow
%matplotlib inline
imshow(tf.pow(img, 1.0/2.2))<jupyter_output>Scene construction, time: 21.46748 s
Forward pass, time: 0.08253 s<jupyter_text>You may notice that the teapot rendering has some weird stripe patterns. This is because the teapot has a low number of polygons, and the normals used to calculate the Lambertian response introduces the pattern to rendering. A remedy for this is to use [Phong normal interpolation](https://en.wikipedia.org/wiki/Phong_shading): we compute a normal field at each vertex on the triangle mesh, and interpolate from the nearby vertices when computing the shading normal. Many Wavefront object files come with vertex normals, but this teapot does not. Redner implements [Nelson Max's algorithm](https://escholarship.org/content/qt7657d8h3/qt7657d8h3.pdf?t=ptt283) for computing the vertex normal. We can attach vertex normals as follows:<jupyter_code>for obj in objects:
    obj.normals = pyredner.compute_vertex_normal(obj.vertices, obj.indices)<jupyter_output><empty_output><jupyter_text>Re-render the scene, we get a smoother teapot:<jupyter_code>scene = pyredner.Scene(camera = camera, objects = objects)
img = pyredner.render_deferred(scene = scene, lights = [light])
imshow(tf.pow(img, 1.0/2.2))<jupyter_output>Scene construction, time: 0.00882 s
Forward pass, time: 0.08277 s<jupyter_text>Apart from point lights, redner also supports ambient light, which is just a multiplier over the albedo values.<jupyter_code>light = pyredner.AmbientLight(intensity = tf.constant((0.8, 1.2, 0.8)))
img = pyredner.render_deferred(scene = scene, lights = [light])
imshow(tf.pow(img, 1.0/2.2))<jupyter_output>Scene construction, time: 0.00929 s
Forward pass, time: 0.08020 s<jupyter_text>Directional lights doesn't exhibit distance falloff:<jupyter_code>light = pyredner.DirectionalLight(direction = tf.constant((1.0, -1.0, 1.0)),
                                                         intensity = tf.constant((2.0, 3.0, 2.0)))
img = pyredner.render_deferred(scene = scene, lights = [light])
imshow(tf.pow(img, 1.0/2.2))<jupyter_output>Scene construction, time: 0.00961 s
Forward pass, time: 0.08078 s<jupyter_text>And spot light is a directional light with exponential falloff over a direction.<jupyter_code>light = pyredner.SpotLight(position = camera.position,
                                               spot_direction = tf.constant((0.0, 0.0, 1.0)),
                                               spot_exponent = tf.constant(100.0),
                                               intensity = tf.constant((2.0, 3.0, 2.0)))
img = pyredner.render_deferred(scene = scene, lights = [light])
imshow(tf.pow(img, 1.0/2.2))<jupyter_output>Scene construction, time: 0.00929 s
Forward pass, time: 0.08456 s<jupyter_text>If you want to adapt the deferred shading functionality, such as using materials other than Lambertian, you can write the shading code yourself in TensorFlow. redner provides the `render_g_buffer` function to output different channels for you:<jupyter_code>img = pyredner.render_g_buffer(scene = scene, channels = [pyredner.channels.position,
                                                                                                         pyredner.channels.shading_normal,
                                                                                                         pyredner.channels.diffuse_reflectance])
pos = img[:, :, :3]
normal = img[:, :, 3:6]
albedo = img[:, :, 6:9]
import matplotlib.pyplot as plt
plt.figure()
pos_vis = (pos - tf.reduce_min(pos)) / (tf.reduce_max(pos) - tf.reduce_min(pos))
imshow(pos_vis)
plt.figure()
normal_vis = (normal - tf.reduce_min(normal)) / (tf.reduce_max(normal) - tf.reduce_min(normal))
imshow(normal_vis)
plt.figure()
imshow(tf.pow(albedo, 1.0/2.2))<jupyter_output>Scene construction, time: 0.04302 s
Forward pass, time: 0.02625 s
{'fraction_non_alphanumeric': 0.09897015185896317, 'fraction_numerical': 0.03281550008727527, 'mean_word_length': 3.7160493827160495, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 27, 'https://': 3, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 21, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '8', 'dir': 'jupyter-structured-clean-dedup', 'id': '172889', 'license': 'MIT', 'n_tokens_mistral': 1866, 'n_tokens_neox': 1733, 'n_words': 522, 'path': 'tutorials/fast_local_shading_tensorflow.ipynb', 'repo_name': 'sgrabli/redner', 'size': '5729'}