我正在尝试做的是从我的相机投射光线.我知道相机的x,y和z坐标,以及它的俯仰和偏航.我需要计算它的方向向量,这样我就可以将它传递给我的光线追踪算法.
相机的向上矢量为(0,1,0).从相机的角度来看,"俯仰"正在向上和向下看.
(我更愿意不使用矩阵,但如果必须,我会这样做)
我需要一种比Bresenham线绘制算法慢一点的算法,但必须更精确.使用'exact'我的意思是:应该打印每个触摸的像素.不多也不少!这意味着使用更粗的线或类似物不是一种选择,因为将涉及太多的像素.此外,我并不需要一个图形框架或类似就像是问 之前,我需要的算法!应用程序实际上不是"图形",它位于像素为"图块" 的地理区域.
对我来说主要的问题是我需要子像素精度,这意味着一条线可以从0.75/0.33开始,而不仅仅是0/0,就像整数值的情况一样.我尝试在过去几个小时内创建一个可行的解决方案,但无法使其正常工作 - 边缘情况太多了.
首先,我认为抗锯齿的版本就像从算法吴应,但它打印像素过多(尤其是起点和终点),并在某些情况下,还惦记着,例如在非常短的线条一些像素.
然后我试着让Bresenham在我用'else if'取代第二个'if'的地方工作,这里指出了它,但它更接近但仍然不存在.然后我尝试将Bresenham从整数移动到浮点精度,这导致无限循环(因为x,y值跳过完成条件if (y1 == y2 && x1 == x2)).
我可以使用天真的线条绘图解决方案,但delta我应该使用哪个?例如,如果我使用0.1,我仍然会错过一些像素并使用较小的值,它可能会花费太长时间(仍然会错过像素).
C/Java/...中的工作解决方案将不胜感激.至少它应该适用于八分之一,但一个完整的解决方案会更好.
更新:我提出了以下想法:使用朴素行光栅化,您可以为每个点计算4个像素候选.然后检查这4个像素,如果该线真正穿过它们.但我不确定线/盒交叉点是否足够快.
我正在尝试在我的光线追踪器中为球体实现纹理.我设法得到了一些工作,但我不确定它的正确性.下面是获取纹理坐标的代码.目前,纹理是随机的,并在运行时生成.
virtual void GetTextureCoord(Vect hitPoint, int hres, int vres, int& x, int& y) {
float theta = acos(hitPoint.getVectY());
float phi = atan2(hitPoint.getVectX(), hitPoint.getVectZ());
if (phi < 0.0) {
phi += TWO_PI;
}
float u = phi * INV_TWO_PI;
float v = 1 - theta * INV_PI;
y = (int) ((hres - 1) * u);
x = (int) ((vres - 1) * v);
}
Run Code Online (Sandbox Code Playgroud)
这就是球体现在的样子:

我不得不规范化生命点的坐标以使球体看起来像那样.否则他们看起来像:

将命中点坐标正规化为正确的方法,还是我的代码中的其他东西被破坏了?谢谢!
我尝试将其翻译为世界原点(就好像球体中心在那里)而不是标准化生命点,并获得以下结果:

