GPU Gems 1

Chapter 7. Rendering Countless Blades of Waving Grass

공대나온남자 2009. 3. 27. 20:02

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

Chapter 7. Rendering Countless Blades of Waving Grass

Kurt Pelzer
Piranha Bytes

7.1 Introduction

To simulate an idyllic nature scene in a realistic fashion, besides detailed trees and bushes, as well as a complex water and sky dome simulation, we need a high-quality grass effect. We must be able to cover large areas of the terrain with it, without monopolizing the GPU. The grass should look naturally grown and should wave realistically in the wind.

 

세밀한 나무와 숲, 복잡한 물과 하늘 돔 시뮬레이션 외에 사실적인 방식으로 아름다운 자연 풍경을 시뮬레이션하기 위해서는, 고화질의 풀 효과가 필요하다. 우리는 GPU를 독점하지 않고 넓은 지역을 풀로 덮을 수 있어야 한다. 풀은 자연스럽게 자라난 것처럼 보여야하고 바람에 사실적으로 흔들려야 한다.

 

In the past, a high-quality grass simulation would have been considered too complex for real-time applications. The Codecreatures Benchmark (published by Codecult in 2002) disproved this pessimistic assertion. See Figure 7-1. In this chapter, we describe a flexible, widely applicable grass simulation based on the grass effect shown in the benchmark. Additionally, a special version of our Codecreatures Benchmark application is included in this book's accompanying material, which offers an interactive demo mode.

 

이전에는, 고화질 풀 시뮬레이션이 실시간 어플리케이션에 사용하기에는 너무 복잡한 것으로 여겨졌다. Codecreatures 벤치마크(2002년 Codecult 가 발표)는 이런 비관적인 주장을 반대했다. 그림 7-1을 보라. 이 챕터에서, 우리는 벤치마크에서 보여준 풀 효과를 기반으로 유연하고 넓리 적용될 수 있는 풀 시뮬레이션을 설명한다. 게다가, 우리의 Codecreatures 벤치마크 어플리케이션의 특별한 버전이 이 책의 부록에 포함되어있다. 그것은 양방향의 데모 방식을 제공한다.

 

 

Figure 7-1 Screenshot of the Codecreatures Benchmark Application

 

7.2 Overview

First, we should realize that a detailed modeling of the individual blades of grass is not meaningful, because the number of polygons that would be required for larger meadows would be much too high. A scene with countless blades of polygonal grass would not be displayable in real time with the graphics hardware available today.

 

우선, 우리는 풀의 개별적인 잎을 자세히 모델링하는 것은 의미가 없다는 것을 이해해야한다. 왜냐하면 넓은 초원에 필요한 폴리곤의 수가 너무 많아질 것이기 때문이다. 잎을 폴리곤으로 만든 무수히 많은 풀이 있는 장면은 현재 이용할 수 있는 그래픽 하드웨어로는 실시간으로 나타낼 수 없을 것이다.

 

So we have to build a simple and useful alternative that meets the following conditions:

 

그래서, 우리는 다음의 조건을 충족하는 간단하고 유용한 대안을 만들 것이다.

  • Many blades of grass must be represented by few polygons.
  • Grass must appear dense from different lines of sight. 
  • 많은 잎을 가진 풀을 적은 폴리곤으로 나타내야한다.
  • 여러 방향에서 바라보았을 때 풀이 무성하게 보여야한다.

In the next section, we build grass objects that meet these conditions.

 

다음 섹션에서, 우리는 이런 조건을 만족하는 풀 오브젝트를 만든다.

 

Additionally, we must be able to animate the grass realistically. In Section 7.4, we discuss three different animation methods.

 

또한, 우리는 풀을 사실적으로 애니메이션할 수 있어야한다. 섹션 7.4에서, 우리는 3가지 애니메이션 방식을 논의한다.

 

7.3 Preparation of the Grass Objects

