texture perturbation effects - amddeveloper.amd.com/wordpress/media/2012/10/shaderx... · texture...

12
Texture Perturbation Effects Texture Perturbation Effects John Isidoro Guennadi Riguer ATI Research ATI Research Introduction The recent generation of graphics hardware has brought about a new level of per- pixel programmability for real time graphics, especially with regards to dependant texture reads. With the ability to perform per-pixel math both before and after texture fetches, a variety of new texture based effects are now possible. This section will focus on per- pixel texture perturbation effects, effects that use the results of a texture fetch to change the texture coordinates used to fetch another texel. Effects such as wispy clouds, billowing smoke, flickering fire, rippling water, and plasma can be rendered in real time using the techniques shown in this section. Wispy Clouds One of the easiest effects that can be achieved using texture perturbation is wispy clouds as seen in the ATI Island Demos. The idea is to scroll two tileable textures past each other in opposite directions. The first texture is the perturbation texture, which has u and v perturbations stored in the red and green channels of the texture. Red Channel of Texture (u perturbation) Green Channel of Texture (v perturbation) The second texture is the cloud texture, which has its texture coordinates perturbed by the perturbation map. For this section, we use a grayscale cloud texture and pack it into the alpha channel of the perturbation map. Because of this packing, only one texture is needed for each layer of clouds. This texture is fetched from twice in the shader, first to obtain the perturbation values, then to read the perturbed texture. Excerpted from ShaderX: Vertex and Pixel Shader Tips and Tricks 1

Upload: others

Post on 16-Jul-2020

28 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Texture Perturbation Effects - AMDdeveloper.amd.com/wordpress/media/2012/10/ShaderX... · Texture Perturbation Effects Cloud Texture Basic Cloud Shader in Action Here is the pixel

Texture Perturbation Effects

Texture Perturbation Effects

John Isidoro Guennadi Riguer ATI Research ATI Research Introduction The recent generation of graphics hardware has brought about a new level of per-pixel programmability for real time graphics, especially with regards to dependant texture reads. With the ability to perform per-pixel math both before and after texture fetches, a variety of new texture based effects are now possible. This section will focus on per-pixel texture perturbation effects, effects that use the results of a texture fetch to change the texture coordinates used to fetch another texel. Effects such as wispy clouds, billowing smoke, flickering fire, rippling water, and plasma can be rendered in real time using the techniques shown in this section. Wispy Clouds

One of the easiest effects that can be achieved using texture perturbation is wispy clouds as seen in the ATI Island Demos. The idea is to scroll two tileable textures past each other in opposite directions. The first texture is the perturbation texture, which has u and v perturbations stored in the red and green channels of the texture.

Red Channel of Texture (u perturbation) Green Channel of Texture (v perturbation)

The second texture is the cloud texture, which has its texture coordinates

perturbed by the perturbation map. For this section, we use a grayscale cloud texture and pack it into the alpha channel of the perturbation map. Because of this packing, only one texture is needed for each layer of clouds. This texture is fetched from twice in the shader, first to obtain the perturbation values, then to read the perturbed texture.

Excerpted from ShaderX: Vertex and Pixel Shader Tips and Tricks

1

Page 2: Texture Perturbation Effects - AMDdeveloper.amd.com/wordpress/media/2012/10/ShaderX... · Texture Perturbation Effects Cloud Texture Basic Cloud Shader in Action Here is the pixel

Texture Perturbation Effects

Cloud Texture

Basic Cloud Shader in Action

Here is the pixel shader code for the basic cloud shader: ps.1.4 texld r0, t0 texcrd r1.rgb, t1 mad r0, r0, c0, r1 //multiply perturbation by scale factor, and add texcoords phase texld r0,r0 mov r0, r0

In order to make the clouds look much more realistic however, its best to use multiple layers of clouds. The layers can be combined in quite a few different ways. A straightforward approach to combining the layers is to linearly interpolate between them within the pixel shader. This gives the appearance of one layer of clouds being on top of the other. The cloud layers are scrolled past each other at different speeds to give the effect of depth through parallax.

