Polar texture mapping a CSphereSceneNode

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
Post Reply
Puck6633
Posts: 27
Joined: Wed Aug 10, 2005 8:35 am

Polar texture mapping a CSphereSceneNode

Post by Puck6633 »

I hope this is the right place for this. I'm having a little problem texture mapping a sphere. I'm generating a polar mapped fbm texture at runtime and applying it to a CSphereSceneNode, but the problem is that the uv mapping for the poles seems to be off. A sample texture looks like this:

Image

And the problem can be seen here:

Image

I've verified that my texture tiles in all directions and the problem exists with polar mapped textures found on Google Images as well, so I don't believe it's my texture. What is the proper way to uv map the poles of a uv sphere? Am I doing something else wrong?

Edit:

The relevant section of the rather extensive code follows:

Code: Select all

 
    IImage* img = driver->createImage(ECF_R8G8B8, dimension2du(planetTextureSize, planetTextureSize));
    int v = 0;
    for (u32 x = 0; x < planetTextureSize; x++) {
        for (u32 y = 0; y < planetTextureSize; y++) {
            if (planetTexturePolar) {
                float a = x/(float)planetTextureSize*PI*2.0;
                float b = y/(float)planetTextureSize*PI;
                v = octave_noise_3d(planetTextureDetail, 1.0, 1, sin(a)*sin(b), cos(b), cos(a)*sin(b))*128+128;
            }
            else v = octave_noise_2d(8, 1.0, 0.001, x, y)*128+128;
 
            img->setPixel(x, y, SColor(0, v, v, v));
        }
    }
    driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false);
    ITexture* tex = driver->addTexture("noise", img);
    driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, true);
 
    IMeshSceneNode* planet = smgr->addSphereSceneNode(planetSize, planetDetail);
    if (planet) {
        planet->getMaterial(0).setTexture(0, tex);
    }
 
Mel
Competition winner
Posts: 2293
Joined: Wed May 07, 2008 11:40 am
Location: Granada, Spain

Re: Polar texture mapping a CSphereSceneNode

Post by Mel »

The top and bottom texture coordinates of the spheres isn't exactly aligned to the top and bottom texture space, so, the top and the bottom seems a bit off. this is done by default i guess that to avoid any distortion or problem with the textures. Draw the texture to a smaller space, or place the texture coordintates so they fill all the space.

Also, remember that the top and the bottom parts of the sphere CAN'T be mapped to polar coordinates because they are triangles, not squares, keep in mind that
"There is nothing truly useless, it always serves as a bad example". Arthur A. Schmitt
Puck6633
Posts: 27
Joined: Wed Aug 10, 2005 8:35 am

Re: Polar texture mapping a CSphereSceneNode

Post by Puck6633 »

Here's something interesting. added the following code to my main loop:

Code: Select all

 
        verts = (S3DVertex*) planet->getMesh()->getMeshBuffer(0)->getVertices();
        u16* inds = (u16*) planet->getMesh()->getMeshBuffer(0)->getIndices();
        for (u32 i = 0; i < planet->getMesh()->getMeshBuffer(0)->getIndexCount()-1; i++) {
            driver->draw2DLine(position2di(verts[inds[i]].TCoords.X*700, verts[inds[i]].TCoords.Y*700), position2di(verts[inds[i+1]].TCoords.X*700, verts[inds[i+1]].TCoords.Y*700));
        }
 
The purpose is to map the uv coordinates of a default sphere scene node to a 2d representation as it would be mapped to a texture. With a CSphereSceneNode of radius of 500 and polyCount of 8, I got this result:

Image

Is it just me or does that look kind of weird? I would expect a cone at the top and bottom with squares in the middle, sort of like this (without the top vertice duplicated):

Image

After that I tried implementing this: http://en.wikipedia.org/wiki/UV_mapping ... n_a_sphere

The code looks like this:

Code: Select all

 
        verts = (S3DVertex*) planet->getMesh()->getMeshBuffer(0)->getVertices();
        f32 TWOPI = 2*PI;
        for (u32 i = 0; i < planet->getMesh()->getMeshBuffer(0)->getVertexCount(); i++) {
            vector3df n = verts[i].Normal*vector3df(-1, -1, -1);
            f32 u = 0.5-atan2(n.Z, n.X)/TWOPI;
            f32 v = 0.5-2*(asin(n.Y)/TWOPI);
            verts[i].TCoords.set(u, v);
        }
 
The result is this uv map which looks good except for one "slice":

ImageImage

Did I implement the algorithm wrong? I'm very confused as to why this is happening, and quite frustrated because I feel like I'm so close. I also tried implementing an ico sphere scene node which had the same "slice" problem. :(
Puck6633
Posts: 27
Joined: Wed Aug 10, 2005 8:35 am

Re: Polar texture mapping a CSphereSceneNode

Post by Puck6633 »

One last thing: The image of the default uv mapping I showed before was the "north pole," toward positive Y. The default "south pole" looks rather different:

Image

Am I really just crazy or is Irrlicht's default mapping a little off?
Puck6633
Posts: 27
Joined: Wed Aug 10, 2005 8:35 am

Re: Polar texture mapping a CSphereSceneNode

Post by Puck6633 »

Mel wrote:Also, remember that the top and the bottom parts of the sphere CAN'T be mapped to polar coordinates because they are triangles, not squares, keep in mind that
I've been thinking about this, and shouldn't it still be possible to map it in a sensible way, especially given that the texture is in polar coordinates? Excuse my unscientific sketch, but my impression is that an ideal uv map for a polyCount of 4 would look like this:

Image

Am I way off?
Post Reply