And here we are with the second part of our candles W.I.P post!
A big amount of stuff has changed in the meantime between this and the first post, I dropped out the first candle concept I had in mind and decided to follow another direction, after a bunch of thoughts and tests on scene layout and optimization.
Even with a highly optimized geometry from Meshlab, a proper melted candle didn’t seem to be very friendly for realtime purposes, a single candle with some melting wax had about 1k triangles. For a single asset: OK, but for something that need to be scattered around a good amount of times? hmm, nope.
In the meantime, what I had discovered in my tests is that with subsurface scattering you could just stack several candles together and they would still look coherent, with an almost seamless transition between them, so I had the idea to model only the candles as a group of assets, and a bunch of melted wax set as a complement. This way I’d be able to create a scene with several melted candles together and stuff like that without the huge drawback of a performance, hit as we’ll just have extra geometry where we really need it.
The modeling and sculpting is no different from what we already saw in the last W.I.P., I made a bunch of cylinders, deformed a bit, then sent them to mudbox for detailing. I tried to maintain the overall silhouette this time, so I could use the base mesh as the low poly mesh as well. Done with that, I kept the UV quite simple too, just a seam on the base, another one on top, and a vertical one to unwrap the cylinders.
I made all the candles at once as a single mesh, since they will probably be used near or together in the level, I decided to keep all islands in the same UV Texture, as an atlas, to save on draw calls. This also eases the task of baking, since I would only need to deal with a single file, instead of multiple bakes. At the end, I can just split the candles and save them separately, work smarter 😉
A tip when dealing with things that will use SSS and/or Emission/Heat shaders is to keep a good padding size when baking the final maps; In order to optimize the overall performance, rendering engines tend to downscale the mask maps a good amount (due to mipmaps), so your seams can be very staring at some distance, also some rendering engines have troubles with smoothing groups when using subsurface scattering, so have that in mind when doing something like this!
Take a look on this previous test I did with the first candle, If you look at it at full size, you’ll notice that the seams are very apparent, this is because the heat map was downscaled so much that a bit of the black areas of the mask were leaking into the UV islands, and with a map that emit light, this can be very showy. (a bit hard to explain but, I think you got it! and if isn’t, just shout a comment at me down there!)
To bake this, I used xNormal for AO, Cavity, Curvature and Normal map, and Knald for Transmission map.
The first thing I did after this was to open the candles in mudbox to paint the final textures, I just googled a base wax texture to start with, then added AO and cavity as multiply, and curvature as overlay, tweaked the opacity of these layers and started painting the diffuse using a stencil from the base texture. Then in Knald I baked a transmission map to use in the subsurface scattering shader, what this map does is simple tell the renderer which parts are more translucent, based on the thickness of the mesh. Later on, I used the diffuse as a way to create the glossiness map, and for specular I just used a constant value.
Now it comes the best part, creating the (sort of) candle light. I decided to fake it with a gradient map plugged onto the heat map, for this I used blender paint tools, with fill brush set to gradient mode. I just masked the candles and applied a gradient from top to bottom, then saving the generated texture map (with sufficient padding), you could do this as well painting straight in your high poly as vertex paint, then projecting that color information to your low poly UV using xNormal.
With all maps in hand, I just dropped everything in Marmoset Toolbag, nothing fancy here, the real gold was the Skin Shader, Heat Shader and Second Reflections, these three together create the true illusion of a candle shader. In the skin shader, I plugged the transmission map baked in knald to the translucency slot, and assigned a light blue color to it (don’t ask me why, it just looked correct for my eyes), then a warm light orange to the subsurface color. Above that, we have the heat map, it’s great to simulate heat behavior like hot metal and such, but can be nice to fake our candle light dispersion too, so I’ve just plugged the gradient map to it, and voila!
The finishing touch was the second reflection layer, notice how a candle has some kind of a sharp reflection, while being extremely diffuse as well, this is a Fresnel Reflection, in a traditional render engine like Cycles, V-Ray, Arnold or Renderman, it’s a already well-established thing to add in your shaders, but until a few time ago, we would need to fake that for realtime, since multiple reflections/angle based are things very CPU/GPU intensive. But HEYO PBR! We can have this in realtime now, so let’s do it!
For the candle wick, I painted a texture straight in Photoshop, and created a variation using Warp, nothing fancy here, just a billboard texture to be placed on top of the candles in the engine later. The candle fire will be done as a particle system in Unreal, I still need to look at it later, but for now I’m just fine faking it in Photoshop to have a preview on how it should look, hope you like it:
See you next time! 😉