PIDI Planar Reflections 2 is an advanced tool to add real-time reflections to your 3D scenes easily and with a low performance impact. The tool comes with dozens of custom shaders that allow you to create all kinds of reflective surfaces from simple mirrors and basic opaque surfaces to complex PBR materials, water and glass floors and walls.
Furthermore, the asset comes with specific shaders and workflows for mobile devices and the new Lightweight SRP renderer, starting with version 5.7 for Unity 2019.1. In this documentation you will find a general description of all the different features of this asset, a small setup guide and some performance tips to help you add reflections to your scenes in no time.
Due to the many limitations in SRP rendering including the inability to render cameras manually, render with custom shaders/effects, the limited access to the rendering process on a per-camera basis and many others, reflections in LWRP are severely limited. In essence, LWRP reflections can use only the basic features of this asset but for a full feature comparison you can see the table below.
|Feature||Lightweight SRP||Standard Rendering|
|Reflection to Render Texture Asset||✓||✓|
|Dynamic reflection resolution||X||✓|
|Advanced rendering control||X||✓|
|Depth based effects||X||✓|
While a LWRP package for older Unity releases (pre 2019.1) is provided, this package is no longer supported nor is recommended to use in any projects.
Two newer packages are provided to support the actual LWRP releases, one for LWRP 5.7 on Unity 2019.1 and one for LWRP 6.9 on Unity 2019.2. These packages are clearly labeled as such and easy to install, just by unpacking their contents inside the Unity Editor after double clicking on either one.
The LWRP capabilities of this asset are then limited to Unity 2019.1 and 2019.2. For future Unity releases and LWRP versions you may want to consider upgrading to PIDI Planar Reflections 3
In this quick guide we will go through the whole process of using PIDI Planar Reflections 2, from installing the software into your project to adding it to a scene.
As a first step, please ensure that your project fully meets the requirements below :
While PIDI : Planar Reflections 2 has been designed to be integrated to any project at any stage of development with little to no setup required, there are still some considerations to be made
For projects working with the Standard Pipeline there is little to no setup required. If this is a first time installation you just need to head to the Asset Store and find this asset either under the section “My Assets” or by a normal search in the store itself.
If you have bought the asset, a Download / Import / Update button will show, depending on if you have never downloaded the asset before, you have downloaded it and it is in cache already or there is a new version available for download, respectively.
Once the import dialog appears, just import all the contents of the asset as usual. To verify that the asset was imported without any errors try to open one of the demo scenes. If they work without issues, the package has been imported correctly. If you see any graphical errors you must re-import the asset. If the issues persist even with a brand new and empty project, please contact us at our support email
In the last step described above, once you see the import dialog while adding this asset to your project, DO NOT import the Standard Pipeline folder to your project. Importing this folder would cause errors due to the shaders and materials included in it being incompatible with LWRP.
Instead, once the tool has been fully imported, unpack LWRP 5.7.unitypackage (which is located inside the LWRP Contents folder) into the project or the LWRP 6.9.unitypackage file if you are working on Unity 2019.2 and import its contents. This will add all the necessary shaders, demo scenes and additional files for you to start using PIDI Planar Reflections 2 in Unity 2019.1+ with LWRP 5.7+
While we do our best to keep up to date with LWRP releases there may be times when Unity updates their pipelines and adds or removes functionality from them (and in most cases breaking the compatibility of LWRP shaders) before we can issue the corresponding update. If your version of LWRP does not load the shaders appropriately or the demo scenes inside the LWRP Add on folder show pink materials please be patient, as we will issue the corresponding patch usually within 1-2 days of a new LWRP release or contact us to let us know the details of the error to our support email.
Warning : Please remember to make a backup of your project before upgrading or installing any tool or asset. While we do our best to ensure that our software is free of errors and easy to use, we are not responsible for any loss of data, corrupted files or projects produced during the installation or use of this software.
Once the asset has been successfully installed into your project, adding reflections to an existing scene is a simple process that can be done in just a few minutes. For more advanced uses and in-depth information about each feature please continue reading this documentation.
There are several ways to add dynamic, real-time reflections to your scene with our plugin. Which one you should use depends a lot on the kind of project you are developing and its target devices. In this section we will describe the basic and general approaches you can use for your projects.
The easiest (and most common) way of adding dynamic planar reflections to your scene is to simply add the PIDI_PlanarReflection component to a GameObject that has a MeshRenderer component and a compatible material (a material with a ReflectionTex property).
The PIDI_PlanarReflection component will automatically try to use the forward direction of the object as the normal from which the reflections will be calculated. This normal is simply put a straight vector perpendicular to the reflective surface.
While this is useful for most flat objects such as floors and walls, sometimes this behavior is not optimal since the forward direction and the actual normal of the reflective surface may not match. In these cases, simply enable the EXPLICIT NORMAL setting and define the explicit normal direction (in world coordinates) that will be used to generate the reflections. Starting on version 1.7 you can enable the LOCAL NORMAL MODE flag so the explicit normal is calculated based on the object's local coordinates. This is useful if the reflective object will rotate during the game.
In some cases, such as a house with floors of different materials but all in the same plane, you may want to render a reflection that can be shared across all of them. In other cases a single mesh may contain more than one reflective material, making it impossible to add the PIDI_PlanarReflection component directly.
For these situations the right solution is to create a Planar Reflector Object. These objects render reflections to a custom RenderTexture asset which can then be assigned by hand to any number of materials. Furthermore, these reflector objects are only visible in the Scene View which makes them ideal for complex scenes and a more precise control over the reflections.
To create a Reflector Object, go to the “GameObject/PIDIFramework/Environment” menu on the Unity's Editor top toolbar, and select Planar Reflector.
Once the Reflector is created, simply assign the RenderTexture asset into the Explicit Output variable of the Rendering Settings tab and it will immediately start rendering an accurate reflection.
IMPORTANT : The Reflector Objects are not compatible with the LWRP workflow and generally are not as flexible as having one reflection component per surface. Please use carefully.
While the Planar Reflections component provides plenty of settings that will be more thoroughly covered in the next sections of this documentation, there are some basic ones that you need to pay special attention to in order to configure basic and efficient reflections.
Besides the EXPLICIT NORMAL value covered before, the REFLECT LAYERS setting can define which layers are reflected and which ones ignored, to ensure a better performance.
Finally, the different resolution settings allow you to control the final quality of the rendered reflection. A higher resolution might help to reduce aliasing in cases where MSAA or FXAA cannot be used, while a lower resolution will greatly help with performance when rendering scenes that use complex per-pixel effects.
Please keep in mind that due to the way Planar Reflections work (by basically re-drawing all the reflected objects for each camera that looks at the reflection) the best way to optimize the framerate of your project is to reduce the total amount of draw calls either by simplifying the scene or by reducing the amount of objects that are reflected. Reducing the resolution of the reflection, its update frequency and other factors will only help performance up to a point.
Also keep in mind that due to the way the reflection textures are handled you will need a different material for each reflective surface unless they are all located in the same plane.
The Planar Reflection Component has a custom inspector that allows you to easily manipulate its settings and configure it according to your needs. The parameters are split in three groups : General Settings, Rendering Settings and Optimization Settings.
In the General Settings section you can find the following settings :
In the Rendering Settings tab you can find all the following settings :
Finally, in the Optimization Settings section you can find the following settings :
In this section of the documentation we will learn more about advanced features included with the system, as well as some features that while now deprecated and unsupported may be useful for some projects with specific needs. Any feature that is no longer supported, is experimental or is deprecated is marked as such. Please read carefully all instructions before trying to use any of the settings described below.
If the shader used by the material of your reflective surface has a _ReflectionDepth parameter, the PIDI Planar Reflection component will render, besides the reflection pass, a depth pass containing information about the distance from every object to the reflective surface itself, allowing it to render more accurate reflections.
The depth calculations of the reflections component are handled internally, without requiring you to do anything to enable them. You just need to make sure that the PIDI_PlanarReflection component has the included PD_Internal_DepthShader assigned to the corresponding DEPTH SHADER slot. To disable depth calculations simply change the shader to one without a _ReflectionDepth parameter.
Reflection Depth is not supported on Planar Reflector objects since all their calculations are made in a per-surface basis and cannot be shared. The additional Reflection Depth pass also causes a higher performance impact, so use it carefully
Starting with version 2.3, PIDI Planar Reflections includes the ability of adding custom components to the reflection renderers themselves. This new workflow gives base support for complex effects such as Post Process Stack v1 and v2 among others, by adding them to the hidden cameras rendering the reflections. This way you can add Ambient Occlusion, Anti aliasing and other effects to the reflections themselves or many other kinds of features.
IMPORTANT : Post Process Effects and other such effects will most likely not work on VR under any circumstances since the projection matrices of the reflection renderer are being dynamically modified by the Planar Reflections component, the VR setup and the custom chain of effects which will most likely cause conflicts and issues. Similarly, any screen based effect such as vignetting will not be displayed accurately since the reflections do not work on screen space.
To add custom components to your reflections you just need to add them to the object that has the PIDI_PlanarReflections component attached and they will be automatically added, set up and synchronized with the default values of the component. To further synchronize the settings there is a brand new toggle called AUTO-SYNC COMPONENTS. This is useful when iterating over different values for each component and to see their results immediately.
IMPORTANT : The custom components workflow depends entirely on System.Reflection commands which may not be supported in your target device. Please research about your devices' capabilities before trying to use this feature. Because of the System.Reflection calls, this feature can be very demanding when the Sync Custom Components flag is enabled so it is heavily recommended to disable it during play time and for the final build.
An additional component is added to all cameras with custom component chains that attempts to preserve their projection matrices to undo-unwanted effects performed by said components. Some projection and clipping errors are, however, unavoidable. To solve them, you can either adjust your near clipping values inside the Planar Reflections component ( even to negative values ) or disable safe clipping entirely.
If you plan to add components to your reflections at runtime then the following process should be followed :
Add the components to the object that has the PIDI Planar Reflections component attached and set up their values. In the Planar Reflections component, call GenerateReflectionsPool(0) and ClearReflectors() one after the other. This will forcefully add the components to the reflection renderers. If you make changes to the components in the original object and want them to be updated in the reflections, enable the synchComponents variable in the Planar Reflections component for as many frames as you need, and ensure you disable it again once the components are updated.
As a quick setup guide, for the Post Process Stack v1 you should ask the Post Process Behavior component next to the Planar Reflections component. For Post Process Stack v2, then the Post Process Layer component should be added.
In short, treat your reflective object as if it was another camera and to add support for post process rendering add the same components you would add to a standard unity camera.
In this section we will cover the basics of all the shaders included on this package as well as a small tutorial that will teach you how to add reflections support to your own custom shaders.
While the plugin is compatible with Mobile devices, most of the included shaders require support for at least OpenGL 3.0. If you are developing for Mobile devices, check the device's capabilities before using the included shaders.
The included shaders can be divided in 5 different groups : Water shader, Mirror Shaders, Generic, Chroma Key and full PBR surface shaders.
SIMPLE WATER, REFLECTION+REFRACTION
(PIDI SHADERS COLLECTION/PLANAR REFLECTION/MIRROR/SIMPLE)
There is one water shader included with this package, the Simple - Reflection+Refraction water shader. While part of the Simple branch of water shaders, has several important features that allow it to be easily extended into more complex shaders.
The only texture required by the shader is the Waves Normal map. A default Normal map is provided with this package.
The reflection texture can be any Render Texture and is automatically assigned if you create a plane with this material and add the PlanarReflection component to it.
The Shore, Bottom and Clarity levels all control the depth based rendering of the transparency and colors of the water. Change these values to move the shore line, the deep end of the water and how clear or colored is the water near the shorelines.
While the water material is easily configurable to look great in both Gamma and Linear color spaces, Linear is recommended for best and most coherent results.
There are several variants included under the mirror shaders section: a simple mirror that just renders the reflection without any further effects; a PBR mirror with support for fogginess and blurred reflections; a mirror with blur support only; mirror with fog support only and mirrors with distortions for broken reflections.
SIMPLE REFLECTION SHADER
(PIDI SHADERS COLLECTION/PLANAR REFLECTION/MIRROR/SIMPLE)
The most basic reflective shader available, it takes a render texture with the reflection from a PIDI_PlanarReflection object and applies a color to it.
FOGGY MIRROR SHADER
(PIDI SHADERS COLLECTION/PLANAR REFLECTION/MIRROR/FOG+BLUR)
This shader is useful to simulate a more complex mirror with support for overlay textures, radial fog coverage, normals to distort the reflections among other effects.
The shader takes an overlay/decal texture which will be rendered on top of the reflection and fog and will react to the scene's lighting. The alpha of the texture is used to show the reflection through.
A Normal map can be assigned as well, to distort the reflections, be used as a normal map or both. The Bump+Distortion/Just Distortion slider controls this transition.
The strength of the distortion effect is controlled with the Reflection Distortion slider.
A color tint can be applied to the reflection through the Reflection Tint color.
The reflection texture can be assigned automatically by the PIDI_PlanarReflection object.
The fog color modifies the final color of the fog in the mirror while the fog texture controls how it spreads. The red channel of the fog texture controls the spreading of the fog. When the Fog Level is changed, the fog will appear spreading from the highest to the lowest red values in the fog texture.
In the example texture this is in a radial gradient towards the center. This is further multiplied by the green and blue channels to give some variation to the spreading. The alpha channel of the fog texture is used to control precisely which parts of the mirror will not have any fog. Internally, the shader automatically blurs the reflection in the fogged zones, making the blur as strong as the fog.
Additional variants with support for only blur, only fog or only the overlay are also provided.
BROKEN MIRROR SHADER
(PIDI SHADERS COLLECTION/PLANAR REFLECTION/MIRROR/BROKEN)
This shader is used to simulate broken reflections such as in damaged mirrors and other similar surfaces. Each shard of the mirror applies distortion and offset to the reflection without generating additional passes, generating complex effects at a very low performance cost.
The shader takes an overlay/decal texture which will be rendered on top of the broken effect while being slightly distorted by it.
The Normal map is used to make a more believable effect and should match the broken pattern.
The Reflection distortion is applied to the reflection texture to make it deform along the breaking patterns and the normal map.
The broken map is a texture that controls the full breaking effect. The alpha channel acts as the height map for the distortion, the red and green channels control the displacement of the reflection along the X/Y axis and the blue channel controls the sign of the direction of the movement (B>0.5 = positive, B< 0.5 = negative )
Four variants of generic reflective shaders based on the Standard Specular shader are included with this package. These generic shaders are meant for regular PBR materials that should display a slight real-time reflection (such as marble floors, plastics, etc ). The variants are : Simple Surface, Simple Surface+ Blur, Depth+Blur, Alpha Surface and Alpha Surface+Blur.
They take a Main texture to be displayed on the surface, a Normal map that will also distort the reflection, a GSOH Map (R=Gloss, G = Specularity, B = Occlusion, A = Height)
The Parallax Height value controls a basic Parallax mapping effect.
The Reflection Tint adds some coloring to the final reflection.
Bump Reflection Distortion is the amount of distortion that the bump mapping will apply over the real-time reflections.
Surface Distortion allows the reflections to be affected by the curvature of surfaces that are not entirely flat
Both the ReflectionTex and ReflectionDepth are provided by the Planar Reflections component automatically.
The reflections can be distorted and blurred (depending on the shader variant) and the alpha channel of the main texture can control the transparency of the material (in Alpha enabled variants )
Additionally, all the generic surface shader have full support for an emission channel to be used and give full control over how the emission will mix with the reflections.
In additive mode the reflection and the emission channels will be added to one another and mixed. In masked mode the emission channel will cover the reflections, hiding them.
Besides these parameters there is also a HDR mode that allows you to use over brightness in your emission channel which is very useful for HDR based effects such as advanced bloom.
In version 1.4+ we have included a new kind of shader designed for performance limited platforms such as mobile, which combines a static cubemap with a real-time reflection whose background color is dynamically removed with a chroma key effect. While the effect is still expensive due to the shader operations, it is far less demanding than rendering unnecessary geometry several times (once for the main scene, once for each reflection).
To use these shaders effectively, enable the Chroma Key Effects flag on the PIDI_PlanarReflection component and define a background color that will be removed. Then, using the Chroma Key Tolerance value, control the amount of background that will be removed.
Finally, nine variants of PBR reflective shaders are included with this package. These shaders are meant for regular PBR materials that should mimic Unity's Standard shader as close as possible. The variants are :
PBR REFLECTIVE SHADERS
(PIDI SHADERS COLLECTION/PLANAR REFLECTION/PBR)
This collection of shaders is based on the Standard shader included with Unity and all the inputs match those of the Standard Unity shader, with just a few differences.
For some values such as the metallic, gloss (smoothness), roughness and specular, the shader allows you to select the source of these inputs. The source can be either the direct values as shown in the shader's interface or the corresponding texture. By using the drop down menu you can select which source to use
On top of the standard shader properties and the default reflection properties such as the reflection tint, distortion and blur, the Depth versions of these shaders also include a variable called “Depth Blur Power” in the Depth variants and “Depth Fade Power” in the Depth (Fade) variants.
This Depth power variable controls how the depth will affect the reflections, either by controlling the amount of blur applied depending on the distance between the reflected objects and the surfaces or by fading out the far away objects in the case of the Depth Fade shaders.
Adding reflections support to a custom shader or any existing shader is very easy. There are just a few bits of code that you need to add to be ready to take full advantage of our tool.
The minimum implementation possible requires a 2D parameter called “_ReflectionTex” which will receive the output reflection texture from the PIDI_PlanarReflection component.
This reflection texture will then be unwrapped using screen coordinates. The standard code for screen coordinates is the following :
Once the texture has been unwrapped and its value stored in a half4 variable the reflection can be used without any issue. In most cases the reflection will be used through the Emission channel of the shader, but this is entirely optional and depends on the effect you want to achieve.
If you need complex examples of the different uses you can give to the reflections and how to integrate them to shaders we recommend you to read the source code of the included shaders as they will provide a good learning material.
If you need to use the reflection's depth for any purpose (as measured from the reflective surface) you just need to add a 2D parameter called “_ReflectionDepth” to your shader and the PIDI_PlanarReflection component will assign it at runtime in the same way as the normal reflection.
Then unwrap this texture by using the tex2Dproj function and use the length of the resulting color vector as your depth value. This depth will go from black (closest to the surface) to color (red for X axis, green for Y and blue for Z) depending on the distance to the reflective surface.