我的软阴影代码出了什么问题?

Jul*_*anR 3 c# algorithm raytracing shadow

我正在尝试编写一个简单的光线跟踪器作为一个爱好项目,它现在都工作正常,除了我无法使软阴影工作.我对软阴影的想法是,光源被认为具有位置和半径.为了对这个光进行阴影测试,我得到主光线撞击场景中物体的点,并向光源投射n个光线,每个新光线对每个轴都有一个随机分量,随机分量变化介于-radius和radius之间.

如果这样的光线撞击场景中的物体,我会增加一个接收器(如果一条光线击中多个物体,它仍然只增加一个).如果它在没有碰撞的情况下进入光源,我将主光线交叉点到光源中心的距离加到变量上.

当拍摄n个样本时,我计算出碰撞的光线的比率,并将光的颜色乘以该比率(因此,颜色为1000,1000,1000的光将变为500,500,500,比率为0.5,其中一半光线碰撞了).然后我通过将先前的距离变量除以非碰撞射线的数量来计算到光源的平均距离.我返回该变量,函数退出.

问题是:它不起作用.至少不是这样.它的外观可以在这里看到.你可以看到它有点像软阴影,如果你真的很难眯眼.

我不明白,我在这里制造某种根本性的缺陷,还是它有点小?我很确定问题出在这种方法中,因为当我计算这种方法直接产生的部分点亮像素的数量时,只有大约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
  }
}
Run Code Online (Sandbox Code Playgroud)

Hat*_*ath 5

小点,但这是随机类的最佳使用..

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

如果这不是..

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