For the proposal, click here.
For the milestone, click here.
Narrated Final Project Summary Video.
Thin film interference seen in soap-bubbles is a time-variant process. Environmental forces like wind or gravity generate velocity fields in the bubble's membrane causing its thickness to vary spatially and temporally. As a result, in nature we often see a splendor of chromatic patterns evolving over a fluid surface.
Inspired by such beauty, we were interested in marrying fluid dynamics with thin film interference to render a simulation of this phenomenon. Here we implement a standalone fluid simulator on a spherical manifold and embed thin film interference functionality directly into the Project 3 Pathtracer codebase by creating a specialized BSDF. How these two elements connect is straightforward. At a high-level, our fluid simulator propagates a scalar quantity along a perscribed velocity vector field defined on the surface of the sphere. We interpret this scalar quantity as the thickness of the film at each point on the spherical bubble surface. As we render each frame, the pathtracer queries a thickness map at the point corresponding to the ray intersection location on the bubble. Using the thickness, the effect of interference for each RGB color channel can be calculated and conveyed to the ray. We demonstrate videos for two different refractive media comprising the bubble: an oily media and a soapy media.
The Navier-Stokes equations for incompressible fluids are a system of PDEs that describe the rate of change of a fluid's velocity vector field \( \mathbf{u} \).
\begin{equation} \tag{1} \label{eq: NS1_vec} \frac{\partial{\mathbf{u}}}{\partial{t}} = -\mathbf{u} \cdot \nabla \mathbf{u} + \nu \nabla^2\mathbf{u} + \mathbf{f} \end{equation} \begin{equation} \tag{2} \label{eq: NS2_vec} \nabla \cdot \mathbf{u} = 0 \end{equation}where \( \nu = \frac{\mu}{\rho_0} \) is the kinematic fluid viscosity, \( \nabla^2 \mathbf{u} \) is the vector laplacian, and \( \mathbf{f} \) is a general force vector field encapsulating both internal and body forces. Generally, \( \mathbf{f} = -\nabla p + \mathbf{f_{ext}} \) where \( \nabla p \) is the density-normalized pressure gradient within the fluid and \( \mathbf{f_{ext}} \) is a density-normalized external force like gravity (e.g. \( \mathbf{f_{ext}} = \mathbf{g} \) ). Density-normalized simply means we've divided out both sides of equation by the fluid density \( \rho_0 \) so that the units are compatible. (Navier-Stokes Wiki). Equation 2 is simply a statement about the incompressibility of the fluid.
In practice, to visualize flow we need to consider the motion of a separate substance within the fluid like smoke or ink. The important feature of this substance is its density in every region of the fluid. This important scalar quantity is transported by the fluid velocity field and diffusion. Its evolution is characterized through Equation 3 below (note the symmetry between equations 1 and 3).
\begin{equation} \tag{3} \label{eq: NS1_scal} \frac{\partial{\Psi}}{\partial{t}} = -\mathbf{u} \cdot \nabla\Psi + \nu \nabla^2\Psi + s \end{equation}Note that the example of density transport is a tautology for the transport of any scalar field. For the purposes of our project, we consider the scalar field to be a thickness map for a thin film object. In other words, we consider the transport of "thickness" within the bubble membrane.
Following [1] we implemented a basic planar fluid simulator with various boundary conditions.
Karman Vortex Sheets!
Kelvin-Helmholtz Instability!
Wrapped boundary conditions!
We implement this by maintaining both a scalar density field and a vector velocity field. Both are updated with a diffusion and advection solver. Diffsion is simulated by solving the poisson equation with gauss-seidel and advection is simulated by backtracing. In addition, at every step we ensure the incompressibility constraint by "projecting" the velocity field \( \mathbf{v} \). We do this by taking advantage of the Helmholtz decomposition, which states that any vector field (under sufficient conditions) can be written as the sum of a solenoidal (divergence-less) field and a conservative (curl-less) field:
\begin{equation} \mathbf{F} = -\nabla \Phi + \nabla \times \mathbf{A} \end{equation}where \(\mathbf{A}\) is the vector potential and \(\Phi\) is the scalar potential. Applying the divergence operator to both sides and using the fact that the divergence of a solenoidal field is 0 we have
\begin{equation} \nabla \cdot \mathbf{F} = -\nabla^2 \Phi \end{equation}This gives us a poisson equation that we can again solve using gauss-seidel, giving us the scalar potential. Subtracting off the gradient of this potential gives us the desired solenoidal projection. Different boundary conditions can be implemented by modifying the gauss-seidel solvers and the backtracing step.
To simulate fluids on a sphere we took two approaches. The first approach involved simply warping the results of a planar simulator on to a sphere. In the second approach we build a native spherical fluid simulator.
The first approach is easy, but doesn't produce good results near the poles (or wherever the singularity of the warping transform is). We use a simple longitude-latitude map and get the following result.
Projective texture map to sphere
Notice here we specifically use a fluid flow that vanishes near the poles
The second approach involves natively simulating the fluid on a sphere. This requires numerically solving the Navier-Stokes PDEs in spherical coordinates. To do this we used the Chebfun library in Matlab. The library is fairly stable (depending on the discretization) so we avoid problems with singularities at the poles. Our implementation yielded the following results:
Native Spherical Fluid Simulator.
Finally, in order to feed these simulations to the ray tracer we embed the density field for each frame into a .DAE file template and save to disk. This .DAE file is later read by the pathtracer when constructing the thin film BSDF objects (See DAE File Guide for details).
Thin film interference is fundamentally a result of the wave-like nature of light. Light incident on a transmissive thin film surface undergoes both reflection and refraction. The refracted portion has an additional opportunity to reflect at the second interface of the thin film. The phase difference between these two reflections induces either constructive or destructive interference. The fractional intensities of the total transmitted and reflected light for given wavelength are defined as:
\begin{equation} \tag{7} \label{eq: I_T and I_R} I_T = 1 - I_R = \frac{n_2 \cos(\theta_2)}{n_0 \cos{\theta_0}} \frac {|\beta|^2} {|\alpha|^2 - 2\alpha \cos(\varphi) + 1} \end{equation}where \(\alpha\) and \(\beta\) are related to the Fresnel coefficients as described in [4] and \(\varphi\) is the phase difference between the two reflections (See Thin Film Derivation for a complete derivation).
\begin{equation} \tag{8} \label{eq: phase diff} \varphi = \frac{2 \pi}{\lambda}(\frac{2 n_1 \delta}{\cos(\theta_i)} + \Delta) \end{equation}The phase difference \(\varphi\) is the crux of this visual phenomena. Importantly, it is dependent on the wavelength \(\lambda\) of the incident light, as well as the thickness \(\delta\) of the thin film. This quantity \(\delta\) is precisely what we query from the 2D fluid simulator at each ray intersection with the bubble. To reemphasize, the thickness of the film is a function of position over the bubble surface for a given instant in time. As the thickness map is a discrete grid, use bilinear interpolation to distill the appropriate thickness for ray intersections that do not map precisely onto grid points. Finally, we restrict our implementation of thin film interactions to systems containing only two material interfaces. Hence, there are a maximum of three refractive indices \(n_1, n_2,\) and \(n_3\) involved in any calculation.
Diagram showing procedure for calculating interference effects.
Here we present videos of our results for two types of thin film media: oil and soap. In an effort to limit lengthy render times, we ran our pathtracer with the following settings: 256 ray samples per pixel, adaptive sampling thresholded at 0.05, and a ray depth of 5. Under these settings, it took our pathtracer about two hours to render all 100 frames comprising each video.
|
|
|
|
|
|