GPU Gems 1

Chapter 1. Effective Water Simulation from Physical Models

공대나온남자 2008. 12. 23. 17:18

원문: http://http.developer.nvidia.com/GPUGems/gpugems_ch01.html


Chapter 1. Effective Water Simulation from Physical Models

Mark Finch
Cyan Worlds

This chapter describes a system for simulating and rendering large bodies of water on the GPU. The system combines geometric undulations of a base mesh with generation of a dynamic normal map. The system has proven suitable for real-time game scenarios, having been used extensively in Cyan Worlds' Uru: Ages Beyond Myst, as shown in Figure 1-1.

 

이 챕터에서는 GPU에서 넓은 물을 시뮬레이션하고 렌더링하는 시스템을 설명한다. 이 시스템은 기본 메쉬의 기하학적 웨이브를 동적 법선맵의 생성과 결합한다. 이 시스템은 그림 1-1에서 보여진 Cyan Worlds의 Uru: Ages Beyond Myst 에서 널리 사용된 것과 같이, 실시간 게임 시나리오에 적합하다는 것이 입증되었다.

 

 

 Figure 1-1 Tranquil Pond

1.1 Goals and Scope

Real-time rendering techniques have been migrating from the offline-rendering world over the last few years. Fast Fourier Transform (FFT) techniques, as outlined in Tessendorf 2001, produce incredible realism for sufficiently large sampling grids, and moderate-size grids may be processed in real time on consumer-level PCs. Voxel-based solutions to simplified forms of the Navier-Stokes equations are also viable (Yann 2003). Although we have not yet reached the point of cutting-edge, offline fluid simulations, as in Enright et al. 2002, the gap is closing. By the time this chapter is published, FFT libraries will likely be available for vertex and pixel shaders, but as of this writing, even real-time versions of these techniques are limited to implementation on the CPU.

 

지난 몇 년동안 오프라인-렌더링 세계는 실시간 렌더링 테크닉으로 바뀌고 있다. Tessendorf 2001에 개요되어있는 것과 같이, 빠른 푸리에 변환(FFT) 테크닉은 충분히 큰 샘플링 격자에 놀라운 사실성을 만들어내고, 보통 크기의 격자는 일반 사용자의 PC에서도 실시간으로 처리될 수도 있다. Navier-Stokes 방정식의 단순화된 형태의 복셀 기반 솔루션 또한 실용적이다(Yann 2003). 비록 우리가 아직 최첨단의 지점까지는 도달하지 않았을지라도, Enright et al. 2002에서의 오프라인 유체 시뮬레이션과 같이 격차는 줄어들고 있다. 이 챕터가 발표될 때에는, 아마 FFT 라이브러리를 정점, 픽셀 쉐이더에서 사용할 수 있을 것이다. 하지만 이 글을 쓰고 있는 현재, 이 테크닉의 실시간 버전은 CPU에서 구현하도록 제한된다.

 

At the same time, water simulation models simple enough to run on the GPU have been evolving upward as well. Isidoro et al. 2002 describes summing four sine waves in a vertex shader to compute surface height and orientation. Laeuchli 2002 presents a shader calculating surface height using three Gerstner waves.

 

동시에, GPU에서 수행될 수 있을 정도로 간단한 물 시뮬레이션 모델이 점점 발전해가고 있다. Isidoro et al. 2002은 표면의 높이와 방위를 계산하기 위해 정점 쉐이더에서 4개의 사인 웨이브를 합하는 것을 설명하고 있다. Laeuchli 2002은 3개의 Gerstner 웨이브를 사용하여 표면 높이를 계산하는 쉐이더를 소개하고 있다.

 

We start with summing simple sine functions, then progress to slightly more complicated functions, as appropriate. We also extend the technique into the realm of pixel shaders, using a sum of periodic wave functions to create a dynamic tiling bump map to capture the finer details of the water surface.

 

우리는 간단한 사인 함수를 합하는 것으로 시작해서, 조금씩 더 복잡한 함수로 진행한다. 또한 수면의 보다 나은 디테일을 잡아내기 위해 동적 타일 범프맵을 생성하는 주기적 웨이브 함수의 합을 사용하는 픽셀 쉐이더의 영역으로 테크닉을 확대한다.

 

This chapter focuses on explaining the physical significance of the system parameters, showing that approximating a water surface with a sum of sine waves is not as ad hoc as often presented. We pay special attention to the math that takes us from the underlying model to the actual implementation; the math is key to extending the implementation.

 

이 챕터는 시스템 파라미터의 물리적 의미를 설명하고 사인 웨이브의 합으로 수면을 근사하는 것이 종종 그리 특별하지 않다는 것을 보여주는데 초점을 맞춘다. 우리는 기본이 되는 모델을 실제 구현에 적용시킬 수 있게 하는 수학에 특히 집중한다; 수학은 구현을 확장하는 열쇠이다.

 

This system is designed for bodies of water ranging from a small pond to the ocean as viewed from a cove or island. Although not a rigorous physical simulation, it does deliver convincing, flexible, and dynamic renderings of water. Because the simulation runs entirely on the GPU, it entails no struggle over CPU usage with either artificial intelligence (AI) or physics processes. Because the system parameters do have a physical basis, they are easier to script than if they were found by trial and error. Making the system as a whole dynamic—in addition to its component waves—adds an extra level of life.

 

이 시스템은 연못에서부터 후미나 섬에서 보는 것과 같은 대양까지의 범위에 있는 물의 몸체를 위해 디자인된다. 비록 정밀한 물리적 시뮬레이션은 아니지만, 이 시스템은 설득력 있고 유연하고 동적인 물의 렌더링을 제공한다. 시뮬레이션은 전적으로 GPU에서 수행되기때문에, 인공지능(AI)이나 물리 처리로 CPU를 사용하는데에 무리를 주지 않는다. 시스템 파라미터들은 물리적 원리를 가지고 있기 때문에, 파라미터를 시행이나 에러로 찾아내는 것보다 스크립트하기 더 쉽다. 시스템의 구성 웨이브에 더하여, 전체적으로 동적인 시스템을 만들면 특별한 수준의 생명이 추가된다.

 

1.2 The Sum of Sines Approximation

 

We run two surface simulations: one for the geometric undulation of the surface mesh, and one for the ripples in the normal map on that mesh. Both simulations are essentially the same. The height of the water surface is represented by the sum of simple periodic waves. We start with summing sine functions and move to more interesting wave shapes as we go.

 

우리는 2가지의 표면 시뮬레이션을 실행한다: 하나는 표면 메쉬에 기하적 웨이브를 만드는 것이고, 다른 하나는 표면 메쉬의 법선맵에 잔물결을 만드는 것이다. 두 시뮬레이션은 본질적으로 동일하다. 수면의 높이는 간단한 주기적 웨이브의 합으로 나타낸다. 우리는 사인 함수를 합하는 것으로 시작해서 더 흥미로운 웨이브 형태를 살펴본다.

 

The sum of sines gives a continuous function describing the height and surface orientation of the water at all points. In processing vertices, we sample that function based on the horizontal position of each vertex, conforming the mesh to the limits of its tessellation to the continuous water surface. Below the resolution of the geometry, we continue the technique into texture space. We generate a normal map for the surface by sampling the normals of a sum of sines approximation through simple pixel shader operations in rendering to a render target texture. Rendering our normal map for each frame allows our limited set of sine waves to move independently, greatly enhancing the realism of the rendering.

 

사인 웨이브의 합은 모든 점에서 물의 높이와 표면 방위를 나타내는 연속된 함수를 제공한다. 정점 처리 과정에서, 우리는 각 정점의 수평 위치에 기반한 그 함수를 샘플링하여 메쉬가 연속된 수면에서 그것의 테셀레이션의 제한을 따르게 한다. 기하의 해상도 내에서, 텍스쳐 공간으로 테크닉을 지속한다. 렌더링 중 간단한 픽셀 쉐이더 연산을 통해 사인 근사의 합의 법선을 샘플링하여 표면을 위한 법선맵을 렌더 타겟 텍스쳐에 생성한다. 각 프레임 별로 법선맵을 렌더링하면 우리의 제한된 사인 웨이브의 세트로 렌더링의 사실성을 독립적으로 크게 향상시킬 수 있다.

 

In fact, the fine waves in our water texture dominate the realism of our simulation. The geometric undulations of our wave surface provide a subtler framework on which to present that texture. As such, we have different criteria for selecting geometric versus texture waves.

 

사실, 물 텍스쳐에서의 뛰어난 웨이브가 시뮬레이션의 사실성을 좌우한다. 웨이브 표면의 기하학적 파동은 그 텍스쳐를 나타내는 더 세밀한 프레임워크를 제공한다. 따라서, 우리는 기하와 텍스쳐 웨이브 중 어떤 것을 선택할지에 대한 다른 기준을 가지고 있다.

1.2.1 Selecting the Waves

We need a set of parameters to define each wave. As shown in Figure 1-2, the parameters are:

 

우리는 각 웨이브를 정의하는 파라미터의 세트가 필요하다. 그림 1-2와 같이 파라미터는 다음과 같다.

 

fig01-02.jpg

Figure 1-2 The Parameters of a Single Wave Function

  • Wavelength (L): the crest-to-crest distance between waves in world space. Wavelength L relates to frequency w as w = 2p/L.
  • Amplitude (A): the height from the water plane to the wave crest.
  • Speed (S): the distance the crest moves forward per second. It is convenient to express speed as phase-constant phase-constant.jpg , where phase-constant.jpg = S x 2p/L.
  • Direction (D ): the horizontal vector perpendicular to the wave front along which the crest travels.
  • 파장(L): 월드 공간에서 웨이브의 꼭대기 사이의 거리. 파장 L 은 진동수 w( w = 2p/L) 와 관련이 있다
  • 진폭 (A): 수평면에서 웨이브 꼭대기까지의 높이.
  • 속도 (S): 꼭대기가 초당 움직이는 거리. 속도를 위상상수 phase-constant.jpg( phase-constant.jpg= S x 2p/L)로 표현하면 편리하다.
  • 방향 (D): 웨이브와 수직이고 꼭대기가 움직이는 방향인 수평 백터

Then the state of each wave as a function of horizontal position (x, y) and time (t) is defined as:

 

