Quad Draw Didnt Create Plane It Created a Sphere

Tiling Textures on the Plane (Part 1)

Written past Paul Bourke
September 1992

In many texturing applications it is necessary to be able to "tile" the texture over a larger region than the texture segment covers. In the ideal case the texture segment automatically tiles, that is, if it laid out in a grid information technology forms a seamless appearance. For example consider the following texture.

If it is laid side by side it forms a continuous seamless surface.

Many textures of tiles form such seamless surfaces easily considering they are naturally bounded past rectangular discontinuities. For example consider the tile

Laid out information technology forms the tiling below

Other regular tiles fit together in more subtle means.

Laid out it forms the tiling beneath

For texture segments that don't have strong directional structure a common tiling method involves mirroring each 2d segment so that side by side edges match, this is illustrated below

and here in a existent example

This larger segment can now exist repeated in the normal fashion indefinitely equally all the edges volition at present join without discontinuities. Sometimes a mixture of mirroring and direct tiling tin be practical, that is, mirror tile in i management and practise a straightforward tile in the other direction.

In what follows one method volition be discussed for making any epitome tile with reduced seams. In the post-obit the image on the left will be used equally an case, it conspicuously doesn't tile. The discontinuities betwixt the tiles can be illustrated by swapping the diagonal halves of the image every bit shown on the right. Sometimes it is possible to edit the image on the right, smoothing out the center vertical and horizontal seams, the consequence would so tile. In general this is hard and has the disadvantage of being a manual procedure.

In what follows, let the original image be represented as O, for simplicity consider the image to exist square with N pixels vertically and horizontally. Each pixel is indexed (C conventions) every bit O[i][j] where i and j range from 0 to N-i.

The diagonally swapped prototype volition be referred to as O d. Each pixel in O d is found as follows (bold N is even):

O d[i][j] = O[(i+N/2)%N][(j+Northward/2)%N]

Two masks are created, there are many alternatives but the example shown below is a radial linear ramp from black to white. Other masks can be used, the requirement is that the mask tends smoothly to pure white at the image boundary. The 2d mask on the right is diagonal swapped version of the mask on the left.

The mask shall exist referred to equally G. The mask above can be formed by the post-obit:

M[i][j] = M[i][N-1-j] = M[Northward-ane-i][j] = Grand[N-one-i][North-1-j] = sqrt((i-N/2)*(i-Due north/two) + (j-N/2)*(j-N/2)) / (Due north/2)

Where i and j range from 0 to Due north/2-i. Thousand d is calculated equally for O d higher up.

The following two images are created by multiplying the two original images by their respective masks. I've chosen a slightly dissimilar convention here to normal, here for purposes of the multiplication black has a value of 1 and white 0. These ii images tile (although rather boringly) because the left prototype decays to cipher at information technology's edges.

And finally, the tilable image on the left is created by averaging the two images to a higher place. On the correct is a reduced 2x2 tiling of the tile on the left showing the absence of any discontinuities.

If T is the tilable texture, this tin be written as

T[i][j] = M[i][j] O / (M[i][j]+M d[i][j]) + M d[i][j] O d / (M[i][j]+M d[i][j])

Note that to avoid zilch separate by the denominators above it is customary constrain the mask values to positive (non zero) values.

This linear mask is calculated equally follows:

1000[i][j] = M[i][N-i-j] = Yard[N-1-i][j] = Yard[N-ane-i][N-1-j] = MAX((N/2-i),(N/two-j)) / (N/two))

For perhaps a more than realistic texture, consider the following photograph of some grass.

A detailed leaf example.

Software

  • C source
    This very crude/simple C source is what I initially used to experiment with these techniques, you may find it useful.

  • PhotoShop has a filter called "offset" that makes the diagonal flipped images. You can and so create the masks with the ramp tool and form the tile with the appropriate operations on layers comprising of original image, mask and their corresponding diagonal images. Employ the "screen" to apply the masks to each paradigm. To combine the ii resulting images, invert one of them so take the "difference".

  • GIMP has a tiling function that seems to work on the same principle as outlined hither using a linear mask.

  • A Shake implementation has been put together by Emmanuel Mogenet, a screen shot is here (shot.jpg) and the source is hither (SoftTile.h).

Parametric Equation of a Sphere and Texture Mapping

Written by Paul Bourke
Baronial 1996

One possible parameterisation of the sphere will be discussed along with the transformation required to texture map a sphere. An angle parameterisation of the sphere is

    x = r sin(theta) cos(phi)
    y = r sin(theta) sin(phi)
    z = r cos(theta)

where r is the radius, theta the angle from the z axis (0 <= theta <= pi), and phi the angle from the x axis (0 <= phi <= 2pi). Textures are conventionally specified as rectangular images which are well-nigh hands parameterised by two cartesian blazon coordinates (u,v) say, where 0 <= u,5 <= one. The equation above for the sphere can be rewritten in terms of u and v equally

    x = r sin(5 pi) cos(u ii pi)
    y = r sin(v pi) sin(u 2 pi)
    z = r cos(5 pi)

