Bram Tempelaere walked us through the creation of the Dream Shaved Ice Cream Shop project, explaining how to build a stylized, dreamlike environment with Blender, ZBrush, Substance 3D, and Unreal Engine 5 and sharing helpful resources.
Introduction
Hello! My name is Bram Tempelaere, and I'm a recent game art graduate from Belgium. Currently, I’m looking for a job in 3D environment art.
For this article, I'll walk you through my workflow and link you to some learning resources I found helpful while working on my first stylized 3D environment, the Dream Shaved Ice Cream Shop. This project is the culmination of my growing love for creating beautiful clouds and stylized art.
Getting Started
The seed for this project started with my graduation work. I was experimenting with volumetric clouds and how to stylize them, as clouds have always amazed me by how beautiful they are. While searching for ideas for my final project for my bachelor's degree in game art, I came across concepts by Cycle Circle, where he painted clouds in a Ghibli/anime style. On top of this being a great opportunity to explore more cloud-creating options in 3D, I wanted to see how close I could push myself to recreate the dreamlike feel of Cycle's concept.
To start, I used a tool called fSpy to match the concept's camera perspective: this tool can generate camera settings, which you can use inside of 3D software that matches the perspective lines you draw on a given image. This helped me align the scene's composition with the original artwork and get the proportions right. I created a blockout in Maya and imported it into Unreal Engine 5 as a hierarchical Blueprint. This made it easy to replace models with detailed versions later on.
One of the most challenging elements was the fish sign on top of the store. Because it's the focal point, I spent a lot of time refining its proportions and textures to capture the personality of the concept. The fSpy to Blender plug-in helped me accurately match the camera perspective for painting textures also, ensuring the fish retained the same personality from the concept when viewed from the main angle.
Modeling & Texturing
I modeled most props in Maya, though I later switched to Blender to speed up my workflow. For prop texturing, I used Substance 3D Painter and developed a smart material to keep the style consistent:
- A base layer that sets up color, roughness, and metallic values;
- 4 layers that add gradients based on up/down lighting and top/bottom position map;
- A layer with an ambient occlusion mask for adding darker color in the base color to cavities;
- Separate folders with woodgrain and anisotropic noise details, which I masked in for wood and metal materials, respectively;
- 3-layered setup to add highlights based on the curvature map (wider, less wide, slimmest mask: least bright, brighter, brightest color) based on a YouTube tutorial made by Lara DэAdda, who talks about how to author better-stylized colormaps:
To give the props a painted feel, I often used slope blurs and overlaid tiling brushstroke textures, which I created in Substance 3D Designer. I also used some tiling brushstroke texture as an overlay on the color to add a more stylized feel for some props.
The interior wasn't initially part of my scope, but as I was nearing the finish line with the exterior, I realized the environment felt incomplete to me without it. I wanted to make it feel like it's a real place where people go and eat ice cream with all the necessary bits and bobs. Pinterest is my favorite place to find references; it has great image results, often way more accurate to what keywords I'm using to search for than when using Google. Using Pinterest for inspiration, I compiled a list of props that would fit the mood of the space I had in mind. Making every single prop fit together was a challenge because I was developing the style of the scene as I was making it. I did a lot of back and forth between Substance 3D and Unreal Engine.
I modeled using a mid-poly workflow. Starting with a blockout that captures the proportions, I made a model with a topology that is easily turned into a subdividable model later. After making the high-poly model from it, I went back to the mid-poly and optimized it to a low-poly version. I used Substance 3D Painter for baking down normal information from the high to low-poly, this is the process of turning the normal or shading information into a texture map, which can then be applied to a lower-resolution version of the mesh.
For the bricks, I made the high-poly sculpt in ZBrush, and for the low-poly, I used ZBrush's Decimation Master, which automatically removes vertices from flat faces, in combination with some manual optimization work in Maya.
I worked with 4 main materials: one for tiling materials like the wall and wooden plank materials, one for props with unique textures, one for texturing the building walls, which uses Vertex Paint blending to reveal different colors, and finally, one for the trim sheet. I also had some extra materials for the clouds, the foliage, and swaying in the wind objects, and one for a void material for the pipes.
I created the tiling materials using Substance 3D Designer. For the wall materials, I created the height information directly with Shape nodes in 3D Designer. For the trim sheet material, I sculpted the height information in ZBrush and then used that to generate the other maps in Substance 3D Designer.
For the wall, I created the wall height map in Substance 3D Designer. The Flood Fill nodes in Substance 3D Designer were a great asset when creating variety in the height map of my wall, I learned a lot about how to use them through this YouTube tutorial by Johnny Nodes:
The Flood Fill to the Gradient node creates a gradient per tile, which you can adjust using levels to chip corners off. Layering these, the tiles started to take shape.
Using the Flood Fill to Bounding Box node was useful to add bigger chips to tiles that smaller ones shouldn't have. I added moss to the wall material in the engine to have more control. I wanted to create those saturation variations in blobs like in the concept, and I also wanted a top-down gradient and localized blobs, which I could get with vertex painting. All these extra controls to add in the moss I found necessary to get where I wanted the wall to get, as it takes up a big part of the image.
I made a directional rocky noise and then quantized it for a stylized look. The Vector Warp node helped prevent the noise from continuing over tiles.
Clouds
To create a performant cloud, I used photo-textured cards. I created masks in Photoshop for highlights and shadows, which allowed me to have control over the color of both in the material instance. Initially, I used a single card with clouds that loosely resembled the concept. Later, I experimented with layering multiple cards with varied material parameters, and that brought the shapes closer to the concept's look. To get closer to the 2D feel and to make multiple cards work together better without obvious seams, I made a post-process material with the Kuwahara filter technique, which I learned through Matthijs Verkuijlen's tutorial, to blur the cloud textures.
The Kuwahara filter is an image processing technique that smooths an image, keeping edges sharp and creating a painterly feel. I multiplied a scene-depth-texture-based mask before the output of the post-process material to make only the clouds/faraway objects affected by the Kuwahara filter. Something to note here is that I had to make sure to set the viewport screen percentage to 100% for this to work properly in the viewport, as the filter works based on the size of the viewport.
Rendering & Lighting
I split up the scene in my Outliner into a foreground, midground, and background folder. I also used empty actors in Unreal to parent groups of objects. This way, I could move big parts of the scene more easily to serve the composition. To make a render with a vertically cropped camera, I had to change the aspect ratio in the Cine Camera Actor to a value lower than 1.
To capture the same mood as the 2D concept piece, I paid close attention to the values of the image. This meant making sure shadows were not as dark, adjusting lighting, and tweaking textures to hit the right values in the render. In the Post-Process Volume, I was able to tweak how dark shadows get and add some bloom to the image to make the values blend together better. I also changed the Toe setting in combination with tweaking color grading settings.
I recommend using the threshold adjustment layer in Photoshop on top of a screenshot of your scene and the reference to see where the biggest differences are in values between your work and the image you're using as your reference. Also, putting a layer above the screenshot filled with black color and setting the layer to color can help to see more clearly where the values of your work differ from your reference.
For the sky, I first used the HDRI Backdrop plug-in, which comes with Unreal Engine, you just have to enable it in the Plug-ins menu. Later, I ended up separating the environment dome mesh inside the Blueprint from the Sky Light by dragging them into the scene separately to give me more control.
To create a soft feel from the concept, I used Spotlights to lighten up shadows. Turning off cast shadows or changing the specular scale to 0 in the details panel of Fill lights helped to not cause any unwanted shadows. To create an artificial shadow inside the pipes that was dark enough while keeping enough light in the scene, I made a Fresnel-masked void material that I applied to half of a squashed sphere.
There's a box with void material (base color=0, roughness=1) under the car's wheels to make sure the bright ground doesn't shine through on the main camera angle, as the stark contrast between the bright ground and the dark car would create a distraction from the main focal point.
I used a post-process material to add colored lines to each object, which helps give it a 2D feel. In the image, you can see how I sampled the color for lines based on the color of the object on said pixel. I linearly interpolated with Lerp node between the Scenetex and this color based on the line art mask, which I learned about how to approach from Kamil Hepner on YouTube:
Conclusion
I began this project during my second-to-last year of study as part of an environment course. After graduating, I revisited it over two months of part-time work, refining textures and props to elevate the final quality. Overall, the project took two months of full-time work.
My piece of advice is to take a step back! It's super easy to get tunnel vision when working on a project for a long time, but after I came back to this project after almost a year, I had so many new ideas about how to approach assets and make them more efficient. Without that, I wouldn't have reached the same quality result, for sure! The time spent away from your project gives you a chance for more creativity when you come back to it!
If you are reading this and want some more detail on a specific part you're welcome to reach out to me on LinkedIn or ArtStation for further discussion!