각 웨이브의 상태는 수평 위치 (x, y)와 시간 (t)의 함수로 정의된다:

 

Equation 1

ch01_eqn001.jpg


And the total surface is:

 

모든 웨이브 i 에 대한 최종 표면은 다음과 같다.

 

Equation 2

ch01_eqn002.jpg


over all waves i.

 

To provide variation in the dynamics of the scene, we will randomly generate these wave parameters within constraints. Over time, we will continuously fade one wave out and then fade it back in with a different set of parameters. As it turns out, these parameters are interdependent. Care must be taken to generate an entire set of parameters for each wave that combine in a convincing manner.

 

장면의 동역학에 변화를 주기 위해, 우리는 일정 제한내에서 웨이브 파라미터를 무작위로 생성할 것이다. 시간이 지나면서 한 웨이브는 계속해서 점점 작아지다가 다른 파라미터 값으로 다시 점점 커지는 것을 반복할 것이다. 웨이브가 생성되는 것처럼, 파라미터들은 상호의존적이다. 설득력있는 방식으로 결합하는 각 웨이브를 위한 파라미터의 전체 세트를 생성하는 것에 주의를 기울여야 한다.

1.2.2 Normals and Tangents

Because we have an explicit function for our surface, we can calculate the surface orientation at any given point directly, rather than depend on finite-differencing techniques. Our binormal B and tangent T vectors are the partial derivatives in the x and y directions, respectively. For any (x, y) in the 2D horizontal plane, the 3D position P on the surface is:

 

우리는 표면을 위한 명시적은 함수를 가지고 있기 때문에, 유한-차분(differencing) 테크닉에 의존하기 보다는, 주어진 점에서 표면 방위를 바로 계산할 수 있다. 종법선 B와 탄젠트 T벡터는 각각 x, y 방향에서의 편미분이다. 2D 수평면에 있는 어떤 점에 대한 3D 표면 위치 P는 다음과 같다:

 

Equation 3

ch01_eqn003.jpg


The partial derivative in the x direction is then:

 

x 방향 편미분은 다음과 같다.

 

Equation 4a

01equ04a.jpg


Equation 4b

01equ04b.jpg


Similarly, the tangent vector is:

 

비슷하게 탄젠트 벡터는 다음과 같다:

 

Equation 5a

01equ05a.jpg


Equation 5b

01equ05b.jpg


The normal is given by the cross product of the binormal and tangent, as:

 

법선은 종법선과 탄젠트를 외적하여 얻는다:

 

Equation 6a

01equ06a.jpg


Equation 6b

01equ06b.jpg


Before putting in the partials of our function H, note how convenient the formulas in Equations 3–6 happen to be. The evaluation of two partial derivatives has given us the nine components of the tangent-space basis. This is a direct consequence of our using a height field to approximate our surface. That is, P(x, y).x = x and P(x, y).y = y, which become the zeros and ones in the partial derivatives. It is only valid for such a height field, but is general for any function H(x, y, t) we choose.

 

함수 H의 편미분을 다루기 전에, 방정식 3~6에 있는 공식들이 어떻게 편리함을 주는지를 주목하라. 두 편미분 방정식은 탄젠트 공간 기저의 9개 성분을 제공한다. 이것은 표면을 근사하기 위해 높이 필드를 사용한 직접적인 결과이다. 즉, P(x, y).x = x, P(x, y).y = y 이고 편미분에서 0과 1이 된다. 이것은 그러한 높이 필드에 대해서만 유효하지만 우리가 선택한 모든 함수 H(x, y, t)에 대해 일반적이다.

 

For the height function described in Section 1.2.1, the partial derivatives are particularly convenient to compute. Because the derivative of a sum is the sum of the derivatives:

 

섹션 1.2.1에 설명한 높이 함수는 편미분으로 계산하는 것이 특히 더 편리하다. 합의 도함수는 도함수의 합과 같기 때문이다:

 

Equation 7

ch01_eqn007.jpg


over all waves i.

 

모든 웨이브 i 에 대해.

 

A common complaint about waves generated by summing sine waves directly is that they have too much "roll," that real waves have sharper peaks and wider troughs. As it turns out, there is a simple variant of the sine function that quite controllably gives this effect. We offset our sine function to be nonnegative and raise it to an exponent k. The function and its partial derivative with respect to x are:

 

사인 웨이브를 직접적으로 더하여 생성된 웨이브에 대한 일반적인 불만사항은 너무 많은 “롤”이 있다는 것이다. 실제 웨이브는 꼭대기가 더 표족하고 간격이 더 넓다. 밝혀진 바와 같이, 이런 효과를 상당히 조절할 수 있는 사인 함수의 간단한 변형식이 있다. 우리의 사인 함수를 음수가 아닌 수로 오프셋시키고 지수 k 로 거듭제곱한다. 그 함수와 x 에 대한 편미분함수는 다음과 같다.

Equation 8a

01equ08a.jpg


Equation 8b

01equ08b.jpg


Figure 1-3 shows the wave shapes generated as a function of the power constant k. This is the function we actually use for our texture waves, but for simplicity, we continue to express the waves in terms of our simple sum of sines, and we note where we must account for our change in underlying wave shape.

 

그림 1-3은 상수 k 로 거듭제곱시킨 함수로 생성된 웨이브의 형태를 보여준다. 이것이 실제로 우리의 텍스쳐 웨이브에 사용할 함수이지만, 간략화하기 위해 웨이브를 계속해서 우리의 간단한 사인의 합의 식으로 표현한다. 그리고 어디서 기본 웨이브 형태에 우리의 변화를 적용해야하는지 표시한다.

 

fig01-03.jpg

Figure 1-3 Various Wave Shapes

1.2.3 Geometric Waves

We limit ourselves to four geometric waves. Adding more involves no new concepts, just more of the same vertex shader instructions and constants.

 

우리는 4개의 기하 웨이브로 제한한다. 더 추가하는 것은 새로운 개념을 필요로 하지 않고, 단지 동일한 정점 쉐이더 명령어와 상수가 더 필요할 뿐이다.

Directional or Circular

We have a choice of circular or directional waves, as shown in Figure 1-4. Directional waves require slightly fewer vertex shader instructions, but otherwise the choice depends on the scene being simulated.

 

우리는 그림 1-4와 같이, 원형이나 지향성 웨이브를 선택할 수 있다. 지향성 웨이브가 정점 쉐이더 명령어를 약간 덜 사용하지만, 어떤 것을 선택할지는 시뮬레이션하는 장면에 달려있다.

 

fig01-04.jpg

Figure 1-4 Directional and Circular Waves

 

For directional waves, each of the D i in Equation 1 is constant for the life of the wave. For circular waves, the direction must be calculated at each vertex and is simply the normalized vector from the center C i of the wave to the vertex:

 

지향성 웨이브의 경우, 방정식 1의 각 D i 는 웨이브의 수명을 위한 상수이다. 원형 웨이브의 경우, 방향은 각 정점에서 계산되어야하고 간단하게는 웨이브의 중점에서 정점으로의 정규화된 백터이다.

 

011equ01.jpg

 

For large bodies of water, directional waves are often preferable, because they are better models of wind-driven waves. For smaller pools of water whose source of waves is not the wind (such as the base of a waterfall), circular waves are preferable. Circular waves also have the nice property that their interference patterns never repeat. The implementations of both types of waves are quite similar. For directional waves, wave directions are drawn randomly from some range of directions about the wind direction. For circular waves, the wave centers are drawn randomly from some finite range (such as the line along which the waterfall hits the water surface). The rest of this discussion focuses on directional waves.

 

큰 몸체의 물의 경우, 지향성 웨이브가 보통 더 적절하다. 왜냐하면 바람이 부는 웨이브의 경우 그것이 더 나은 모델이기 때문이다. 웨이브의 근원이 바람이 아닌 더 작은 웅덩이 같은 경우(폭포의 기반같은), 원형 웨이브가 더 적절하다. 원형 웨이브는 또한 간섭 패턴이 절대 반복되지 않는 멋진 특성이 있다. 두 웨이브 형태의 구현은 상당히 비슷하다. 지향성 웨이브의 경우, 웨이브 방향은 바람 방향에 대한 일정 범위 내에서 무작위로 그려진다. 원형 웨이브의 경우, 웨이브 중심은 어떤 한정된 범위(폭포가 수면을 치는 곳을 이은 선 같은)내에서 무작위로 그려진다. 이 논의의 나머지 부분은 지향성 웨이브에 초점을 맞춘다.

Gerstner Waves

For effective simulations, we need to control the steepness of our waves. As previously discussed, sine waves have a rounded look to them—which may be exactly what we want for a calm, pastoral pond. But for rough seas, we need to form sharper peaks and broader troughs. We could use Equations 8a and 8b, because they produce the desired shape, but instead we choose the related Gerstner waves. The Gerstner wave function was originally developed long before computer graphics to model ocean water on a physical basis. As such, Gerstner waves contribute some subtleties of surface motion that are quite convincing without being overt. (See Tessendorf 2001 for a detailed description.) We choose Gerstner waves here because they have an often-overlooked property: they form sharper crests by moving vertices toward each crest. Because the wave crests are the sharpest (that is, the highest-frequency) features on our surface, that is exactly where we would like our vertices to be concentrated, as shown in Figure 1-5.

 

효과적인 시뮬레이션을 위해, 우리의 웨이브의 가파름을 조절할 필요가 있다. 이전에 논의한 것과 같이, 사인 웨이브는 둥근 모양이다. 이것은 잔잔하고 전원적인 연못을 원할 때에는 정확한 것일지도 모른다. 하지만 거친 바다를 표현하기 위해서는, 더 뾰족한 꼭대기와 더 넓은 간격의 웨이브가 필요하다. 방정식 8a와 8b가 원하는 형태를 만들어 내기 때문에 이 방정식을 사용할 수도 있다. 하지만 그 대신에 우리는 이와 관련된 Gerstner 웨이브를 선택한다. Gerstner 웨이브 함수는 원래 물리적인 원리로 바다를 모델링하기 위해 컴퓨터 그래픽 훨씬 이전에 개발되었다. 따라서, Gerstner 웨이브는 꽤 설득력있는 미묘한 표면 움직임에 기여한다. (자세한 설명은 Tessendorf 2001을 보라.) 우리는 여기서 Gerstner 웨이브를 선택한다. 왜냐하면 자주 간과되는 특성을 가지고 있기 때문이다. Gerstner 웨이브는 정점을 각 꼭대기 쪽으로 이동하여 더 뾰족한 꼭대기를 형성한다. 우리의 표면에서 웨이브 꼭대기가 제일 뾰족한(즉, 최고주파) 지형이기 때문에, 그림 1-5와 같이 우리의 정점들을 원하는 곳에 밀집시키는 것이 정확하다.

 

