Я пытаюсь добавить функции для трассировки лучей в 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;
}
Я пропустил остальную часть кода, чтобы не застревать в сообщении, но это можно увидеть здесь . Любая помощь очень ценится. Единственная часть, не включенная в код, - это где я определяю данные текстуры, которые, как я уже сказал, просто берутся прямо из файла растрового изображения вышеупомянутого изображения.
Спасибо.