我目前正在实施光线跟踪器.由于光线追踪的计算量非常大,而且无论如何我都要研究CUDA编程,我想知道是否有人有任何将这两者结合起来的经验.我无法确定计算模型是否匹配,我想知道会发生什么.我得到的印象是它不是天堂般的匹配,但是一个体面的速度增加会比没有好.
我正试图在我的光线跟踪器中遍历3D KD树.树是正确的,但我的遍历算法似乎有问题,因为与使用强力方法相比,我遇到了一些错误(一些小的表面区域似乎被忽略).
注意:所讨论的光线都不与任何轴平行.
这是我的遍历算法:
IntersectionData* intersectKDTree(const Ray &ray, KDTreeNode* node, double tMin, double tMax) const{
if (node->GetObjectCount()==0) return 0;
IntersectionData* current = 0;
bool intersected = false;
if (node->m_isLeaf){
...test all primitives in the leaf...
}
else{
int axis = node->m_splitAxis;
double splitPos = node->m_splitPos;
double tSplit = (splitPos-ray.point[axis])/ray.direction[axis];
KDTreeNode* nearNode = ray.point[axis]<splitPos?node->m_leftnode:node->m_rightnode;
KDTreeNode* farNode = ray.point[axis]<splitPos?node->m_rightnode:node->m_leftnode;
if (tSplit > tMax)
return intersectKDTree(ray, nearNode , tMin, tMax);//case A
else if (tSplit < tMin){
if(tSplit>0)
return intersectKDTree(ray, farNode, tMin, tMax);//case B …Run Code Online (Sandbox Code Playgroud) 我有一个复杂的3D场景,我需要在3D坐标的基础上显示HTML元素.(我只是将div标签叠加在顶部并用CSS定位.)但是,当3D坐标被模型遮挡时(或者以另一种方式表达时,我也需要部分隐藏它(例如,使其透明))它在相机中不可见).这些模型可能有数十万个面孔,我需要一种方法来确定它是否模糊得足以让它每秒运行多次.
目前,我正在使用Three.js的内置光线跟踪器,其代码如下:
// pos = vector with (normalized) x, y coordinates on canvas
// dir = vector from camera to target point
const raycaster = new THREE.Raycaster();
const d = dir.length(); // distance to point
let intersects = false;
raycaster.setFromCamera(pos, camera);
const intersections = raycaster.intersectObject(modelObject, true);
if (intersections.length > 0 && intersections[0].distance < d)
intersects = true;
// if ray intersects at a point closer than d, then the target point is obscured
// otherwise it is visible …Run Code Online (Sandbox Code Playgroud) 我一直想用C++编写自己的多线程实时光线跟踪器,但我不想实现它附带的所有矢量和矩阵逻辑.我想我会做一些研究,为此找到一个好的图书馆,但我没有取得多大成功......
重要的是实施速度很快,最好是它带有一些友好的许可.我读过它boost有基本的代数,但我找不到任何关于它的速度有多好.
其余的,谷歌给了我Armadillo,声称速度非常快,并将自己与其他一些我没有听说过的图书馆进行比较.
然后我得到了Seldon,这也声称是高效和方便的,虽然我无法找到他们在规模上的确切位置.
最后我读了一下Eigen,在这里搜索时我也在StackOverflow上看过这个.
在我大学的CG讲座中,他们使用HLSL代数(让学生实现/优化光线跟踪器的部分),这让我思考是否可以使用GLSL它.同样,我不知道哪个选项最有效,或者对代数库的一般共识是什么.我希望SO可以帮助我,所以我可以开始一些真正的开发:)
PS:我尝试链接到网站,但我还没有足够的代表
我正在写一个光线追踪器(主要是为了好玩),虽然我过去写了一个,花了相当多的时间搜索,没有任何教程似乎揭示了透视投影中计算眼睛光线的方式,不使用矩阵.
我相信我最后一次这样做是因为(可能)x/y使用Quaternion类别从摄像机方向矢量无效地旋转眼睛矢量度.这是在C++中,我在C#中做这个,虽然这不是那么重要.
伪代码(假设V*Q =变换操作)
yDiv = fovy / height
xDiv = fovx / width
for x = 0 to width
for y = 0 to height
xAng = (x / 2 - width) * xDiv
yAng = (y / 2 - height) * yDiv
Q1 = up vector, xAng
Q2 = camera right vector, yAng
Q3 = mult(Q1, Q2)
pixelRay = transform(Q3, camera direction)
raytrace pixelRay
next
next
Run Code Online (Sandbox Code Playgroud)
我认为这个问题的实际问题在于它模拟的是球形屏幕表面,而不是平面屏幕.
请注意,虽然我知道如何以及为什么使用交叉产品,点积,矩阵等,但我实际的3D数学问题解决技巧并不是很棒.
所以给出:
为光线跟踪器生成x/y像素坐标的眼睛光线的实际方法是什么?
澄清 …
我正在使用Python/numpy/scipy编写一个小型光线跟踪器.曲面被建模为二维函数,其高度高于法线平面.我减少了找到光线和曲面之间的交点以找到具有一个变量的函数的根的问题.功能是连续的,可连续区分的.
有没有办法比使用scipy根查找器(并且可能使用多个进程)简单地循环遍历所有函数更有效地执行此操作?
编辑:函数是表示光线的线性函数和表面函数之间的差异,约束到交叉平面.
我一直在阅读有关光线追踪和阴影的大量文章,但我的光线追踪图像看起来并不太好.我在谈论镜面高光附近非常明亮的绿色区域.结果绿色在这里最大化,看起来像.如何调整颜色和/或阴影计算以使其看起来正确?
(别担心愚蠢的代码,我只是想先把原则弄清楚).
以下是它的外观:

这里只是漫反射组件:

这是仅镜面反射分量:

编辑:将漫反射更改为颜色diffuseColor = ColorMake(0.0f,0.6f,0.0f); 然后图像看起来像这样:

Point lightPosition = PointMake(-100.0f, 100.0f, -100.0f);
Color diffuseColor = ColorMake(0.0f, 1.0f, 0.0f);
Color specularColor = ColorMake(1.0f, 1.0f, 1.0f);
Color pixelColor = ColorMake(0.0f, 0.0f, 0.0f);
// Trace...
// Diffuse
Point intersectionPosition = PointMake(x, y, z);
Vector intersectionNormal = VectorMake((x - xs) / rs, (y - ys) / rs, (z - zs) / rs);
Vector intersectionNormalN = VectorNormalize(intersectionNormal);
Vector lightVector = VectorSubtract(lightPosition, intersectionPosition);
VectorlightVectorN = VectorNormalize(lightVector);
float cosTheta = VectorDotProduct(intersectionNormalN, lightVectorN);
if (cosTheta …Run Code Online (Sandbox Code Playgroud) 我试图通过计算着色器在OpenGL中做一些光线跟踪,我遇到了一个奇怪的问题.目前我只想显示没有任何阴影的球体.我的计算着色器为每个像素启动一条光线,如下所示:
#version 430
struct Sphere{
vec4 position;
float radius;
};
struct Ray{
vec3 origin;
vec3 dir;
};
uniform image2D outputTexture;
uniform uint width;
uniform uint height;
float hitSphere(Ray r, Sphere s){
float s_vv = dot(r.dir, r.dir);
float s_ov = dot(r.origin, r.dir);
float s_mv = dot(s.position.xyz, r.dir);
float s_mm = dot(s.position.xyz, s.position.xyz);
float s_mo = dot(s.position.xyz, r.origin);
float s_oo = dot(r.origin, r.origin);
float d = s_ov*s_ov-2*s_ov*s_mv+s_mv*s_mv-s_vv*(s_mm-2*s_mo*s_oo-s.radius*s.radius);
if(d < 0){
return -1.0f;
} else if(d == 0){
return (s_mv-s_ov)/s_vv;
} else { …Run Code Online (Sandbox Code Playgroud) 我正在尝试在我的光线追踪器中为球体实现纹理.我设法得到了一些工作,但我不确定它的正确性.下面是获取纹理坐标的代码.目前,纹理是随机的,并在运行时生成.
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?我将不得不使用其他数学库来摆脱铸造,我会采用浮动方式.