fig01-05.jpg

Figure 1-5 Gerstner Waves

 

The Gerstner wave function is:

 

Gerstner 웨이브 함수는 다음과 같다.

 

Equation 9

013equ01.jpg


Here Qi is a parameter that controls the steepness of the waves. For a single wave i, Qi of 0 gives the usual rolling sine wave, and Qi = 1/(wi Ai ) gives a sharp crest. Larger values of Qi should be avoided, because they will cause loops to form above the wave crests. In fact, we can leave the specification of Q as a "steepness" parameter for the production artist, allowing a range of 0 to 1, and using Qi = Q/(wi Ai x numWaves) to vary from totally smooth waves to the sharpest waves we can produce.

 

Qi 는 웨이브의 가파름을 조절하는 매개변수이다. 단일 웨이브 i 에 대해, Qi 의 값이 0이면 일반적인 둥근 사인 웨이브가 되고, Qi = 1/(wi Ai )이면 뾰족한 꼭대기가 만들어진다. Qi 의 값이 매우 커지는 것은 피해야하는데, 웨이브 꼭대기 위에 형성된 만곡선을 유발할 것이기 때문이다. 사실, 우리는 Q의 명세를 연출 아티스트를 위한 “가파름” 매개변수로서 남겨두고, 범위는 0~1로 하고 전체적으로 부드러운 웨이브를 우리가 생성할 수 있는 가장 뾰족한 웨이브로 바꾸기 위해서는 Qi = Q/(wi Ai x numWaves)를 사용한다.

 

Note that the only difference between Equations 3 and 9 is the lateral movement of the vertices. The height is the same. This means that we no longer have a strict height function. That is, ch01_eqn011.jpg However, the function is still easily differentiable and has some convenient cancellation of terms. Mercifully saving the derivation as an exercise for the reader, we see that the tangent-space basis vectors are:

 

방정식 3과 9의 유일한 차이점은 정점의 수평 움직임인 것을 주목하라. 높이는 같다. 이것은 우리가 더 이상 정밀한 높이 함수를 가지고 있지 않다는 것을 의미한다. 즉, ch01_eqn011.jpg 이다. 하지만 함수는 여전히 쉽게 미분 가능하고 약분하기 편한 항들을 가지고 있다. 미분은 독자의 과제로 남겨두고, 탄젠트 공간 기저 벡터들을 보자.

 

Equation 10

013equ02.jpg


Equation 11

013equ03.jpg


Equation 12

013equ04.jpg


where:

013equ05.jpg

 

These equations aren't as clean as Equations 4b, 5b, and 6b, but they turn out to be quite efficient to compute.

 

이 방정식들은 방정식 4b, 5b, 6b처럼 깔끔하진 않지만, 계산하기에 꽤 효율적이게 된다.

 

A closer look at the z component of the normal proves interesting in the context of forming loops at wave crests. While Tessendorf (2001) derives his "choppiness" effect from the Navier-Stokes description of fluid dynamics and the "Lie Transform Technique," the end result is a variant of Gerstner waves expressed in the frequency domain. In the frequency domain, looping at wave tops can be avoided and detected, but in the spatial domain, we can see clearly what is going on. When the sum Qi x wi x Ai is greater than 1, the z component of our normal can go negative at the peaks, as our wave loops over itself. As long as we select our Qi such that this sum is always less than or equal to 1, we will form sharp peaks but never loops.

 

법선의 z 성분을 자세히 보면 웨이브 꼭대기에 만곡선이 형성되는 상황이 흥미롭다는 것을 볼 수 있다. Tessendorf (2001)가 유체역학의 Navier-Stokes 내용과 “리 변환(Lie Transform) 기술”로부터 그의 “변화도”를 유도하긴 하지만, 최종 결과는 주파수 도메인으로 표현된 Gerstner 웨이브의 변형이다. 주파수 도메인에서는 웨이브 꼭대기에 있는 만곡선을 탐지하고 피할 수 있지만, 공간 도메인에서는 어떤 일이 진행되고 있는지 확실히 볼 수 있다. Qi x wi x Ai 의 합이 1보다 클 때, 우리의 법선의 z 성분이 꼭대기에서 음수가 되어 그 위에 만곡선이 생길 것이다. 이 합이 1보다 작거나 같게 Qi을 선택하면, 뾰족한 꼭대기를 형성하고 만곡선은 결코 생기지 않을 것이다.

Wavelength and Speed

We begin by selecting appropriate wavelengths. Rather than pursue real-world distributions, we would like to maximize the effect of the few waves we can afford. The super-positioning of waves of similar lengths highlights the dynamism of the water surface. So we select a median wavelength and generate random wavelengths between half and double that length. The median wavelength is scripted in the authoring process, and it can vary over time. For example, the waves may be significantly larger during a storm than while the scene is sunny and calm. Note that we cannot change the wavelength of an active wave. Even if it were changed gradually, the crests of the wave would expand away from or contract toward the origin, a very unnatural look. Therefore, we change the current average wavelength, and as waves die out over time, they will be reborn based on the new length. The same is true for direction.

 

우리는 적당한 파장을 선택하는 것으로 시작한다. 실세계 분포를 추구하기보다는, 우리가 만들어 낼 수 있는 웨이브에 대해 효과를 최대화시킬 것이다. 비슷한 길이를 가진 웨이브를 겹쳐놓으면 수면의 역동성이 강조된다. 그래서 우리는 중간 길이의 파장을 선택하고 1/2에서 2배의 길이 사이에서 무작위로 파장을 생성한다. 중간 길이의 파장은 오서링(authoring) 과정에서 스크립트되고, 시간에 따라 변경될 수 있다. 얘를 들면, 웨이브는 폭풍이 치는 동안에는 햇빛이 비치고 잔잔한 장면일때보다 훨씬 더 커질 것이다. 활동중인 웨이브의 파장은 변경할 수 없다는 것을 주의하라. 파장이 점차적으로 변하지는 않아도, 웨이브의 꼭대기는 부자연스런 형태로 멀리 퍼지거나 중심으로 모여든다. 따라서, 현재 평균 파장을 변경하고, 웨이브가 시간이 끝나 없어지게 되면 새 파장을 기반으로 다시 생성될 것이다. 방향은 동일하다.

 

Given a wavelength, we can easily calculate the speed at which it progresses across the surface. The dispersion relation for water (Tessendorf 2001), ignoring higher-order terms, gives:

 

파장이 주어지면, 표면을 움직이는 속도는 쉽게 계산할 수 있다. 고차항은 무시하고, 물의 분산 관계(Tessendorf 2001)는 다음과 같다.

Equation 13

ch01_eqn018.jpg


where w is the frequency and g is the gravitational constant consistent with whatever units we are using (such as 9.8 m/s2), and L is the crest-to-crest length of the wave.

 

w 는 주파수이고, g 는 어떤 단위(9.8 m/s2같은)를 사용하든 그에 맞는 중력상수이다. L 은 웨이브의 꼭대기 사이의 거리이다.

Amplitude

How to handle the amplitude is a matter of opinion. Although derivations of wave amplitude as a function of wavelength and current weather conditions probably exist, we use a constant (or scripted) ratio, specified at authoring time. More exactly, along with a median wavelength, the artist specifies a median amplitude. For a wave of any size, the ratio of its amplitude to its wavelength will match the ratio of the median amplitude to the median wavelength.

 

진폭을 어떻게 다룰지는 의견이 갈린다. 파장의 함수와 현재의 날씨 상태로부터 진폭을 유도하는 방법도 있을 수 있겠지만, 우리는 오서링(authoring) 시간에 지정된 고정(혹은 스크립트된) 비율을 사용한다. 더 정확하게는, 중간 파장에 따라 아티스트들이 중간 진폭을 지정한다. 웨이브가 어떤 크기던간에, 파장에 대한 진폭의 비율은 중간 파장에 대한 중간 진폭의 비율과 일치할 것이다.

Direction

The direction along which a wave travels is completely independent of the other parameters, so we are free to select a direction for each wave based on any criteria we choose. As mentioned previously, we begin with a constant vector that is roughly the wind direction. We then choose randomly from directions within a constant angle of the wind direction. That constant angle is specified at content-creation time, or it may be scripted.

 

웨이브가 움직이는 방향은 다른 매개변수들과 완전히 독립적이다. 따라서 우리가 선택한 어떤 기준을 기반으로 한 웨이브라도 방향을 자유롭게 선택할 수 있다. 이전에 언급한 것처럼, 우리는 바람의 방향을 나타내는 대략적인 상수 벡터를 가지고 시작한다. 그런 다음, 바람 방향의 특정 각 내에서 무작위로 방향을 선택한다. 그러한 특정 각은 컨텐츠 제작 단계에서 지정되고, 혹은 스크립트될 수도 있다.

1.2.4 Texture Waves

The waves we sum into our texture have the same parameterization as their vertex cousins, but with different constraints. First, in the texture it is much more important to capture a broad spectrum of frequencies. Second, patterns are more prone to form in the texture, breaking the natural look of the ripples. Third, only certain wave directions for a given wavelength will preserve tiling of the overall texture. Also, note that all quantities here are in units of texels, rather than world-space distance.

 

텍스쳐에 웨이브를 더하여 저장하는 것은 정점을 이용하는 것과 같은 매개변화수를 가지지만, 다른 제약이 있다. 우선, 텍스쳐에서는 주파수의 넓은 스펙트럼을 잡아내는 것이 훨씬 더 중요하다. 두번째로, 텍스쳐에 패턴들이 더 발생하기 쉬워, 잔물결의 자연스러운 모양이 흐트러질 수 있다. 세번째로, 주어진 파장에 대해 특정 웨이브 방향만이 전체 텍스쳐의 타일을 유지할 것이다. 또한, 모든 수치는 월드 공간 거리가 아닌 텍셀 단위인 것을 주의하라.

 