Solving for the u and v from the to a higher place gives

    five = arccos(z/r) / pi
    u = ( arccos(x/(r sin(5 pi))) ) / (2 pi)

So, given a signal (x,y,z) on the surface of the sphere the higher up gives the betoken (u,five) each component of which can be accordingly scaled to index into a texture image.

Notation

  • A sphere cannot be "unwrapped" without distortion, for example, the length between points on the sphere volition not equal the altitude between points on the unwrapped plane.

  • When implementing this in lawmaking it is of import to note that most implementations of arccos() returns value from 0 to pi and non 0 to 2 pi equally the the formula above assumes. The second one-half cycle of the arccos part is obtained by noticing the sign of the y value. So the transformation written in C might be equally follows

#define PI three.141592654 #ascertain TWOPI vi.283185308  void SphereMap(x,y,z,radius,u,v) double x,y,z,r,*u,*5; {    *5 = acos(z/radius) / PI;    if (y >= 0)       *u = acos(x/(radius * sin(PI*(*v)))) / TWOPI;    else       *u = (PI + acos(x/(radius * sin(PI*(*v))))) / TWOPI; }        

In that location are still 2 special points, the verbal north and s poles of the sphere, each of these ii points needs to be "spread" out along the whole edge five=0 and v=1. In the formula higher up this is where sin(v pi) = 0.

OpenGL sphere with texture coordinates

Written by Paul Bourke
January 1999

A more efficient contribution past Federico Dosil: sphere.c

While straightforward many people seem to have problem creating a sphere with texture coordinates. Here'southward the style I do it (written for clarity rather than efficiency).

Note

  • The whole line at the North pole and the South pole texture map onto a single point at the poles.

  • While this linear mapping of lines of latitude is fine for full general textures, it may not be right for particular image textures such as maps of the Earth. In those cases the latitude texture coordinates demand to be matched to the latitude function used to make the paradigm.

  • On many implementations triangle strips are muck efficient than quad strips. On the other hand triangle strips don't look so adept in wireframe style. Depending on personal taste the line glBegin(GL_QUAD_STRIP); can be replaced with glBegin(GL_TRIANGLE_STRIP);

/*    Create a sphere centered at c, with radius r, and precision due north    Describe a indicate for zero radius spheres */ void CreateSphere(XYZ c,double r,int n) {    int i,j;    double theta1,theta2,theta3;    XYZ e,p;     if (r < 0)       r = -r;    if (due north < 0)       n = -n;    if (northward < 4 || r <= 0) {       glBegin(GL_POINTS);       glVertex3f(c.x,c.y,c.z);       glEnd();       return;    }     for (j=0;j<n/2;j++) {       theta1 = j * TWOPI / northward - PID2;       theta2 = (j + ane) * TWOPI / n - PID2;        glBegin(GL_QUAD_STRIP);       for (i=0;i<=n;i++) {          theta3 = i * TWOPI / n;           e.x = cos(theta2) * cos(theta3);          e.y = sin(theta2);          e.z = cos(theta2) * sin(theta3);          p.ten = c.x + r * eastward.10;          p.y = c.y + r * e.y;          p.z = c.z + r * e.z;           glNormal3f(eastward.10,e.y,eastward.z);          glTexCoord2f(i/(double)north,ii*(j+one)/(double)n);          glVertex3f(p.x,p.y,p.z);           e.10 = cos(theta1) * cos(theta3);          e.y = sin(theta1);          e.z = cos(theta1) * sin(theta3);          p.x = c.x + r * eastward.ten;          p.y = c.y + r * e.y;          p.z = c.z + r * e.z;           glNormal3f(e.x,e.y,eastward.z);          glTexCoord2f(i/(double)n,2*j/(double)northward);          glVertex3f(p.x,p.y,p.z);       }       glEnd();    } }          

It is a small modification to enable 1 to create subsets of a sphere....3 dimensional wedges. As an case see the following code.

/*    Create a sphere centered at c, with radius r, and precision northward    Describe a indicate for naught radius spheres    Use CCW facet ordering    "method" is 0 for quads, i for triangles       (quads await nicer in wireframe way)    Partial spheres can be created using theta1->theta2, phi1->phi2    in radians 0 < theta < 2pi, -pi/2 < phi < pi/two */ void CreateSphere(XYZ c,double r,int due north,int method,    double theta1,double theta2,double phi1,double phi2) {    int i,j;    double t1,t2,t3;    XYZ e,p;     /* Handle special cases */    if (r < 0)       r = -r;    if (n < 0)       n = -n;    if (northward < 4 || r <= 0) {       glBegin(GL_POINTS);       glVertex3f(c.x,c.y,c.z);       glEnd();       return;    }     for (j=0;j<north/two;j++) {       t1 = phi1 + j * (phi2 - phi1) / (northward/2);       t2 = phi1 + (j + 1) * (phi2 - phi1) / (n/2);        if (method == 0)          glBegin(GL_QUAD_STRIP);       else          glBegin(GL_TRIANGLE_STRIP);        for (i=0;i<=northward;i++) {          t3 = theta1 + i * (theta2 - theta1) / n;           e.10 = cos(t1) * cos(t3);          e.y = sin(t1);          due east.z = cos(t1) * sin(t3);          p.x = c.x + r * e.x;          p.y = c.y + r * e.y;          p.z = c.z + r * east.z;          glNormal3f(e.x,due east.y,e.z);          glTexCoord2f(i/(double)north,2*j/(double)due north);          glVertex3f(p.x,p.y,p.z);           due east.10 = cos(t2) * cos(t3);          due east.y = sin(t2);          e.z = cos(t2) * sin(t3);          p.10 = c.x + r * e.x;          p.y = c.y + r * e.y;          p.z = c.z + r * due east.z;          glNormal3f(e.ten,due east.y,e.z);          glTexCoord2f(i/(double)n,two*(j+ane)/(double)n);          glVertex3f(p.x,p.y,p.z);        }       glEnd();    } }          

