Thursday, January 8, 2015

Texture Mapping

2D Texture Mapping onto Objects:
3D Texture Mapping - Procedural Texture/ Solid Texture
For 3D texture we will discuss about checkerboard and Smooth Colors
In this i will only be helping you with code and algorithms used for mapping textures onto surface
2D Texture Mapping:
Algorithm:
The easiest way to texture map onto a sphere is by defining v to be the latitude of the point and u to be the longitude of the point on the sphere.
This way, the texture image will be "wrapped" around the sphere, much as a rectangular world map is wrapped around a globe. 
Figure 8. Mapping a rectangular world map onto a globe
Figure 9. Mapping a texture image onto a sphere
First we find the two unit-length vectors Vn and Ve, which point from the center of the sphere towards the ``north pole'' and a point on the equator, respectively. We then find the unit-length vector Vp, from the center of the sphere to the point we're coloring. The latitude is simply the angle between Vp and Vn. Since we noted above that the dot product of two unit-length vectors is equal to the cosine of the angle between them, we can find the angle itself by
 
      phi = arccos( -dot_product( Vn, Vp ))
and since v needs to vary between zero and one, we let 
      v = phi / PI
We then find the longitude as 

theta = ( arccos( dot_product( Vp, Ve ) / sin( phi )) ) / ( 2 * PI) 
 if ( dot_product( cross_product( Vn, Ve ), Vp ) > 0 )
    u = theta 
 else
    u = 1 - theta 

The last comparison simply checks on what side of the equator vector Ve the point is (clockwise or counterclockwise to it), and sets u accordingly.
Now the color of the point is the pixel at (u * texture_width,v * texture_height ) within the texture image.
NOTE:Reference http://www.cs.unc.edu/~rademach/xroads-RT/RTarticle.html
C++ CODE:
Copy all the library from this LINK into your project. These libraries
are used to read pixels and pixel color from a 2D picture.

SbVec3f SphereRT::imageMap(SbVec3f point){
    SbVec3f pole(0,1,0),equator(1,0,0);
    float U=0,V=0,PI = 22/7, phi = 0, theta = 0;
    SbVec3f normal = point - SbVec3f(0,0,0);
    normal.normalize();

    phi = acos(pole.dot(normal));
    V=phi/PI;

    theta = (acos( normal.dot(equator))/ sin( phi )) / ( 2 * PI);
    if ( normal.dot(pole.cross(equator)) > 0 )
       U = theta;
    else
       U = 1 - theta;
    
    int r,g,b;
    float red=0.0,green=0.0,blue=0.0;
    int height=0;
    int width=0;

    height = (int)U*p.getheight();
    width = (int)V*p.getwidth();

    p.getpixel(width,height,r,g,b);
    red = (float)r/255;
    green = (float)g/255;
    blue =(float)b/255;
    SbVec3f color;
    color.setValue(red,green,blue);
    return color;
}

This above convert 3D intersection point(x,y,z) on the sphere to 2D point(x,y) on the texture using the algorithm mentioned above and get the color of that pixel. Then this color is set as diffuse color of the sphere.
If facing some trouble in doing it contact me by writing comment.

No comments:

Post a Comment