Как использовать наложение текстуры в простом трассировщике лучей? - PullRequest
2 голосов
/ 16 апреля 2010

Я пытаюсь добавить функции для трассировки лучей в C ++. А именно, я пытаюсь добавить наложение текстур к сферам. Для простоты я использую массив для хранения данных текстуры. Я получил данные текстуры с помощью шестнадцатеричного редактора и скопировал правильные значения байтов в массив в моем коде. Это было только для моих целей тестирования. Когда значения этого массива соответствуют изображению, которое просто красного цвета, оно, кажется, работает близко к тому, что ожидается, за исключением того, что нет затенения. первое изображение http://dl.dropbox.com/u/367232/Texture.jpg Внизу справа показано, как должна выглядеть правильная сфера. Цвет этой сферы, используя один заданный цвет, а не карту текстуры.

Другая проблема состоит в том, что когда карта текстуры имеет что-то, кроме одного цветного пикселя, она становится белой. Мое тестовое изображение - это изображение воды, и когда оно отображается, оно показывает только одно кольцо голубоватых пикселей, окружающее белый цвет.

BMP http://dl.dropbox.com/u/367232/vPoolWater.bmp

Когда это сделано, это просто выглядит так: второе изображение http://dl.dropbox.com/u/367232/texture2.jpg

Вот несколько фрагментов кода:

  Color getColor(const Object *object,const Ray *ray, float *t)
  {
   if (object->materialType == TEXTDIF || object->materialType == TEXTMATTE) {
    float distance = *t;
    Point pnt = ray->origin + ray->direction * distance;
    Point oc = object->center; 
    Vector ve = Point(oc.x,oc.y,oc.z+1) - oc;
    Normalize(&ve);
    Vector vn = Point(oc.x,oc.y+1,oc.z) - oc;
    Normalize(&vn);
    Vector vp = pnt - oc;
    Normalize(&vp);

    double phi = acos(-vn.dot(vp));

    float v = phi / M_PI;
    float u;

    float num1 = (float)acos(vp.dot(ve));
    float num = (num1 /(float) sin(phi));

    float theta = num /(float) (2 * M_PI);
    if (theta < 0 || theta == NAN) {theta = 0;}
    if (vn.cross(ve).dot(vp) > 0) {
        u = theta;
    }
    else {
        u = 1 - theta;
    }
    int x = (u * IMAGE_WIDTH) -1;
    int y = (v * IMAGE_WIDTH) -1;
    int p = (y * IMAGE_WIDTH + x)*3;

    return Color(TEXT_DATA[p+2],TEXT_DATA[p+1],TEXT_DATA[p]);

}
else {
    return object->color;
}
};

Я вызываю цветовой код здесь в Trace:

if (object->materialType == MATTE)
    return getColor(object, ray, &t);

Ray shadowRay;
int isInShadow = 0;
shadowRay.origin.x = pHit.x + nHit.x * bias;
shadowRay.origin.y = pHit.y + nHit.y * bias;
shadowRay.origin.z = pHit.z + nHit.z * bias;
shadowRay.direction = light->object->center - pHit;
float len = shadowRay.direction.length();
Normalize(&shadowRay.direction);
float LdotN = shadowRay.direction.dot(nHit);
if (LdotN < 0)
    return 0;
Color lightColor = light->object->color;
for (int k = 0; k < numObjects; k++) {
    if (Intersect(objects[k], &shadowRay, &t) && !objects[k]->isLight) {
        if (objects[k]->materialType == GLASS)
            lightColor *= getColor(objects[k], &shadowRay, &t); // attenuate light color by glass color
        else
            isInShadow = 1;
        break;
    }
}
lightColor *= 1.f/(len*len);
return (isInShadow) ? 0 : getColor(object, &shadowRay, &t) * lightColor * LdotN;
}

Я пропустил остальную часть кода, чтобы не застревать в сообщении, но это можно увидеть здесь . Любая помощь очень ценится. Единственная часть, не включенная в код, - это где я определяю данные текстуры, которые, как я уже сказал, просто берутся прямо из файла растрового изображения вышеупомянутого изображения.

Спасибо.

Ответы [ 2 ]

1 голос
/ 16 апреля 2010

Может быть, текстура просто размыта, потому что свет такой яркий и такой близкий. Обратите внимание, что в сплошном красном корпусе, кажется, нет никаких градаций вокруг сферы. Красный выглядит насыщенным.

Ваше U, V отображение выглядит правильно, но там может быть ошибка. Я бы добавил несколько операторов assert, чтобы убедиться, что u и v действительно между 0 и 1, и что индекс p в вашем массиве TEXT_DATA также находится в пределах диапазона.

0 голосов
/ 25 октября 2010

Если вы отлаживаете свои текстуры, вы должны использовать постоянный материал, цвет которого определяется только текстурой, а не светом. Таким образом, вы можете убедиться, что вы правильно сопоставляете свою текстуру своему примитиву и фильтруете ее должным образом, прежде чем делать какое-либо освещение. Тогда вы знаете, что это не проблема.

...