As we just mentioned, many blades of grass must be represented by few polygons. We start by solving this problem. Independent of the camera position and direction, the appearance should be like that of an open countryside. Fortunately, the solution is not too difficult. In Section 7.3.1, we start by combining several blades of grass and displaying them in one texture. But this is not enough: some polygons that use this texture must be combined in such a way that the individual polygons are not noticeable (see Section 7.3.2). When the viewer moves around, we add or remove grass objects in the distance by blending them in or out. This ensures that the complete grass effect will have robust visual quality.

 

우리가 방금 말한 것과 같이, 풀의 많은 잎들을 적은 폴리곤으로 나타내야한다. 이 문제를 푸는 것부터 시작한다. 카메라의 위치와 방향에 상관없이, 탁 트인 시골처럼 보여야한다. 다행히도, 해법은 그리 어렵지 않다. 섹션 7.3.1에서, 우리는 풀의 여러 잎들을 결합하여 하나의 텍스쳐에 나타내는 것으로 시작한다. 하지만 이것만으로는 충분하지 않다. 이 텍스쳐를 사용하는 폴리곤은 각각의 폴리곤이 눈에 띄지 않는 방식으로 결합되어야한다. (섹션 7.3.2를 보라). 관찰자가 이동할 때, 먼 곳에서 풀 오브젝트를 섞거나 분리하여 풀 오브젝트를 추가하거나 제거한다. 이것은 완전한 풀 효과가 뛰어난 시각적 효과를 가질 수 있게 한다.

 

7.3.1 Grass Texture

Now let us see how to build a texture for the task we have to solve. The required texture has to cluster several blades of grass; otherwise, it will have large transparent areas. We obtain this simply by drawing solid grass stems in a transparent alpha channel. In the color channel, we should use different shades of green and yellow to get a better differentiation of single blades. We may want to simulate blades of grass in good and bad conditions, to represent differences in age or ripeness, and even to distinguish front and back faces of the blades.

 

이제 우리가 풀어야할 과제를 위해 텍스쳐를 어떻게 생성할지를 알아보자. 필요한 텍스쳐는 풀의 여러 잎을 무리지어야한다. 그렇지 않으면, 많은 투명한 영역을 가질 것이다. 우리는 풀 줄기를 투명한 알파 채널에 그려서 이것을 간단히 얻을 수 있다. 색 채널에는, 각각의 잎을 더 잘 구분하기 위해 녹색과 노란색에 다른 명암을 사용해야한다. 나이나 익은 정도를 나타내거나 잎의 앞뒷면을 구별하기 위해 풀의 잎을 좋고 나쁜 상태에서 시뮬레이션하길 원할 수도 있다.

 

A concrete example of a grass texture is shown in Figure 7-2.

 

풀 텍스쳐의 구체적인 에는 그림 7-2에 나타나있다.

 

fig07-02.jpg

Figure 7-2 Schematic of a Grass Texture

 

7.3.2 Grass Objects

This section explains how to combine some polygons, mapped with the grass texture built in the previous section, in a way that the simulated grass appears dense, and without highlighting individual polygons. The technique also guarantees that the individual polygons are not visible.

 

이 섹션은 시뮬레이션된 풀이 각각의 폴리곤이 강조되지 않고 밀집되어 보이는 방식으로, 이전 섹션에서 만든 풀 텍스쳐를 맵핑한 폴리곤을 어떻게 결합할 것인지를 설명한다. 이 기법은 도한 각각의 폴리곤이 눈에 보이지 않는 다는 것을 보증한다.

 

Because the user can navigate freely through the scene, a construction similar to the one shown in Figure 7-3 would be insufficient to produce a convincing effect. A linear arrangement of the grass polygons would immediately make the structure recognizable if someone were to view the scene perpendicular relative to the direction of the polygons. Additionally, the grass would look very thin in this case. An arrangement like this one should be considered only with automatic camera navigation or unreachable, far-distant meadows.

 

사용자는 장면을 자유롭게 돌아다니기 때문에, 그림 7-3에 있는 것과 같은 구조는 설득력있는 효과를 만들기에 충분하지 않다. 풀 폴리곤을 선형으로 배열하면 폴리곤 방향과 수직인 곳에서 장면을 보았을 때 구조를 바로 알아볼 수 있을 것이다. 게다가, 이런 경우에 풀은 매우 얇게 보일 것이다. 이와 같은 배열은 카메라가 자동으로 움직이거나 다가갈 수 없는 먼 곳에 있는 초원에서만 사용되어야 할 것이다.

 

fig07-03.jpg

Figure 7-3 Linear Arrangement

 

To ensure good visual quality independent of the current line of sight, we have to cross the grass polygons. Using configurations that look like stars proves very worthwhile. Figure 7-4 presents two possible variants of "grass objects," consisting of three intersecting quads. We have to render the polygons with disabled back-face culling to achieve visibility on both sides. To attain proper illumination, we should orient the normal vectors of all vertices parallel to the polygons' vertical edges. This guarantees correct lighting for all grass objects situated on slopes, with no differences due to the brightness of the terrain.

 

현재 시선에 상관없이 좋은 시각적 품질을 보장하기 위해서, 풀 폴리곤을 교차시켜야한다. 볓과 같은 모양의 구성을 사용하는 것이 매우 유용하다는 것으로 알려져 있다. 그림 7-4는 3개의 교차된 사각형으로 구성된 “풀 오브젝트”의 2가지 가능한 변형을 나타낸다. 우리는 양쪽면에 모두 보이게 하기 위해 후면 컬링을 비활성화하여 폴리곤을 렌더링해야 한다. 적절한 조명을 만들기 위해, 모든 정점의 법선 벡터를 폴리곤의 수직 모서리에 평행하게 방향을 맞춰야한다. 이것은 지형의 밝기로 인한 차이없이, 경사면에 위치해있는 모든 풀 오브젝트에 정확한 조명을 보장한다.

 

fig07-04.jpg

Figure 7-4 Grass Objects

 

If we set these grass objects quite close together in a large area, as shown in Figure 7-5, sort them back-to-front at runtime, use alpha blending, and enable z-testing/writing in the draw call, then the impression of a naturally and thickly grown meadow appears.

 

그림 7-5와 같이, 넓은 지역에 이 풀 오브젝트들을 매우 가깝게 같이 놓고, 실행시간에 뒤에서 앞으로 정렬하여 알파 블렌딩을 사용하고, 그리기 호출에서 z-테스트/쓰기를 활성화시면, 자연스럽고 무성하게 자란 초원의 느낌이 나타난다.

 

fig07-05.jpg

Figure 7-5 An Expanse of Grass

 

7.4 Animation

To continue with the next step, we want to realistically animate the grass of a complete meadow, built with "grass objects" like those presented in Figure 7-5. This section describes three different variants of animation. Each has its pros and cons. Section 7.4.1 presents the general idea of our animation methods. In Section 7.4.2, clusters of several grass objects standing close together are animated in the same way. In Section 7.4.3, each vertex gets its own translation vector. Finally, in Section 7.4.4, we try to find the golden mean: a different animation for each grass object.

 

다음 단계로 넘어가서, 우리는 그림 7-5에 나와있는 것과 같은 “풀 오브젝트”로 만들어진 초원의 풀을 사실적으로 애니메이션하길 원한다. 이 섹션은 애니메이션의 3가지 다른 변형을 설명한다. 각 방식은 모두 장단점이 있다. 섹션 7.4.1은 우리 애니메이션 방식의 일반적인 개념을 보여준다. 섹션 7.4.2에서는, 가까이 있는 여러 풀 오브젝트의 무리들은 같은 방식으로 애니메이션된다. 섹션 7.4.3에서는, 각 정점은 자신만의 이동 백터를 가진다. 마지막으로, 섹션 7.4.4에서는, 그 중간 방식인, 각 풀 오브젝트가 다르게 애니메이션되는 방식을 찾으려고 한다.

 

