Stylized Water 2 documentation

Stylized Water 2

Stylized Water 2
Author: jonathan
Version: 1.1.4
Dated: 22 Sep 2020

7.Performance guidelines #

I strongly recommend to learn and use the Profiler and Frame Debugger tools to get an insight into how rendering is performed in your project. This is the only correct way to gauge where rendering optimization is needed.


The shader at its core is optimized through efficient use of resources and will outperform anything similar you would create using Shader Graph. Though, the “Simple” shading mode remains best suited for mobile. Water is a complex phenomenon, and requires a lot of steps to achieve a believable effect. It is arguably one of the most expensive shaders in a game, worth keeping in mind.

A general rule of thumb is: The more features are enabled, the longer it takes to render the water in a single frame.

Modern devices can run the shader in a simple scene with all features enabled and not notice a difference. If you’re targeting older devices, be sure to disable any features that do not contribute to the art direction.

  • If the scene is not using any dynamic lighting, but rather a fixed directional light and ambient color, you can disable lighting on the material to gain performance. Reflections will still work in this case, if they’re enabled.
  • If the water doesn’t take up a lot of screen space, fewer pixels have to be calculated. You can possibly use this leeway to enable more features.
  • Rendering the depth texture in URP essentially doubles the amount of draw calls for objects. If you assets aren’t already optimized for this, it has a negative impact. Consider disabling it in your URP asset and under the “Advanced” tab on the water material. Instead, use vertex colors to paint on foam effects.
  • When having waves enabled, keep the “Count” parameter value as low as possible.
  • The shader automatically takes into account if the URP is configured to use shadows and renders lights per-pixel, or per-vertex.

Planar Reflections

This involves re-rendering the scene from a mirrored perspective, so can potentially double the amount of draw calls. Shadows unfortunately cannot be disabled due to what seems to be a design flaw. For example, reflection probes always render shadows, even if they have a shadow distance of 0. This appears to be a bug.

Culling Mask

It’s important to make use of the Culling Mask field, and only reflect layers that are important for the visual result. This would require you to create new layers, and set specific objects/prefabs to these layers.

At the time the “Render Layer” dropdown on renderers cannot be used for culling. Once this functionality evolves, the Planar Reflections feature will be updated to make use of this.


Because a 2nd camera is used, this camera will also render using a the default renderer, which means any Render Features (eg. third-party post processing effects) will execute for this camera as well. This is wasteful, since the reflection is applied directly to the water, so any effects may appear to be applied to the reflected image twice.

To solution to this is to create a renderer, specifically for planar reflections. To do so:

In the Project window, right-click and go to Create->Rendering->Universal Render Pipeline->Forward Renderer

Next, in your pipeline asset, add the new renderer to the Renderer List (repeat this for any other pipeline asset used)

On the Planar Reflection Renderer component, configure it to use this renderer, instead of the default one

With this set up, you can ensure no unnecessary or unwanted rendering is performed for the reflections.


Because it’s common for a project to have varying quality scales, there’s a static function in place which can toggle planar reflections globally. This could be tied into something like an option in a settings menu.

You can call the static function StylizedWater2.PlanarReflectionRenderer.SetQuality(bool allowReflections, float renderScale = -1f, float renderRange = -1f, int maxLodLevel = -1) to change settings for all active Planar Reflection Renderer instances. The last 3 parameters are optional, if left untouched these values aren’t changed.

As a performance safeguard; reflections will never be rendered for any hidden or overlay cameras. If you’re using a hidden/off-screen camera, ensure the camera object is using HideFlags.

Yes No Suggest edit
Last updated on August 31, 2021
2 of 2 users found this section helpful
Suggest Edit