2

C++のレイトレーサーに機能を追加しようとしています。つまり、球にテクスチャマッピングを追加しようとしています。簡単にするために、配列を使用してテクスチャデータを格納しています。16進エディターを使用し、正しいバイト値をコードの配列にコピーして、テクスチャデータを取得しました。これは私のテスト目的のためだけでした。この配列の値が単純に赤の画像に対応している場合、陰影がないことを除いて、期待どおりに機能しているように見えます。 最初の画像http://dl.dropbox.com/u/367232/Texture.jpg画像 の右下は、正しい球がどのように見えるかを示しています。テクスチャマップではなく、1つのセットカラーを使用したこの球のカラー。

もう1つの問題は、テクスチャマップが1つのカラーピクセル以外のものである場合、それが白くなることです。私のテスト画像は水の写真であり、マップすると、白い色を囲む青みがかったピクセルのリングが1つだけ表示されます。

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

これが行われると、次のように表示されます 。2番目の画像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;
}
};

私はここでトレースでカラーコードを呼び出します:

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;
}

投稿を滞らせないように残りのコードを省略しましたが、ここで確認できます。どんな助けでも大歓迎です。コードに含まれていない唯一の部分は、テクスチャデータを定義する場所です。これは、前述のように、上記の画像のビットマップファイルから直接取得されたものです。

ありがとう。

4

2 に答える 2

1

光がとても明るくてとても近いので、テクスチャがちょうど洗い流されている可能性があります。赤い実線の場合、球の周りにグラデーションがないように見えることに注意してください。赤は飽和しているように見えます。

u、vマッピングは正しく見えますが、間違いがある可能性があります。assertuとv、そして実際には0から1の間であり、TEXT_DATA配列へのpインデックスも範囲内にあることを確認するために、いくつかのステートメントを追加します。

于 2010-04-16T00:13:11.137 に答える
0

テクスチャをデバッグする場合は、ライトではなくテクスチャによってのみ色が決定される一定のマテリアルを使用する必要があります。そうすることで、テクスチャをプリミティブに正しくマッピングし、適切にフィルタリングしてから、ライティングを行うことができます。そうすれば、その部分は問題ではないことがわかります。

于 2010-10-24T23:46:51.423 に答える