7.4.1 The General Idea

In order to achieve a highly realistic animation, we are going to use a calculation based on trigonometric functions, especially sine and cosine. This calculation should take into account the position that has to be moved (whether it is a vertex or the center of an object or cluster) and the current time. Also, the direction and strength of the prevailing wind will be factors. Each of our techniques moves only the upper vertices of the grass objects. In a vertex shader it is easy to differentiate between these vertices and the lower ones by examining the texture coordinates. All upper vertices should have the same v coordinate for the grass texture: such as zero, or a value close to it. The framework in the vertex shader code, as shown in Listing 7-1, is the same in all three techniques; only the pure animation part differs. The animation code can be found in the following sections.

 

매우 사실적인 애니메이션을 만들기 위해, 우리는 삼각함수, 특히 사인과 코사인을 기반으로한 계산을 사용할 것이다. 이 계산은 움직여야 하는 위치(정점 혹은 오브젝트나 무리의 중심)와 현재 시간을 고려해야한다. 가장 우세한 바람의 방향과 세기 또한 인자가 될 것이다. 우리의 각 기법들은 풀 오브젝트의 위쪽 정점만 움직인다. 정점 쉐이더에서 텍스쳐 좌표를 검사하여 위쪽 정점과 아랫쪽 정점을 쉽게 구별할 수 있다. 모든 위쪽 정점은 풀 텍스쳐에 대해 같은 v 좌표(0이나 그에 가까운 값)를 가지고 있어야 한다. Listing 7-1과 같이, 정점 쉐이더 코드에 있는 프레임워크는 3가지 기법 모두 동일하다. 애니메이션에 해당되는 부분만 다르다. 애니메이션 코드는 이어질 섹션에서 찾을 수 있다.

 

Example 7-1. Framework in the Vertex Shader

//
   // Equal Cg / HLSL framework in the vertex shaders
   // for Sections 7.4.2, 7.4.3, and 7.4.4
   //
   struct VS_INPUT {
  float3 vPosition : POSITION;
  float3 vNormal   : NORMAL;
  float2 TexCoords : TEXCOORD0;
  // This member is needed in Section 7.4.4
   float3 vObjectPosition : TEXCOORD1;
};
struct VS_OUTPUT {
  float4 vPosition : POSITION;
  float4 vDiffuse  : COLOR;
  float2 TexCoords : TEXCOORD0;
};
struct VS_TEMP {
  float3 vPosition;
  float3 vNormal;
};
float4x4 mWorldViewProjMatrix;
float4   vLight;
float    fObjectHeight;
VS_OUTPUT main(const VS_INPUT v)
{
  VS_OUTPUT out;
  VS_TEMP temp;
  // Animate the upper vertices and normals only
   if (v.TexCoords.y <= 0.1) {  // Or: if(v.TexCoords.y >= 0.9)
   // A N I M A T I O N  (to world space)
   // Insert the code for 7.4.2, 7.4.3, or 7.4.4
    . . .  // <- Code for our different animation methods
  }
  // Output stuff
  out.vPosition = mul(float4(temp.vPosition, 1),
                      mWorldViewProjMatrix);
  out.vDiffuse = dot(vLight, temp.vNormal);
  out.TexCoords = v.TexCoords;
  return out;
}

7.4.2 Animation per Cluster of Grass Objects

The following method was used in the Codecreatures Benchmark and produces a realistic look with gusting winds that constantly change strength and direction. Here, the shift of the upper polygon vertices happens uniformly for a group of nearby grass objects. To produce a natural-looking animation, we should select a cluster size that is not too large. See Figure 7-6.

 

다음의 방식은 Codecreatures 벤치마크에 사용되었고, 계속해서 세기와 방향이 변해서 부는 바람으로 실제 같은 모양을 만들어낸다. 여기서, 위쪽 폴리곤 정점의 이동은 가까이 있는 풀 오브젝트 무리들에 동일하게 발생한다. 자연스러워 보이는 애니메이션을 만들기 위해, 무리의 크기가 너무 크지 않게 선택해야한다. 그림 7-6을 보라.

 

