Click or drag to resize
AB4D logo

PlanarShadowRenderingProvider Class

PlanarShadowRenderingProvider provides support for rendering shadows on a 3D plane surface.
Inheritance Hierarchy
SystemObject
  Ab3d.DirectXDXResourceBase
    Ab3d.DirectXDisposableDXResource
      Ab3d.DirectXDXSceneResource
        Ab3d.DirectXShadowRenderingProviderBase
          Ab3d.DirectXPlanarShadowRenderingProvider

Namespace: Ab3d.DirectX
Assembly: Ab3d.DXEngine (in Ab3d.DXEngine.dll) Version: 7.1.9105.2048 (1.0.0.0)
Syntax
C#
public class PlanarShadowRenderingProvider : ShadowRenderingProviderBase

The PlanarShadowRenderingProvider type exposes the following members.

Constructors
 NameDescription
Public methodPlanarShadowRenderingProvider Constructor
Top
Properties
 NameDescription
Public propertyApplyShadowMatrix Gets or sets a Boolean that specifies if a shadow matrix is applied to the rendered 3D objects. By default this property is set to true, but when rendering custom shadow objects (defined in a custom RenderingQueue) that already have shadow matrix applied, then this property should be set to false.
Public propertyCustomShadowLight When CustomShadowLight is set, then it is used as a light that generates the shadow instead of a light from a 3D scene. This way it is possible to generate a shadow from a light that does not illuminate the scene. The only possible types of lights that can be assigned to this property are PointLight and DirectionalLight. It is also possible to use a custom light with overriding the CalculateShadowMatrix method.
Public propertyCutShadowToPlaneBounds Gets or sets a boolean that specifies if shadow is clipped to the shadow plane's bounds. When true then stencil buffer is used to render only the the part where the plane is rendered; when false the mesh need to be clipped on the CPU (for example with using PlanarShadowMeshCreator from Ab3d.PowerToys).
Public propertyDepthStencilFormat Gets or sets format of depth stencil buffer that is set by this PlanarShadowRenderingProvider. Possible values are D32_Float_S8X24_UInt (default) and D24_UNorm_S8_UInt. When changed the change need to be done before initializing the PlanarShadowRenderingProvider.
Public propertyFilterRenderingQueuesFunction Gets or sets a filter function that can be used to filter RenderingQueue that will be rendered (returning false for RenderingQueue that are not rendered). This property can be set to render only shadow objects that are defined in a custom RenderingQueue or to prevent rendering transparent objects.
Public propertyIsCheckingIsCastingShadow Gets or sets a Boolean that specifies if PlanarShadowRenderingProvider is checking if object has IsCastingShadow property set. That check can slightly decrease performance therefore the default value is false.
Public propertyShadowColor Gets or sets a color that is used to render shadow. Default value is Black. See also ShadowTransparency that defines the transparency of the shadow.
Public propertyShadowOffsetFromPlane Gets or sets a float number that specifies the distance of the shadow "objects" from the plane. This distance needs to be specified to prevent z-fighting artifacts that would occur is plane and shows objects are rendered to the same 3D positions. Default value is 0.01f.
Public propertyShadowPlaneBackMaterial Gets or sets a DirectX Material that is used to render the back (bottom) side of the shadow plane.
Public propertyShadowPlaneCenterPosition Gets or sets a Vector3 that specifies the center position of the shadow plane. Default value is (0, 0, 0).
Public propertyShadowPlaneHeightDirection Gets or sets a Vector3 that specifies the direction of the height (in the plane's size). Default value is (0, 0, -1).
Public propertyShadowPlaneMaterial Gets or sets a DirectX Material that is used to render the front (top) side of the shadow plane.
Public propertyShadowPlaneNormalVector Gets or sets a Vector3 that specifies the normal vector of the shadow plane. Default value is (0, 1, 0).
Public propertyShadowPlaneRenderingQueue Gets a RenderingQueue that is used to render shadow plane. If you are rendering your own shadow plane, then use this RenderingQueue.
Public propertyShadowPlaneSize Gets or sets a Vector2 that specifies the size of the shadow plane. When size is set to (0, 0), then the shadow plane is not rendered and also the shadow is not cut to shadow plane.
Public propertyShadowTransparency Gets or sets a float value that defines the transparency of the shadow (1 means no transparency; 0 means full transparency; default value is 0.65f).
Top
Methods
 NameDescription
Public methodCalculateShadowMatrix CalculateShadowMatrix is a virtual method that calculates the shadow matrix from the shadow light. This matrix is used to transform the 3D objects into flat shadow meshes.
Public methodStatic memberGetDirectionalLightShadowMatrix GetDirectionalLightShadowMatrix is a static method that calculates the shadow matrix for the specified light direction and shadow plane.
Public methodStatic memberGetPointLightShadowMatrix GetPointLightShadowMatrix is a static method that calculates the shadow matrix for the specified light position and shadow plane.
Public methodUpdate Update method is called on each DXScene.Update call before rendering of the scene begins. If derived class need to create some SceneNodes then they should be created in the overridden methods.
(Overrides ShadowRenderingProviderBaseUpdate)
Top
Fields
 NameDescription
Public fieldStatic memberPlanarShadowsRenderingStepsGroupName Name of the RenderingStepsGroup that contains rendering steps that render planar shadow.
Public fieldStatic memberRenderPlanarShadowsRenderingStepName Name for RenderPlanarShadows RenderingStep - renders shadow.
Public fieldStatic memberRenderShadowPlaneRenderingStepsName Name of the RenderShadowPlane RenderingStep - renders plane 3D object.
Public fieldStatic memberShadowPlaneRenderingQueueName Name for RenderingQueue that contains shadow plane renderable object.
Top
Remarks

PlanarShadowRenderingProvider provides support for rendering shadows on a 3D plane surface.

Its advantage over VarianceShadowRenderingProvider is that it can render sharp shadows that do not loose precision even when user zoom into the shadow. It is also much faster to render. The shadows are rendered with applying a shadow matrix to all objects. This matrix flatten all the objects so that they have no height and become only a 2D shape of the object's shadow. That shape is then rendered a 3D object on top of the plane.

To support clipping to plane's bounds by the GPU (when using Ab3d.PowerToys this need to be done in software) and to prevent rendering some parts of the shadow multiple times, a DirectX stencil buffer is used.

Disadvantages of VarianceShadowRenderingProvider are:
- it can render shadows only to a 3D plane,
- it cannot render soft shadows,
- shadows are rendered for object behind the plane or point light,
- some objects that lie on the plane or are very close to the plane may get slightly invalid shadow.

It is also possible to render planar shadows without PlanarShadowRenderingProvider and with using only PlanarShadowMeshCreator from Ab3d.PowerToys but this does not provide hardware accelerated shadows rendering (shadow object need to be created on the CPU) and cannot render transparent shadows correctly - see samples that come with Ab3d.PowerToys.

PlanarShadowRenderingProvider support only directional or point light as source of the shadow. To use a custom light that does not illuminate the 3D scene set the CustomShadowLight property. Otherwise, the first light that has DXAttributeType.IsCastingShadow attribute set to true is used. If no light has IsCastingShadow attribute set, then the first directional or point light is used.

PlanarShadowRenderingProvider also renders the 3D plane that receives the shadow. If you want to render your the plane by yourself, then set ShadowPlaneMaterial and ShadowPlaneBackMaterial to null. But you must still provide ShadowPlaneSize (and ShadowPlaneCenterPosition, ShadowPlaneNormalVector and ShadowPlaneHeightDirection when they differ from default values). This is needed to correctly set the stencil buffer to clip shadow to the plane's area. If ShadowPlaneSize is set to (0,0) them the shadow plane will not be rendered and the shadow will not be clipped by the PlanarShadowRenderingProvider.

Example

To enable planar shadow rendering the InitializeShadowRendering(ShadowRenderingProviderBase) method must be called with an instance of PlanarShadowRenderingProvider. The following code shows that:

C#
// Create new PlanarShadowRenderingProvider
var planarShadowRenderingProvider = new PlanarShadowRenderingProvider()
{
    ShadowPlaneCenterPosition = new Vector3(0, 0, 0),
    ShadowPlaneSize = new Vector2(400, 400),
    ShadowPlaneNormalVector = new Vector3(0, 1, 0),
    ShadowPlaneHeightDirection = new Vector3(0, 0, -1),

    ShadowPlaneMaterial = new StandardMaterial()
    {
        DiffuseColor = Colors.Green.ToColor3()
    },

    ShadowPlaneBackMaterial = new StandardMaterial()
    {
        DiffuseColor = Colors.DimGray.ToColor3()
    },

    ShadowColor = Color3.Black,
    ShadowTransparency = 0.65f,

    // Because shadow is rendered as standard 3D object, we need to offset it from the shadow plane
    // to prevent z-fighting problems that occur when two 3D objects are rendered to the same 3D position.
    // This value need to be very small so that it is not seen that the shadow is above the plane.
    // Default value is 0.01f.
    ShadowOffsetFromPlane = 0.01f,

    // When using PlanarShadowRenderingProvider we do not need PlanarShadowMeshCreator from Ab3d.PowerToys
    // to prepare a special MeshGeometry3D for us. Also PlanarShadowMeshCreator does not need to manually (on the CPU)
    // cut the shadow to the plane bounds but this can be done with using hardware accelerated algorithm (using stencil buffer).
    // But if we still want to use PlanarShadowMeshCreator we can set the following two properties to false 
    // (for example if we wanted to use PlanarShadowRenderingProvider just to provide proper transparent shadows).
    ApplyShadowMatrix = true,
    CutShadowToPlaneBounds = true,

    // To use a custom light that does not illuminate the 3D scene set the CustomShadowLight.
    // Otherwise the first light that has DXAttributeType.IsCastingShadow attribute set to true is used.
    // If no light has IsCastingShadow attribute set, then the first directional or point light is used.
    //CustomShadowLight = new Ab3d.DirectX.Lights.DirectionalLight(new Vector3(0, -1, 1))
    //CustomShadowLight = new Ab3d.DirectX.Lights.PointLight(new Vector3(0, 500, 0), 300)
};

// Initialize shadow rendering with DXEngine
MainDXViewportView.DXScene.InitializeShadowRendering(planarShadowRenderingProvider);
See Also