光线追踪 路径追踪
For the past month or so I’ve been working on a passion project in my spare time to build a path tracer. This is the story of why what I created is really bad at its job, but also has a lot to teach about computer generated graphics. If you’d like to cut to the chase, you can see it in action or check out the source code.
在过去大约一个月的时间里,我一直在业余时间从事一个激情项目,以构建路径跟踪器。 这就是为什么我创作的作品确实做起来很糟糕,但是对于计算机生成的图形也有很多启示的故事。 如果您想切入实际,可以查看实际操作或查看源代码。
什么是路径跟踪? (What is path tracing?)
A path tracer is essentially a computer program that makes pretty pictures using some code and a 3D model. That’s it! Like many methods of creating graphics with a computer — think 3D video games or digital animations — there’s no cameras or photo manipulation involved. Just a computer and some mathematics!
路径跟踪器本质上是一种计算机程序,它使用一些代码和3D模型制作漂亮的图片。 而已! 就像使用计算机创建图形的许多方法一样(例如3D视频游戏或数字动画),无需相机或照片处理。 只是一台电脑和一些数学!
Path tracing is a little different to other graphics rendering methods though. It tries a lot harder to mimic the way that real light rays travel through space and bounce off things in the real world. Other methods take shortcuts and try to trick your eyes into thinking they’re looking at a graphic that resembles the real world. Not a path tracer though. Path tracing algorithms are very careful to try and match the way that real light behaves, right down to the way it scatters in random directions off rough surfaces. This means that images produced by a path tracer are some of the most photo realistic you’ll find, but it comes at a cost.
但是,路径跟踪与其他图形渲染方法略有不同。 它更努力地模仿真实光线在太空中传播并反射现实世界中事物的方式。 其他方法则采用捷径,并试图欺骗您的眼睛,使他们认为他们正在看的是类似于真实世界的图形。 虽然不是路径跟踪器。 路径跟踪算法非常谨慎,试图匹配真实光线的行为方式,一直到它在随机方向上从粗糙表面散射的方式。 这意味着由路径跟踪器生成的图像是您可以找到的最真实的照片,但这是有代价的。
Ever heard of ray tracing? If you have it’s probably because Nvidia thrust the concept into the mainstream in 2018 with the release of their RTX line of gaming graphics cards. Only very recently has mainstream graphics hardware become so powerful that it can perform techniques like ray tracing in real time. Path tracing is very closely related to ray tracing, but the reason you may not have heard of path tracing is that it is horrendously slow and can’t be done in real time in games. It’s so much slower than ray tracing that it can take multiple seconds, minutes or even hours to create a single image as opposed to the fractions of a second in which a ray tracer can produce an image in order to create convincing real time animations.
听说过射线追踪吗? 如果有的话,可能是因为Nvidia于2018年通过发布其RTX系列游戏图形卡将这一概念推向了主流。 直到最近,主流图形硬件才变得如此强大,以至于它可以实时执行诸如光线追踪之类的技术。 路径跟踪与光线跟踪非常相关,但是您可能没有听说过路径跟踪的原因是它非常慢且无法在游戏中实时完成。 它比光线跟踪要慢得多,以至于创建单个图像可能要花费几秒钟,几分钟甚至几小时,而不是光线跟踪器可以生成图像以创建令人信服的实时动画的几分之一秒。
为什么编写了错误的路径跟踪器? (Why did you write a bad path tracer?)
Sounds like path tracing is already slow enough to be pretty limited in what it can do right? It certainly is mostly restricted to non-real time applications at the moment, but production grade path tracers are widely used in film and animation. I, however, made a path tracer that is even slower!
听起来好像路径跟踪已经足够慢,以至于它只能做什么就受限制了吗? 目前,它肯定主要限于非实时应用,但是生产级路径跟踪器已广泛用于电影和动画中。 但是,我制作的路径跟踪器甚至更慢!
Most computer generated graphics algorithms rely on casting pretend rays of light through a 3D model of a scene to be rendered, using some maths to determine what they might hit, and how they might bounce when they do. They cast these rays backwards though. They start from where your eye would be if it were in the pretend world of this 3D scene, travel through a pretend ‘screen’ made up of pixels similarly to the way that a real computer screen is, until they collide with a surface in the scene. This is how the algorithm knows what colour to make a given pixel on the screen in the real world; just make it the colour of the object that a ‘light’ ray hits after it passes through the same pixel on the pretend ‘screen’ in the scene. Simple enough.
大多数计算机生成的图形算法都依赖于通过要渲染的场景的3D模型投射假装的光线,使用一些数学运算来确定它们可能会撞到什么,以及在运动时如何反弹。 他们向后投射这些光线。 它们从您在3D场景的假装世界中所处的视线开始,穿过由像素组成的假装“屏幕”,类似于真实计算机屏幕的样子,直到它们与屏幕中的表面碰撞为止。现场。 这就是算法知道现实世界中屏幕上给定像素的颜色的方式。 只需使其成为光线穿过场景中假装的“屏幕”上相同像素后所命中物体的颜色即可。 很简单。
A path tracer isn’t any old graphics algorithm though. Remember how I said path tracers try very hard to mimic real world light, even the way it scatters randomly off rough surfaces? This means that when a path tracer casts a ray through a pixel in a pretend screen it doesn’t stop at the first collision it has with something in the scene. It does some maths to work out how that ray would bounce off the thing it collided with, including some randomisation of direction for rough surfaces, and continues along this new reflected path. It repeats this process many times over and uses the colours of all the things it bounced off to determine what colour the pixel it was cast through should be. This makes for some beautiful, realistic reflections in the images it produces but it also adds a lot of calculations that need to be performed to create said images.
路径跟踪器并不是任何旧的图形算法。 还记得我曾经说过的路径追踪器非常努力地模仿真实世界的光,甚至是它从粗糙表面随机散射的方式吗? 这意味着,当路径跟踪器将光线投射到假装屏幕中的像素上时,它不会在与场景中的物体发生第一次碰撞时停止。 它进行了一些数学运算,以计算出光线如何从与之碰撞的物体上反弹,包括对粗糙表面的方向进行一些随机化,并沿着这条新的反射路径继续前进。 它将重复此过程多次,并使用其反弹的所有物体的颜色来确定投射的像素应为哪种颜色。 这在其产生的图像中产生了一些美丽,逼真的反射,但同时也增加了创建该图像所需的大量计算。
In addition to having to calculate lots of reflection angles for each pixel in an image, the random direction in which a ray is reflected when it hits a rough surface means that the next thing it hits might be different each time an image is rendered. This leads to a speckly image in which pixels end up being random colours based on how their rays were randomly reflected as they bounced through the scene. A path tracing algorithm compensates for this by creating the same image of the same scene many, many times over and averaging them all together. Known as Monte Carlo rendering, this simulates the countless light particles that would actually be scattered off the same part of an object in the real world and lead to a blending of colours from its surroundings being delivered to a viewer’s eye. To produce an end result that is clear and reasonably realistic sometimes takes combining thousands of images of the same scene. That’s thousands of times more calculations that need to be done than if we only needed one image of the scene!
除了必须为图像中的每个像素计算很多反射角外,射线撞击粗糙表面时反射的随机方向还意味着每次渲染图像时,射线撞击的下一个方向可能都不同。 这会导致斑点的图像,其中像素最终基于其光线在场景中反弹时如何被随机反射而成为随机颜色。 路径跟踪算法通过多次创建同一场景的同一图像并将它们平均在一起来对此进行补偿。 这被称为蒙特卡洛渲染,它模拟了无数的光粒子,这些光粒子实际上会从现实世界的对象的同一部分散射出来,并导致其周围环境的色彩混合传递到观看者的眼睛。 为了产生清晰合理的最终结果,有时需要合并同一场景的数千张图像。 这比我们只需要一个场景图像要进行的计算要多数千倍!
It gets even more challenging when you consider that on your 1920x1080 pixel monitor there are 1920 x 1080 = 2073600 pixels that all need a colour each time you want to render a new frame in an animation or a game. That’s a lot of calculations to do for one image! This is where a graphics processor comes in. It turns out that all of those colours can be calculated independently of one another. The path that one light ray takes as it passes through a pixel in the screen and what it collides with on the other side is completely unaffected by what path another might take and what it collides with; light rays don’t crash into one another mid flight! So you could calculate all the colours that every pixel needs to be for a given image at the same time. Graphics processors are really good at doing lots of calculations at the same time. Modern GPUs have thousands of cores that can each be doing their own thing in parallel. This is what makes them great for rendering computer generated images quickly. Much more quickly than a central processing unit for instance. The quad core CPU in your average laptop can only do 4 different things at once.
当您考虑到1920 x 1080像素监视器上的1920 x 1080 = 2073600像素时,每次要在动画或游戏中渲染新帧时都需要一种颜色,这就变得更具挑战性。 对于一张图像,要进行大量的计算! 这是图形处理器的用武之地。事实证明,所有这些颜色都可以彼此独立地计算。 一条光线穿过屏幕上的像素时所采取的路径以及与另一侧发生碰撞的路径完全不受另一条可能采取的路径以及与之碰撞的路径的影响。 光线不会在飞行途中撞向对方! 因此,您可以同时计算给定图像的每个像素所需的所有颜色。 图形处理器确实擅长于同时进行大量计算。 现代GPU具有数千个内核,每个内核可以并行执行自己的任务。 这就是使它们非常适合快速渲染计算机生成的图像的原因。 比起中央处理单元要快得多。 您的普通笔记本电脑中的四核CPU一次只能执行4种不同的操作。
Running a path tracing algorithm is clearly a lot of work to do, even if it’s running on a GPU, but I wrote my path tracer in a code language called JavaScript which runs on the CPU and is single threaded to boot, which means that it can’t even take advantage of those measly 4 cores! It can only use one at a time!
运行路径跟踪算法显然是很多工作,即使它在GPU上运行也是如此,但是我用一种称为JavaScript的代码语言编写了路径跟踪器,该语言在CPU上运行并且是单线程启动的,这意味着它甚至无法利用那些仅4个内核! 一次只能使用一个!
So how atrocious is this path tracer you might ask? It’s actually not terrible. It turns out modern computers are pretty darn fast even if you’re only using one of the potentially thousands of processing cores available across the CPU and GPU. It can create recognisable if not amazing images within a minute or two on my 2016 MacBook Pro, and pretty attractive renders in 15 minutes or so.
因此,如何在恶劣的这个路径追踪你可能会问? 实际上并不可怕。 事实证明,即使您仅使用CPU和GPU上可能存在的数千个处理内核之一,现代计算机的速度也相当快。 它可以在我的2016 MacBook Pro上在一两分钟之内创建出即使不是令人惊叹的图像,也可以在15分钟左右的时间内创建漂亮的渲染。
I also didn’t build it to be a state of the art, production ready tool to be used in the next Star Wars film; there are already a few of those around that do a much better job than I ever could (check out Blender if you’re interested in playing with one). I built it for fun, to teach myself more about how computer graphics work, and hopefully to teach other people too.
我也没有将其构建为可在下一部《星球大战》电影中使用的最先进的生产就绪工具。 已经有一些人比我做得更好(如果您有兴趣与一个人玩耍,请查看Blender )。 我创建它的目的很有趣,可以教自己更多有关计算机图形学的知识,并希望也可以教其他人。
说到…… (Speaking of which …)
If you’re interested in trying something like this yourself then take a look at the source code which is available on Gitlab. It’s designed to be easier to follow than the shader code that makes up other path tracers which, while it allows for running programs on a graphics processor, can be a little confusing if you’re new to the world of computer graphics. It also runs in a web browser which is pretty neat (check it out here! Chrome only for now).
如果您有兴趣自己尝试类似的事情,请查看Gitlab上提供的源代码。 它被设计为比组成其他路径跟踪器的着色器代码更易于遵循,虽然它允许在图形处理器上运行程序,但是如果您不熟悉计算机图形学,可能会有些困惑。 它也可以在非常整洁的网络浏览器中运行(在此处查看!仅适用于Chrome)。
I also highly recommend this tutorial by Rye Terrell on which I based most of my work. The example there also runs in a web browser but uses WebGL shader code instead of JavaScript so it will run on your graphics card instead of your CPU and is therefore way faster than my effort.
我也强烈推荐Rye Terrell撰写的本教程,我将大部分工作作为本教程的基础。 这个例子也有运行在Web浏览器,但使用WebGL的着色器代码,而不是JavaScript以将您的显卡,而不是你的CPU上运行,因此方式比我努力得更快。
If you want to know more feel free to post questions in the comments. Check out nomossgames.com and nomoss.co to see what our game development studio and tech consultancy has been up to recently.
如果您想了解更多信息,请随时在评论中发表问题。 请访问nomossgames.com和nomoss.co,以了解我们的游戏开发工作室和技术咨询最近的发展。
翻译自: https://medium.com/nomoss/how-to-write-a-bad-path-tracer-7b0e2795811d
光线追踪 路径追踪