标签: raytracing

射线盒交叉理论

我想确定光线和盒子之间的交点.该框由其最小3D坐标和最大3D坐标定义,并且光线由其原点和它指向的方向定义.

目前,我正在为盒子的每个面形成一个平面,我正在将光线与平面相交.如果光线与平面相交,那么我检查交叉点是否实际位于框的表面上.如果是这样,我检查它是否是此光线的最近交点,并返回最近的交点.

我检查平面交叉点是否在盒子表面上的方式是通过一个函数

bool PointOnBoxFace(R3Point point, R3Point corner1, R3Point corner2)
{
  double min_x = min(corner1.X(), corner2.X());
  double max_x = max(corner1.X(), corner2.X());
  double min_y = min(corner1.Y(), corner2.Y());
  double max_y = max(corner1.Y(), corner2.Y());
  double min_z = min(corner1.Z(), corner2.Z());
  double max_z = max(corner1.Z(), corner2.Z());
  if(point.X() >= min_x && point.X() <= max_x && 
     point.Y() >= min_y && point.Y() <= max_y &&
     point.Z() >= min_z && point.Z() <= max_z)
     return true;

  return false;
}
Run Code Online (Sandbox Code Playgroud)

哪个corner1是该框面的矩形的一角,corner2是对面的角.我的实现大部分时间都在工作,但有时它给了我错误的交集.请看图片:

替代文字

图像显示来自相机眼睛并撞击盒子表面的光线.其他光线是盒子表面的法线.可以看出,特别是一条光线(它实际上是看到的法线)从盒子的"背面"出来,而法线应该从盒子的顶部出来.这似乎很奇怪,因为有多个其他光线正确地击中了盒子的顶部.

我想知道我正在检查交叉点是否在盒子上的方式是正确的还是我应该使用其他算法.

谢谢.

algorithm 3d raytracing intersection

20
推荐指数
1
解决办法
1万
查看次数

如何在"用于光线跟踪的快速体素遍历算法"中初始化t变量?

我正在尝试实现本文中解释的算法,用于按照直线顺序遍历网格单元,这对于光线跟踪非常有用:

http://www.cse.yorku.ca/~amana/research/grid.pdf

本文将算法描述为两部分:初始化和迭代遍历.我可以忽略迭代遍历部分,但我无法理解初始化部分中的某些变量是如何计算的.

我需要帮助正在初始化tMaxX,tMaxY,tDeltaXtDeltaY.他们的初始化程序解释如下:

接下来,我们确定光线穿过第一个垂直体素边界的t值,并将其存储在变量tMaxX中.我们在y中执行类似的计算并将结果存储在tMaxY中.这两个值中的最小值将指示我们可以沿着光线行进多少并且仍然保留在当前体素中.

最后,我们计算tDeltaX和tDeltaY.TDeltaX指示我们必须沿着光线移动多远(以t为单位),以使这种运动的水平分量等于体素的宽度.类似地,在tDeltaY中存储沿着光线的移动量,其具有等于体素高度的垂直分量.

我无法从上面给出的英文描述中推断出我需要的代码.有人可以为我翻译成数学/伪代码表达式吗?

language-agnostic algorithm math grid raytracing

19
推荐指数
2
解决办法
5709
查看次数

光线追踪折射?

我一直在研究我的光线跟踪器.我添加了反射和多线程支持.目前我正在努力增加折射,但它只有一半工作. 球

如您所见,有一个中心球体(没有镜面反射高光),一个反射球体(右侧)和一个折射球体(左侧).我很高兴反思,看起来非常好.对于折射它有点工作......光被折射并且球体的所有阴影都在球体中可见(折射率1.4),但是有一个外部黑色环.

编辑:当我增加球体的折射率时,显然黑色环变大,因此球体变小.相反,当降低折射率时,球体变大,黑色环变小......直到折射率设为1,环完全消失.IOR = 1.9 在此输入图像描述 IOR = 1.1 在此输入图像描述 IOR = 1.00001 在此输入图像描述 有趣的是,在IOR = 1时,球体失去透明度并变白. 在此输入图像描述

我认为我涵盖了全部内部反思,这不是问题所在.

现在的代码:我正在使用operator |for dot产品,因此(vec|vec)是一个点积和operator ~反转向量.物体,包括ligths和spheres都存储在Object **objects;.光线跟踪功能

Colour raytrace(const Ray &r, const int &depth)
{
    //first find the nearest intersection of a ray with an object
    Colour finalColour = skyBlue *(r.getDirection()|Vector(0,0,-1)) * SKY_FACTOR;
    double t, t_min = INFINITY;
    int index_nearObj = -1;
    for(int i = 0; i < objSize; i++)
    {
        if(!dynamic_cast<Light *>(objects[i]))//skip light src
        {
            t = objects[i]->findParam(r); …
Run Code Online (Sandbox Code Playgroud)

c++ 3d graphics raytracing

19
推荐指数
1
解决办法
6332
查看次数

光线追踪、光线投射、光线行进和路径追踪之间有什么区别?

据我所知,标题中提到的所有技术都是看起来非常相似的渲染算法。所有基于光线的技术似乎都围绕着通过图像的每个像素投射光线来表示真实光线。这允许渲染非常逼真的图像。

\n

事实上,我正在制作一个简单的程序,根据光线追踪在一个周末自行渲染此类图像。

\n

现在的问题是我想以某种方式命名这个程序。我使用了术语 \xe2\x80\x9cray Tracer\xe2\x80\x9d,因为这是书中使用的术语。

\n

然而,我听过很多不同的术语,我有兴趣知道光线追踪、光线匹配、光线投射、路径追踪和任何其他常见的光线相关算法之间到底有什么区别。我能够在网上找到这些技术的一些比较,但它们都只比较了其中的两种,并且一些定义重叠,所以我想问这个关于所有四种技术的问题。

\n

algorithm rendering raytracing terminology

19
推荐指数
1
解决办法
1万
查看次数

提高光线跟踪器的性能

我在D(http://dsource.org/projects/stacy)中编写了一个相对简单的光线跟踪器/路径跟踪器,但即使进行全面优化,每条光线仍需要几千个处理器周期.我还能做些什么来加快速度吗?更一般地说,您是否知道光线跟踪的良好优化/更快的方法?

编辑:这就是我现在正在做的事情.

  • 代码已经高度并行运行
  • 临时数据以高效缓存方式构建,并与16b对齐
  • 屏幕分为32x32-tiles
  • 目标阵列以这样的方式排列,即图块中的所有后续像素在存储器中是顺序的
  • 执行基本场景图优化
    • 对象的常见组合(如框中的平面平面CSG)被预先优化的对象替换
  • 矢量结构能够利用GDC的自动矢量化支持
  • 通过懒惰评估找到后续的射线命中; 这可以防止对CSG进行不必要的计算
  • 三角形既不支持也不优先.仅限普通基元,以及CSG操作和基本材料属性
  • 支持边界

graphics performance raytracing d

18
推荐指数
3
解决办法
9611
查看次数

什么导致我的光线跟踪器中的工件?

编辑:我现在已经解决了这个问题; 你可以在答案中看到我的解决方案.

我正在使用OpenGL(在GLSL计算着色器中)编写实时光线跟踪器,我遇到了一些线三角交叉点的问题(或者至少,我相信它们是罪魁祸首) .这是一张正在发生的事情的图片:

球体在一个房间里有一些文物

如您所见,一些像素在图像顶部附近的两个三角形的交叉点处被涂成黑色.它可能与我正在处理花车或其他东西的方式有关,我尝试在线搜索解决方案,但找不到类似的情况.也许我错过了一个重要的关键词?

无论如何,重要的代码是这一个:

#define EPSILON 0.001f
#define FAR_CLIP 10000.0f
float FindRayTriangleIntersection(Ray r, Triangle p)
{
    // Based on Moller-Trumbone paper
    vec3 E1 = p.v1 - p.v0;
    vec3 E2 = p.v2 - p.v0;
    vec3 T = r.origin - p.v0;
    vec3 D = r.dir;
    vec3 P = cross(D, E2);
    vec3 Q = cross(T, E1);

    float f = 1.0f / dot(P, E1);
    float t = f * dot(Q, E2);
    float u = f * dot(P, T);
    float v = …
Run Code Online (Sandbox Code Playgroud)

c++ opengl 3d raytracing glsl

18
推荐指数
1
解决办法
1751
查看次数

是否有光栅化或光线追踪的渲染替代方案?

光栅化(三角形)和光线跟踪是我遇到的渲染3D场景的唯一方法.还有其他人吗?此外,我很想知道任何其他真正"在那里"做3D的方法,例如不使用多边形.

3d graphics raytracing rasterizing

14
推荐指数
2
解决办法
7954
查看次数

如何在Haskell中滚动快速BVH表示

我正在玩Haskell Raytracer,目前正在使用BVH实现,它强调一个天真的二叉树来存储层次结构,

data TreeBvh
   = Node Dimension TreeBvh TreeBvh AABB
   | Leaf AnyPrim AABB
Run Code Online (Sandbox Code Playgroud)

其中Dimension是X,YZ(用于更快的遍历)和AABB是我的类型的轴对齐边界框.这种方法运行得相当不错,但我真的很想尽可能快地得到它.所以我的下一步(当使用C/C++时)将使用这个树来构造一个扁平表示,其中节点存储在一个数组中,"left"子节点紧跟在它的父节点和父节点的右子节点的索引之后与父母一起存储,所以我有这样的事情:

data LinearNode
   = LinearNode Dimension Int AABB
   | LinearLeaf AnyPrim AABB

data LinearBvh
   = MkLinearBvh (Array Int LinearNode)
Run Code Online (Sandbox Code Playgroud)

我还没有真正尝试过这个,但我担心性能仍然低于标准,因为我不能将LinearNode实例存储在UArray中,也不能将Int正确子项的索引与组成该Float值的值一起存储.单个UArray中的AABB(如果我弄错了,请纠正我).使用两个阵列意味着缓存一致性差.所以我基本上都在寻找一种有效存储树的方法,因此我可以期待良好的遍历性能.它应该是

  • 紧凑
  • 具有良好的地方特性
  • 与最近的GHC编译器合作
  • 应尽可能小的间接(尽管"thunk"无法帮助表现,所以"unboxed"类型会让我觉得有帮助)

arrays haskell raytracing vector bounding-box

14
推荐指数
1
解决办法
877
查看次数

为什么KD树在点集中最近邻搜索的速度如此之慢?

我正在使用CGAL(最新的)KD树实现来搜索点集中的最近邻居.维基百科和其他资源似乎也暗示KD树是可行的方式.但不知怎的,它们太慢了,而且Wiki也暗示了O(n)的最坏情况,这远非理想.

[BEGIN-EDIT] 我现在正在使用"nanoflann",这比用于K邻居搜索的CGAL中的等效物快约100-1000倍.我正在使用"英特尔Embree"进行光线投射,这比CGAL的AABB树快约100-200倍. [END-EDIT]

我的任务看起来像这样:

我有一个巨大的点集,比如高达几百万.点!它们的分布在三角形几何体的表面上(是的,光子示踪剂).所以可以说它们的分布在3D空间中是2D的,因为它在3D中是稀疏的,但在观察表面时是密集的......这可能是问题对吗?因为对我而言,这似乎触发了KD树的最坏情况性能,这可能会更好地处理3D密集点...

CGAl非常擅长它的功能,所以我有点怀疑它们的实现很糟糕.我用它进行光线追踪的AABB树在地上几分钟内燃烧了十亿个光线......我猜这是非常了不起的.但另一方面,他们的KD树甚至无法处理mio.在任何合理的时间点和250k样本(点查询)......

我提出了两个解决方案,从KD树中剔除废话:

1)使用纹理贴图将光子存储在几何体上的链接列表中.这总是一个O(1)操作,因为你无论如何都必须进行光线投射......

2)使用视图相关的切片哈希集.这是你得到的越远,哈希集越粗.所以基本上你可以想到NDC坐标中的1024x1024x1024光栅,但是使用哈希集来节省稀疏区域的内存.这基本上具有O(1)复杂度,并且可以有效地并行化,用于插入(微分片)和查询(无锁).

前一解决方案的缺点在于,几乎不可能对相邻光子列表进行平均,这在较暗区域中是重要的,以避免噪声.后一种解决方案没有这个问题,并且应该与KD树特征相同,只是它具有O(1)最坏情况性能,lol.

所以你怎么看?糟糕的KD树实施?如果没有,对于有界最近邻居查询,是否存在比KD树"更好"的东西?我的意思是我没有反对上面的第二个解决方案,但提供类似性能的"经过验证的"数据结构会更好!

谢谢!

这是我使用的代码(不可编译):

#include "stdafx.h"
#include "PhotonMap.h"

#pragma warning (push)
    #pragma warning (disable: 4512 4244 4061)
    #pragma warning (disable: 4706 4702 4512 4310 4267 4244 4917 4820 4710 4514 4365 4350 4640 4571 4127 4242 4350 4668 4626)
    #pragma warning (disable: 4625 4265 4371)

    #include <CGAL/Simple_cartesian.h>
    #include <CGAL/Orthogonal_incremental_neighbor_search.h>
    #include <CGAL/basic.h>
    #include <CGAL/Search_traits.h>
    #include <CGAL/point_generators_3.h>

#pragma warning (pop)

struct PhotonicPoint
{
    float vec[3];
    const Photon* photon;

    PhotonicPoint(const Photon& photon) : …
Run Code Online (Sandbox Code Playgroud)

c++ raytracing kdtree cgal data-structures

14
推荐指数
3
解决办法
2万
查看次数

射线平面交叉怎么办?

如何计算光线与平面之间的交点?我一直在访问我能找到的每个可能的网站,这是我迄今为止取得的成就:

float denom = normal.dot(ray.direction);

if (denom > 0)
{
    float t = -((center - ray.origin).dot(normal)) / denom;

    if (t >= 0)
    {
        rec.tHit = t;
        rec.anyHit = true;
        computeSurfaceHitFields(ray, rec);
        return true;
    }
}
Run Code Online (Sandbox Code Playgroud)

这不起作用:s
我的函数输入是:
ray:包含原点和方向.
rec:用于存储命中信息的容器类(bool,t等)

我的函数可以访问平面:
点:定义平面
法线的点:定义平面的法线

c++ raytracing

14
推荐指数
3
解决办法
3万
查看次数