fig07-06.jpg

Figure 7-6 Animation per Cluster of Grass Objects

 

The translation vector for the animation is computed by the CPU and is handed over to the vertex shader as a constant parameter. Using a more expensive algorithm on the CPU allows us to take advantage of a very complex wind simulation. Because we supply each cluster of grass objects with its own translation vector, we have to change this constant parameter for each cluster. So we have to interrupt the rendering of a complete meadow quite often and use a separate draw call for each cluster.

 

애니메이션을 위한 이동 벡터는 CPU에서 계산하고, 정점 쉐이더에 상수로 전달된다. CPU에서 비용이 더 많이 드는 알고리즘을 사용하면 매우 복잡한 바람 시뮬레이션을 이용할 수 있다. 우리는 풀 오브젝터의 각 무리에 자신만의 이동 벡터를 제공하기 때문에, 각 무리에 대해 이 상수를 변경해야 한다. 그래서 우리는 전체 초원을 렌더링하는 것을 매우 자주 중단하여 각 무리에 대해 개별적인 그리기 호출을 사용해야한다.

 

Pros

  • Complex animation calculations are made through CPU-based algorithms.
  • There are no distortions, because of the constant distance of the upper vertices of a polygon.
  • 복잡한 애니메이션 계산이 CPU 기반 알고리즘을 통해 수행된다.
  • 폴리곤의 위쪽 정점들이 일정한 거리를 유지하기 때문에 왜곡이 없다.

Cons

  • Many draw calls are required to display a complete meadow.
  • Clusters may be apparent due to synchronized animation of all vertices of a complete object cluster.
  • 전체 초원을 나타내기 위해 많은 그리기 호출이 요구된다.
  • 전체 오브젝트 무리의 모든 정점이 동일하게 애니메이션되어 무리들을 식별할 수도 있다.

Algorithm

  1. On the CPU, calculate the current translation vector for the next cluster using the position of the cluster's center.
  2. Set the translation vector as a constant for the vertex shader.
  3. Execute a draw call for the cluster.
  4. In the vertex shader, add the translation vector to the positions of the upper vertices. See Listing 7-2.

 

    1. CPU에서, 무리 중심 위치를 사용하여 다음 무리를 위해 현재 이동 벡터를 계산한다.
    2. 이동 벡터를 정점 쉐이더 상수로 설정한다.
    3. 무리에 대한 그리기 호출을 실행한다.
    4. 정점 쉐이더에서, 위쪽 정점 위치에 이동 벡터를 추가한다. Listing 7-2를 보라.

 

Example 7-2. Code for Animation per Cluster of Grass Objects

//
   // Animation per Cluster of Grass Objects (7.4.2)
   //
   float3 vClusterTranslation; // Calculated on CPU
VS_OUTPUT main(const VS_INPUT v)
{
  . . .
  // A N I M A T I O N (to world space)
   // Here comes the code for 7.4.2
  temp.vPosition = v.vPosition + vClusterTranslation;
  temp.vNormal = normalize(v.vNormal * fObjectHeight +
                           vClusterTranslation);
  ...
}

7.4.3 Animation per Vertex

One of the main problems with the method discussed in Section 7.4.2 is poor performance because of the high number of draw calls, which individually render only a small number of polygons. It would be better if we could render a large area covered with grass by using a much lower number of draw calls. However, we have to relocate the complete animation computation into the vertex shader to be able to move each vertex separately, relative to its position. See Figure 7-7.

 

