Animated Water Rendering: Streaming Landscape and Dynamic Lighting, Schemes and Mind Maps of Computer science

The implementation of animated water rendering using streaming landscape and dynamic lighting techniques. the use of GPU memory for storing landscape data, the computation of surface normals, and the rendering of animated water with bump mapping. The document also touches upon the topic of dynamic point and directional light sources and their impact on performance.

Typology: Schemes and Mind Maps

2021/2022

Uploaded on 09/27/2022

sctsh3
sctsh3 🇬🇧

4.8

(6)

294 documents

1 / 13

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
Effects for a Game Engine
Christian Bay Kasper Amstrup Andersen
Department of Computer Science University of Copenhagen
Figure 1: Coastal area. Water is animated and the
sun is reflected in the small surface waves.
Abstract
In this paper we present 3 extensions for the engine
used in the Game Animation course at the Depart-
ment of Computer Science University og Copenhagen
(DIKU). The extensions are animated water, stream-
ing landscape, and dynamic directional and point light
sources. With the next generation of gaming con-
soles (Playstation 3, Xbox360 etc.) it becomes im-
portant to have a large, complex, and visually pleas-
ing landscape. Our approach introduces an infinitely
large landscape with constant framerate and no stalls
at runtime. With more computational power, more
resources will be used for dynamic lightning, and nat-
ural effects like water. We present simple and fast
shader approaches for both of these effects.
Keywords: Graphics, shader programming, landscape,
lightning, water.
Figure 2: Multiple point light sources reflected in wa-
ter at night.
1 The existing game engine
Previously, we have seen seen a large amount of games
that have visually pleasing landscapes, but also lots of
stalls at runtime due to geometry reorganization. As
computers have grown more powerful and with the in-
troduction of GPU’s, it seems natural to try to reduce
stalls by offloading landscape computations to the
GPU. The GPU can continuously stream landscape
such that a small part of the landscape is swapped in
while another part is swapped out each time a frame
is rendered.
The existing game engine used at DIKU is imple-
mented in C++ [Stroustrup, 1997] and uses OpenGL
[Shreiner et al., 2005], GLUT [Kilgard, 2001] and
OpenTissue [OpenTissue, 2006]. Shaders are written
in Cg [CgManual, 2005]. Landscape is implemented
as a virtual grid data structure where blocks of land-
scape geometry are moved around at runtime. The
landscape is generated with Perlin Noise [Perlin, 1985]
pf3
pf4
pf5
pf8
pf9
pfa
pfd

Partial preview of the text

Download Animated Water Rendering: Streaming Landscape and Dynamic Lighting and more Schemes and Mind Maps Computer science in PDF only on Docsity!

Effects for a Game Engine

Christian Bay Kasper Amstrup Andersen

Department of Computer Science University of Copenhagen

Figure 1: Coastal area. Water is animated and the sun is reflected in the small surface waves.

Abstract

In this paper we present 3 extensions for the engine used in the Game Animation course at the Depart- ment of Computer Science University og Copenhagen (DIKU). The extensions are animated water, stream- ing landscape, and dynamic directional and point light sources. With the next generation of gaming con- soles (Playstation 3, Xbox360 etc.) it becomes im- portant to have a large, complex, and visually pleas- ing landscape. Our approach introduces an infinitely large landscape with constant framerate and no stalls at runtime. With more computational power, more resources will be used for dynamic lightning, and nat- ural effects like water. We present simple and fast shader approaches for both of these effects.

Keywords: Graphics, shader programming, landscape, lightning, water.

Figure 2: Multiple point light sources reflected in wa- ter at night.

1 The existing game engine

Previously, we have seen seen a large amount of games that have visually pleasing landscapes, but also lots of stalls at runtime due to geometry reorganization. As computers have grown more powerful and with the in- troduction of GPU’s, it seems natural to try to reduce stalls by offloading landscape computations to the GPU. The GPU can continuously stream landscape such that a small part of the landscape is swapped in while another part is swapped out each time a frame is rendered.

The existing game engine used at DIKU is imple- mented in C++ [Stroustrup, 1997] and uses OpenGL [Shreiner et al., 2005], GLUT [Kilgard, 2001] and OpenTissue [OpenTissue, 2006]. Shaders are written in Cg [CgManual, 2005]. Landscape is implemented as a virtual grid data structure where blocks of land- scape geometry are moved around at runtime. The landscape is generated with Perlin Noise [Perlin, 1985]

