Je tente d'ajouter des fonctionnalités à un ray tracer en C++. À savoir, j'essaye d'ajouter le mappage de texture aux sphères. Pour simplifier, j'utilise un tableau pour stocker les données de texture. J'ai obtenu les données de texture en utilisant un éditeur hexadécimal et en copiant les valeurs d'octets correctes dans un tableau dans mon code. C'était juste pour mes tests. Lorsque les valeurs de ce tableau correspondent à une image qui est simplement rouge, il semble fonctionner près de ce qui est attendu, sauf qu'il n'y a pas d'ombrage. first image http://dl.dropbox.com/u/367232/Texture.jpg La partie inférieure droite de l'image montre à quoi devrait ressembler une sphère correcte. La couleur de cette sphère en utilisant une couleur de jeu, pas une carte de texture.Comment utiliser la cartographie de texture dans un simple traceur de rayons?
Un autre problème est que lorsque la carte de texture a autre chose qu'un seul pixel de couleur, elle devient blanche. Mon image de test est une image de l'eau, et quand elle est mappée, elle montre seulement un anneau de pixels bleutés entourant la couleur blanche.
bmp http://dl.dropbox.com/u/367232/vPoolWater.bmp
Lorsque cela est fait, il apparaît simplement comme ceci: second image http://dl.dropbox.com/u/367232/texture2.jpg
Voici quelques extraits de code:
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;
}
};
J'appelle le code couleur ici 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;
}
J'ai omis le reste du code pour ne pas emboîter le poteau, mais on peut le voir here. Toute aide est grandement appréciée. La seule partie non incluse dans le code, est où je définis les données de texture, qui, comme je l'ai dit, est simplement pris directement à partir d'un fichier bitmap de l'image ci-dessus.
Merci.
Ensuite, je ne suis pas sûr si je mets la sphère simplement pour afficher la couleur et pas de texture, les gradations semblent bien. Je vais regarder dans l'ajout d'assert déclarations et aussi voir ce qui se passe lorsque je réduis la luminosité de la lumière. – fastrack20
Cela faisait partie du problème. La lumière était trop brillante et la sphère était lavée, mais la sphère ne montre toujours qu'une seule couleur solide, aucune idée? http://dl.dropbox.com/u/367232/image3.jpg – fastrack20
Au lieu de rendre dans un 'int', quels clips, essayez d'utiliser' float' ou 'double' pour votre tampon de rendu (et tout le calcul). Puis examinez le résultat et convertissez le tampon en int en divisant l'intensité de chaque pixel par le pixel le plus lumineux (intensité maximum) de l'image entière. – SingleNegationElimination