gpt4 book ai didi

c++ - 如何在简单的光线追踪器中使用纹理贴图?

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:36:52 24 4
gpt4 key购买 nike

我正在尝试向 C++ 中的光线追踪器添加功能。也就是说,我正在尝试向球体添加纹理映射。为简单起见,我使用数组来存储纹理数据。我通过使用十六进制编辑器并将正确的字节值复制到代码中的数组中来获取纹理数据。这只是为了我的测试目的。当此数组的值对应于纯红色的图像时,除了没有阴影外,它看起来接近预期的效果。 first image http://dl.dropbox.com/u/367232/Texture.jpg图像的右下角显示了正确的球体应该是什么样子。这个球体的颜色使用一套颜色,而不是纹理贴图。

另一个问题是,当纹理贴图不是只有一种颜色像素时,它会变成白色。我的测试图像是一张水的图片,当它贴图时,它只显示白色周围的一圈蓝色像素。

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

完成后,它简单地显示为: second image 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;
}

为了不让帖子陷入困境,我省略了其余代码,但可以看到 here .任何帮助是极大的赞赏。唯一没有包含在代码中的部分是我定义纹理数据的地方,正如我所说,它只是直接从上述图像的位图文件中获取。

谢谢。

最佳答案

可能是纹理刚刚被洗掉,因为光线太亮太近了。请注意,在纯红色的情况下,球体周围似乎没有任何渐变。红色看起来已经饱和了。

您的 u,v 映射看起来正确,但那里可能有错误。我会添加一些 assert 语句来确保 u 和 v 确实在 0 和 1 之间,并且 TEXT_DATA 数组中的 p 索引也在范围内。

关于c++ - 如何在简单的光线追踪器中使用纹理贴图?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2649674/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com