Grossing billions of dollars, Disney's Frozen franchise spreads its compelling story across the world, motivating many then boys and girls to pursue computer graphics and animation as a career - including us. Therefore, we present our final project as a tribute to the appealing visual imagery in Frozen.
During the Let It Go sequence, Elsa breaks out of her sorrow and crafts a spectacular ice castle on top of the North Mountain (which is based off of Mt. Matterhorn in real life) using her ice magic. With the joy of relief, she walks into the new dawn and finishes the sequence amid a passionate proclamation to her new life.
Leveraging the rendering techniques learned in class, we aim to recreate this fascinating scene with a path tracer built from scratch.
Our take on Elsa's palace as appeared in the movie Frozen (2013)
Set Dressing
The first step was to clean up meshes. We remeshed the mountain to a lower polygon count. To pronounce the snow on top of the mountain, we projected a thin layer of snow coverage above mountain surfaces, then subdivide an extruded copy of the snow geometry.
Castle Model
Mountain Range
Lighting
Our lighting configuration is similar to which of Homework 2: two rectangular light panels staggering next to the scene camera, focusing on the ice palace. We have chosen a a contrasting blue-magenta lighting scheme as used in the reference image.
Classic two-light layout: blue (left), magenta (right)
Overview
We implement our renderer using Intel's Embree, a collection of high-performance ray tracing kernels. All source code are written in C++ 17.
Asset Loading
We used the tinyobjloader library to load model assets in .obj formats. lodepng was also used to load image textures.
Monte-Carlo Path Tracing
Our path tracer implements many essential functionalities such as Russian-roulette, Next Event Estimation, and Multiple Importance Sampling.
Preview: diffuse "clay" rendering (32 spp)
Smoothed Normal
As shown in the previous image, Embree practices a per-face "flat" normal by default. Therefore, we appended pre-computed per-vertex normal as vertex attributes, then smoothly interpolated dN/du and dN/dv on traced shading points to achieve a smoothed normal shading.
Flat Shading
Smoothly Interpolated Normal
Texture Mapping
As aforementioned, we've simplified the mountain asset for better topology and lower polygon count. However, this step forfeits the intricate details, such as the rugged terrain and layer of snow on the mountain range. One common technique used in production to replicate such details on lower LOD meshes is texture baking. We followed this idea and baked a 4K high-res mountain rock texture onto a diffuse map for sampling texture. Following the same interpolation technique mentioned earlier, we smoothly interpolate texture uv coordinates from pre-computed uv map encoded in the .obj file.
Texture Mapped (32 spp)
Non-Local Means Denoise Filter
As seen in the above image, battling noise would be a major effort of our render, as it suffers heavy noise from the complex reflections out of the castle surface. We implemented a patch-wise non-local means denoise image filter as a post-processing step of our renderer to resolve this issue. We've used parameter heuristics suggested by the aforementioned paper and categorized them into "off", "moderate", and "excessive", respectively. We showcase our NLmeans results in different parameter settings:
16spp, NLmeans off
16spp, 3x3 patch, 21x21 block, h=0.55
(moderate)
16spp, 5x5 patch, 35x35 block, h=0.4
(excessive)
32spp, NLmeans off
32spp, NLmeans moderate
1024spp, NLmeans moderate
Despite its statistical performances in denoising, the visual artifacts it pertains to due to loss of high-frequency details are not negligible. Therefore, it comes to a trade-off between sample count and NLmeans parameters. In light of this, we found an additional heuristic can be performed to assist finding the visual balance between noisy and denoised images. Observer the image, our region of interest are mainly the ice castle itself, but not the mountain range, particular those with high frequency texture details. We attached a mask parameter to materials to produce an intermediate mask which later helps in compositing the usage of NLmeans filter:
Color-coded Material Mask
Weighted NLmeans (mixed noisy and denoised)
We composited the output image against a matte background in Adobe Photoshop and added some lens effects, such as vignette. Please enjoy our final composition!
Awarded "Best Project" for CSE168: Computer Graphics - Rendering, Spring 2021.
"Here I stand, in the light of day.
Let the storm rage on, the cold never bother me anyway!"