The following shader is the result of combining two layers of clouds with a horizon.

Excerpted from ShaderX: Vertex and Pixel Shader Tips and Tricks

2

Page 3: Texture Perturbation Effects - AMDdeveloper.amd.com/wordpress/media/2012/10/ShaderX... · Texture Perturbation Effects Cloud Texture Basic Cloud Shader in Action Here is the pixel

Texture Perturbation Effects

In order to give the clouds a color gradient from a grayscale texture map, we use a multiply operation which is scaled by two, and then saturated. In the example, the color to be modulated with the clouds is orange (RGB values: 1.0, 0.7, 0.5). The gradient that results from the scale and modulation ranges between brown, orange, yellow and white. Cloud texture intensity Color after modulation 0.00 (0.000, 0.000, 0.000) black 0.25 (0.500, 0.375, 0.250) brown 0.50 (1.000, 0.750, 0.500) orange 0.75 (1.000, 1.000, 0.750) yellow 1.00 (1.000, 1.000, 1.000) white

Because the same grayscale texture is used for both intensity and transparency, the black regions of the clouds are completely transparent. The two cloud layers are then linearly interpolated with the background. The background texture is just a gradient from purple to blue.

Scene using Two Layer Cloud Shader with Horizon

// SetPixelShaderConstant 0 psConstVec (0.0, 0.5, 1.0, 0.75) // SetPixelShaderConstant 1 cloud0PerturbationFactor // SetPixelShaderConstant 2 cloud0Color // SetPixelShaderConstant 3 cloud1PerturbationFactor // SetPixelShaderConstant 4 cloud1Color ps.1.4 texld r0, t1 //perturbation map 0 texld r1, t3 //perturbation map 1 texcrd r2.rgb, t0 //cloud layer 0 tex coord texcrd r3.rgb, t2 //cloud layer 1 tex coord mad r0.rgb, c1, r0_bx2, r2 //perturb base map coords by cloud coords mad r1.rgb, c3, r1_bx2, r3 //perturb base map coords by cloud coords phase texld r0, r0

Excerpted from ShaderX: Vertex and Pixel Shader Tips and Tricks

3

Page 4: Texture Perturbation Effects - AMDdeveloper.amd.com/wordpress/media/2012/10/ShaderX... · Texture Perturbation Effects Cloud Texture Basic Cloud Shader in Action Here is the pixel

Texture Perturbation Effects

texld r1, r1 texld r2, t4 mul_x2_sat r4.rgb, r0.a, c2 //cloud layer 0, multiply by color +mul r4.a, r0.a, c2.a //cloud layer 0, alpha scale mul_x2_sat r3.rgb, r1.a, c4 //cloud layer 1, multiply by color +mul r3.a, r1.a, c4.a //cloud layer 1, alpha scale lrp r0.rgb, r1.a, r3, r4 //interpolate between layers 0 and 1 +add_sat r0.a, r3.a, r4.a //add transparency values for layer lrp_sat r0, r0.a, r0, r2 //interpolate between clouds and horizon

Cloud layers can be combined in ways other than simple linear interpolation. Another technique is to use the horizon texture to brighten the edges of the clouds around the moon to give a light halo effect. This shader is quite complex. The images below show each step of the shader.

Horizon map Alpha of horizon map (glow map)

Cloud layer 0 Cloud layer 1

Cloud edges of both maps combined extracted from cloud texture

Excerpted from ShaderX: Vertex and Pixel Shader Tips and Tricks

4

Page 5: Texture Perturbation Effects - AMDdeveloper.amd.com/wordpress/media/2012/10/ShaderX... · Texture Perturbation Effects Cloud Texture Basic Cloud Shader in Action Here is the pixel

Texture Perturbation Effects

Combined cloud layers

Combined cloud alphas (transparency map)

Cloud Edges * Glow

Excerpted from ShaderX: Vertex and Pixel Shader Tips and Tricks

5