Texture map correction for spherical mapping

Written by Paul Bourke
Jan 2001

Lua/gluas script contributed by Philip Staiger.
Python script for utilise with GIMP by Rafael Navega.

When texture mapping a sphere with a rectangular texture image with polar texture coordinates, the parts of the image near the poles get distorted. Given the unlike topology between a sphere and plane, there will always exist some nonlinear distortion or cutting involved. This normally manifests itself in pinching at the poles where rows of pixels are being compressed tighter and tighter together the closer 1 gets to the pole. At the poles is the extreme example where the whole top and lesser row of pixels in the texture map is compressed down to one betoken. The spherical images below on the left are examples of this pinching using the rectangular texture also on the left.

Information technology is elementary to correct for this by distorting the texture map. Assume the texture map is mapped vertically onto lines of breadth (theta) and mapped horizontally onto lines of longitude (phi). At that place is no need to modify theta but phi is scaled as we approach the 2 poles by cos(theta). The diagram below illustrates the conventions used here.

The pseudo-code for this distortion might exist something similar the following, annotation that the details of how to create and read the images are left upwards to your personal preferences.

          double theta,phi,phi2;    int i,i2,j;    BITMAP *imagein,*imageout;     Class the input and output image arrays    Read an input image from a file     for (j=0;j<image.superlative;j++) {       theta = PI * (j - (prototype.acme-1)/2.0) / (double)(epitome.height-i);       for (i=0;i<image.width;i++) {          phi  = TWOPI * (i - image.width/ii.0) / (double)image.width;          phi2 = phi * cos(theta);          i2  = phi2 * image.width / TWOPI + prototype.width/ii;          if (i2 < 0 || i2 > image.width-i) {             newpixel = red;                         /* Should not happen */          } else {             newpixel = imagein[j*paradigm.width+i2];          }          imageout[j*epitome.width+i] = image.newpixel;       }    }     Do something with the output image        

Applying this transformation to a regular filigree is show below.

Mayhap a more illustrative case is given below for a "moon" texture. Note that in full general if the texture tiles vertically and horizontally then after this baloney it will no longer tile horizontally. A number of tiling methods can exist used to right for this. One is to replicate and mirror the texture horizontally, since the baloney is symmetric most the horizontal eye line of the epitome, the result volition tile horizontally. Another method is to overlap two copies of the texture after the distortion with advisable masks that fade the appropriate texture out at the not-tiling borders.

This last example illustrates how later the distortion the image detail is evenly spread over the spherical object instead of acting similar lines of longitude that get closer near the poles.

Texture mapping a fisheye projection onto a hemisphere

Written past Paul Bourke
Apr 2012

The post-obit illustrates how to calculate the texture coordinates for the vertices of a hemisphere such that a fisheye image can be applied as a texture with the "expected" results. To exam the mathematics and code presented here the following texture image will be used, the expected result is for the hemisphere to be textured with lines of longitude and latitude.

The texture coordinate for any vertex of the hemisphere mesh is calculated by determining the polar angles theta and phi. These tin can then exist mapped directly into the fisheye texture plane. The equations are shown below and too in the source code provided.

Source code that illustrates this is give here (tab stops prepare to 3 for right indenting): fishtexture.c. It creates a textured hemisphere centered at the origin with unit radius described every bit an obj file: fishtexture.obj with associated cloth file: fishtexture.mtl.

Resulting views of the above obj file.

Texture Mapping Schemes in Common Usage

Written by Paul Bourke
March 1987

The post-obit lists some of the nearly common texture mapping methods use past raytracing/rendering engines. The methods are illustrated by mapping the simple rectangular tile texture on the right onto a cube, sphere, and cylinder. Repeated tiling is used in all cases and where possible the tiling calibration factors are kept constant.

Planar

Cubic

Cylindrical

Rectangular Cylindrical

Spherical

Miscellaneous examples

Logo for the
The Australasian Society for Psychophysiology, Inc.
VRML version of the comprehend for Neuroimage viii. For a paper entitled "Steady Country Visually Evoked Potential Correlates of Auditory Hallucinations in Schizophrenia".

guzmanimeling1963.blogspot.com

Source: http://www.paulbourke.net/geometry/tiling/

0 Response to "Quad Draw Didnt Create Plane It Created a Sphere"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel