C++에서 레이 트레이서에 피쳐를 추가하려고합니다. 즉, 구체에 텍스처 매핑을 추가하려고합니다. 간단히하기 위해 배열을 사용하여 텍스처 데이터를 저장하고 있습니다. 16 진수 편집기를 사용하고 올바른 바이트 값을 내 코드의 배열에 복사하여 텍스처 데이터를 가져 왔습니다. 이것은 단지 테스트 목적이었습니다. 이 배열의 값이 단순히 빨간색 인 이미지에 해당하면 음영이없는 경우를 제외하고는 예상 한 것과 거의 유사하게 작동합니다. first image http://dl.dropbox.com/u/367232/Texture.jpg 이미지의 오른쪽 하단에는 정확한 구 모양을 보여줍니다. 이 구체의 색상은 텍스처 맵이 아닌 설정된 색상 하나를 사용합니다.간단한 광선 추적기에서 텍스처 매핑을 사용하려면 어떻게해야합니까?
또 다른 문제는 텍스처 맵이 단색 픽셀이 아닌 다른 것일 때 흰색이됩니다. 내 테스트 이미지는 물 사진이며, 매핑하면 흰색을 둘러싼 한 개의 푸른 색 픽셀 링 만 표시됩니다. 이 작업이 완료
는bmp http://dl.dropbox.com/u/367232/vPoolWater.bmp
, 단순히이 같이 나타납니다 : 내가 추적 여기에 컬러 코드를 호출
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;
}
};
: 여기 second image http://dl.dropbox.com/u/367232/texture2.jpg
몇 가지 코드 조각입니다
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을 볼 수있다. 어떤 도움이라도 대단히 감사합니다. 코드에 포함되지 않은 유일한 부분은 텍스처 데이터를 정의하는 곳입니다. 위에서 말했듯이 위 이미지의 비트 맵 파일에서 바로 가져옵니다.
감사합니다.
그렇다면 구를 단순히 색을 표시하고 텍스처를 표시하지 않으면 그라디언트가 잘 표시됩니다. 나는 assert 문장을 추가하고 빛의 밝기를 줄일 때 어떤 일이 일어나는지 살펴볼 것이다. – fastrack20
그것이 문제의 일부였습니다. 빛은 너무 밝아서 구를 씻어 내고 있었지만 구가 여전히 단색만을 보여주고 있습니까? http://dl.dropbox.com/u/367232/image3.jpg – fastrack20
'int'로 렌더링하는 대신 클립을 사용하여 렌더링 버퍼 (및 모든 계산)에'float' 또는'double'을 사용해보십시오. 그런 다음 결과를 조사하고 전체 픽셀의 가장 밝은 (최대 강도) 픽셀로 각 픽셀의 강도를 나눔으로써 버퍼를 int로 변환하십시오. – SingleNegationElimination