We currently use about 15 waves of varying frequency and orientation, taking from two to four passes. Four passes may sound excessive, but they are into a 256x256 render-target texture, rather than over the main frame buffer. In practice, the hit from the fill rate of generating the normal map is negligible.

 

우리는 지금 2~4개의 패스를 이용하여 주파수와 방위가 다른 15개 정도의 웨이브를 사용한다. 4개의 패스를 사용한다는 것이 과도한 것으로 들릴 수도 있겠지만, 메인 프레임 버퍼 대신, 256X256 크기의 렌더-타겟 텍스쳐를 사용한다. 사실, 법선맵을 생성하는 필레이트로 인한 손해는 무시할 수 있다.

Wavelength and Speed

Again, we start by selecting wavelengths. We are limited in the range of wavelengths the texture will hold. Obviously, the sine wave must repeat at least once if the texture is to tile. That sets the maximum wavelength at TEXSIZE, where TEXSIZE is the dimension of the target texture. The waves will degrade into sawtooth patterns as the wavelength approaches 4 texels, so we limit the minimum wavelength to 4 texels. Also, longer wavelengths are already approximated by the geometric undulation, so we favor shorter wavelengths in our selection. We typically select wavelengths between about 4 and 32 texels. With the bump map tiling every 50 feet, a wavelength of 32 texels corresponds to about 6 feet. This leaves geometric wavelengths ranging upward from about 4 feet, and texture wavelengths ranging downward from about 6 feet, with just a little overlap.

 

다시, 우리는 파장을 선택하는 것으로 시작한다. 파장의 범위는 텍스쳐에 저장할 수 있는 범위로 제한된다. 텍스쳐가 타일로 입혀진다면 사인 웨이브는 적어도 한번은 반복되어야한다. 따라서 최대 파장을 TEXSIZE 에 설정한다. TEXSIZE 는 타겟 텍스쳐의 크기이다. 파장이 4텍셀에 가까워지면 톱니모양의 패턴이 생겨 웨이브의 질이 떨어질 것이다. 따라서, 우리는 최소 파장을 4텍셀로 제한한다. 또한, 긴 파장은 기하 파동에서 이미 근사하였기 때문에 여기서는 짧은 파장만 다룬다. 우리는 일반적으로 파장을 4~32 텍셀로 선택한다. 50피트마다 타일링된 범프맵에서, 32텍셀의 파장은 6피트 정도가 된다. 이것은 기하 파장은 4피트보다 길게, 텍스쳐 파장은 6피트보다 짧게 하여 서로 조금만 겹치게 한다.

 

The wave speed calculation is identical to the geometric form. The exponent in Equations 8a and 8b controls the sharpness of the wave crests.

 

웨이브 속도 계산은 기하 형식과 동일하다. 방정식 8a와 8b의 지수는 웨이브 꼭대기의 가파른 정도를 조절한다.

Amplitude and Precision

We determine the amplitude of each wave as we did with geometric waves, keeping amplitude over wavelength a constant ratio, kAmpOverLen. This leads to an interesting optimization.

 

우리는 기하 웨이브에서 했던 것처럼 각 웨이브의 진폭을 결정하여, 진폭/파장의 값을 상수 비율 kAmpOverLen 에 저장한다. 이것은 흥미있는 최적화를 가능하게 한다.

 

Remember that we are not concerned with the height function here; we are only building a normal map. Our lookup texture contains cos(2p u), where u is the texture coordinate ranging from 0 to 1. We store the raw cosine values in our lookup texture rather than in the normals because it is actually easier to convert the cosine into a rotated normal than to store normals and try to rotate them with the texture.

 

여기서 높이 함수와는 관계가 없다는 것을 기억하라; 우리는 법선맵만을 생성하고 있다. 우리의 룩업 테이블은 cos(2p u) 값을 담고 있다. 여기서 u는 0~1까지의 텍스쳐 좌표이다. 우리는 원시 코사인값을 법선 텍스쳐가 아니라 우리의 룩업 텍스쳐에 저장한다. 왜냐하면 법선을 저장해서 텍스쳐로 그 법선을 회전하는 것보다 코사인을 회전된 법선으로 변환하는게 더 쉽기 때문이다.

 

We evaluate the normal of our sum of sines by rendering our lookup texture into a render target. Expressing Equation 7 in terms of u-v space, we have:

 

우리의 룩업 텍스쳐를 렌더 타겟에 렌더링하여 우리의 사인합의 법선을 구한다. 방정식 7을 u-v 공간에 대한 식으로 표현하면 다음과 같다.

 

Equation 14

ch01_eqn020.jpg


where u and v vary from 0 to 1 over the render target. We calculate the inner term, ch01_eqn021.jpg in the vertex shader, passing the result as the u coordinate for the texture lookup in the pixel shader. The outer terms, ch01_eqn022.jpg and ch01_eqn023.jpg , are passed in as constants. The resulting pixel shader is then a constant times a texture lookup per wave. We note that to use the sharper-crested wave function in Equation 8a, we simply fill in our lookup table with:

 

u와 v는 렌더 타겟 내에서 0~1로 변한다. 우리는 정점 쉐이더에서 내부항 ch01_eqn021.jpg을 계산하여 픽셀 쉐이더에서 텍스쳐 룩업을 위해 사용하는 u좌표로서 그 결과를 전달한다. 외부항  ch01_eqn022.jpg와 ch01_eqn023.jpg 는 상수로 전달된다. 결과 픽셀 쉐이더는 웨이브당 상수 시간 텍스쳐 룩업이다. 방정식 8a에 있는 뾰족한 꼭대기의 웨이브 함수를 사용하기 위해 우리의 룩업 테이블을 cos(2p u) 대신에 다음의 값으로 채운다.

 

016equ02.jpg

instead of cos(2p u), and pass in ch01_eqn026.jpg as the outer term.

 

ch01_eqn026.jpg은 외부항으로 전달한다.

 

Using a lookup table here currently provides both speed and flexibility. But just as the relative rates of increase in processor speed versus memory access time have pushed lookup tables on the CPU side out of favor, we can expect the same evolution on the GPU. Looking forward, we expect to be much more discriminating about when we choose a lookup texture over direct arithmetic calculation. In particular, by using a lookup table here, we must regenerate the lookup table to change the sharpness of the waves.

 

룩업 테이블을 사용하는 것은 일반적으로 속도와 유연성을 모두 제공한다. 그러나 메모리 엑세스 시간에 대한 프로세서 속도 증가의 상대적인 비율이 CPU에 있는 룩업 테이블을 신경쓰지 않는 것과 마찬가지로, GPU에서도 같은 전개를 기대해볼 수 있다. 앞으로를 생각하면, 우리는 직접 산술 연산을 통해 룩업 텍스쳐를 선택했을 때 훨씬 더 차별적인 것이 되길 기대한다. 특히, 룩업 테이블을 사용함으로 인해, 웨이브의 뾰족함을 변화시키기 위해 룩업 테이블을 재생성해야한다.

 

Unlike our approach to the composition of geometric normals in the vertex shader, in creating texture waves we are very concerned with precision. Each component of the output normal must be represented as a biased, signed, fixed-point value with 8 bits of precision. If the surface gets very steep, the x or y component will be larger than the z component and will saturate at 1. If the surface is always shallow, the x and y components will always be close to 0 and suffer quantization errors. In this work, we expect the latter case. If we can establish tight bounds on values for the x and y components, we can scale the normals in the texture to maximize the available precision, and then "un-scale" them when we use them.

 

정점 쉐이더에서 기하 법선을 조합하는 우리의 접근방식과는 달리, 텍스쳐 웨이브를 생성할 때에는 정밀도가 아주 많은 관계가 있다. 출력 법선의 각 성분은 8비트 정밀도의 바이어스되고, 부호가 있는, 고정 소수점 값으로 나타내야한다. 표면이 매우 가파르다면, x나 y성분이 z성분보다 더 커져 1이 될 것이다. 만약 표면이 항상 얕다면 x와 y성분은 항상 0에 가까울 것이고 양자화 오류가 발생할 것이다. 여기서 우리는 후자쪽을 살펴본다. 만약 x와 y성분의 범위를 빈틈없이 정할 수 있다면, 텍스쳐에 있는 법선을 유용한 최대 정밀도로 스케일하고, 그것을 사용할 때 원래 크기로 되될릴 수 있다.

 

Examining the x component of the generated normal, we first see that both the cosine function and the x component of the direction vector range over the interval [–1..1]. The product of the frequency and the amplitude is problematic, because the frequency and amplitude are different for each wave.

 

생성된 법선의 x성분을 검사하기 위해, 우선 코사인 함수와 -1~1의 범위를 가지는 방향 백터의 x성분을 본다. 주파수와 진폭의 내적은 확실치가 않다. 왜냐하면 주파수와 진폭은 각 웨이브마다 다르기 때문이다.

 

Expressing Equation 7 with the frequency in terms of wavelength, we have:

 

방정식 7을 파장에 대한 주파수로 나타내면 다음과 같다:

 

017equ01.jpg

 

Whereas the height is dominated by waves of greater amplitude, the surface orientation is dominated by waves with greater ratios of amplitude to wavelength.

 

높이가 진폭이 더 큰 웨이브에 의해 많은 영향을 받는 것에 반해, 표면 방위는 진폭/파장의 비율에 많은 영향을 받는다.

 

We first use this result to justify having a constant ratio of amplitude to wavelength across all our waves, reasoning that because we have a very limited number of waves, we choose to omit those of smaller ratios. Second, because of that constant ratio, we know that the x and y components of our waves are limited to having absolute values less than kAmpOverLen x 2p, and the total is limited to numWaves x kAmpOverLen x 2p. So to preserve resolution during summation, we accumulate:

 

우리는 우선 우리의 모든 웨이브에 걸쳐 진폭/파장의 고정비를 사용하는 것을 정당화하기 위해 이 결과를 사용한다. 우리는 매우 제한된 수의 웨이브를 사용하기 때문에 더 작은 비율의 웨이브는 생략하도록 한다. 두번재로, 그 고정비로 인해 웨이브의 x와 y성분은 kAmpOverLen x 2p 보다 작은 절대값을 가지도록 제한되고, 총합은 numWaves x kAmpOverLen x 2p 로 제한된다는 것을 알 수 있다. 따라서 합계의 결과를 보존하기 위해 다음을 누적하고:

 

