This year’s U.S. Open is being held at Chambers Bay, just south of Seattle. It’s a unique course for many reasons: its fescue grass changes the way the ball bounces, its wild elevation shifts and terrain require creative approaches to each hole, and there’s only a single tree on the entire course. We wanted to let readers tour Chambers Bay right from their web browser, so we got in touch with Robert Trent Jones II, the course architect, and asked if we could use the elevation data.
Luckily, they said yes! Unluckily, they provided the elevations as a rather hefty 15MB AutoCAD file. We didn’t have an AutoCAD license, but a trial version works for 30 days, which gave us a deadline on figuring out how to convert it to something more web-friendly.
The second problem was that the file didn’t contain actual polygons, which we would need to run it in a browser. Instead, it was a set of unconnected contour lines. They were at the right height and looked great, but didn’t form the shapes that a computer could use. I looked into several solutions — most of which were miserable failures —and was about to try writing an AutoLISP script to extract elevations into a file when an architect friend suggested using Google’s SketchUp. Some simplification and use of the “drape” function later, we had ourselves a mesh.
(Incidentally, SketchUp starts every new project with what looks like Stan Lee standing awkwardly in the middle of an empty green plane. This isn’t related to our project at all, I just think it’s weird.)
For this project, we used the industry-standard three.js library for creating our WebGL scene. In addition to handling the camera and object positioning, three.js made it easy to put together the various props (flags, golf balls, tree) that we needed. It also has a great web-based editor that I could use to prototype object placement and try out various model formats.
Once we had the landscape loading, our next job was to texture it by applying color from an image to make it look real. Unlike most 3D models, we didn’t have coordinates at each vertex for the texture position (nor did we have a texture to use). But we did have a PDF of the AutoCAD model prior to mesh conversion. Our graphics team was also struggling with the USGA course diagrams, which didn’t include all the hills and other elevation features. Graphic designer Garland Potts and I worked out a deal: she used our CAD diagram to create a more detailed print graphic, then handed back a shaded and textured image for us to apply to the landscape.
I wrote a custom WebGL shader to “project” this image down onto the terrain, then added lighting and some dithering to make up for the low resolution. This approach to texturing wouldn’t be appropriate for anything with a lot of vertical surfaces, but the relatively gentle slopes of Chambers Bay are more tolerant.
Finally, over about a week, I placed the tees and holes in the landscape, then set up camera positions for each one. Every hole gets a flyover tour, which usually just consists of moving the camera up and over from tee to green. For several, however, we hand-coded camera movements to draw attention to course features, or to follow the path that the ball would have to take.
Looking back at the project, there are several improvements we’d like to make. The landscape file is enormous, and could probably be culled to reduce size without removing visual detail. We also never added a free camera to the experience, and it would have been nice to have more information about the ideal path of the ball. But overall, I’m very happy with how it turned out.
More importantly, I’m really looking forward to applying this to other projects, where being able to explore something spatially is an asset to our storytelling. For example, stories about large-scale redevelopment, our local mountain ranges or distinctive machinery (see: tunnel digger Bertha) are all excellent potential 3D experiences. Now that we have more experience with the 3D workflow, it’s just another technique in our repertoire for data journalism.