and [Perlin, 2002]. This means that the game engine has infinite landscape. However, when moving around the player will notice a dramatic drop in framerate due to block loading. This may be acceptable in turn based games but for realtime games, especially 3D shooting games (Half-Life, Quake etc.), this approach makes games practically unplayable. We present a method for rendering an infinite landscape without any stalls and with constant framerate at all times. Our method is inspired by [Pharr et al., 2005, chapter 2] and [Hoppe et al., 2004] but does not use clipmaps which will probably be patented in the near-future [USPatent, Terrain].

The default lightning in the existing game engine is a global point light source and multiple directional light sources stored in shaders. All light sources are static. We present a simple and fast method for dynamic directional and point light sources.

Using sums of sine waves as described in [Erleben et al., 2005] we present a computation- ally fast method for rendering animated water.

Screenshots from the extended engine are shown in Figure 1 and 2.

2 New game engine effects

In the following section we present our 3 extensions for the existing game engine.

2.1 Streaming landscape

Landscape is stored in GPU memory as a k × k vertex grid where k = 2n^ for some integer n. This grid thus contains k · k vertices Vi,j.

Vi,j = (i, j, 0) (1)

where i and j are vertex grid indices and 0 ≤ i < k and 0 ≤ j < k as shown in Figure 3.

A combined height and normal map with size k × k is also stored in GPU memory. Both normals and height values are precomputed on the CPU, all other landscape computations are done in a vertex shader. Height values are generated with Perlin Noise but other height generation algorithms could be used as well. The map is initially transfered to the GPU with the OpenGL function glTexImage2D. The map is a 4 channel 32 bit floating point texture. The first 3 chan- nels contain precomputed normal vector values, and

k

k

V(0, 0)

V(k-1, k-1)

V(i, j)

(0,0,0)

(i,j,0)

(k-1,k-1,0)

Figure 3: Vertex grid with size k × k stored in GPU memory.

the 4th^ channel contains a height value. Thus, each vertex Vi,j has a corresponding texel^1 ei,j containing the height and the normal vector of the vertex.

ei,j = (¯nx, n¯y , n¯z , z) (2)

where ¯n is the normal vector and z is the height for the corresponding vertex. For a vertex, the function tex2D is used to look up the corresponding texel. We need the proper texture coordinates (u, v) for tex2D though.

(u, v) = (((i + posx) mod k)/k, ((j + posy ) mod k)/k)

where a mod b = a−ba/bcb, and btc denotes the near- est integer smaller than t. Initially, posx = posy = 0 but this changes as the landscape is moved, as de- scribed in section 2.1.1. We define two functions, that will be used in the following sections.

Definition 2.1. hecmp(ei,j ) returns the height com- ponent z of a texel ei,j.

Definition 2.2. nocmp(ei,j ) returns the normal com- ponent ¯n of a texel ei,j.

(^1) Texture element. The texture map equivalent of a pixel.

used upon lookup. Again we move the landscape ∆x units resulting in the situation depicted in Figure 7. Here, the area marked D′^ is updated in the texture.

2.2 Animated water

Water can be modeled in many ways ranging from simple 2D water surfaces to complex, full 3D water. Our approach lies in between. We use a displace- ment map generated with sine waves combined with bump mapping to achieve both surface displacement and water-like effects.

Water is stored in GPU memory as a grid of vertices Vi,j.

Vi,j = (x, y, z) (6)

where z is constant, i.e. z = c for some real number c. Water can be raised or lowered by changing z. Vertices are then displaced in a vertex shader in the samme manner as the streaming landscape described in section 2.1.1. We define a function for extracting the (x, y) part of Vi,j.

Definition 2.3. xycmp(Vi,j ) returns the (x, y) part of a vertex Vi,j.

The method used for surface displacement is heavily inspired by [CgManual, 2005]. Here a number of sine and cosine waves with different frequency and am- plitude and slightly different directions are summed. This gives the final waves a random look. The dis- advantage of this approach is that the resolusion of the waves is only as good as the resolusion of the grid used. Thus very small waves cannot be simulated ef- ficiently using this method. To simulate small waves on the water surface and to achieve water-like light- ning effects we add bump mapping. This is shown in Figure 9 and 10.

