質問

私は趣味のプロジェクトとして、単純なレイトレーサを書き込もうとすることだし、それは私がソフトな影がまったく仕事を得ることができない以外のすべてが、今で正常に動作します。ソフトな影の私の考えは、光源が場所と半径を有すると考えられるということです。この光に影のテストを行うために、私は、主光線がシーン内のオブジェクトをヒットポイントを取り、それぞれの新しいレイは、ランダム成分が変化する毎に軸、ランダム成分を有する光源に向かって光線のN量をキャスト-radiusと半径との間。

このようなレイがシーン内のオブジェクトをヒットした場合、私は(光線が複数のオブジェクトをヒットした場合、それはまだ一つだけでインクリメント)hitcounterをインクリメントします。それが衝突することなく、光源にそれを作る場合、私は、変数への光源の中心部に主光線の交差地点の距離を追加します。

n個のサンプルが採取されている場合、私が衝突した光線の比率を計算し、この比によって光の色を乗算(SO色1000,1000,1000の光がここで、0.5の比500500500となるであろう半分の光線が衝突しました)。私は、非衝突する光線の量によって、以前の距離変数を分割して光源までの平均距離を計算します。私はその変数や関数が終了を返します。

問題がある:それは動作しません。ない、非常に少なくとも。それはここを見ることができますどのように見えますか。あなたは本当のハード目を細めた場合、それは一種の、ソフトシャドウに似て見ることができます。

私はそれを得ることはありません、私はここに根本的な欠陥のいくつかの並べ替えを行う、またはそれは小さなものですのですか?私はこの方法で直接生成部分的に点灯する画素の数をカウントするとき、より多くのがあるべきときには、わずか約250ありますので、私は、問題はこの方法であるかなり確信しています。あなたは絵をよく見る時、あなたは残りのコードだけで罰金、部分的に点灯ピクセルを処理示唆、いくつかの部分的に点灯する画素があります見ることができます。

ここで、ソフトシャドウクラスの実際の光です:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MyFirstRayTracer
{
  public class AreaLight : ILight
  {
    private const int _radius = 5;
    private const int _samples = 16;
    public Color Color { get; set; }
    public Vector Location { get; set; }
    #region ILight Members

    public float GetLightingInformation(Vector point, ISceneObject[] scene, out Color color)
    {
      int intersectCount = 0;
      float distance = -1;
      for(int i = 0; i < _samples; i++)
      {
    bool intersects = false;
    float rand = 0;
    rand = _radius - (float)(new Random().NextDouble()*(2*_radius));
    foreach (ISceneObject obj in scene)
    {
      Vector iPoint;

      Vector loc = new Vector(Location.X + rand, Location.Y + rand, Location.Z + rand);

      if (!obj.Intersect(new Ray(point, loc), out iPoint))
      {
        distance += (Location - point).SqLength;

      }
      else
      {
        intersects = true;
        distance -= (Location - point).SqLength;
      }
    }
    if (intersects)
      intersectCount++;
      }
      float factor = 1-((float)intersectCount/_samples);

      color = new Color(factor*Color.R, factor*Color.G, factor*Color.B);

      return (float)Math.Sqrt(distance / (_samples - intersectCount));
    }


    #endregion
  }
}
役に立ちましたか?

解決

「LOC」の各コンポーネントの異なる「ランド」を生成してみてください。であるとして、あなたのジッタのポイントすべてがライン上にある。

他のヒント

マイナーなポイントをしかし、これはランダムクラスの最善の使用である..

 for(int i = 0; i < _samples; i++)
      {
        bool intersects = false;
        float rand = 0;
        rand = _radius - (float)(new Random().NextDouble()*(2*_radius));

これはすべきではない..

    var rnd = new Random()    
    for(int i = 0; i < _samples; i++)
              {
                bool intersects = false;
                float rand = 0;
                rand = _radius - (float)(rnd.NextDouble()*(2*_radius));

あなたが実際の方向(1、1、1)と一直線上にライン上の点を生成します。光源が本当に線形で?

また、私はやっとあなたの例では何も見ることができます。影に-ことと、光の方向から向いていないのより近くにあなたのカメラを作ることができる?

を参照してください、私はこのサイトに来る理由です:)

すべての軸は現在、独自のランダムを持っており、それはかなり良く見えます。これは、サンプル数を増やすことができますけれども、まだ見て少し奇妙です。それは今こののようになります。

あなたはパターン形成を減らすために、より効率的な方法を知っていますか?

しかし最大のヘルプ:サンプル毎にランダムをインスタンスません。それは真剣にソフトシャドウと私のレンダリング速度を三倍に!私はランダムインスタンス化するのはコストがかかるであることを知っていたことはありません。うわーます。

どうもありがとうございました。

あなたの応答では、ソフトシャドウを作成するための改良方法を尋ねました。改善は、代わりに同じ点から全ての光線をランダム化する、各光線を効果的にそれらを中にランダム化する別々の小さなウィンドウを与えるためにすべての軸上の異なるオフセットを与える。このことは、より均一な分布をもたらすはずであることができます。それが明らかになった場合、私は知りませんが、それを記述するための別の方法は、シャドウレイに垂直なグリッドとしてあります。グリッド内の各タイルは、n個の影光線のいずれかを含むが、グリッド内の位置はランダムです。 ここでは、これを使用することができます方法について説明チュートリアルの一部を見つけることができますするソフトシャドウ用ます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top