섹션 7.4.2에 논의된 방식의 주요 문제점 중 하나는 각 그리기 호출이 적은 수의 폴리곤만을 렌더링하여 매우 많은 그리기 호출로 인한 성능 저하이다. 훨씬 더 적은 수의 그리기 호출을 사용하여 풀로 덮힌 넓은 지역을 렌더링할 수 있다면 더 나을 것이다. 그러나, 각 정점을 따로따로 그 위치에 관련하여 움직일 수 있기 위해서는 모든 애니메이션 계산을 정점 쉐이더로 이동시켜야한다. 그림 7-7을 보라.

 

fig07-07.jpg

Figure 7-7 Animation per Vertex

 

Because the translations for each vertex are computed individually, the length of the edge between the upper vertices of the grass polygons is no longer constant, as shown in Figure 7-8. Therefore, visible distortions may appear because of the inconstant length and thickness of each blade of grass, but typically these artifacts will not be very noticeable.

 

각 정점의 이동이 개별적으로 계산되기 때문에, 그림 7-8과 같이 풀 폴리곤의 위쪽 정점 사이의 거리가 더 이상 일정하지 않다. 그러므로, 풀의 각 잎이 길이와 두께가 일정하지 않기 때문에 눈에 보이는 왜곡이 나타날 수도 있다. 하지만 일반적으로 이러한 결함은 눈에 잘 띄지 않을 것이다.

 

fig07-08.jpg

Figure 7-8 Texture Distortion

 

Additionally, the overall effect may seem more unnatural than in the previous method. Because the translation of all vertices in a nearby region is very similar, an absence of local chaos and a very homogeneous animation results. We are able to eliminate this disadvantage by using a pseudo-random function in the vertex shader to achieve more varied results.

 

또한, 전체 효과가 이전 방식보다 더 부자연스러워 보일 수도 있다. 가까운 지역에 있는 모든 정점들의 움직임이 매우 비슷하기 때문에, 근거리에서의 무질서가 없고 동일한 애니메이션이 생길 수 있다. 더 다양한 결과를 만들기 위해 정점 쉐이더에서 의사-랜덤 함수를 사용하여 이런 문제를 없앨 수 있다.

 

Pros

  • Only a few draw calls, perhaps even just one, are necessary to display a complete meadow.
  • Varying the vertex position in the vertex shader allows for the continuity of a rippling wave of wind.
  • The clusters are indistinguishable.
  • 전체 초원을 나타내는데 적은 수의 그리기 호출(아마, 단 한번)만이 필요하다.
  • 정점 쉐이더에서 정점 위치는 변경하면 연속된 바람의 물결을 만들 수 있다.
  • 무리가 구별되지 않는다.

Cons

  • Distortion appears, due to the variable distance of the upper vertices of a polygon.
  • Animation may appear homogeneous due to a lack of local chaos.
  • The complexity of the animation calculation is limited.
  • 폴리곤의 위쪽 정점 사이의 거리가 변하기 때문에 왜곡이 생긴다.
  • 근거리에서의 무질서 부족으로 애니메이션이 비슷하게 나타날 수 있다.
  • 애니메이션 계산의 복잡성이 제한적이다.

Algorithm

  1. Set constants, such as time stamp and the basic strength and direction of the wind, for the vertex shader.
  2. Execute one draw call for the complete meadow or large area of grass.
  3. Use the vertex shader to calculate animation based on vertex position. See Listing 7-3.

    1. 정점 쉐이더에 시간 스탬프, 바람의 기본 세기와 방향 같은 것들을 상수로 설정한다.
    2. 전체 초원이나 넓은 지역에 대한 그리기 호출을 한번 수행한다.
    3. 정점 위치를 기반으로 애니메이션을 계산하기 위해 정점 쉐이더를 사용한다. Listing 7-3을 보라.

Example 7-3. Code for Animation per Vertex

//
   // Animation per Vertex (7.4.3)
   //
   float  fTimeStamp;
float3 vWindDirection;
float  fWindStrength;
VS_OUTPUT main(const VS_INPUT v)
{
  . . .
  // A N I M A T I O N  (to world space)
   // Here comes the code for 7.4.3
   float3 vVertexTranslation = CalcTranslation(v.vPosition,
                                              fTimeStamp,
                                              vWindDirection,
                                              fWindStrength);
  temp.vPosition = v.vPosition + vVertexTranslation;
  temp.vNormal = normalize(v.vNormal * fObjectHeight +
                           vVertexTranslation);
  . . .
}