Page 6: Texture Perturbation Effects - AMDdeveloper.amd.com/wordpress/media/2012/10/ShaderX... · Texture Perturbation Effects Cloud Texture Basic Cloud Shader in Action Here is the pixel

Texture Perturbation Effects

Two cloud layers combined with Cloud Edges * Glow

Final result: Cloud Layers with Glowing Edges Blended with Horizon

// SetPixelShaderConstant 0 psConstVec (0.0, 0.5, 1.0, 0.75) // SetPixelShaderConstant 1 cloud0DistortionFactor // SetPixelShaderConstant 2 cloud0Color // SetPixelShaderConstant 3 cloud1DistortionFactor // SetPixelShaderConstant 4 cloud1Color // SetPixelShaderConstant 5 horizonBoost ps.1.4 texld r0, t1 texld r1, t3 texcrd r2.rgb, t0 texcrd r3.rgb, t2 mad r0.rgb, c1, r0_bx2, r2 //perturb base map coords by cloud coords mad r1.rgb, c3, r1_bx2, r3 //perturb base map coords by cloud coords phase texld r0, r0 texld r1, r1 texld r2, t4 mov_x2 r3.rgb, r2.a //alpha of horizon (glow map) +mul_sat r3.a, 1-r0.a, 1-r1.a //mask edges for cloud glow mad_sat r0.rgb, 1-r0.a, c2, c2.a //scale and bias inverted clouds layer 0 +mov_x2_sat r0.a, r0.a //boost cloud alpha 0 mad_sat r1.rgb, 1-r1.a, c4, c4.a //scale and bias inverted clouds layer 1

Excerpted from ShaderX: Vertex and Pixel Shader Tips and Tricks

6

Page 7: Texture Perturbation Effects - AMDdeveloper.amd.com/wordpress/media/2012/10/ShaderX... · Texture Perturbation Effects Cloud Texture Basic Cloud Shader in Action Here is the pixel

Texture Perturbation Effects

+mov_x2_sat r1.a, r1.a //boost cloud alpha 1 lrp r0.rgb, r1.a, r1, r0 //combine cloud layers +mov r4.a, c5.a // mul_x2 r3, r3.a, r3 //multiply glow by edges of clouds mad_x2 r3, r3, c5, r4.a //scale and bias glowing sections of clouds mul r0.rgb, r3, r0 //multiply glow by combination of cloud layers +add_d2_sat r0.a, r0.a, r1.a //add alphas of cloud layers lrp_sat r0, r0.a, r0, r2 //Lerp between clouds and horizon Perturbation Based Fire

Another interesting effect that can be created using texture perturbation is flickering fire, as shown in the ATI Fire & Water Demo. Traditionally this was accomplished as either an animation, a texture feedback effect, or a particle system. However, each of these approaches has limitations.

Rendering fire as an animation has the disadvantages of looking unrealistic due to the cycling animation and of requiring a lot of texture memory to store the frames of animation. In addition to this, if there are many flames in the scene, and all use the same animation, the scene will look even more artificial. To capture the randomness of fire, cycling animations are not a good choice.

Another approach is to use a texture feedback. The basic idea is for each frame to generate a row of random pixels at the bottom of the texture, then blur and scroll the image upward in the texture. Although the visual effect of this is quite random, the repetitive blurring of the texture feedback process does not have the sharp edges that real fire has, and therefore looks very unrealistic.

Particle systems can also be used to create fire effects. Even though fire effect they can produce is random in nature, calculating the physics for the particle system requires CPU time, and can be prohibitive to perform for the amount of particles needed to create a realistic fire. In addition to this particle fires tend not to have the opaqueness of real fire.

The technique described in this section for generating fire overcomes all of these shortcomings. Because it only requires two textures, a perturbation map and a base map, the technique requires much less texture memory than the animated fire. Also, due to the way we use the perturbation maps, the fire is both non-repetitive and preserves the sharp edges present in the base map. Also, the shader can be programmed to use vertex data to seed the offsets of the perturbation maps so that multiple flames in the same scene can have different appearances.