017equ02.jpg

 

and scale by numWaves x 2p x kAmpOverLen when we use them.

 

그것을 사용할 때 numWaves x 2p x kAmpOverLen로 스케일한다.

Direction and Tiling

If the render target has enough resolution to be used without tiling, we can accumulate arbitrary sine functions into it. In fact, we can accumulate arbitrary normal maps into it. For example, we might overlay a turbulent distortion following the movements of a character within the scene. Alternately, we might begin with a more complex function than a single sine wave, getting more wave complexity with the accumulation of fewer "wave" functions. Keep in mind that the power of this technique is in the relative motion of the waves. A complex wave pattern moving as a unit has less realism and impact than simpler waves moving independently.

 

만약 렌더 타겟이 타일없이 사용될 수 있을 만큼 충분한 해상도이면, 렌더 타겟에 임의의 사인 함수를 누적할 수 있다. 사실, 우리는 렌더 타겟에 임의의 법선맵을 누적할 수 있다. 예를 들면, 장면 내에 있는 캐릭터의 움직임을 따른 휘몰아치는 일그러짐을 씌울 수도 있다. 또는, 단일 사인 웨이브보다 더 복잡한 함수로 시작하여, 더 적은 “웨이브” 함수의 누적을 통해 더 많은 웨이브 복잡성을 얻을 수도 있다. 이 테크닉의 강점은 웨이브의 상대적인 움직임에 있다는 것을 염두에 두어라. 한 개 단위로 움직이는 복잡한 웨이브 패턴은 독립적으로 움직이는 더 간단한 웨이브보다 실제감과 효과가 덜하다.

 

These additions are relatively straightforward. Getting the render target to tile, however, imposes some constraints on the wave functions we accumulate. In particular, note that a major appeal of circular waves is that they form no repeating patterns. If we want our texture to tile, we need our waves to form repeating patterns, so we limit ourselves to directional waves.

 

이 추가사항들은 상대적으로 간단하다. 그러나 타일로 구성할 렌더 타겟을 얻는 것은 우리가 누적할 웨이브 함수에 몇몇 제약을 가져온다. 특히, 원형 웨이브의 가장 큰 매력은 반복된 패턴을 형성하지 않는 다는 것을 주목하라. 만약 텍스쳐를 타일로 구성하길 원한다면, 웨이브를 반복되는 패턴으로 형성할 필요가 있기때문에, 방향성 웨이브로 제한한다.

 

Obviously, a tiling of a texture will tile itself only if the texture is repeated an integer number of times. Also, for a sine wave of given wavelength that tiles, only certain rotations of the texture will still tile. Less obvious, but equally true, is that if each of the rotated sine functions we add in will tile, then the sum of those sine functions also tiles.

 

분명히, 텍스쳐를 타일로 까는 것은 텍스쳐가 정수 횟수 만큼 반복되었을 때만 타일로 될 것이다. 또한, 타일로된 주어진 파장의 사인 웨이브의 경우, 텍스쳐를 특정각으로 회전했을 때만 여전히 타일로 되어있을 것이다. 우리가 넣은 회전된 각 사인 함수가 타일로 되어있으면, 그 사인 함수의 합 또한 타일로 되어 있을 것이라는 것이 덜 분명하긴 하지만 사실이다.

 

Because we rotate and scale the sine functions through the texture transform, we can ensure that both conditions for tiling are met by making certain that the scaled rotation elements of the texture transform are integers. We then translate the wave by adding a phase component into the transform's translation. Note that because the texture is really 1D, we need concern ourselves only with the transformed u coordinate.

 

우리는 텍스쳐 변환을 통해 사인 함수를 회전하고 스케일하기 때문에, 텍스쳐 변환의 스케일된 회전 성분이 정수라는 것을 확인함으로써 타일을 형성하기 위한 두 조건이 충족된다는 것을 확신할 수 있다. 그 후에 우리는 텍스쳐 변환의 변형에 위상(phase) 성분을 추가하여 웨이브를 변형한다.

1.3 Authoring

We briefly discuss in this section how the water system is placed and modeled offline. Through the modeling of the water mesh, the content author controls the simulation down to the level of the vertex. See Figure 1-6.

 

이 섹션에서 우리는 물 시스템이 오프라인에서 어떻게 배치되고 모델링되는지 간단히 논의한다. 물 메쉬의 모델링을 통해서, 콘텐츠 작가는 정점 수준에서 시뮬레이션을 관리한다. 그림 1-6을 보라.

 

fig01-06.jpg

Figure 1-6 Ocean and Pond Water

 

In our implementation, the mesh data is limited to the tessellation of the mesh, the horizontal positions of each vertex in the mesh, the vertical position of the bottom of the body of water below the vertex, and an RGBA color. Texture coordinates may be explicitly specified or generated on the fly. See Figure 1-7.

 

우리의 구현에서는 메쉬 데이터는 메쉬의 테셀레이션, 메쉬에 있는 각 정점의 수평 위치, 정점 아래의 물 몸체 바닥의 수직 위치, RGBA 색으로 제한된다. 텍스쳐 좌표는 명시적으로 지정되거나 작동 중에 생성될 것이다. 그림 1-7을 보라.

 

fig01-07.jpg

Figure 1-7 The User Interface of the 3ds max Authoring Tool

 

First, we discuss using the depth of the water at a vertex as an input parameter, from which the shader can automatically modify its behavior in the delicate areas where water meets shore. We also cover some vertex-level system overrides that have proven particularly useful. To prevent aliasing artifacts, we automatically filter out waves for which the sampling frequency of the mesh is insufficient. Finally, we comment on the additional input data necessary when the texture mapping is explicitly specified at content-creation time, rather than implicitly based on a planar mapping over position.

 

우선, 우리는 물이 물가를 만나는 다루기 까다로운 지역에서 정점의 행동을 자동적으로 수정할 수 있는 쉐이더와 함께, 정점에서 입력 파라미터로써 물의 깊이를 사용하는 것을 논의한다. 또한 특히 유용한다고 알려진 몇몇 정점-수준의 시스템 재정의도 다룬다. 엘리어싱 문제를 막기 위해, 메쉬의 샘플링 주파수가 부족한 웨이브를 자동으로 걸러낸다. 마지막으로, 텍스쳐 맵핑이 위치에 의한 평면 맵핑을 기반으로 암시적으로 정해지는 것이 아니라 콘텐츠-생성 시간에 명시적으로 정해질 때에 필요한 추가적인 입력 데이터에 대해서도 다룬다.

1.3.1 Using Depth

Because the height of the water will be computed, the z component of the vertex position might go unused. We could take advantage of this to compress our vertices, but we choose rather to encode the water depth in the z component instead. More precisely, we put the height of the bottom of the water body in the vertex z component, pass in the height of the water table as a constant, and have the depth of the water available with a subtraction. Again, this assumes a constant-height water table. To model something like a river flowing downhill, we need an explicit 3D position as well as a depth for each vertex. In such a case, the depth may be calculated offline using a simple ray cast from water surface to riverbed, or it can be explicitly authored as a vertex color, but in any case, the depth must be passed in as an additional part of the vertex data.

 

물의 높이는 계산할 것이기 때문에, 정점 위치의 z성분은 쓸모가 없을 것이다. 이것을 정점을 압축하는데 이용할 수 있지만, 그 대신에 우리는 z성분에 물의 깊이를 인코딩하는 것을 선택한다. 더 정확하게는, 물 몸체의 바닥 높이를 정점의 z성분에 넣고, 물 테이블의 높이를 상수로 전달하여, 뺄셈을 통해 물의 깊이를 얻는다. 다시 말해, 이것은 상수-높이 물 테이블이 있다고 가정한다. 아래로 흐르는 강물 같은 것을 모델링하기 위해서는, 명시적은 3D 위치뿐만 아니라 각 정점의 깊이도 필요하다. 그런 경우에, 깊이는 물 표면에서 강바닥으로의 간단한 광선 추적을 사용하여 계산하거나 정점 색으로써 명시적으로 정해질 수도 있다. 어떤 경우이든, 정점 데이터의 추가적인 부분으로 깊이가 전달되어야 한다.

 

We use the water depth to control the opacity of the water, the strength of the reflection, and the amplitude of the geometric waves. For example, one pair of input parameter for the system is a depth at which the water is transparent and a depth at which it is at maximum opacity. This might let the water go from transparent to maximum opacity as the depth goes from 0 at the shore to 3 feet deep. This is a very crude modeling of the fact that shallow water tints the bottom less than deep water does. Having the depth of the water available also allows for more sophisticated modeling of light transmission effects.

 

우리는 물의 투명도, 반사도, 기하 웨이브의 진폭을 조절하기 위해 물의 깊이를 사용한다. 예를 들면, 깊이값이 따라 물이 투명할 수도 있고 아예 불투명할 수도 있다. 물가에서의 깊이가 0에서 3피트로 변할수록 물이 투명에서 완전 불투명으로 변할 것이다. 이것은 얕은 물이 깊은 물보다 바닥의 색이 연하다는 사실을 간단히 모델링한 것이다. 물의 깊이를 알고 있으면 빛의 전달 효과를 더 멋지게 모델링할 수도 있다.

 

Attenuating the amplitude of the geometric waves based on depth is as much a matter of practicality as physical modeling. Attenuating out the waves where the water mesh meets the water plane allows for water vertices to be "fixed" where the mesh meets steep banks. It also gives a gradual die-off of waves coming onto a shallow shore. Because we constrain our vertices never to go below their input height, attenuating the waves to zero slightly above the water plane allows waves to lap up onto the shore, while enabling us to control how far up the shore they can go.

 

깊이에 기반한 기하 웨이브 진폭의 감쇠는 물리 모델링만큼 매우 실지적인 문제이다. 물 메쉬가 수면을 만나는 곳에서 웨이브를 감쇠하면 메쉬가 가파른 강기슭을 만나는 곳에서 물 정점이 “고정되게” 할 수 있고, 얕은 물가 위로 오는 웨이브가 점차적으로 소멸되게 할 수 있다. 우리는 정점이 입력 높이보다 절대 낮아지지 않게 강제하기 때문에, 수면 약간 위에서 웨이브를 0으로 감쇠하면 웨이브가 물가 위에 얇게 겹치게 하고, 웨이브가 물가에서 얼마나 멀리 갈 수 있는지 우리가 조절할 수 있게 한다.

