| |
|
|
||||
![]() |
||||||
| |
|
|||||
|
A Non-Integer Power Function on the Pixel Shader The Pixel
Shader
It should be noted that, since interpolated colors do not support negative values, we place the sign corrected light vector in color 0. This can be written as L' = 0.5(L + (1,1,1) ). We need to have access to KAmbc and LAmbc that are constant from one pixel to the next. Due to the nature of the equation, we can precompute the product of these coefficients. Therefore, we store the resulting vector (KAmbR*LAmb, KAmbG*LAmbG, KAmbB*LAmbB ) in the first three components of constant register c0. We also need the values of constant coefficients LDiffc and LSpecc. These are stored in the first three components of registers c1 and c2, respectively. Finally, we need to pick the approximation exponent m used for the power function. In our example, we use m = 8. We also use _x4 as the multiply instruction modifier for each instruction of the power function approximation. Since we wish to use a value of n varying per pixel, we must precompute k-1/m = 0.074325. We store this value in the alpha channel of constant register c0. Looking at Table 2, we find that the maximal n that can be achieved is 116.34. Also, using the function TranslateTexture of Listing 10 we can convert per texel values of n into values of A' to be placed in the alpha component of texture 0. The pixel shader that computes per pixel Phong shading then becomes:
Listing
14. Code for Phong shading with various features Summary The method has several advantages over traditional exponentiation techniques that use either a texture look-up or a series of sequential multiplications. Texture look-ups are only accurate for pixel shader versions 1.4 and greater, and even then will require two phases. Sequential multiplications need a large number of stages to compute high power-of-two exponents and even more for non-power-of-two. Additionally, since the multiplications are inherently uniform during the entire shader, they do not allow for a smooth variation in power. A couple of applications were suggested, and Phong shading in particular is covered in the results below. We believe such a useful technique can be applied to many other algorithms that require a power function, especially considering that it can be abstracted to any effect requiring a sharp yet smooth transition, such as a spotlight's cone falloff. The per pixel variation of the exponent, which is a handy extension to the basic principle, can provide important visual cues for surfaces whose specularity varies, such as for a material including both metallic and organic features. Its main disadvantages are that m constrains the lower bound of the specular exponent n, as explained in the mathematical details section, and that one component of a texture must be used to encode the exponent. The latter, however, is expected of any technique that varies the exponent per pixel. The shading code of Listing 14 was applied to red spheres with different properties, such as faceted per pixel exponent maps, wrinkled normal maps, and orange specular maps. The results can be seen in Figure 12. Due to the many iterative multiplications, there is a large accumulation of error that manifests itself as banding. Generally speaking, the greater the exponent, the more banding will be evident, however, this is mostly noticeable on smooth surfaces, such as those expressed with uniform normal maps. The banding artifacts are less significant when using normal maps that contain some perturbation because the specular falloff is quite sharp due to the abrupt changes in the normal. Therefore, visual artifacts are reduced as detail in the normal map is increased. Banding can also result from reduced instruction counts. If additional instructions are available, we recommend using them to maximize precision. Note that since the Phong shading algorithm presented only requires exponentiation of a single component, the instructions easily fit into the scalar pipeline of the pixel shader, which reduces the number of dedicated stages. The shader code of Listing 14 consumes two stages purely for exponentiation purposes, but instructions in the vector pipeline can be co-issued at these stages if desired. For example, the specular texture can be removed if the diffuse and specular materials are represented by a single texture. We can then use a cube map at that stage to represent the surrounding environment, even encoding a Fresnel term in the remaining colour register. The math computations can easily be accommodated within the two remaining vector instructions. Finally, the images in Figure 12 were rendered on hardware with 8 bits of fractional precision. Other hardware is available which has more than 8 bits of fractional precision and will suffer less from the banding artifacts. We hope you found this trick helpful and that you will find many more uses for an approximating power function in your shading endeavors.
|
||||||||||||||||||||||
|
|