The idea behind this shader is to scroll three perturbation texture images (all three use the same texture) past each other vertically, and adding the results together to get a perturbation value. The three maps scroll at rates that are not integer multiples of the

Excerpted from ShaderX: Vertex and Pixel Shader Tips and Tricks

7

Page 8: Texture Perturbation Effects - AMDdeveloper.amd.com/wordpress/media/2012/10/ShaderX... · Texture Perturbation Effects Cloud Texture Basic Cloud Shader in Action Here is the pixel

Texture Perturbation Effects

others so that the fire does not repeat as time advances. Using three maps ensures that repetition only happens after a very long time. When two of the perturbation maps line up, the third one is almost always offset from the other two. Giving the maps slightly different scroll speeds in the horizontal direction as well, prevents the mechanical upward scrolling appearance of the fire.

The perturbation value is attenuated slightly based on the interpolated texture coordinate v value and then used to perform a perturbed fetch of a pixel in the base map. The attenuation is used to weaken the perturbation near the base of the fire in order to make the top of the fire flicker more than the base. After this, the perturbed fetch is performed in the same way as in the cloud shader, but both RGB components and alpha components are used from the fetched pixel.

Fire Effect in action

Base Map (rgb) Opacity Map (alpha) Distortion Texture

Excerpted from ShaderX: Vertex and Pixel Shader Tips and Tricks

8

Page 9: Texture Perturbation Effects - AMDdeveloper.amd.com/wordpress/media/2012/10/ShaderX... · Texture Perturbation Effects Cloud Texture Basic Cloud Shader in Action Here is the pixel

Texture Perturbation Effects

//SetPixelShaderConstant 0 texLerp //SetPixelShaderConstant 1 distortAmount0 //SetPixelShaderConstant 2 distortAmount1 //SetPixelShaderConstant 3 distortAmount2 //SetPixelShaderConstant 4 heightAtten //SetPixelShaderConstant 5 fireBoost ps.1.4 texcrd r0.rgb, t0 texld r2, t1 texld r3, t2 texld r4, t3 mul r2.rgb, c1, r2_bx2 //noise0 * dis0 mad r2.rgb, c2, r3_bx2, r2 //noise1 * dis1 + noise0 * dis0 mad r2.rgb, c3, r4_bx2, r2 //noise2 * dis2 + noise1 * dis1 + noise0 * dis0 +mad r0.a, r0.g, c4.x, c4.y // scale and bias y coord of base map mad r2.rgb, r2, r0.a, r0 //mult distortion by scaled biased y coord phase texld r0, r2 mov r0, r0 Plasma Glass

In addition to the simulation of real world phenomena there are many other effects possible using texture perturbation. For instance, many science fiction movie style special effects such as warping plasma are possible. The following technique produces something similar to the glass plasma spheres that emanate streams of plasma toward the surface of the glass when touched.

The concept behind the plasma effect is to use two scrolling textures again, but to use each one as both a perturbation map and a base map. The base map is stored in the RGB components of the texture, and the perturbation map is stored in the alpha component. Each texture map perturbs the subsequent texel fetch of the other map. The following shader shows the basic plasma effect.

//SetPixelShaderConstant 1 Perturbation scaling ps.1.4 texld r1, t1 //Perturbation map 1 / base map 0 texld r2, t2 //Perturbation map 0 / base map 1 texcrd r4.rgb, t1 //Base map coords 0 texcrd r5.rgb, t2 //Base map coords 1 mad r4.rgb, c1, r2.a, r4 // Use alpha for Perturbation mad r5.rgb, c1, r1.a, r5 // Use alpha for Perturbation phase texld r1, r5 //Base map 0 texld r2, r4 //Base map 1 add_d2 r0, r1, r2 // Add two perturbed textures together

Excerpted from ShaderX: Vertex and Pixel Shader Tips and Tricks

9

Page 10: Texture Perturbation Effects - AMDdeveloper.amd.com/wordpress/media/2012/10/ShaderX... · Texture Perturbation Effects Cloud Texture Basic Cloud Shader in Action Here is the pixel