1.3.2 Overrides

For the most part, the system "just works," processing all vertices identically. But there are valid occasions for the content author to override the system behavior on a per-vertex basis. We encode these overrides as the RGB vertex color. Left at their defaults of white, these overrides pass all control to the simulation. Bringing down a channel to zero modulates an effect.

 

대다수의 부분에서, 시스템은 모든 정점을 동일하게 처리하여 “그냥 작동한다”. 하지만 콘텐츠 작가가 정점당 기반에서 시스템 행동을 재정의하는 유효한 경우가 있다. 우리는 이 재정의들을 RGB 정점 색으로 인코딩한다. 기본값을 흰색으로 남겨두고, 이 재정의들은 시뮬레이션에 모든 제어를 전달한다. 채널을 0으로 떨어뜨려 효과를 조절한다.

 

The red component governs the overall transparency, making the water surface completely transparent when red goes to zero. Green modulates the strength of the reflection on the surface, making the water surface matte when green is zero. Blue limits the opacity attenuation based on viewing angle, which affects the Fresnel term. An alternate use of one of these colors would be to scale the horizontal components of the calculated per-pixel normal. This would allow some areas of the water to be rougher than others, an effect often seen in bays.

 

Red 성분은 전체 투명도를 제어한다. Red 값이 0이 되면 물 표면이 완전히 투명해진다. Green 성분은 표면의 반사도를 제어한다. Green 값이 0이면 물 표면이 무광택이 된다. Blue 성분은 시야각에 기반한 불투명 감쇠를 제한하여 프레넬 항에 영향을 미친다. 이 색의 하나를 번갈아 사용하면 픽셀당 계산된 법선의 수평 성분을 스케일할 것이다. 이로 인해 물의 일부 지역이 다른 곳보다 더 거칠어져, 효과가 종종 만(灣)에 있는 것으로 보인다.

1.3.3 Edge-Length Filtering

If you are already familiar with signal-processing theory, then you readily appreciate that the shortest wavelength we can use to undulate our mesh depends on how finely tessellated the mesh is. From the Nyquist theorem, we need our vertices to be separated by at most half the shortest wavelength we are using. If that doesn't seem obvious, refer to Figure 1-8, which gives an intuitive, if nonrigorous, explanation of the concept. As long as the edges of the triangles in the mesh are short compared to the wavelengths in our height function, the surface will look good. When the edge lengths get as long as, or longer than, half the shortest wavelengths in our function, we see objectionable artifacts.

 

당신에 만약 신호-처리 이론에 이미 친숙하다면, 우리의 메쉬가 물결치게 하기 위해 사용할 수 있는 가장 짧은 파장은 메쉬가 얼마나 정교하게 테셀레이션되어 있는지에 달려 있다는 것을 쉽게 알아차릴 것이다. Nyquist의 정리로부터, 정점을 적어도 우리가 사용하고 있는 제일 짧은 파장의 반으로 분리할 필요가 있다. 이것이 분명하지 않다면, 개념을 직관적으로 설명하고 있는 그림 1-8을 보라. 우리의 높이 함수에서의 파장과 비교하여 메쉬에 있는 삼각형의 모서리가 짧을 수록, 표면은 좋게 보일 것이다. 모서리의 길이가 우리 함수에서의 가장 짧은 파장의 반과 같거나 더 길면, 못마땅한 결함이 보인다.

 

fig01-08.jpg

Figure 1-8 Matching Wave Frequencies to Tessellation

 

One reasonable and common approach is to decide in advance what the shortest wavelength in our height function will be and then tessellate the mesh so that all edges are somewhat shorter than that wavelength. In this work we take another approach: We look at the edge lengths in the neighborhood of a vertex and then filter out waves that are "too short" to be represented well in that neighborhood.

 

한가지 적당하고 일반적인 접근법은 우리 높이 함수에서 가장 짧은 파장이 얼마가 될 것인지 미리 결정한 다음 메쉬를 테셀레이션하여 모든 모서리가 그 파장보다 다소 더 짧게 되도록 하는 것이다. 여기서 우리는 또다른 접근법을 취한다: 정점의 이웃 모서리 길이를 보고, 그 이웃에 나타내기에 “너무 짧은” 웨이브는 걸러낸다.

 

This technique has two immediate benefits. First, any wavelengths can be fed into the vertex processing unit without undesirable artifacts, regardless of the tessellation of the mesh. This allows the simulation to generate wavelengths solely based on the current weather conditions. Any wavelengths too small to undulate the mesh are filtered out with an attenuation value that goes from 1 when the wavelength is 4 times the edge length, to 0 when the wavelength is twice the edge length. Second, the mesh need not be uniformly tessellated. More triangles may be devoted to areas of interest. Those areas of less importance, with fewer triangles and longer edges, will be flatter, but they will have no objectionable artifacts. An example would be modeling a cove heavily tessellated near the shore, using larger and larger triangles as the water extends out to the horizon.

 

이 테크닉은 두가지 직접적인 이득이 있다. 첫번째는, 어떤 파장이든 잘못된 결함없이, 메쉬의 테셀레이션에 개의치 않고 정점 처리 단위에 제공할 수 있다. 이것은 현재 날씨 상태에 따라 시뮬레이션이 파장을 단독으로 생성할 수 있게 한다. 메쉬를 물결치게 하기에 너무 작은 어떠한 파장이라도, 파장이 모서리 길이의 4배일 때 1에서 2배일 때는 0으로 변하는 감쇠값으로 걸러진다. 두번째는, 메쉬가 균일하게 테셀레이션될 필요가 없다는 것이다. 원하는 지역에 더 많은 삼각형을 모을 수도 있다. 중요성이 덜한 지역은 삼각형이 더 적고 모서리가 더 길어 더 평평해질 것이지만 못마땅한 결함은 없을 것이다. 예를 들면, 물가 근처의 만 내부는 빽빽하게 테셀레이션하여 모델링하고, 수평선에 펼쳐진 물은 더 큰 삼각형을 사용한다.

1.3.4 Texture Coordinates

Usually, texture coordinates need not be specified. They are easily derived from the vertex position, based on a scale value that specifies the world-space distance that a single tile of the normal map covers.

 

보통, 텍스쳐 좌표는 지정될 필요가 없다. 텍스쳐 좌표는 법선맵의 타일 하나가 덮고 있는 월드-공간 거리를 지정한 스케일 값을 기반으로 정점 위치로부터 쉽게 구해진다.

 

In some cases, however, explicit texture coordinates can be useful. one example is having the water flow along a winding river. In this case, the explicit texture coordinates must be augmented with tangent-space vectors, to transform the bump-map normals from the space of the texture as it twists through bends into world space. These values are automatically calculated offline from the partial derivatives of the position with respect to texture coordinate, as is standard with bump maps. The section "Per-Pixel Lighting" in Engel 2002 gives a practical description of generating tangent-space basis vectors using DirectX.

 

그러나, 어떤 경우에는 명시적인 텍스쳐 좌표가 유용할 수 있다. 한 예는 꾸불꾸불한 강을 따라 흐르는 물이 있을 때이다. 이 경우, 월드 공간에서 굴곡이 생기도록 범프맵 법선을 텍스쳐 공간으로부터 변환하기 위해, 탄젠트-공간 벡터와 함께 명시적 텍스쳐 좌표가 추가되어야 한다. 이 값들은 범프맵과 같은 기준으로 텍스쳐 좌표에 대한 위치의 편미분으로 오프라인에서 자동으로 계산한다. Engel 2002의 “Per-Pixel Lighting” 섹션에 DirectX를 사용하여 탄젠트-공간 기저 벡터를 생성하는 것에 대한 실제적인 설명이 나와있다.

1.4 Runtime Processing

Let's consider the processing in the vertex and pixel shaders here at a high level. Refer to the accompanying source code for specifics. With the explanations from the previous sections behind us, the processing is fairly straightforward. only one subtle issue remains unexplored.

 

고차원에서 정점과 픽셀 쉐이더에서의 프로세싱에 대해 생각해보자. 세부사항은 동봉된 소스코드를 참고하라. 이전 섹션에서 설명한 것으로 인해, 프로세싱은 아주 간단하다. 한가지 미묘한 이슈만이 남아있다.

 

Having a dynamic, undulating geometric surface, and a complex normal map of interacting waves, we need only to generate appropriate bump-environment mapping parameters to tie the two together. Those parameters are the transform to take our normals from texture space to world space, and an eye vector to reflect off our surface into our cubic environment map. We derive those first and then walk through the vertex and pixel processing.

 

동적이고 물결치는 기하 표면과 상호작용하는 웨이브의 복잡한 법선맵이 있을 때, 이 둘을 함께 묶기 위해서는 적절한 범퍼-환경 맵핑 파라미터만 생성하면 된다. 그 파라미터는 우리의 법선을 텍스쳐 공간에서 월드 공간으로 바꾸는 변환과, 우리의 표면을 입방체 환경맵으로 반사시키기 위한 눈 벡터이다. 우리는 이것들을 먼저 얻어낸 다음에 정점과 픽셀 프로세싱으로 진행한다.

1.4.1 Bump-Environment Mapping Parameters

Tangent-Space Basis Vectors

We can compute space basis vectors from the partial derivatives of our water surface function. Equations 10, 11, and 12 give us the binormal B, the tangent T, and the normal N.

 

우리는 우리의 물 표면 함수의 편미분으로부터 공간 기저 벡터를 계산할 수 있다. 방정식 10, 11, 12를 이용해 종법선 B, 탄젠트 T, 법선 N 을 얻을 수 있다

 

We stack those values into three vectors (that is, output texture coordinates) to be used as a row-major matrix, so our matrix will be:

 

우리는 행-우선 행렬을 사용하기 위해 그 값들을 3개의 벡터에 쌓는다. 그 행렬은 다음과 같을 것이다:

 

023equ01.jpg

 

