c# - 我的软阴影代码有什么问题?

标签 c# algorithm raytracing shadow

我正在尝试编写一个简单的光线追踪器作为一个业余项目,现在一切正常,除了我根本无法使用软阴影。我对软阴影的想法是认为光源具有位置和半径。为了对这种光线进行阴影测试,我取主光线照射场景中物体的点,并向光源转换 n 条光线,其中每条新光线对每个轴都有一个随机分量,其中随机分量会变化在 -radius 和 radius 之间。

如果这样一条光线击中场景中的一个物体,我会增加一个 hitcounter(如果一条光线击中多个物体,它仍然只会增加一个)。如果它在没有碰撞的情况下到达光源,我将主光线的交点到光源中心的距离添加到一个变量中。

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

问题是:它不起作用。至少不完全是。长什么样子可以看看here .如果你用力眯眼,你会看到它有点像柔和的阴影。

我不明白,我是在制造一些根本性的缺陷,还是一些微小的缺陷?我相当确定问题出在这种方法中,因为当我计算这种方法直接产生的部分点亮像素的数量时,只有大约 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
  }
}

最佳答案

次要点,但这是随机类的最佳用途吗..

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

关于c# - 我的软阴影代码有什么问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/515693/

相关文章:

c++ - 使用 GLSL 进行光线追踪

c# - 光线追踪出了问题

c# - 如何重用 Type 返回值生成新的源代码

r - 基于节点权重构建图的优化算法

algorithm - 路径追踪 : scaling color

python - 高效的粒子对相互作用计算

java - 光线追踪三角形的问题(方向和着色)

c# - asp.net母版页执行的顺序

c# - 公共(public)静态方法+接口(interface)

c# - 如何关闭网络浏览器控件中的查找窗口