An equation for computing approximations of wave normals is described in [CgManual, 2005].

N¯ =

waves

− cos(xycmp(Vi,j ) · W )hf wx − cos(xycmp(Vi,j ) · W )hf wy 0

where W is the projection of the wave direction on the xy-plane, h is the wave height and f is the frequency of the wave. wx and wy are the x and y components of W respectively. We sum over all waves contributing to the normal. The resulting vector N¯ needs to be normalized before use.

N

Wave

WaveCS

Bump mapped wave

n

Bump map BumpCS

N

Wave

n

Bump map

n

Figure 8: Adding bump mapping to waves. Initially, the bump map contains normal vectors relative its own local coordinate system. The normals are then transformed to the correct wave point coordinate sys- tem.

2.3 Adding bump mapping

When using the bump map in a shader the normals ¯n are encoded, by the Photoshop plugin, as 4 channel RGBA colors, C. More precisely, they are encoded as floating point values ranging from 0 to 1. The normal

Figure 9: Water with no bump mapping. Figure 10: Water with bump mapping.

Figure 13: 3 animated point light sources: A red, a blue and a green.

2.5 Dynamic lightning

A lightning model that supports an unlimited num- ber of both point and directional light sources is the Phong illumination model described in [Foley et al., 1997]. We have used a modified version of this model: We have removed the reflection coeffi-

cient kλ since we want to upload as little data to the GPU as possible, and since kλ can easily be combined with an object’s material color for both diffuse and specular light.

Oλ,k = kλOλ (13)

This gives us the complete equation for computing lightning.

I = Oaλ,k +

lights

fatt(Odλ,kLd(¯n · ¯l)+

Osλ,kLs(¯n · ¯h)n)

where I is the resulting illumination in the vertex or fragment, and Oaλ,k, Odλ,k and Osλ,k is the object’s ambient, diffuse and specular material color respec- tively. Ld and Ls is the light source’s diffuse and specular color. ¯n is the normal vector in the vertex or fragment. ¯l is the light source direction vector. ¯h is the halfway vector, which is halfway between the direction of the light source and the eye. n is the spec- ular reflection exponent. In equation 14, all vectors are assumed to be normalized.

For point light sources, we need to calculate a light vector from the vertex or fragment to the light source ¯l = pl −po; where ¯l is the light vector, pl is the position of the light source, and po is the position of the vertex or fragment, that we currently are illuminating. All lightning computations are done in the WCS.

2.6 Lightning in vertex and pixel shaders

We light the landscape in a vertex shader which means that landscape is illuminated with Gouraud shading. Water is illuminated in a fragment shader so here we use Phong shading. One problem with multiple light sources, when using shaders, is that when a shader program is compiled it needs to know the size of the array containing the lights. This means that a finite maximum number of lights has to be known before compiling the shader program. To set the array size a shared array parameter with a size equal to the num- ber of lights can be used. This is shown in algorithm 1 in appendix C.

When uploading the shader program to the GPU, we need to disable automatic compilation and connect the shared parameter from algorithm 1 to the pro- gram. This is shown in algorithm 2.

Now, array elements can be modified like all other parameters. Each light source l′^ is contained in a 4x4 matrix such that updating all light sources in the array can be done in a single function call.

l′^ =

¯lx ¯ly ¯lz lw Ld,x Ld,y Ld,z - Ls,x Ls,y Ls,z - c 1 c 2 c 3 -

where ¯l is the light source direction vector, Ld is the light source’s diffuse color, and Ls is the light source’s specular color. lw is used to determine if the light source is a point or direction; lw = 1 means point, lw = 0 means direction. c 1 , c 2 , c 3 are user controlled attenuation constants that are used to compute fatt as described in [Foley et al., 1997, equation 16.8].

fatt = min

c 1 + c 2 dL + c 3 d^2 L

where dL is the distance the light travels from the point light source to the surface. Entries in equation 15 marked with ′′−′′^ are unused. The result of using multiple point light sources is shown in Figure 13.

3 Analyzing performance