Except for where we got the basis vectors, this is the usual transform for bump mapping. It accounts for our surface being wavy, not flat, transforming from the undulating surface space into world space. If the texture coordinates for our normal map are implicit—that is, derived from the vertex position—then we can assume that there is no rotation between texture space and world space, and we are done. If we have explicit texture coordinates, however, we must take into account the rotations as the texture twists along the river.

 

기저 백터를 구해야 하지만, 이것은 범프 맵핑을 위한 유용한 변환이다. 우리의 표면은 파도가 치고 평평하지 않으며, 물결치는 표면 공간에서 월드 공간으로 변환된다. 우리 법선맵에 대한 텍스쳐 좌표가 암시적 이라면-즉, 정점 위치로부터 얻은 것이라면, 텍스쳐 공간과 월드 공간 사이에 회전이 없다고 가정할 수 있다. 하지만, 명시적인 텍스쳐 좌표를 가지고 있다면, 텍스쳐가 강을 따라 휘어지는 회전을 고려해야한다.

 

Having computed U2202.GIF P/U2202.GIF u and U2202.GIF P/U2202.GIF v offline, we use these to form a rotation matrix to transform our texture-space normals into surface-space normals.

 

오프라인으로 U2202.GIFP/ U2202.GIFu 와  U2202.GIFP/ U2202.GIFv 을 계산하면, 텍스쳐-공간 법선을 표면-공간 법선으로 변환하기 위한 회전 행렬을 만드는데 이 값을 사용한다.

 

024equ01.jpg

 

This is clearly a rotation in the horizontal plane, which we expect because we collapsed the water mesh to z = 0 before computing the gradients. In the more general case where the base surface is not flat, this would be a full 3x3 matrix. In either case, order is important, so our concatenated matrix is Surf2World x Tex2Surf.

 

이것은 정확히 우리가 기대하는 수평면에서의 회전이다. 왜냐하면 우리는 경사도를 계산하기 전에 물 메쉬를 z = 0로 떨어뜨리기 때문이다. 기본 표면이 평평하지 않은 더 일반적인 경우에, 이 행렬은 꽉 찬 3x3행렬이 될 것이다. 어떤 경우든, 순서가 중요해다. 그래서 행렬은 Surf2World x Tex2Surf 순서로 이어진다.

 

If we want to rescale the x and y components of our normals, we must take one final step. We might want to rescale the components because we had scaled them to maximize precision when we wrote them to the normal map. Or we might want to rescale them based on their distance from the camera, to counter aliasing. In either case, we want the scale to be applied to the x and y components of the raw normal values, before either of the preceding transforms. Then, assuming a uniform scale factor s, our scale matrix and final transform are:

 

우리 법선의 x와 y 성분을 다시 스케일하고 싶다면, 마지막 단계를 수행해야한다. 성분을 법선맵에 쓸 때 최고 정밀도로 스케일해서 다시 스케일하고 싶을 수도 있다. 아니면 앨리어싱을 없애기 위해, 카메라까지의 거리를 기반으로 다시 스케일하고 싶을 수도 있다. 어떤 경우이든, 우리는 이전의 변환이 적용되기 전에 원래 법선 값의 x, y성분에 스케일을 적용하기를 바란다. 그래서, 동일 스케일 인수를 s 라하면, 우리의 스케일 행렬과 최종 변환은 다음과 같다:

 

ch01_eqn033.jpg

Eye Vector

We typically use the eye-space position of the vertex as the eye vector on which we base our lookup into the environment map. This effectively treats the scene in the environment map as infinitely far away.

 

우리는 일반적으로 정점의 눈-공간 위치를 환경맵으로 우리의 룩업을 참조하는 눈 벡터로 사용한다. 이것은 실제로 환경맵에 있는 장면이 무한대로 멀리 있다고 간주한다.

 

If all that is reflected in the water is more or less infinitely far away—for example, a sky dome—then this approximation is perfect. For smaller bodies of water, however, where the reflections show the objects on the opposite shore, we would like something better.

 

만약 물에 비치는 모든 것은 거의 무한히 떨어져 있다면 -예를 들면, 하늘 천장- 이러한 근사는 완벽하다. 그러나, 반대편 물가에 있는 물체를 반사되는 더 작은 몸체의 물의 경우, 우리는 더 나은 것을 원한다.

 

Rather than at an infinite distance, we would like to assume the reflected features are at a uniform distance from the center of our pool. That is, we will project the environment map onto a sphere of the same radius as our pool, centered about our pool. Brennan 2002 describes a very clever and efficient approximation for this. We offer an alternate approach.

 

무한한 거리 대신에, 우리는 반사되는 물체가 물의 중심으로부터 동일한 거리에 있다고 가정한다. 즉, 우리의 물과 중심과 반지름이 같은 구에 환경맵을 투영할 것이다. Brennan 2002은 이것에 대해 매우 영리하고 효율적인 근사를 설명하고 있다. 우리는 또 다른 접근법을 제공한다.

 

Figure 1-9 gives an intuitive feel for the problem as well as the solution. Given an environment map generated from point C, the camera is now at point E looking at a vertex at point P. We would like our eye vector to pass from E through P and see the object at A in the environment map. But the eye vector is actually relative to the point from which the environment map was generated, so we would sample the environment map at point B.

 

그림 1-9는 문제와 해결책에 대해 직관적인 느낌을 준다. 점 C로부터 생성된 환경맵이 주어지면, 이제 카메라는 점 E에서 점 P에 있는 정점을 바라본다. 우리는 눈 벡터가 점 E에서 점 P로 지나가고, 환경맵에 있는 점 A에서 물체를 보길 원한다. 하지만 눈 벡터는 실제로 환경맵이 생성된 점에 상대적이기 때문에, 점 B에서 환경맵을 샘플링할 것이다.

 

fig01-09.jpg

Figure 1-9 Correction of the Eye Vector

 

We would like to calculate an eye vector that will take us from C to A. We can find A as the point where our original eye vector intersects the sphere, and then our corrected eye vector is A - C. Because A is on the sphere of radius r, and A = E + (P - E)t, we have:

 

우리는 C에서 A를 얻을 수 있는 눈 벡터를 계산하길 원한다. 우리는 원래의 눈 벡터와 구가 만나는 점에서 A를 찾을 수 있다. 따라서 옳바른 눈 벡터는 A - C 이다. A는 반지름이 r인 구 위에 있기 때문에, A = E + (P - E)t 이고, 다음의 식을 얻게 된다:

 

025equ01.jpg

 

This expands out to:

 

이 식을 전개하면 다음과 같이 된다.

 

0 = (P - E)2 · t 2 - 2(P - E)(E - C) · t + (E - C)2 - r 2.

 

We solve for t using the quadratic equation, giving:

 

2차 방정식을 이용해 t를 구하면 다음과 같다:

 

026equ01.jpg

 

Here we make some substitutions:

 

여기에 몇가지 대입을 만든다:

 

ch01_eqn039.jpg

 

Substituting in and discarding the lesser root gives us:

 

대입하여 작은 루트를 버리면 다음과 같다:

 

026equ03.jpg

 

