Graphics Reference
In-Depth Information
and finding the min and max X and Y values of the eight resulting coordinates. Figure 11.9
illustrates this process.
This process can be optimized if it is assumed that the projection is perspective, and
that it is symmetrical with respect to the camera's X and Y axes. In this case, we can deter-
mine if the minimal or maximal X or Y value will be on the face of the box closest to the
camera, or on the face of the box farthest from the camera, based on the view-space X and
Y coordinates of the sphere. The code in Listing 11.14 uses this optimization to determine
the final screen-space rectangle that will be passed to the ID3D11DeviceContext::RSSet
ScissorRects method.
D3D11_RECT ViewLights: :CalcScissorRect( const Vector3f& lightPos,
float lightRange )
{
// Create a bounding sphere for the light., based on the position
// and range
Vector4f centerWS = Vector4f( lightPos, 1.0f );
float radius = lightRange;
// Transform the sphere center to view space
Vector4f centerVS = ViewMatrix * centerWS;
// Figure out the four points at the top, bottom, left, and
// right of the sphere
Vector4f topVS = centerVS + Vector4f( 0.0f, radius, 0.0f, 0.0f );
Vector4f bottomVS = centerVS - Vector4f( 0.0f, radius, 0.0f, 0.0f );
Vector4f leftVS = centerVS - Vector4f( radius, 0.0f, 0.0f, 0.0f );
Vector4f rightVS = centerVS + Vector4f( radius, 0.0f, 0.0f, 0.0f );
// Figure out whether we want to use the top and right from quad
// tangent to the front of the sphere, or the back of the sphere
leftVS.z = leftVS.x < 0.0f ? leftVS.z - radius : leftVS.z + radius;
rightVS.z = rightVS.x < 0.0f ? rightVS.z + radius : rightVS.z - radius;
topVS.z = topVS.y < 0.0f ? topVS.z + radius : topVS.z - radius;
bottomVS.z = bottomVS.y < 0.0f ? bottomVS. z - radius
: bottomVS.z + radius;
// Clamp the z coordinate to the clip planes
leftVS.z = Clamp( leftVS.z, m_fNearClip, m_fFarClip );
rightVS.z = Clamp( rightVS.z, m_fNearClip, m_fFarClip );
topVS.z = Clamp( topVS.z, m_fNearClip, m_fFarClip );
bottomVS.z = Clamp( bottomVS. z, m_fNearClip, m_fFarClip );
// Figure out the rectangle in clip-space by applying the
// perspective transform. We assume that the perspective
// transform is symmetrical with respect to X and Y.
float rectLeftCS = leftVS.x * ProjMatrix( 0, 0 ) / leftVS.z;
float rectRightCS = rightVS.x * ProjHatrix( 0, 0 ) / rightVS.z;
float rectTopCS = topVS.y * ProjMatrix( 1, 1 ) / topVS.z;
float rectBottomCS = bottomVS.y * ProjMatrix( 1, 1 ) / bottomVS.z;
Search WWH ::




Custom Search