Graphics Reference
In-Depth Information
simplify the process of rendering the geometry into our paraboloid maps. Since we are
using the geometry shader to pass the geometry to the appropriate render target, we will
need to create one copy of the geometry for each paraboloid map. This could either be
statically performed by copying the paraboloid projection code twice, or it could also be
implemented with a simple loop. Both of these methods are less than optimal, and either
clutter the code (in the case of repeating the code) or introduce additional work to imple-
ment (in the case of looping). Instead, we can simply use geometry shader instancing to
produce multiple copies of each primitive that the geometry shader receives. Then the
SV_GSInstanceID system value semantic can be used to determine which paraboloid map
each invocation of the geometry shader should be applied to. This results in very clean
shader code that can efficiently fill multiple paraboloid maps simultaneously. 2
13.2.2 Rendering Paraboloid Maps
The first step in using our paraboloid maps is to render the scene into one for a reflective
object. For the sake of discussion, we will begin by assuming that we have a single reflec-
tive object and a single textured object in our scene. Thus, we need a technique to render
the textured object into a paraboloid map. The majority of this work will be split between
the vertex shader and geometry shader stages. Listing 13.1 provides the vertex shader for
this operation, and Listing 13.2 provides the geometry shader.
As seen in Listing 13.1, the vertex shader receives vertices with just a posi-
tion and a texture coordinate. We assume that the matrix passed in to the shader in the
WorldViewMatrix is the concatenation of a world matrix for the object being rendered,
and a view matrix that defines the basis of the paraboloid being filled. In reality, this is just
a view matrix taken from the location and orientation of the reflective object where the ori-
entation will define the forward and backward directions of the two paraboloids. The first
step in the vertex shader is to transform the incoming vertex position into this "paraboloid
basis."
Next, the distance from the origin of the paraboloid basis is calculated and used to
generate a normalized length vector pointing to the vertex. The normalized z-component
of this vector is passed to the next stage in the OUT. z_value variable, and a scaled version
of the distance to the vertex is also passed to the next shader stage for eventual use in the
depth buffer. Finally, the w -coordinate is simply set to 1, since we haven't performed any
perspective projections, and the input texture coordinates are simply passed through to the
next stage.
2 In fact, we don't need to limit ourselves to only filling the two paraboloid maps of a single object in each ren-
dering pass. If there are four reflective objects in a scene, we can fill all eight of the corresponding paraboloid
maps in the same rendering pass. For simplicity, we will use only two geometry shader instances at a time for the
remainder of this chapter.
Search WWH ::




Custom Search