Canceling our 2s and recognizing that D 2 = 1 (it's normalized), gives us:

 

2를 약분하고 D 2 = 1 라는 것을 알아보게 되면(정규화되었기 때문에), 식은 다음과 같아 진다:

 

026equ04.jpg

 

and

 

026equ05.jpg

 

We already have D, the normalized eye vector, because we use it for attenuating the water opacity based on viewing angle. F and G are constants. So calculating t and our corrected eye vector, although it started out ugly, requires only five arithmetic operations. This underlines a powerful point made in Fernando and Kilgard 2003, namely, that collapsing values that are constant over a mesh into shader constants can bring about dramatic and surprising optimizations within the shader code.

 

우리는 이미 정규화된 눈 벡터 D를 알고 있다. 왜냐하면 시야각을 기반으로 물의 불투명도를 감쇠하는데 그것을 사용하기 때문이다. F와 G는 상수이다. 따라서 지저분하기 시작은 했지만 5번의 연산으로 t와 옳바른 눈 벡터를 계산할 수 있다. 이것은 Fernando와 Kilgard 2003에서 만들어진 강력한 점이라는 것을 확실히 나타낸다. 즉, 메쉬에 따라 변하지 않는 값을 쉐이더 상수로 정리하는 것은 쉐이더 코드 내에서 극적이고 놀라운 최적화를 가져온다.

 

Because we have essentially intersected a ray with a sphere, this method will obviously fail if that ray does not intersect the sphere. This possibility doesn't especially concern us, however. There will always be a real root if either the eye position or the vertex position lies within the sphere, and since the sphere encompasses the scenery around the body of water, it is safe to constrain the water vertices to lie within the sphere.

 

우리는 본질적으로 광선을 구와 교차시키기 때문에, 이 방법은 광선이 구와 만나지 않는다면 분명히 실패할 것이다. 그러나 이러한 가능성은 우리와 그리 관계가 없다. 구는 물 주위의 배경을 둘러싸고 있기 때문에, 눈이나 정점 위치가 구 내부에 있으면 항상 실수 루트값을 얻을 것이다.

 

Note that where the surroundings reflected off a body of water are not well approximated by a mapping onto a sphere, or where the surroundings are too dynamic to be captured by a static environment map, a projective method such as the one described in Vlachos et al. 2002 might be preferable.

 

물을 반사하는 환경이 구에 맵핑하는 것으로 잘 근사되지 않을 때나, 주위환경이 정적 환경맵으로 잡아내기에 너무 동적이라면, Vlachos et al. 2002에 설명된 것과 같은 투영 방식이 더 나을 것이다.

1.4.2 Vertex and Pixel Processing

We begin by evaluating the sine and cosine functions for each of our four geometric waves.

 

우리는 4개의 기하 웨이브 각각에 대한 사인, 코사인 함수를 구하는 것으로 시작한다.

 

Before summing them, we subtract our input vertex Z from our water-table height constant to get the depth of the water at this vertex. That depth forms our first wave-height attenuation factor by some form of interpolation between input constant depths.

 

그것을 합하기 전에, 정점에서의 물 깊이를 얻기 위해 우리의 물-테이블 높이 상수에서 입력 정점 Z를 뺀다. 그 깊이는 입력 상수 깊이 사이의 몇몇 형태의 보간법을 통해 우리의 첫번째 웨이브-높이 감쇠 인수를 형성한다.

 

Because we have stored the minimum edge length in the neighborhood of this vertex, we now use that to attenuate the heights of the waves independently, based on wavelength. That attenuation will filter out waves as the edge length gets as long as a fraction of the wavelength.

 

우리는 이 정점의 이웃에 최소 모서리 길이를 저장하기 때문에, 이제 파장을 기반으로 웨이브 높이를 독립적으로 감쇠하기 위해 그것을 사용한다. 그 감쇠는 모서리 길이가 파장보다 작은 웨이브는 걸려낼 것이다.

 

Explicit texture coordinates are passed through as is. Implicit coordinates are simply a scaling of the x and y positions of the vertex. The transformation from texture space to world space is calculated as described in Section 1.4.1. The scale value used is the input constant numWaves x 2p x kAmpOverLen, as described in the "Amplitude and Precision" subsection of Section 1.2.4. The scale value is modulated by another scale factor that goes to zero with increasing distance from the vertex to the eye. This causes the normal to collapse to the geometric surface normal in the distance, where the normal map texels are much smaller than pixels. The eye vector is computed as the final piece needed for bump environment mapping.

 

명시적 텍스쳐 좌표에 대해서 살펴보았었다. 암시적 텍스쳐 좌표는 정점의 x, y 위치를 스케일하여 간단히 구해진다. 텍스쳐 공간에서 월드 공간으로의 변환은 섹션 1.4.1에 설명된 것처럼 계산된다. 섹션 1.2.4의 "Amplitude and Precision" 항목에 설명한 것과 같이, 사용된 스케일 값은 입력 상수 numWaves x 2p x kAmpOverLen 이다. 스케일 값은 정점에서 눈으로의 거리가 증가할수록 0에 가까워지는 또 다른 스케일 인자에 의해 수정된다. 이로 인해 법선이 법선맵 텍셀이 픽셀보다 훨씬 더 작은 먼 곳에서는 기하 표면 법선으로 축소된다.

 

We emit two colors per vertex. The first is the color of the water proper. The second will tint the reflections off the water. The opacity of the water proper is modulated first as a function of depth, generally getting more transparent in shallows. Then it is modulated based on the viewing angle, so that the water is more transparent when viewed straight on than when viewed at a glancing angle. A per-pixel Fresnel term, as well as other more sophisticated effects, could be calculated by passing the view vector into the pixel shader, rather than computing the attenuation at the vertex level. The reflection color is also modulated based on depth and viewing angle, but independently to provide separate controls for when and how transparent the reflection gets.

 

우리는 정점당 2가지 색을 낸다. 첫번째 색은 물 특성 색이다. 두번째 색은 물에 비치는 반사에 색일 입힐 것이다. 물 특성의 불투명도는 우선 깊이 함수로 수정된다. 보통 얕은 곳은 더 투명해진다. 그런 다음 시야각에 따라 수정되어, 비스듬히 봤을 때보다 정면에서 봤을 때 물이 더 투명해진다. 픽셀당 프레넬 항은 물론 다른 더 복잡한 효과들은 정점 수준에서 감쇠를 계산하기 보다는, 픽셀 쉐이더로 뷰 벡터를 전달하여 계산할 수 있다. 반사 또한 깊이와 시야각에 따라 수정된다. 하지만 반사를 언제 얼마나 투명하게 할 것인지에 따라 독립적으로 분리된 조절한다.

 

In the pixel processing stage, there is little left to do. A simple bump lookup into an environment map gives the reflection color. We currently look up into a cubic environment map, but the projected planar environment maps described in Vlachos et al. 2002 would be preferable in many situations. The reflected color is modulated and added to the color of the water proper. The pixel is emitted and alpha-blended to the frame buffer.

 

픽셀 처리 단계에서 할 것이 조금 남아있다. 환경맵 안에 간단한 범프 룩업을 넣으면 반사색을 얻을 수 있다. 우리는 지금은 입방체 환경맵을 사용했지만, Vlachos et al. 2002에 설명되어 있는 투영 평면 환경맵이 많은 경우에 더 나을 것이다. 반사된 색은 수정되어 물 특성 색에 더해진다. 픽셀은 프레임 버퍼에 뿌려지고 알파블렌딩된다.

1.5 Conclusion

Water simulation makes an interesting topic in the context of vertex and pixel shaders, partly because it leverages such distinct techniques into a cohesive system. The work described here combines enhanced bump environment mapping with the evaluation of complex functions in both vertex and pixel shaders. We hope this chapter will prove useful in two ways: First, by detailing the physics and math behind what is frequently thought of as an ad hoc system, we hope we have shown how the system itself becomes more extensible. More and better wave functions on the geometric as well as the texture side could considerably improve the system, but only with an understanding of how the original waves were used. Second, the system as described generates a robust, dynamic, controllable, and realistic water surface with minimal resources. The system requires only vs.1.0 and ps.1.0 support. on current and future hardware, that leaves a lot of resources to carry forward with more sophisticated effects in areas such as light transport and reaction to other objects.

 

물 시뮬레이션은 정점과 픽셀 쉐이더 영역에서 매우 흥미로운 주제이다. 어느 정도는, 이런 별개의 테크닉이 통합적인 시스템에 포함되는데에 영향을 주기 때문이다. 여기서 설명한 방식은 정점과 픽셀 쉐이더 양쪽에서 강화된 범프 환경 맵핑과 복잡한 함수의 풀이를 결합한다. 우리는 이 챕터가 2가지 방식에서 유용할 것이라는 것을 희망한다: 첫번째는, 보통은 특별한 시스템으로 여겨지는 물리와 수학을 자세히 설명함으로써, 시스템 자체가 얼마나 더 확장될 수 있는지를 보여주었길 희망한다. 기하와 텍스쳐 쪽에 더 좋은 웨이브를 더 많이 사용하면 시스템이 상당히 향상하겠지만, 그것은 원래의 웨이브가 어떻게 사용되었는지를 이해하고 있을 때의 얘기다. 두번째로, 설명한 것과 같이 시스템이 최소의 자원으로 거칠고, 동적이며 조절가능하고 사실적인 물 표면을 생성한다는 것이다. 시스템은 단지 vs.1.0과 ps.1.0의 지원만이 필요하다. 현재와 미래의 하드웨어에서는, 빛의 이동이나 다른 물체와의 상호작용 같은 영역에 있는 더 고급스런 효과에 넘겨줄 많은 자원을 남겨둔다.

1.6 References

Jeff Landers has a good bibliography of water techniques on the Darwin 3D Web site: http://www.darwin3d.com/vsearch/FluidSim.txt

And another good one, on the Virtual Terrain Project Web site: http://www.vterrain.org/Water/index.html

Brennan, Chris. 2002. "Accurate Reflections and Refractions by Adjusting for Object Distance." In ShaderX, edited by Wolfgang Engel. Wordware. http://www.shaderx.com

Engel, Wolfgang. 2002. "Programming Pixel Shaders." In ShaderX, edited by Wolfgang Engel. Wordware. http://www.shaderx.com

Enright, Douglas, Stephen Marschner, and Ronald Fedkiw. 2002. "Animation and Rendering of Complex Water Surfaces." In Proceedings of SIGGRAPH 2002. Available online at http://graphics.stanford.edu/papers/water-sg02/water.pdf

Fernando, Randima, and Mark J. Kilgard. 2003. The Cg Tutorial. Addison-Wesley.

Isidoro, John, Alex Vlachos, and Chris Brennan 2002. "Rendering Ocean Water." In ShaderX, edited by Wolfgang Engel. Wordware. http://www.shaderx.com

Laeuchli, Jesse. 2002. "Simple Gerstner Wave Cg Shader." online article. Available online at http://www.cgshaders.org/shaders/show.php?id=46

Tessendorf, Jerry. 2001. "Simulating Ocean Water." In Proceedings of SIGGRAPH 2001. Course slides available online here at online.cs.nps.navy.mil

Vlachos, Alex, John Isidoro, and Chris Oat. 2002. "Rippling Reflective and Refractive Water." In ShaderX, edited by Wolfgang Engel. Wordware. http://www.shaderx.com

Yann, L. 2003. "Realistic Water Rendering." E-lecture. Available online at http://www.andyc.org/lecture/viewlog.php?log=Realistic%20Water%20Rendering,%20by%20Yann%20L


Copyright

Many of the designations used by manufacturers and sellers to distinguish their products are claimed as trademarks. Where those designations appear in this book, and Addison-Wesley was aware of a trademark claim, the designations have been printed with initial capital letters or in all capitals.

The authors and publisher have taken care in the preparation of this book, but make no expressed or implied warranty of any kind and assume no responsibility for errors or omissions. No liability is assumed for incidental or consequential damages in connection with or arising out of the use of the information or programs contained herein.

The publisher offers discounts on this book when ordered in quantity for bulk purchases and special sales. For more information, please contact:

      U.S. Corporate and Government Sales
      (800) 382-3419
      corpsales@pearsontechgroup.com

For sales outside of the U.S., please contact:

      International Sales
      international@pearsoned.com

Visit Addison-Wesley on the Web: www.awprofessional.com

Library of Congress Control Number: 2004100582

GeForce™ and NVIDIA Quadro® are trademarks or registered trademarks of NVIDIA Corporation.
RenderMan® is a registered trademark of Pixar Animation Studios.
"Shadow Map Antialiasing" © 2003 NVIDIA Corporation and Pixar Animation Studios.
"Cinematic Lighting" © 2003 Pixar Animation Studios.
Dawn images © 2002 NVIDIA Corporation. Vulcan images © 2003 NVIDIA Corporation.

Copyright © 2004 by NVIDIA Corporation.

All rights reserved. No part of this publication may be reproduced, stored in a retrieval system, or transmitted, in any form, or by any means, electronic, mechanical, photocopying, recording, or otherwise, without the prior consent of the publisher. Printed in the United States of America. Published simultaneously in Canada.

For information on obtaining permission for use of material from this work, please submit a written request to:

      Pearson Education, Inc.
      Rights and Contracts Department
      One Lake Street
      Upper Saddle River, NJ 07458

Text printed on recycled and acid-free paper.

5 6 7 8 9 10 QWT 09 08 07

5th Printing September 2007