7.4.4 Animation per Grass Object

To increase the apparent visual complexity of the animation based on the methods presented in Sections 7.4.2 and 7.4.3, we combine an undistorted grass texture and a low number of draw calls with local chaos—and thereby gain the advantages of both methods. We are able to combine these methods because we do not compute the animation for each vertex based on its position; rather, we do it based on the center position of the grass object—each consisting of three intersecting quads (see Section 7.3.2). Because neighboring grass objects now have different animations, we can represent the desired local chaos, as shown in Figure 7-9. Additionally, the constant animation for each grass object prevents the horizontal texture distortions.

 

섹션 7.4.2와 7.4.3에서 소개한 방식에 기반한 애니메이션에 분명힌 시각적 복잡성을 증가시키기 위해서, 왜곡이 없는 풀 텍스쳐와 근거리에서의 무질서를 가지는 적은 수의 그리기 호출을 혼합한다. 그리하여, 두 방식의 이점을 모두 얻는다. 각 정점에 대한 애니메이션을 그 정점의 위치를 기반으로 계산하기 않기 때문에, 이 두 방식을 혼합할 수 있다. 그 대신, 3개의 교차된 사각형으로 구성된(섹션 7.3.2를 보라) 각 풀 오브젝트의 중심 위치를 기반으로 애니메이션을 계산하다. 이제 이웃 풀 오브젝트는 다른 애니메이션을 가지기 때문에, 그림 7-9와 같이 근거리에서의 무질서를 나타낼 수 있다. 게다가, 각 풀 오브젝트에 대한 동일한 애니메이션은 수평 텍스쳐 왜곡을 방지한다.

 

fig07-09.jpg

Figure 7-9 Animation per Grass Object

 

To make this possible, each vertex must know the center position of its object, either relative to its position or absolute in the world. The grass object position vector needed for this information must be in the vertex format (that is, stored in texture coordinates), because the vertex shader has to read this value.

 

이것을 가능하게 하기 위해, 각 정점은 오브젝트 중심의 상대적 위치나 월드 공간에서의 절대적 위치를 알고 있어야 한다. 이 정보를 위해 필요한 풀 오브젝트 위치 벡터는 정점 포멧에 포함되어야 한다(즉, 텍스쳐 좌표에 저장된다). 왜냐하면 정점 쉐이더가 이 값을 읽어어하기 때문이다.

 

Pros

  • Only a few draw calls, perhaps even just one, are necessary to display a complete meadow.
  • There are no distortions, because of the constant distance of the upper vertices of a polygon.
  • Local variance creates a more natural look.
  • 전체 초원을 나타내기 위해 적은 수의 그리기 호출(아마 단 한번)만이 필요하다.
  • 폴리곤의 위쪽 정점 사이의 거리가 일정하기 때문에 왜곡이 없다.
  • 근거리에서의 무질서가 더 자연스러운 모양을 만들어낸다.

Cons

  • Additional data is required in the vertex format, because each vertex also contains the center position value of its grass object.
  • The complexity of the animation calculations is limited, in order to minimize shader cost.
  • 각 정점은 풀 오브젝트의 중심 위치 값을 포함해야하기 때문에, 정점 포멧에 추가적인 데이터가 필요하다.
  • 쉐이더 비용을 최소화하기 위해, 애니메이션 계산의 복잡성이 제한된다.

Algorithm

  1. Set constants, such as time stamp and the basic strength and direction of the wind, for the vertex shader.
  2. Execute one draw call for the complete meadow or large area of grass.
  3. In the vertex shader, compute animation based on the center position of the grass object. See Listing 7-4.

    1. 정점 쉐이더를 위해, 시간 스탬프와 바람의 기본 세기와 방향 같은 상수를 설정한다.
    2. 전체 초원이나 넓은 지역에 대한 그리기 호출을 한번 수행한다.
    3. 정점 쉐이더에서, 풀 오브젝터의 중심 위치를 기반으로 애니메이션을 계산하다. Listing 7-4를 보라.

