Menos
Menos

Reputation: 361

RayTracer spherical Mapping

I'm using the "Ray Tracer From The Ground Up" book as tutorial, but I don't have the same resaults in the same code, I think it's the same( I have checked it couple of times).

My problem is spherical Mapping texture to Sphere.Spherical Mapping

the code(d_type::Bfloat is double) :

void getTexelCoord(const Vector3Bf localHitPoint, const d_type::Bint m_width, const d_type::Bint m_height, d_type::Bint& row, d_type::Bint& column) const
{
    d_type::Bfloat theta=acosf(localHitPoint.y);
    d_type::Bfloat phi= atan2f(localHitPoint.x,localHitPoint.z);
    if(phi<0.0)
    {
        phi+=TWO_PI;
    }
    d_type::Bfloat u =phi*INV_TWO_PI;
    d_type::Bfloat v=1-theta*INV_PI;

    column = (d_type::Bint)((m_width-1)*u);
    row = (d_type::Bint)((m_height-1)*v);

}


virtual Colour getColour(const Info&info )const
{
    d_type::Bint row,column;
    if(m_mapping)
    {
         m_mapping->getTexelCoord(info.m_localHitPoint,hres, vres, row, column);
    }
    else
    {
         row=(int)(info.uv.x*(hres-1));
         column=(int)(info.uv.y*(vres-1));

    }
        return m_image->getColour(row,column);
}



 Colour getColour(const int row, const int column) const {
        int index = column + hres * (vres - row - 1);
        int pixels_size = hres*vres;

        if (index < pixels_size)
                return (m_pixels[index]);
        else
                return (Colour::Red);    
}

local hit point in Sphere is calculated like this :

info.m_localHitPoint=(ray.getOrigin()+(ray.getDirection()*t));

where t is the closes intersection point

Upvotes: 0

Views: 1023

Answers (2)

Menos
Menos

Reputation: 361

It's all weird... but the radiance of sphere must be 1.. and everything is working;)enter image description here

The problem was in the localHitPoint. it wasn't local it was global so, so in this question everything is explaned. The code of working SphereMapping :

void getTexelCoord(const Vector3Bf &localHitPoint, const d_type::Bint m_width, const d_type::Bint m_height, d_type::Bint& row, d_type::Bint& column) const
    {

        Vector3Bf normal=localHitPoint - m_sphere->getCenter();
        Vector3Bf::normalize(normal);
        d_type::Bfloat u=0.5+atan2(normal.z,normal.x)*INV_TWO_PI;
        d_type::Bfloat v = 0.5-asin(normal.y)*INV_PI;
        column =(int)(m_width*u);
        row =(int)(m_height)*v;
    }

Where m_sphere is sphere that has the material(texture) of this mapping.

Upvotes: 0

Alnitak
Alnitak

Reputation: 339846

Depending on the handedness of your coordinate space, I have the following almost equivalent code in my own ray tracer:

double u = 0.5 - atan2(n.z, n.x) * math::one_over_2pi;
double v = 0.5 - asin(n.y) * math::one_over_pi;

Note the uses of 0.5, in my case the coordinates all run in the range 0..1.

Upvotes: 2

Related Questions