There are 3 things in the world I could look at forever: Fire, other People working and the Diablo 3 resource bubbles. I already fell in love with Blizzards art style like you maybe noticed in my article about their 2.5D trees. But today we’ll have a deeeep look at Diablos crystal balls and search for the truth.
Source: Diablo 3
They look so deep. So round. A delicious mix of blur and sharpness. Let me state my initial thought how this could be achieved (long story short: they’re both wrong. I’m on the woodway like we say Germany):
Take a polysphere, cut it half and pull some textures over the surface. Why is it wrong? Because i checked the ingame wireframe of the “bubble”. Guess what? It’s not a bubble! Here you can see my approach (red sphere) and the Diablo 3 mesh (green) which btw. contains only 218 tris instead of my 960.
I asked Neox and he suggested to take a sphere, bake it into a normal map and do the rest with a shader. This is a good idea but i couldn’t find such a texture in the Diablo files. So why the hull do i waste your time with this nonsense?
Because mikiex posted a great example which is similar to Neox’ idea. I think this will be my next article. For now, just look at the image and see how great the world is wrapping around the sphere. But it’s not the way the devil went.
So let’s talk about the right way.
Hellway 1nd “UV Layout”
I was able to extract the “bubble” mesh and had a look at the UVs. And here’s how they look like:
The UVs are modified (stretched at the border, compressed in the center). Let’s watch what happens when we drop a checker pattern on the bubble and let the UVs move from left to right:
It maybe doesn’t look like a perfect sphere (more like a round hat) but since the border areas of the bubble are mostly covered by painted reflections or this sad stone angel, it works very well in my eyes. In fact, i think it looks awesome.
Hellway 2nd “Geometry”
But moving only one texture wouldn’t create this beautiful mix of motion & depth. Thanks to the D3 model viewer we can see that there’s not only one plane.
666 points for you, if you noticed that these textures contain the totally wrong color & pattern. As an old Diablo 2 player i searched for “Mana” in the files but in Diablo 3 the stuff of the Wizard is called: Arcane Energy. Mana is used by the Witch Doctor.
But i think they re-use the Mana-Bubble-Mesh since i can’t find any special geometry for the arcane sphere.
Lucky for us that Julian Love mentioned how it was done here.
Hellway 3rd “Textures”
The textures for the wizard resources look like this:
To be honest, i can’t say how exactly these are blended together. But i want to make some notes:
03 is the alpha channel of 02. Except for 04 none of the other textures does have an alpha channel.
I really dig how they let the fluid texture reach a bit above the actual filling level. 04 and the 3 other small textures are used for the level line.
If you look at it drawcall by drawcall you see a transparent sphere and i think 01 is used as alpha for it. I don’t get why the other stuff is rendered later, but i guess this isn’t how the game handles it.
You reached the end of the article. Simon is too sad to write more because he doesn’t like that he couldn’t find more information about the texture blending. He hopes that Blizzard hires him as a sad angel sitting on the left side of the bubble. Then he could gather more awesome stuff directly from the art heart.
“The textures are all being multiplied together. Not blended. This is where all the color motion complexity comes from. It’s also how the motion of the water line is handled. […] Here is the formula for the water line alpha mask:
a = tex1.a * tex2.a * 4
Also, the water line is being deformed by the UVs, but you can’t easily see that distortion when you look at sphere straight on…”
Because i have not much knowledge about shader code, i asked him if the “* 4” is for brighten up the textures since multiply darkens them pretty much. His reply:
Yes, the *4 at the end brightens it back up significantly. We do the same thing with the color as well, only using *2. The color formula is
rgb = ((tex1.rgb * text2.rgb * 2) * text3.rgb * 2)
Each texture is actually an instance of the same texture, but each stage has a different UV offset, UV scroll speed and UV scale.