Projector Manager is a singleton component which manages projectors in a scene. It will activate the projectors which are close to the main camera, and deactivate the projectors which are far from the main camera or not visible from the main camera. To activate/deactivate projectors, you need to setup “Projector Controls” properties.
For the deactivated projectors, Projector Manager will create quadrangle polygons to draw shadows. So, even when a projector is deactivated, it can project a shadow on a plane. For this purpose, you might need to setup “Plane Shadows” properties and “Plane Shadow Textures” properties.
For the activated projectors, you can use shadow receiver objects. However, it is meaningless to use InfinitePlaneShadowReceiver or RaycastShadowReceiver, because Projector Manager can also create quadrangle polygons like these two shadow receivers. If you want to use MeshShadowReceiver, you need to setup “Shadow Receivers” properties.
Shadow Receivers
- Receiver Layer Mask
Projector Manager will duplicate a set of shadow receiver objects in ‘Receivers’ array for each active projector object at runtime, and assign one of the layers in ‘Receiver Layer Mask’ to a duplicated set so that only one projector object can project a shadow onto the set of the receiver instances. If ‘Receiver Layer Mask’ doesn’t have enough layers, more than one projector objects will project shadows onto the same shadow receiver instance. Usually, it won’t cause a problem, but if the projection volumes intersect each other, some shadows will be drawn more than once, and a part of the shadow will be darker than the normal shadow. - Receivers
Specify a set of shadow receivers which will be duplicated for each active projector object at runtime. Usually, the set must have only one MeshShadowReceiver. Even if the environment model consists of multiple objects, it is better to combine these objects into one Mesh Tree object for performance reason. However, if the scene has an open field, you might want to create environment models at runtime. In such cases, you can add multiple MeshShadowReceiver objects from script using this following code:ProjectorManager.Instance.AddReceiver(shadowReceiver);
Also, you can remove a shadow receiver with this code:
ProjectorManager.Instance.RemoveReceiver(shadowReceiver);
If the array of ‘Receivers’ is empty, ‘Plane Shadows’ are used for activated projectors as well as deactivated projectors.
Projector Controls
- Main Camera
Specify a main camera in your scene. If not specified, Camera.main will be used. This camera is used to activate/deactivate projectors. Only the projectors which are close and visible to the camera will be activated. - Environment Layers (from Version 1.4.0)
Specify layers for the environment objects. This layer mask is used for projectors to ignore the environment objects. If you specify this layer mask properly, you don’t need to set the environment layers to Ignore Layers of the projectors so that you can see shadows in Editor. - Projector Fadeout Distance
Specify a range where the projectors can be active around the main camera. - Fade Duration
Specify fade in/out duration. To enable fade in/out, the material of a projector should have “_Alpha” property to control the darkness of shadows.
Plane Shadows
- Raycast Plane Mask
Specify a layer mask which will be passed to Physics.Raycast function. Raycast is performed for each projector to create a quadrangle polygon at the position where a ray from the projector hit. If ‘Nothing’ is specified, no raycast will be performed. - Use Infinite Plane
Specify if a infinite plane is used to create plane shadows or not. Raycast Plane has a higher priority than Infinite Plane. A quadrangle shadow polygon will be created on the infinite plane only when a raycast hit nothing. If this option is checked, the following three parameters will be shown. - Infinite Plane Transform
Specify a transform of the infinite plane. If not specified, the infinite plane will be placed in world space. - Infinite Plane Normal
Specify a normal vector of the infinite plane. - Infinite Plane Height
Specify a distance from the position of ‘Infinite Plane Transform’ to the plane.
Plane Shadow Textures
- Blob Shadow Textures
Set all the blob shadow textures used in the scene here. - Packed Blob Shadow Texture
Specify a combined texture which includes all the textures in ‘Blob Shadow Textures’ array. You can generate a combined texture by clicking “Pack Blob Shadow Textures” button. - Packed Shadow Texture Rects
Specify a uv rect in the combined texture for each ‘Blob Shadow Texture’. The uv rects will be generated in conjunction with the combined texture when “Pack Blob Shadow Textures” button is clicked. - Packed Texture Padding
Specify a padding size in pixels between the packed textures. - Packed Texture Max Size
Specify a maximum size of a texture which will be generated by “Pack Blob Shadow Textures” button. - Shadow Tex Name
Specify a texture name used in both Projector’s material and Projector Manager’s material. By default, it is “_ShadowTex”.
Manual Update
If ‘Manual Update’ is checked, Projector Manager will not be updated automatically. If you want to control the update timing, use this option and call
ProjectorManager.Instance.UpdateScene();
at the right timing.
If ‘Manual Update’ is unchecked, Projector Manager will be updated on LateUpdate.
I found a strange shadow behaviour during using ProjectorManager.
My camera has complex movements, one of it is to circling around and look at a target .If I set the “Projector Fadeout Distance” say 100, when the camera run into some specific angles , the shadow will disappear , and i can sure the distance between camera and shadow target less than 100.
After trace into the code, i found a line 295 at ProjectManager.cs, plane = m_cameraClipPlanes[2];
please make sure it’s using index 2, i changed it to 1, then the shadow behaviours exactly like what i expected.
Thanks for letting me know about the bug. You are right. The correct plane was m_cameraClipPlanes[1] for non-orthogonal camera. I will fix the line 260 and 261 rather than 295 so that m_cameraClipPlanes[2] can be a correct plane for both orthogonal and perspective camera.
Thanks