Example 7-4. Code for Animation per Grass Object

//
   // Animation per Grass Object (7.4.4)
   //
   float  fTimeStamp;
float3 vWindDirection;
float  fWindStrength;
VS_OUTPUT main(const VS_INPUT v)
{
  . . .
  // A N I M A T I O N  (to world space)
   // Here comes the code for 7.4.4
   float3 vObjectTranslation = CalcTranslation(v.vObjectPosition,
                                              fTimeStamp,
                                              vWindDirection,
                                              fWindStrength);
  temp.vPosition = v.vPosition + vObjectTranslation;
  temp.vNormal = normalize(v.vNormal * fObjectHeight +
                           vObjectTranslation);
  . . .
}

7.5 Conclusion

We have succeeded in building a realistic grass simulation that meets the three most important requirements:

 

우리는 3가지의 가장 중요한 요구사항을 만족하는 사실적은 풀 시뮬레이션을 만드는데 성공했다.

 

  • Extensive usability without overly stressing performance
  • Natural appearance from all lines of sight
  • Animation based on prevailing wind conditions (with three different variants)
  • 성능을 많이 압박하지 않는 넓은 유용성
  • 모든 방향의 시야에서 자연스러운 외형
  • 가장 우세한 바람 조건에 기반한 애니메이션 (3가지 형태)

A special version of the Codecreatures Benchmark application, offering an interactive demo mode as shown in Figure 7-10, can be found on the book's CD or Web site. In the application, you can navigate using a free camera and switch the render states. You are encouraged to examine this application and take a look behind the scenes!

 

그림 7-10에 나와있는 양방향을 데모 형식을 제공하는, Codecreatures 벤치마크의 특별한 버전은 책의 부록이나 웹사이트에서 찾을 수 있다. 어플리케이션에서, 자유롭데 돌아다니고, 렌더링 상태를 바꿀 수 있다. 이 어플리케이션을 검토하고 장면 뒤에서 살펴보길 바란다.

 

fig07-10.jpg

Figure 7-10 Screenshot of the Codecreatures Benchmark

 

7.6 Further Reading

If you are interested in doing some more research on simulating animated grass, here are some resources that deal with this subject.

 

애니메이션된 풀을 시뮬레이션하는 더 많은 연구를 살펴보고 싶다면, 이 주제를 다루는 자료들이 여기에 있다.

 

You can find articles that describe vertex shaders using a sine function to do the procedural animation of the grass geometry here:

 

풀 기하의 절차적 애니메이션을 수행하는 사인 함수를 이용한 정점 쉐이더를 설명하는 논문을 여기서 찾을 수 있다.

 

NVIDIA Corporation. 2003. "Basic Profile Sample Shaders: Grass." In The Cg Toolkit User's Manual. Available online at http://developer.nvidia.com/object/cg_users_manual.html

Isidoro, J., and D. Card. 2002. "Animated Grass with Pixel and Vertex Shaders." In Direct3D ShaderX, edited by W. F. Engel. Wordware Publishing.

Other demos presenting grass effects are available on the following two Web sites. These two demos also use vertex shaders to calculate the waving motions of the grass geometry:

NVIDIA Web site: http://developer.nvidia.com/view.asp?IO=demo_grass

ATI Web site: http://www.ati.com/developer/Samples/Grass.html

I would like to thank my colleagues at Piranha Bytes and Codecult who contributed to the Codecreatures Benchmark, especially Horst Dworczak (Lead Artist), who had the idea to build and animate the grass objects in the way presented in the Benchmark; and Oliver Hoeller (Lead Programmer), who helped to integrate the complete effect into the engine.


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