顺便说一句,我使用256x256分辨率纹理.
上学期我们必须为学校的课程开发光线跟踪器.学校正在完成,我试图用它来捣乱.
我想知道如果我将所有浮点计算从double更改为float(所有计算都是使用双精度计算)会发生什么变化.所以我将每个变量更改为float类型,并简单地将从Math方法返回的每个double转换为float.在几个场景中测试我的光线跟踪器显示了相当不错的性能提升.
在网上搜索我发现浮动可能更快的各种原因,但也有人说在64位环境中双倍可以更快,甚至更快.问题是,我在64位环境和JVM中运行.这种性能提升的原因是什么?
现在,我正在阅读PBRT书,并计划在此之后从头开始重写光线跟踪器.为所有浮点计算选择浮点数会产生任何问题吗?在我的测试中我没有注意到任何东西,但是对于某些场景来说可能较低的精度(交叉点测试似乎可能会造成问题)?或者可能是一种权衡,比如在关键测试中使用double,为不太关键的计算使用float?我将不得不使用其他数学库来摆脱铸造,我会采用浮动方式.
我知道kd-tree传统上用于存储点,但我想存储线.是否最好在每个交叉点拆分kd-tree的分割线?或者只将端点存储到kd中以便最近邻找到?
在光线跟踪中,我想计算光线照射点的阴影.我向所有光源"绘制"线条并检查它们是否被物体阻挡.如果它们没有被阻挡,那么我根据它们的强度和"命中光线"与表面法线之间的程度来计算光照强度.
但如果光被部分透明的表面阻挡怎么办?然后光应该点亮这个点,但是它的强度和颜色会受到它通过的表面颜色的影响,并且为了计算我需要对光线通过的点进行光线追踪(实际上对于2个点,一个入口和一个出口),这将是非常昂贵的,并且可能几乎永远不会结束(我想在光源和表面的正确定位中,您可以将示踪剂置于几乎无限的每次击中循环).
是否有一种快速而好的方法来近似颜色,或者我应该将表面的颜色作为浅色和透明度作为强度?
我想用WPF编写一个简单的光线跟踪器.这是一个学习项目,因此我赞成对性能的可配置性(否则我会选择C++).
我仍然想要相对较快的像素绘制.关于StackOverflow 的上一个问题包含通过获取GDI位图在WPF中实现此目的的代码.从我对Windows编程的了解相对较少,
是否可以通过WPF Canvas(或类似)使用DirectX(而不是GDI)获得像素级访问?
如果可能的话,我还会考虑在WPF窗口(以及其他WPF控件)中合并DirectX API调用的建议.
提前致谢.
在过去的几天里,我第一次一直在攻击光线跟踪器.然而,有一些困扰我的怪癖,我真的不知道如何解决.从一开始就存在的是场景中球体的形状 - 渲染时,它们实际上看起来像椭圆形.当然,场景中有透视,但最终的形状看起来仍然很奇怪.我附上了一个样本渲染,我所遇到的问题在图像左下角的反射球上特别明显.

我真的不知道是什么原因引起的.它可能是光线球体交叉代码,如下所示:
bool Sphere::intersect(Ray ray, glm::vec3& hitPoint) {
//Compute A, B and C coefficients
float a = glm::dot(ray.dir, ray.dir);
float b = 2.0 * glm::dot(ray.dir, ray.org-pos);
float c = glm::dot(ray.org-pos, ray.org-pos) - (rad * rad);
// Find discriminant
float disc = b * b - 4 * a * c;
// if discriminant is negative there are no real roots, so return
// false as ray misses sphere
if (disc < 0)
return false;
// compute q
float …Run Code Online (Sandbox Code Playgroud) 我正在使用 vulkan 计算着色器开发路径跟踪器。我实现了一个表示边界卷层次结构的树。BVH 的想法是最小化需要执行光线交叉测试的对象数量。
#1 幼稚的实现
我的第一个实现非常快,它将树向下遍历到BVH 树的单个叶子。但是,射线可能会与多个叶子相交。这段代码会导致一些三角形没有被渲染(尽管它们应该)。
int box_index = -1;
for (int i = 0; i < boxes_count; i++) {
// the first box has no parent, boxes[0].parent is set to -1
if (boxes[i].parent == box_index) {
if (intersect_box(boxes[i], ray)) {
box_index = i;
}
}
}
if (box_index > -1) {
uint a = boxes[box_index].ids_offset;
uint b = a + boxes[box_index].ids_count;
for (uint j = a; j < b; j++) { …Run Code Online (Sandbox Code Playgroud) raytracing ×10
c++ ×2
graphics ×2
java ×2
algorithm ×1
bounding-box ×1
bresenham ×1
c# ×1
geometry ×1
glsl ×1
intersection ×1
kdtree ×1
lwjgl ×1
math ×1
ray-picking ×1
shader ×1
vulkan ×1
wpf ×1