我正在尝试并行化光线跟踪器.这意味着我有一个很长的小计算列表.vanilla程序在67.98秒内在特定场景上运行,总内存使用量为13 MB,生产率为99.2%.
在我的第一次尝试中,我使用parBuffer了缓冲区大小为50 的并行策略.我之所以选择parBuffer它是因为它只是在消耗火花的情况下遍历列表,并且不会强制列表的主干parList,这会占用大量内存因为清单很长.有了-N2它,它运行时间为100.46秒,总内存使用量为14 MB,生产率为97.8%.火花信息是:SPARKS: 480000 (476469 converted, 0 overflowed, 0 dud, 161 GC'd, 3370 fizzled)
大部分失败的火花表明火花的粒度太小,所以接下来我尝试使用策略parListChunk,将列表分成块并为每个块创建一个火花.我得到了最好的结果,大小为0.25 * imageWidth.该程序运行时间为93.43秒,总内存使用量为236 MB,生产率为97.3%.火花信息是:SPARKS: 2400 (2400 converted, 0 overflowed, 0 dud, 0 GC'd, 0 fizzled).我相信更大的内存使用是因为parListChunk强制列表的主干.
然后我试着编写自己的策略,懒洋洋地将列表分成块,然后传递块parBuffer并连接结果.
concat $ withStrategy (parBuffer 40 rdeepseq) (chunksOf 100 (map colorPixel pixels))
Run Code Online (Sandbox Code Playgroud)
这运行时间为95.99秒,总内存使用量为22MB,生产率为98.8%.在所有火花都被转换并且内存使用率低得多的意义上,这是成功的,但速度没有提高.以下是事件日志配置文件的一部分图像.
正如您所看到的,由于堆溢出,线程正在停止.我尝试添加+RTS -M1G,它将默认堆大小一直增加到1Gb.结果没有改变.我读到如果堆栈溢出,Haskell主线程将使用堆中的内存,所以我也尝试增加默认堆栈大小,+RTS -M1G -K1G但这也没有影响.
还有什么我可以尝试的吗?如果需要,我可以发布更详细的内存使用情况或事件日志的分析信息,我没有全部包含它,因为它是很多信息,我不认为所有这些都是必要的.
编辑:我正在阅读有关Haskell RTS多核支持的内容,并且它讨论了每个内核都有一个HEC(Haskell执行上下文).除了别的以外,每个HEC都包含一个分配区域(它是单个共享堆的一部分).每当HEC的分配区域耗尽时,必须执行垃圾收集.似乎是一个控制它的RTS选项,-A.我试过-A32M,但没有看到任何区别.
EDIT2: 这是一个专门针对这个问题的github仓库的链接 …
我正在修补Joost van Dongen的内部映射着色器,我正在尝试实现自我阴影.我仍然无法弄清楚阴影投射光矢量需要的坐标.你可以在这里看到一些有用的演示 我已经附加了光线位置,偏移到相机位置只是为了看看发生了什么,但显然它没有看起来也不错.着色器代码如下.在片段着色器中查找SHADOWS DEV.有问题的向量是:shad_E和shad_I.
顶点着色器:
varying vec3 oP; // surface position in object space
varying vec3 oE; // position of the eye in object space
varying vec3 oI; // incident ray direction in object space
varying vec3 shad_E; // shadow light position
varying vec3 shad_I; // shadow direction
uniform vec3 lightPosition;
void main() {
// inverse veiw matrix
mat4 modelViewMatrixInverse = InverseMatrix( modelViewMatrix );
// surface position in object space
oP …Run Code Online (Sandbox Code Playgroud) 我正在写一个基于平铺的小游戏,为此我想支持光源.但是我的算法太弱了,所以我来找你帮忙.
情况是这样的:有一个基于图块的地图(作为二维阵列保存),包含一个光源和几个站在周围的物品.我想计算哪些瓷砖被光源点亮,哪些瓷砖处于阴影中.
大约是它的外观的视觉辅助.L是光源,X是阻挡光线的项目,0是点亮的瓷砖,-s是阴影中的瓷砖.
0 0 0 0 0 0 - - 0
0 0 0 0 0 0 - 0 0
0 0 0 0 0 X 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 L 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 X X X X 0 0
0 0 0 - - - - - 0
0 0 - - - …Run Code Online (Sandbox Code Playgroud) 在对光栅化和光线追踪进行了一些研究之后.我发现没有太多关于CPU如何在互联网上提供光线跟踪的信息.我偶然发现了关于皮克斯的文章,以及他们如何在CPU上预渲染汽车2.这花了他们每帧11.5小时.GPU是否会以相同的图像质量更快地渲染? http://gizmodo.com/5813587/12500-cpu-cores-were-required-to-render-cars-2 https://www.engadget.com/2014/10/18/disney-big-hero-6/ http://www.firstshowing.net/2009/michael-bay-presents-transformers-2-facts-and-figures/ 干杯,萨姆
我有兴趣找到关于编写光线跟踪器的书籍的建议,可以在网上看到的简单而清晰的光线跟踪实现,以及关于介绍光线跟踪的在线资源.
理想情况下,该方法将是渐进式和教学式的,并从基础开始解释编程技术和基础数学.
我正在做一个光线跟踪器爱好项目,最初我使用的是我的Vector和Ray对象的结构,我认为光线跟踪器是使用它们的完美情况:你创造了数百万个它们,它们的寿命不长于单个方法,它们很轻巧.但是,通过简单地在Vector和Ray上将'struct'更改为'class',我获得了非常显着的性能提升.
是什么赋予了?它们都很小(Vector为3个浮点数,Ray为2个向量),不要过度复制.当然,我确实将它们传递给方法,但这是不可避免的.那么在使用结构时会导致性能下降的常见缺陷是什么?我已阅读此 MSDN文章,其中说明如下:
运行此示例时,您将看到struct循环的速度提高了几个数量级.但是,当您将ValueTypes视为对象时,请注意使用ValueTypes.这会给你的程序增加额外的装箱和拆箱开销,并且最终会比你坚持使用物品时花费更多!要查看此操作,请修改上面的代码以使用foos和bar数组.你会发现性能或多或少相等.
然而它已经很老了(2001年)而整个"把它们放在一个阵列导致拳击/拆箱"让我觉得奇怪.真的吗?但是,我确实预先计算了主光线并将它们放在一个数组中,所以我接受了这篇文章,并在我需要时计算了主光线并且从未将它们添加到数组中,但它没有改变任何东西:课程,它仍然快1.5倍.
我正在运行.NET 3.5 SP1,我相信修复了一个问题,即struct方法没有内联,所以也不可能.
所以基本上:任何提示,需要考虑的事项和避免的事项?
编辑:正如在一些答案中所建议的那样,我已经设置了一个测试项目,我尝试将结构作为参考传递.添加两个向量的方法:
public static VectorStruct Add(VectorStruct v1, VectorStruct v2)
{
return new VectorStruct(v1.X + v2.X, v1.Y + v2.Y, v1.Z + v2.Z);
}
public static VectorStruct Add(ref VectorStruct v1, ref VectorStruct v2)
{
return new VectorStruct(v1.X + v2.X, v1.Y + v2.Y, v1.Z + v2.Z);
}
public static void Add(ref VectorStruct v1, ref VectorStruct v2, out VectorStruct v3)
{
v3 = new VectorStruct(v1.X + v2.X, v1.Y + v2.Y, v1.Z + v2.Z);
}
Run Code Online (Sandbox Code Playgroud)
对于每个我得到以下基准方法的变体: …
所以,我应该开始点亮我的平面彩色模特.测试应用程序是仅实现最新方法的测试用例,因此我意识到理想情况下它应该实现光线跟踪(从理论上讲,它可能是几年内实时图形的理想选择).
但是我从哪里开始呢?
假设我从未在旧的OpenGL中完成照明,所以我将直接使用不推荐的方法.
应用程序当前正确设置了顶点缓冲区对象,顶点,法线和颜色输入,并以平面颜色正确绘制和转换空间模型.
是否存在从平坦的彩色顶点到通过GLSL获得正确最终结果所需的全部信息的来源?理想情况下,可能需要任何其他额外的照明方法来补充它.
我在上学期为一项任务写了一篇Ray Tracer,并希望继续努力.在赋值中有5种材料(用于对象),我们得到了它们的环境,漫反射,镜面反射和光泽值.我很难找到这些值的列表来在线创建新材料(其中一个也包括折射指数会非常棒)并且想知道是否有人知道这是一个很好的资源.
这是迄今为止我发现的最好的一种,但它没有那么多的材料和具有折射率的材料没有我上面提到的其他值:http://www.nicoptere.net/dump/ materials.html
我从来没有为Ray Tracer做过折射(计划好好学习它),欢迎任何一般建议.
我正在打扫我的一个旧项目.它必须做的事情之一是 - 给定一个笛卡尔网格系统,并在网格上有两个正方形,找到所有正方形的列表,连接这两个正方形的中心的线将通过.
这里的特殊情况是所有起点和终点都被限制在正方形/单元的确切中心.
以下是一些示例 - 包含样本起点和终点对.阴影方块是应由相应函数调用返回的方块
删除了死的ImageShack链接 - 例子
的起始和结束点由它们在方块表示.另外,在上述画面中,假定左下方是[1,1],在右下角的线将被识别为[6,2]至[9,5].
也就是说,从(的中心)正方形上从左边第六列,上(的中心)的第二行从底部方上从左侧第九列,从底部起的第五行上
这真的不那么复杂.但是,我似乎在网上找到了一些复杂的算法并实现了它.
我记得它非常非常快.比如,每帧数百或数千倍的优化速度.
基本上,它沿着直线从边界跳到正方形的边界(线与网格线交叉的点).它知道下一个交叉点的位置是通过查看哪个交叉点更接近 - 水平的或垂直的 - 然后移动到下一个交叉点.
这在概念上是好的,但实际的实现结果非常不那么漂亮,而且我担心优化程度可能太高而不是我实际需要的(我称之为遍历)算法可能每分钟五到六次).
是否有简单易懂的透明直线网格遍历算法?
在计划方面:
def traverse(start_point,end_point)
# returns a list of all squares that this line would pass through
end
Run Code Online (Sandbox Code Playgroud)
给定坐标识别方块本身.
一些例子:
traverse([0,0],[0,4])
# => [0,0], [0,1], [0,2], [0,3], [0,4]
traverse([0,0],[3,2])
# => [0,0], [0,1], [1,1], [2,1], [2,2], [3,2]
traverse([0,0],[3,3])
# => [0,0], [1,1], [2,2], [3,3]
Run Code Online (Sandbox Code Playgroud)
请注意,直接通过角落的线条不应包括线条"翼"上的方块.
(好的'Bresenham'可能会在这里工作,但它有点落后于我想要的东西.据我所知,为了使用它,我基本上必须将它应用到线上,然后扫描每个方块上的网格为真或假.对于大网格而言不可行 - 或者至少是不优雅的) …
我目前正在研究光线跟踪器,只是为了好玩而且我在折射处理方面遇到了麻烦.
整个光线跟踪器的代码源可以在Github上找到.
这是渲染的图像:
右侧球体的折射率为1.5(玻璃).
在折射的基础上,我想处理一个"透明度"系数,其定义如下:
该球体的透明度为1.
这是处理折射部分的代码.它可以在github上找到.
Color handleTransparency(const Scene& scene,
const Ray& ray,
const IntersectionData& data,
uint8 depth)
{
Ray refracted(RayType::Transparency, data.point, ray.getDirection());
Float_t eta = data.material->getRefraction();
if (eta != 1 && eta > Globals::Epsilon)
refracted.setDirection(Tools::Refract(ray.getDirection(), data.normal, eta));
refracted.setOrigin(data.point + Globals::Epsilon * refracted.getDirection());
return inter(scene, refracted, depth + 1);
}
// http://graphics.stanford.edu/courses/cs148-10-summer/docs/2006--degreve--reflection_refraction.pdf
Float_t getFresnelReflectance(const IntersectionData& data, const Ray& ray)
{
Float_t n = data.material->getRefraction();
Float_t cosI = -Tools::DotProduct(ray.getDirection(), data.normal); …Run Code Online (Sandbox Code Playgroud)