Class ShadowGenerator

3DS Max Plug-In SDK

Class ShadowGenerator

See Also: Class ShadowType, Class ShadBufRenderer, Class RendContext, Class RenderGlobalContext, Class ShadeContext, Class Matrix3, Class Point3, Class Color.

class ShadowGenerator

Description:

This class is available in release 3.0 and later only.

This class is used by a Shadow Type plug-in to generate the shadows. It only exists during a render, with one per instance of the light. Methods of this class perform the shadow buffer creation and sampling.

The ShadowGenerator API allows for two methods of sampling: A generator can use either a "generic" sampling method:

float Sample(ShadeContext &sc, Point3 &norm, Color& color);

Or, if it the generator is to work with Volumetric lights, it must use the following sampling shadow-map style interface:

float Sample(ShadeContext &sc, float x, float y, float z, float xslope, float yslope);

BOOL QuickSample(int x, int y, float z);

FiltSample(int x, int y, float z, int level);

LineSample(int x1, int y1, float z1, int x2, int y2, float z2);

To indicate that the latter interface is used, the method ShadowType::SupportStdMapInterface() must return TRUE;

The following functions are not part of this class but are available for use:

Function:

ShadowType *NewDefaultShadowMapType();

Remarks:

This global function returns a new default shadow-map shadow generator.

Function:

ShadowType *NewDefaultRayShadowType();

Remarks:

This global function returns a new default ray-trace shadow generator.

Methods:

public:

Prototype:

virtual int Update(TimeValue t, const RendContext& rendCntxt, RenderGlobalContext *rgc, Matrix3& lightToWorld, float aspect, float param, float clipDist = DONT_CLIP)=0;

Remarks:

This is called on every frame to create a new shadow buffer for that frame. For example, the objects in the scene will have moved to different position, etc., so a new shadow buffer will need to be set up. See Class ShadBufRenderer for a helper class used for generating shadow map buffers.

Parameters:

TimeValue t

The time for the update.

const RendContext& rendCntxt

The render context -- this is used for the progress bar.

RenderGlobalContext *rgc

This is used to get an instance list.

Matrix3& lightToWorld

The light to world space transformation matrix. This is not necessarily the same as that of the light.

float aspect

This is the aspect ratio for non-square buffers. The aspect gives the height/width ratio of the shadow rectangle. The shadow buffer bitmap is always the same number of pixels wide as it is high, but it can be mapped into a non-square rectangle.

float param

This is the field-of-view of the light in radians for perspective projections or the width in world coordinates for parallel projections.

float clipDist = DONTCLIP

This parameter specifies the far clipping distance for the light. This is used when the far distance attenuation is turned on, and can result in much more efficient shadow buffer creation. If you have a small scene in the middle of a large complex scene, and the small scene is lit by, for instance, a shadow-casting omni, if you don't use far attenuation the omni has to take into account the entire large scene in its shadow map. Using far attenuation will clip all this outside stuff. Also omnis free up any of their 6 shadow buffer that end up being empty, so this can save memory usage.

Return Value:

Nonzero on success; otherwise zero.

Prototype:

virtual int UpdateViewDepParams(const Matrix3& worldToCam)=0;

Remarks:

If things such as automatic cubic maps or mirror are used, the rendering is done from several different points of view. This method is called to allow the view matrix to be computed and cached so it won't have to be computed over and over again. The shadow buffer caches the matrix that does the transformation from the current view coordinates into its coordinates.

Parameters:

const Matrix3& worldToCam

This is the direction the view is looking from. Object coordinates are relative to this 'camera'. This is not always a 'camera', it is just world to whatever view is needed, for example from a mirror.

Return Value:

Nonzero on success; otherwise zero.

Prototype:

virtual void FreeBuffer()=0;

Remarks:

This method is used to delete the memory associated with the buffer.

Prototype:

virtual void DeleteThis()=0;

Remarks:

Call this to destroy the ShadowGenerator.

Prototype:

virtual float Sample(ShadeContext &sc, Point3 &norm, Color& color);

Remarks:

Generic shadow sampling function. Implement this when ShadowType::SupportStdMapInterface() returns FALSE.

This is the Sample method used for ray traced shadows, for example. It takes the color that would illuminate the surface if there were no shadows, and returns a modified value. The shade context provides the point on the surface (sc.P()) and norm is the normal to the surface.

Parameters:

ShadeContext &sc

The shade context provides the point on the surface (sc.P()).

Point3 &norm

This is the normal to the surface.

Color& color

The input color.

Return Value:

It returns an attenuation, where 1.0 indicates it is not in shadow, and 0.0 indicates it is in shadow.