We have benchmarked the existing and the extended game engines, and compared the results. Benchmark- ing was done with landscape alone, with water, and with a single and multiple light sources. The camera was moving at all times and was positioned with a 90 o^ camera angle relative to the landscape. Further, frustum culling and occlusion queries were disabled in both engines. We used an AMD Barton 2500+ with 1GB ram and a GeForce 6600GT with 128MB ram. Results for the existing engine is shown in Table 1 and appendix A, while results for the extended en- gine is shown in Table 2, 3, 4 and in appendix B. It should be noted that comparisons are only approxi- mate since the different underlying implementations make it impossible to make exact comparisons.

The measure for whether the engines perform real- time, is if rendering is possible at an average of mini- mum 30f ps.

The existing engine performs realtime, but has signif- icant framerate drops. This is marked on the graphs in appendix A. The framerate drops are due to block loading. After each drop, we momentarily experience

an increase in the framerate. This is because that while the CPU computes geometry for the new blocks, the GPU finishes all its current work, and thus waits for the CPU. When the CPU then feeds geometry to the GPU again, it can be processed fast since the pipeline is empty.

Size Low FPS Avg. FPS High FPS 65 × 65 53 61 68 117 × 117 40 61 80 273 × 273 7 30 41 Table 1: Landscape. 1 directional light source.

The average performance of the extended engine is practically equal to that of the existing, and hence it performes realtime. With multiple light sources and water enabled, however, only landscape sizes up to 64 × 64 can be used for real time purposes. The old engine does not support water and/or multiple direc- tional and point light sources so these extensions can not be compared.

Size Low FPS Avg. FPS High FPS 64 × 64 59 61 62 128 × 128 59 61 64 256 × 256 29 30 31 Table 2: Landscape. 1 directional light source.

Size Low FPS Avg. FPS High FPS 64 × 64 59 61 63 128 × 128 30 30 31 256 × 256 12 12 12 Table 3: Landscape. Water. 1 directional light source.

Size Low FPS Avg. FPS High FPS 64 × 64 59 61 63 128 × 128 14 15 16 256 × 256 5 5 5 Table 4: Landscape. Water. 3 point and 1 directional light sources.

The bottleneck in the extended engine is the tex- ture lookups in the vertex program; vertex tex- ture lookup are much more expensive than texture lookups in fragment programs [GPUGuide, 2005] and [Gerasimov et al., 2005]. However the next genera- tion of GPU will definitely have better vertex tex- ture performance so it is expected that our method will seem even more attractive in the future. In [Hoppe et al., 2004] they were able to render ter- rain the size of North America using vertex texture

[USPatent, Terrain] Hoppe, Hugues et al. US Patent Application 20050253843: Terrain rendering us- ing nested regular grids. http://www.uspto.gov/patft/index.html

A Existing engine performance

Landscape. 1 directional light source. 5x13.

0

10

20

30

40

50

60

70

80

1 11 21 31 41 51 61 71 81 91

Landscape. 1 directional light source. 9x13.

0

10

20

30

40

50

60

70

80

1 11 21 31 41 51 61 71 81 91

Landscape. 1 directional light source. 21x13.

0

10

20

30

40

50

60

70

80

1 11 21 31 41 51 61 71 81 91

Frame

Frame

Frame

FPS

FPS

FPS

B Extended engine performance

Landscape. 1 directional light source. 1x64.

0

10

20

30

40

50

60

70

80

1 11 21 31 41 51 61 71 81 91

Landscape. 1 directional light source. 1x128.

0

10

20

30

40

50

60

70

80

1 11 21 31 41 51 61 71 81 91

Landscape. 1 directional light source. 1x256.

0

10

20

30

40

50

60

70

80

1 11 21 31 41 51 61 71 81 91

FPS

FPS

FPS

Frame

Frame

Frame

C Pseudocode for setting up dynamic

lightning

Function : InitSharedParams() 1.1 size = maximum number of light sources; 1.2 sharedparam = cgCreateParameterArray( ..., size ); Algorithm 1: Setting the size of the array containing light sources.

Function : InitProgram() 2.1 cgSetAutoCompile( ..., CG COMPILE MANUAL ); 2.2 program = cgCreateProgramFromFile( ... ); 2.3 param = cgGetNamedParameter( program, ”Lights” ); 2.4 cgConnectParameter( sharedparam, param ); 2.5 cgCompileProgram( program ); 2.6 cgGLLoadProgram( program ); Algorithm 2: Creates a program with an unsized uniform array parameter, and sets the array size to the same size as a shared parameter.