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

1 comment:

  1. Hi
    This is a good way to apply on mobile game,coyld you share how to finish this shader?


    Thanks

    ReplyDelete