March 23, 2016

UE4 Water Caustics - Light Function Method

In an earlier post, I showed how to make caustics with a material function. This is the light function method. This system functions much in the same way the earlier one did, except instead of world position determining the size of the caustics, I used a texture coordinate, and since pixel depth is not available to light function materials, I used the distance between the absolute world position and camera position. There is a second directional light in this scene which does not cast dynamic lighting or shadows, but projects the caustics function into the world. This method respects all material qualities and there is the capability of using both shadow maps and dynamic shadows to improve the quality of the function. However, light functions do not support colored textures (I believe the performance benefit comes from handling most functions using 1-vectors as opposed to RGB 3-vectors), so the caustics are completely desaturated here.



Aside from the color issue, this method supports all the functions of the previous caustics system: the texture blurs and fades out as it approaches the bottom of the water. The caustics are mapped and aligned with the directional light as if it has been cast from the sun. And it even cuts off at the water level! On top of all that, this method also respects the shadow environment and surface properties (color, metallic, roughness, etc). This is the proper way to handle caustics in UE4. The light function uses 85 instructions.

I also used the material function method to shade the particles in the water.

This caustics texture was made with the free caustics generator provided with Allegorithmic's Substance Player. The player is free as well. The distortion is provided by a simple noise texture converted to a normal map. I provided the assets below. Please note if you wish to use a texture for the light function, flag the compression as a Grayscale image. This will use the same amount of memory as a standard texture but improve the quality by decompressing the texture. Because the caustics function relies heavily on the quality of the mipmaps, and to eliminate tiling, it is a much better idea to make sure the texture is large enough so that accurate mipmaps can be produced. Alternatively, you can also hide the texture in one of the channels of a larger mask texture to save memory.

Click here to download the caustics texture, wavy normals, and a Phong material function.

March 22, 2016

Underwater Caustics

I may have figured out a (somewhat) cheap method to get realistic caustics underwater in UE4. This method is all done purely within materials and requires no lights. The caustics rendering itself only takes 30 instructions, and depending on how you shade it, anywhere from an extra 0-20 instructions.



This technique uses a light vector to correctly planar map a panning image of caustics. The shimmering effect is then provided through a noise normal map distorting the UVs. The caustics will map on both sides of an object's normals, so they have to be shaded with either Phong or GGX specular and Lambertian shading.

The Caustics texture was generated from a free plugin provided by Allegorithmic with their Substance Player. The texture has chromatic aberration (colors), and plenty of detail and depth. The function also uses the exposed Mip levels of the texture to blur and "scatter" it based off of its depth in the water. Close to the shore, the caustics are crisp and clear. Deeper down, they become blurry and less noticeable. It automatically cuts off the caustics rendering above the water as well.

As an added bonus, because caustics use the World Position nodes to map itself onto objects, you get the transmission of the caustics through the surface and onto the other side for free. To make translucent grass, you don't even need to bother shading it! Unlit grass can look too even without the GI to differentiate itself, so for this demo I used the Masked/Two Sided Foliage shading model. A custom Mip function means you can also make the caustics blur more in the distance as a cheap way of showing scattering in the water, though I did use proper depth of field post process in the demo.

The Caustics function is automatically linked up to a Material Parameter Collection, so when certain properties are adjusted (like the depth of the caustics blurring effect, or the intensity), those values change for all of the models where the caustics appear.


Pros:
  • Cheapest way to render underwater caustics (does not require complicating entire scene through the use of a light function)
  • Automatically respects the direction of sunlight
  • Mip level adjustments can scatter and blur caustics into water based on depth (extremely cheap feature, and very convincing)
  • Ability to use forward custom shading that can be adapted to many uses and shading techniques (Phong, Blinn, Beckerman, Cook-Torr, or GGX + Lambertian diffuse, and transmission)
  • Free transmission for grass and plants (more complex subsurface scattering can be simulated through a more interesting Mip adjustment)
  • Colorful chromatic aberration (light functions currently do not support colored textures, and post process applies evenly to the entire scene)
  • Can be adjusted per-object and universally through individual material parameters and collection parameters
Cons:
  • Does not respect surface properties or UE4's lighting renderer. Because the caustics are sitting on top of UE4's lighting, not integrated as a light function would be, this material mapping function method does not respect any surface properties and requires its shading to be handled separately. Any Lambertian or GGX specular lighting must be applied separately, nearly doubling the shading work.
    • Alternatively, you can render objects as unlit to save greatly on instructions, but at the cost of the GI, shadow environment, and reflection environment. For products not requiring too much power, rendering unlit with all light being supplied by the caustics is definitely the cheapest option to render caustics at all. Fully rough materials can also work.
  • Does not respect shadow environment, so areas that should be shaded appear to have the caustics effect. This can be mitigated through the use of textures or vertex painting, but it would be more ideal to have the caustics respect the built-in shadow environment.
  • Must be applied manually to all materials requiring it