Default Implementation:

{ return 1.0f; }

Prototype:

virtual float Sample(ShadeContext &sc, float x, float y, float z, float xslope, float yslope);

Remarks:

Implement this method when ShadowType::SupportStdMapInterface() returns TRUE. This interface allows illuminated atmospherics.

This method is called to determine how much the point (x, y, z) is in shadow. It returns an attenuation, where 1.0 indicates it is not in shadow, and 0.0 indicates it is in shadow, and potentially a small negative number. A small negative number should be returned when the sample falls outside of the buffer (this is needed in order to fix a problem occuring with Omni Lights when using shadow maps). All shadow generators that implement this function need to do this. The value itself isn't important, as long as it is negative and very small (for instance (-float(1.0e-30)).

Parameters:

ShadeContext &sc

The shade context.

float x

The x coordinate of the point to check. This point is normalized into shadow buffer space. For example if the shadow buffer was 256x256 a point at the center would be 128, 128.

float y

The y coordinate of the point to check. This point is normalized into shadow buffer space.

float z

The z coordinate of the point to check. This is the distance perpendicular to the light where 0.0 is right at the light.

float xslope

This indicates the slope of the surface relative to the shadow buffer in x.

float yslope

This indicates the slope of the surface relative to the shadow buffer in y.

Default Implementation:

{ return 1.0f; }

Prototype:

virtual BOOL QuickSample(int x, int y, float z);

Remarks:

Implement this method when ShadowType::SupportStdMapInterface() returns TRUE. This interface allows illuminated atmospherics.

This method determines if the given point is in a shadow. It samples a single pixel in the shadow map.

Parameters:

int x

The x coordinate of the point to check. This point is normalized into shadow buffer space. For example if the shadow buffer was 256x256 a point at the center would be 128, 128.

int y

The y coordinate of the point to check. This point is normalized into shadow buffer space.

float z

The z coordinate of the point to check. This is the distance perpendicular to the light where 0.0 is right at the light.

Return Value:

TRUE if the point is in shadow; otherwise FALSE.

Default Implementation:

{ return 1; }

Prototype:

virtual float FiltSample(int x, int y, float z, int level);

Remarks:

Implement this method when ShadowType::SupportStdMapInterface() returns TRUE. This interface allows illuminated atmospherics.

This method is called to determine how much the point (x, y, z) is in shadow. It returns an attenuation, where 1.0 indicates it is not in shadow, and 0.0 indicates it is in shadow. The method QuickSample() above looks at a single pixel in the shadow buffer. This method looks at either 4 or 8 pixels (based on the level parameter) to compute the result. The center pixel is given the highest weighting, while the other pixels are given lesser weightings. However this method is still fairly quick, since it doesn't base the weighting on the location within the pixel. This is in contrast to the Sample() method above, where the blending of the adjacent pixels is weighted by the position within the sub-pixel.

Parameters:

int x

The x coordinate of the point to check. This point is normalized into shadow buffer space. For example if the shadow buffer was 256x256 a point at the center would be 128, 128.

int y

The y coordinate of the point to check. This point is normalized into shadow buffer space.

float z

The z coordinate of the point to check. This is the distance perpendicular to the light where 0.0 is right at the light.

int level

This may be 0 or 1. If 0, four neighboring pixels are blended in. If 1, eight neighboring pixels are blended in.

Return Value:

A value in the range 0.0 to 1.0.

Default Implementation:

{ return 1.0f; }

Prototype:

virtual float LineSample(int x1, int y1, float z1, int x2, int y2, float z2);

Remarks:

Implement this method when ShadowType::SupportStdMapInterface() returns TRUE. This interface allows illuminated atmospherics.

This method is called to sample the shadow map along a line segment. It uses a line between x1, y1 and x2, y2. The z values are interpolated between z1 and z2 and compared to the z value in the shadow map for that pixel.

Parameters:

int x1

The start x coordinate of the line. This point is normalized into shadow buffer space. For example if the shadow buffer was 256x256 a point at the center would be 128, 128.

int y1

The start y coordinate of the line. This point is normalized into shadow buffer space.

float z1

The start z coordinate of the line. This is the distance perpendicular to the light where 0.0 is right at the light.

int x2

The end x coordinate of the line. This point is normalized into shadow buffer space.

int y2

The end y coordinate of the line. This point is normalized into shadow buffer space.

float z2

The end z coordinate of the line. This is the distance perpendicular to the light where 0.0 is right at the light.

Return Value:

A value in the range 0.0 to 1.0 which represents how much of the ray was inside the light and how much was outside the light.

Default Implementation:

{ return 1.0f; }