6

C++ でレイトレーサーを書いていますが、屈折に問題があります。球と地面をレンダリングしていますが、球は屈折するはずです。ただし、球の中の球のように見えます。「外側の」球は適切にシェーディングされているように見えますが、屈折していないように見えますが、「内側の」球はセルフ シャドウされているように見えます。これがどのように見えるかへのリンクは次のとおりです: http://imgur.com/QVGkeBT

関連するコードは次のとおりです。

//inside main raytrace function
     if(refraction > 0.0f){ //the surface is refractive
        //calculate refraction vector
        Ray refract(intersection,
          objList[bestObj]->refractedRay(
            ray.dir,intersection,&cos_theta,&R0));
        //recurse
        refrColor = raytrace(refract);
      }
      else{ //no refraction
        refrColor = background;
      }


//refractedRay(vec3,vec3,float*,float*)
  //...initialize variables, do geometric transforms
  //into air out of obj
  if(dot(ray,normal) < 0){
    n1 = ior;
    n2 = 1.0f;
    *cos = dot(ray,-normal);
  }
  //into obj out of air
  else{
    n1 = 1.0f;
    n2 = ior;
    *cos = dot(ray,normal);
    normal = -normal;
  }

  //check value under sqrt
  float n = n1/n2;
  float disc = 1-(pow(n,2)*(1-pow(*cos,2)));
  if(disc < 0){ //total internal reflection
    return ray - 2*-(*cos)*normal; //reflection vector
  }

  return (n*ray)+(((n*(*cos))-sqrt(disc))*normal);

以前は球体の見た目が悪かったので、ベクトルを正規化することを思い出したところ、次のようになりました。以前は、全体を通して内側の球だけのように見えました。メインのレイトレース機能の中で、代わりに屈折した光線を使用するだけで、反射と同じ方法で屈折を行います。また、シャドーイングで得られる自己屈折をチェックするために、イプシロンを使用して交点と光線の着信点を変更しようとしました。

どんな助けでも大歓迎です:)

4

1 に答える 1

3

屈折式を確認していませんが、これは間違っているようです:

//into air out of obj
if(dot(ray,normal) < 0){
  n1 = ior;
  n2 = 1.0f;
  *cos = dot(ray,-normal);
}

入射光線と法線の内積がゼロ未満で、法線がオブジェクトの外側を向いていると仮定すると (おそらくそうあるべきです)、このケースは に対応するair -> insideため、屈折率を交換する必要があります。現在、ior1 / iorを使用して球体をレンダリングしていますが、その屈折率が 1 未満であるため、エッジで全反射が観察されています。

これは、何かが欠けているかどうかを確認するために見ることができる私の実装の 1 つです(より多くの機能がありますが、関心のある部分を特定し、計算が一致することを確認できるはずです)。私には問題ないように見えるので、屈折率を修正する必要があると思います。

ただし、球の中心にある非決定論的なパターンは、間違いなく自己交差のように見えます。反射の場合は、反射した光線を交差するサーフェスの外側にわずかに押し出し、屈折の場合は、屈折した光線をわずかに内側に押し込んで、自己交差を回避するようにしてください。

于 2013-05-09T05:53:28.550 に答える