Texture Perturbation Effects

Base Texture Perturbation Texture

Simple plasma effect applied to a sphere

Mathematically, this effect is almost identical to the two layer cloud effect, where

the layers are added together, but the appearance of the effect is drastically different. Most of the difference in appearance can be attributed to using very different base and perturbation textures.

The plasma effect can be used as a building block to create more complex effects. For instance, the plasma effect can be combined with a glass effect, to create a glass plasma sphere.

Excerpted from ShaderX: Vertex and Pixel Shader Tips and Tricks

10

Page 11: Texture Perturbation Effects - AMDdeveloper.amd.com/wordpress/media/2012/10/ShaderX... · Texture Perturbation Effects Cloud Texture Basic Cloud Shader in Action Here is the pixel

Texture Perturbation Effects

The first step is to use an environment cube map:

Environment Map

To help give this a more glass-like appearance, the environment map is combined

with a per-pixel Fresnel term. The per-pixel Fresnel term allows the glass to have a slightly bumpy appearance, which can be used to create a bumpy or a frosted glass appearance.

Environment Map * Per-Pixel Fresnel Term * Glass Color

The environment map is linearly interpolated with the plasma effect to produce

the final result. For the final alpha value, the per-pixel Fresnel term, and the plasma transparency value are added together.

Excerpted from ShaderX: Vertex and Pixel Shader Tips and Tricks

11

Page 12: Texture Perturbation Effects - AMDdeveloper.amd.com/wordpress/media/2012/10/ShaderX... · Texture Perturbation Effects Cloud Texture Basic Cloud Shader in Action Here is the pixel

Texture Perturbation Effects

Excerpted from ShaderX: Vertex and Pixel Shader Tips and Tricks

12

Final Effect (Interpolate between Environment and Plasma)

Here is the pixel shader for the plasma glass effect. //SetPixelShaderConstant 0 psConstVec (0.0, 0.5, 1.0, 0.75) //SetPixelShaderConstant 1 psDistortScaleFactor //SetPixelShaderConstant 2 glassColor //SetPixelShaderConstant 3 plasmaColor ps.1.4 texld r0, t0 //bump map texld r1, t1 //perturbation map/ base map texld r2, t2 //perturbation map/ base map texld r3, t3 //tan space view vector lookup into normalization cube map texcrd r4.rgb, t1 //base map coords texcrd r5.rgb, t2 //base map coords dp3 r0, r3_bx2, r0_bx2 //V.N mad r4.rgb, c1, r2.a, r4 //calc perturbed texture coords +cmp r0.a, r0, r0, -r0 //abs(V.N) mad r5.rgb, c1, r1.a, r5 //calc perturbed texture coords mov_sat r0, 1-r0.a //1-abs(V.N) (Fresnel term) phase texcrd r0, r0 //pass through fresnel texld r1, r5 //perturbed base texture 0 texld r2, r4 //perturbed base texture 1 texld r4, t4 //env map reflective lookup. mul_x2 r4.rgb, r4, c2 //reflection map * glass color +add_d2_sat r1.a, r1.r, r2.r //textures together mul r1.a, r1.a, r1.a //square base texture (increases contrast) mul_x4_sat r1.rgb, r1.a, c3 //(plasma^n) * plasma color +mov r0.a, r0.r //fresnel term lrp r0.rgb, r0.a, r4, r1 //lerp plasma and environment map +mad_sat r0.a, r1.a, c3.a, r0.a //plasma * plasma alpha + fresnel

Summary

A variety of effects have been created using texture perturbation. Several other effects are also possible using a variation of the above shaders, such as rippling water or billowing smoke. By merely changing the base and perturbation textures a vast array of new and interesting effects can be achieved. It is recommended that you experiment with these shaders yourself.

Reference [Ebert98] David S. Ebert, F. Kenton Musgrave, Darwyn Peachey, Ken Perlin, Steven Worley “Texturing & Modeling: A Procedural Approach (Second Edition),” 1998.