Upcoming Events
Southwest Gaming Expo
11/20 - 11/22 @ Dallas, TX

Workshop on Network and Systems Support for Games (NetGames 2009)
11/23 - 11/25 @ Paris, France

ICIDS 2009 Interactive Storytelling
12/9 - 12/11 @ Guimarães, Portugal

Global Game Jam
1/29 - 1/31  

More events...


Quick Stats
6790 people currently visiting GDNet.
2341 articles in the reference section.

Help us fight cancer!
Join SETI Team GDNet!



Link to us

Link to us

  Intel sponsors gamedev.net search:   

Spherical Scale Mapping


3. Rendering with the Scale Map

To reconstruct the original model from the computed scale map a polygonal sphere is rendered employing a vertex shader. The suggested type of sphere is a geosphere [3] [4], which provided better quality than a polar sphere due to a better distribution of vertices.

During the rendering process the vertex shader performs a texture-lookup into the cubemap using the vertex' normal (normal retrieved from the base-sphere) and scales the vertex' position. After this step the vertex can be transformed into worldspace.

float32 fGetScale( const vector3 &i_vNormal, const float32 i_fInterpolation ) {
  vector4 vScaleA, vScaleB;
  SampleTexture( vScaleA, 2, i_vNormal.x, i_vNormal.y, i_vNormal.z );
  SampleTexture( vScaleB, 3, i_vNormal.x, i_vNormal.y, i_vNormal.z );
  return fLerp( vScaleA.r, vScaleB.r, i_fInterpolation );
}
 
void Execute( const shaderreg *i_pInput, vector4 &o_vPosition, shaderreg *o_pOutput ) {
  const vector3 &vPos = i_pInput[0]; // Get position of vertex.
  const float32 fInterpolation = fGetFloat( 0 ); // Get interpolation-delta.
 
  // Determine vertex scale from the cubemap: Here we simply use the vertex position as the
  // vertex normal, due to the nature of the base-sphere (origin at (0,0,0)).
  const vector3 vScaledPos = vPos * fGetScale( vPos, fInterpolation );
 
  // Transform the final vertex position.
  const vector4 vFinalPos = vector4( vScaledPos.x, vScaledPos.y, vScaledPos.z, 1 );
  o_vPosition = vFinalPos * matGetMatrix( m3dsc_wvpmatrix );
}
Listing 2. Muli3D [5] vertex-shader code: interpolates between two cubemap-samples and scales the vertex in the local coordinate system.

3.1.Reconstructing vertex normals

Rendering the geometry itself didn't pose much of a problem, yet the reconstruction of the original model isn't finished: per vertex normal vectors are not recalculated from the cubemap.

One solution to this problem can be implemented in the preprocessing step: When determining the scale-factor for a particular vertex we could go along and also store the normal vector in the cubemap. This would mean an additional usage of three color-channels, which would lead to a RGBA-cubemap texture (Normal scaled to [0,255] range and stored in the RGB channels; λ scaled to [0,255] and stored in the alpha-channel), effectively resulting in an increase of the size of a factor of four.

With the advent of consumer-level hardware with support for VS-model 3.0 the reconstruction of vertex-normals can be moved to a shader with the cubemap only storing scale-factors and limited to a single-channel texture.

The basic idea behind the algorithm is the lookup of neighbour vertex positions - a normal per three vertices is calculated using the cross-product; all normals are averaged and renormalized to find the normal of the vertex in question.


Figure 2. Reconstruction of a vertex normal vector (Figure ignores vertex-scaling).

How do we determine the scaled positions of the neighbour vertices? First we have to generate the correct points on the surface of the base-sphere. We do this by determining the spherical coordinates for the current vertex and creating new points by offsetting these coordinates and converting back to the Cartesian system. The four created points n0 - n3 correspond to the four directions North, East, South and West.

      (3)

After having scaled these four points in the vertex shader we form vectors from the current vertex position to each neighbour position and calculate four seperate normals by applying the cross-product to two adjacent vectors. We sum these four normals and renormalize the result to get the final vertex normal vector.


Figure 3. Choosing ε so, that a new texel is sampled for each vertex.

      (4)

How can the offset ε be determined? The ideal solution would be to sample a new scale-value for each neighbour-vertex.

      (2)

Although this function can be implemented in a vertex shader it is relatively complex. A better and easier solution is to choose a fixed ε for all vertices: provided good results in the sample application for a scale-map edgelength of 128 pixels and with linear filtering enabled.






Results and Conclusions


Contents
  Overview
  Rendering with the Scale Map
  Results and Conclusions

  Printable version
  Discuss this article