environment_lighting.html 18.3 KB
Newer Older
allai5's avatar
allai5 committed
1
<!DOCTYPE html> <html lang="en-US"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=Edge"> <title>(Task 7) Environment Lighting - </title> <link rel="shortcut icon" href="/favicon.ico" type="image/x-icon"> <link rel="stylesheet" href="/assets/css/just-the-docs-default.css"> <script type="text/javascript" src="/assets/js/vendor/lunr.min.js"></script> <script type="text/javascript" src="/assets/js/just-the-docs.js"></script> <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- Begin Jekyll SEO tag v2.7.1 --> <title>(Task 7) Environment Lighting</title> <meta name="generator" content="Jekyll v4.2.0" /> <meta property="og:title" content="(Task 7) Environment Lighting" /> <meta property="og:locale" content="en_US" /> <meta name="twitter:card" content="summary" /> <meta property="twitter:title" content="(Task 7) Environment Lighting" /> <script type="application/ld+json"> {"headline":"(Task 7) Environment Lighting","@type":"WebPage","url":"/pathtracer/environment_lighting","@context":"https://schema.org"}</script> <!-- End Jekyll SEO tag --> </head> <body> <svg xmlns="http://www.w3.org/2000/svg" style="display: none;"> <symbol id="svg-link" viewBox="0 0 24 24"> <title>Link</title> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-link"> <path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path> </svg> </symbol> <symbol id="svg-search" viewBox="0 0 24 24"> <title>Search</title> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-search"> <circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line> </svg> </symbol> <symbol id="svg-menu" viewBox="0 0 24 24"> <title>Menu</title> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-menu"> <line x1="3" y1="12" x2="21" y2="12"></line><line x1="3" y1="6" x2="21" y2="6"></line><line x1="3" y1="18" x2="21" y2="18"></line> </svg> </symbol> <symbol id="svg-arrow-right" viewBox="0 0 24 24"> <title>Expand</title> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-chevron-right"> <polyline points="9 18 15 12 9 6"></polyline> </svg> </symbol> <symbol id="svg-doc" viewBox="0 0 24 24"> <title>Document</title> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-file"> <path d="M13 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9z"></path><polyline points="13 2 13 9 20 9"></polyline> </svg> </symbol> </svg> <div class="side-bar"> <div class="site-header"> <a href="/" class="site-title lh-tight"> </a> <a href="#" id="menu-button" class="site-button"> <svg viewBox="0 0 24 24" class="icon"><use xlink:href="#svg-menu"></use></svg> </a> </div> <nav role="navigation" aria-label="Main" id="site-nav" class="site-nav"> <ul class="nav-list"><li class="nav-list-item"><a href="/" class="nav-list-link">Home</a></li><li class="nav-list-item"><a href="/git/" class="nav-list-link">GitHub Setup</a></li><li class="nav-list-item"><a href="/build/" class="nav-list-link">Building Scotty3D</a></li><li class="nav-list-item"><a href="#" class="nav-list-expander"><svg viewBox="0 0 24 24"><use xlink:href="#svg-arrow-right"></use></svg></a><a href="/guide/" class="nav-list-link">User Guide</a><ul class="nav-list "><li class="nav-list-item "><a href="/guide/animate_mode/" class="nav-list-link">Animate</a></li><li class="nav-list-item "><a href="/guide/layout_mode/" class="nav-list-link">Layout</a></li><li class="nav-list-item "><a href="/guide/model_mode/" class="nav-list-link">Model</a></li><li class="nav-list-item "><a href="/guide/render_mode/" class="nav-list-link">Render</a></li><li class="nav-list-item "><a href="/guide/rigging_mode/" class="nav-list-link">Rig</a></li><li class="nav-list-item "><a href="/guide/simulate_mode/" class="nav-list-link">Simulate</a></li></ul></li><li class="nav-list-item"><a href="#" class="nav-list-expander"><svg viewBox="0 0 24 24"><use xlink:href="#svg-arrow-right"></use></svg></a><a href="/meshedit/" class="nav-list-link">A2: MeshEdit</a><ul class="nav-list "><li class="nav-list-item "><a href="/meshedit/halfedge" class="nav-list-link">Halfedge Mesh</a></li><li class="nav-list-item "><a href="#" class="nav-list-expander"><svg viewBox="0 0 24 24"><use xlink:href="#svg-arrow-right"></use></svg></a><a href="/meshedit/local/" class="nav-list-link">Local Operations</a><ul class="nav-list"><li class="nav-list-item "> <a href="/meshedit/local/edge_flip" class="nav-list-link">Edge Flip Tutorial</a> </li><li class="nav-list-item "> <a href="/meshedit/local/bevel/" class="nav-list-link">Bevelling</a> </li></ul></li><li class="nav-list-item "><a href="#" class="nav-list-expander"><svg viewBox="0 0 24 24"><use xlink:href="#svg-arrow-right"></use></svg></a><a href="/meshedit/global/" class="nav-list-link">Global Operations</a><ul class="nav-list"><li class="nav-list-item "> <a href="/meshedit/global/catmull/" class="nav-list-link">Catmull-Clark Subdivision</a> </li><li class="nav-list-item "> <a href="/meshedit/global/remesh/" class="nav-list-link">Isotropic Remeshing</a> </li><li class="nav-list-item "> <a href="/meshedit/global/linear/" class="nav-list-link">Linear Subdivision</a> </li><li class="nav-list-item "> <a href="/meshedit/global/loop/" class="nav-list-link">Loop Subdivision</a> </li><li class="nav-list-item "> <a href="/meshedit/global/simplify/" class="nav-list-link">Simplification</a> </li><li class="nav-list-item "> <a href="/meshedit/global/triangulate/" class="nav-list-link">Triangulation</a> </li></ul></li></ul></li><li class="nav-list-item active"><a href="#" class="nav-list-expander"><svg viewBox="0 0 24 24"><use xlink:href="#svg-arrow-right"></use></svg></a><a href="/pathtracer/" class="nav-list-link">A3: Pathtracer</a><ul class="nav-list "><li class="nav-list-item "><a href="/pathtracer/camera_rays" class="nav-list-link">(Task 1) Camera Rays</a></li><li class="nav-list-item "><a href="#" class="nav-list-expander"><svg viewBox="0 0 24 24"><use xlink:href="#svg-arrow-right"></use></svg></a><a href="/pathtracer/intersecting_objects" class="nav-list-link">(Task 2) Intersections</a><ul class="nav-list"><li class="nav-list-item "> <a href="/pathtracer/ray_triangle_intersection" class="nav-list-link">Ray Triangle Intersection</a> </li><li class="nav-list-item "> <a href="/pathtracer/ray_sphere_intersection" class="nav-list-link">Ray Sphere Intersection</a> </li></ul></li><li class="nav-list-item "><a href="/pathtracer/bounding_volume_hierarchy" class="nav-list-link">(Task 3) BVH</a></li><li class="nav-list-item "><a href="/pathtracer/shadow_rays" class="nav-list-link">(Task 4) Shadow Rays</a></li><li class="nav-list-item "><a href="/pathtracer/path_tracing" class="nav-list-link">(Task 5) Path Tracing</a></li><li class="nav-list-item "><a href="#" class="nav-list-expander"><svg viewBox="0 0 24 24"><use xlink:href="#svg-arrow-right"></use></svg></a><a href="/pathtracer/materials" class="nav-list-link">(Task 6) Materials</a><ul class="nav-list"><li class="nav-list-item "> <a href="/pathtracer/dielectrics_and_transmission" class="nav-list-link">Dielectrics and Transmission</a> </li></ul></li><li class="nav-list-item active"><a href="#" class="nav-list-expander"><svg viewBox="0 0 24 24"><use xlink:href="#svg-arrow-right"></use></svg></a><a href="/pathtracer/environment_lighting" class="nav-list-link active">(Task 7) Environment Lighting</a><ul class="nav-list"><li class="nav-list-item "> <a href="/pathtracer/importance_sampling" class="nav-list-link">Environment Light Importance Sampling</a> </li></ul></li><li class="nav-list-item "><a href="/pathtracer/visualization_of_normals" class="nav-list-link">Visualization of normals</a></li></ul></li><li class="nav-list-item"><a href="#" class="nav-list-expander"><svg viewBox="0 0 24 24"><use xlink:href="#svg-arrow-right"></use></svg></a><a href="/animation/" class="nav-list-link">A4: Animation</a><ul class="nav-list "><li class="nav-list-item "><a href="/animation/splines" class="nav-list-link">Splines</a></li><li class="nav-list-item "><a href="/animation/skeleton_kinematics" class="nav-list-link">Skeleton Kinematics</a></li><li class="nav-list-item "><a href="/animation/skinning" class="nav-list-link">Skinning</a></li><li class="nav-list-item "><a href="/animation/particles" class="nav-list-link">Particles</a></li></ul></li></ul> </nav> <footer class="site-footer"> This site uses <a href="https://github.com/pmarsceill/just-the-docs">Just the Docs</a>, a documentation theme for Jekyll. </footer> </div> <div class="main" id="top"> <div id="main-header" class="main-header"> <div class="search"> <div class="search-input-wrap"> <input type="text" id="search-input" class="search-input" tabindex="0" placeholder="Search " aria-label="Search " autocomplete="off"> <label for="search-input" class="search-label"><svg viewBox="0 0 24 24" class="search-icon"><use xlink:href="#svg-search"></use></svg></label> </div> <div id="search-results" class="search-results"></div> </div> </div> <div id="main-content-wrap" class="main-content-wrap"> <nav aria-label="Breadcrumb" class="breadcrumb-nav"> <ol class="breadcrumb-nav-list"> <li class="breadcrumb-nav-list-item"><a href="/pathtracer/">A3: Pathtracer</a></li> <li class="breadcrumb-nav-list-item"><span>(Task 7) Environment Lighting</span></li> </ol> </nav> <div id="main-content" class="main-content" role="main"> <h1 id="task-7-environment-lighting"> <a href="#task-7-environment-lighting" class="anchor-heading" aria-labelledby="task-7-environment-lighting"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> (Task 7) Environment Lighting </h1> <p>The final task of this assignment will be to implement a new type of light source: an infinite environment light. An environment light is a light that supplies incident radiance (really, the light intensity dPhi/dOmega) from all directions on the sphere. Rather than using a predefined collection of explicit lights, an environment light is a capture of the actual incoming light from some real-world scene; rendering using environment lighting can be quite striking.</p> <p>The intensity of incoming light from each direction is defined by a texture map parameterized by phi and theta, as shown below.</p> <p><img src="envmap_figure.jpg" alt="envmap_figure" /></p> <p>In this task you need to implement the <code class="language-plaintext highlighter-rouge">Env_Map::sample</code> and <code class="language-plaintext highlighter-rouge">Env_Map::sample_direction</code> method in <code class="language-plaintext highlighter-rouge">student/env_light.cpp</code>. You’ll start with uniform direction sampling to get things working, and then move to a more advanced implementation that uses <strong>importance sampling</strong> to significantly reduce variance in rendered images.</p> <h2 id="step-1-uniform-sampling"> <a href="#step-1-uniform-sampling" class="anchor-heading" aria-labelledby="step-1-uniform-sampling"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Step 1: Uniform sampling </h2> <p>To get things working, your first implementation of <code class="language-plaintext highlighter-rouge">Env_Map::sample</code> will be quite simple. You should generate a random direction on the sphere (<strong>with uniform (1/4pi) probability with respect to solid angle</strong>), convert this direction to coordinates (phi, theta) and then look up the appropriate radiance value in the texture map using <strong>bilinear interpolation</strong> (note: we recommend you begin with bilinear interpolation to keep things simple.)</p> <p>Since high dynamic range environment maps can be large files, we have not included them in the starter code repo. You can download a set of environment maps from this <a href="http://15462.courses.cs.cmu.edu/fall2015content/misc/asst3_images/asst3_exr_archive.zip">link</a>. You can designate rendering to use a particular environment map from the GUI: go to <code class="language-plaintext highlighter-rouge">layout</code> -&gt; <code class="language-plaintext highlighter-rouge">new light</code> -&gt; <code class="language-plaintext highlighter-rouge">environment map</code>-&gt; <code class="language-plaintext highlighter-rouge">add</code>, and then select one of the environment maps that you have just downloaded.</p> <p><img src="envmap_gui.png" alt="envmap_gui" /></p> <p>For more HDRIs for creative environment maps, check out <a href="https://hdrihaven.com/">HDRIHAVEN</a></p> <p><strong>Tips:</strong></p> <ul> <li>You must write your own code to uniformly sample the sphere.</li> <li>check out the interface of <code class="language-plaintext highlighter-rouge">Env_Map</code> in <code class="language-plaintext highlighter-rouge">rays/env_light.h</code>. For <code class="language-plaintext highlighter-rouge">Env_Map</code>, the <code class="language-plaintext highlighter-rouge">image</code> field is the actual map being represented as a <code class="language-plaintext highlighter-rouge">HDR_Image</code>, which contains the pixels of the environment map and size of the environment texture. The interface for <code class="language-plaintext highlighter-rouge">HDR_Image</code> is in <code class="language-plaintext highlighter-rouge">util/hdr_image.h</code>.</li> </ul> <h2 id="step-2-importance-sampling-the-environment-map"> <a href="#step-2-importance-sampling-the-environment-map" class="anchor-heading" aria-labelledby="step-2-importance-sampling-the-environment-map"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Step 2: Importance sampling the environment map </h2> <p>Much like light in the real world, most of the energy provided by an environment light source is concentrated in the directions toward bright light sources. <strong>Therefore, it makes sense to bias selection of sampled directions towards the directions for which incoming radiance is the greatest.</strong> In this final task you will implement an importance sampling scheme for environment lights. For environment lights with large variation in incoming light intensities, good importance sampling will significantly improve the quality of renderings.</p> <p>The basic idea is that you will assign a probability to each pixel in the environment map based on the total flux passing through the solid angle it represents.</p> <p>A pixel with coordinate <img src="environment_eq1.png" width="45" /> subtends an area <img src="environment_eq2.png" width="80" /> on the unit sphere (where <img src="environment_eq3.png" width="20" /> and <img src="environment_eq4.png" width="20" /> the angles subtended by each pixel – as determined by the resolution of the texture). Thus, the flux through a pixel is proportional to <img src="environment_eq5.png" width="45" />. (We only care about the relative flux through each pixel to create a distribution.)</p> <p><strong>Summing the fluxes for all pixels, then normalizing the values so that they sum to one, yields a discrete probability distribution for picking a pixel based on flux through its corresponding solid angle on the sphere.</strong></p> <p>The question is now how to sample from this 2D discrete probability distribution. We recommend the following process which reduces the problem to drawing samples from two 1D distributions, each time using the inversion method discussed in class:</p> <ul> <li> <p>Given <img src="environment_eq6.png" width="45" /> the probability distribution for all pixels, compute the marginal probability distribution <img src="environment_eq7.png" width="100" /> for selecting a value from each row of pixels.</p> </li> <li> <p>Given for any pixel, compute the conditional probability <img src="environment_eq8.png" width="100" />.</p> </li> </ul> <p>Given the marginal distribution for <img src="environment_eq9.png" width="10" /> and the conditional distributions <img src="environment_eq10.png" width="45" /> for environment map rows, it is easy to select a pixel as follows:</p> <ol> <li>Use the inversion method to first select a “row” of the environment map according to <img src="environment_eq11.png" width="35" />.</li> <li>Given this row, use the inversion method to select a pixel in the row according to <img src="environment_eq12.png" width="45" />.</li> </ol> <p><strong>Here are a few tips:</strong></p> <ul> <li>When computing areas corresponding to a pixel, use the value of theta at the pixel centers.</li> <li>We recommend precomputing the joint distributions p(phi, theta) and marginal distributions p(theta) in the constructor of <code class="language-plaintext highlighter-rouge">Sampler::Sphere::Image</code> and storing the resulting values in fields <code class="language-plaintext highlighter-rouge">pdf</code>. See <code class="language-plaintext highlighter-rouge">rays/sampler.h</code>.</li> <li><code class="language-plaintext highlighter-rouge">Spectrum::luma()</code> returns the luminance (brightness) of a Spectrum. The probability of a pixel should be proportional to the product of its luminance and the solid angle it subtends.</li> <li><code class="language-plaintext highlighter-rouge">std::lower_bound</code> is your friend. Documentation is <a href="https://en.cppreference.com/w/cpp/algorithm/lower_bound">here</a>.</li> </ul> <h2 id="sample-results-for-importance-sampling"> <a href="#sample-results-for-importance-sampling" class="anchor-heading" aria-labelledby="sample-results-for-importance-sampling"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Sample results for importance sampling: </h2> <p>ennis.exr with 32 spp</p> <p><img src="new_results/ennis32importance.png" alt="ennis" /></p> <p>uffiz.exr with 32 spp</p> <p><img src="new_results/uffiz32importance.png" alt="uffiz" /></p> <p>field.exr with 1024 spp</p> <p><img src="new_results/field1024importance.png" alt="ennis" /></p> </div> </div> <div class="search-overlay"></div> </div> </body> </html>