Перейти к содержимому

Directx raytracing что это

  • автор:

Announcing Microsoft DirectX Raytracing!

If you just want to see what DirectX Raytracing can do for gaming, check out the videos from Epic, Futuremark and EA, SEED. To learn about the magic behind the curtain, keep reading.

3D Graphics is a Lie

For the last thirty years, almost all games have used the same general technique—rasterization—to render images on screen. While the internal representation of the game world is maintained as three dimensions, rasterization ultimately operates in two dimensions (the plane of the screen), with 3D primitives mapped onto it through transformation matrices. Through approaches like z-buffering and occlusion culling, games have historically strived to minimize the number of spurious pixels rendered, as normally they do not contribute to the final frame. And in a perfect world, the pixels rendered would be exactly those that are directly visible from the camera:

Figure 1a: a top-down illustration of various pixel reduction techniques. Top to bottom: no culling, view frustum culling, viewport clipping

Figure 1b: back-face culling, z-buffering

Through the first few years of the new millennium, this approach was sufficient. Normal and parallax mapping continued to add layers of realism to 3D games, and GPUs provided the ongoing improvements to bandwidth and processing power needed to deliver them. It wasn’t long, however, until games began using techniques that were incompatible with these optimizations. Shadow mapping allowed off-screen objects to contribute to on-screen pixels, and environment mapping required a complete spherical representation of the world. Today, techniques such as screen-space reflection and global illumination are pushing rasterization to its limits, with SSR, for example, being solved with level design tricks, and GI being solved in some cases by processing a full 3D representation of the world using async compute. In the future, the utilization of full-world 3D data for rendering techniques will only increase.

Figure 2: a top-down view showing how shadow mapping can allow even culled geometry to contribute to on-screen shadows in a scene

Today, we are introducing a feature to DirectX 12 that will bridge the gap between the rasterization techniques employed by games today, and the full 3D effects of tomorrow. This feature is DirectX Raytracing. By allowing traversal of a full 3D representation of the game world, DirectX Raytracing allows current rendering techniques such as SSR to naturally and efficiently fill the gaps left by rasterization, and opens the door to an entirely new class of techniques that have never been achieved in a real-time game. Readers unfamiliar with rasterization and raytracing will find more information about the basics of these concepts in the appendix below.

What is DirectX Raytracing?

At the highest level, DirectX Raytracing (DXR) introduces four, new concepts to the DirectX 12 API:

  1. The acceleration structure is an object that represents a full 3D environment in a format optimal for traversal by the GPU. Represented as a two-level hierarchy, the structure affords both optimized ray traversal by the GPU, as well as efficient modification by the application for dynamic objects.
  2. A new command list method, DispatchRays, which is the starting point for tracing rays into the scene. This is how the game actually submits DXR workloads to the GPU.
  3. A set of new HLSL shader types including ray-generation, closest-hit, any-hit, and miss shaders. These specify what the DXR workload actually does computationally. When DispatchRays is called, the ray-generation shader runs. Using the new TraceRay intrinsic function in HLSL, the ray generation shader causes rays to be traced into the scene. Depending on where the ray goes in the scene, one of several hit or miss shaders may be invoked at the point of intersection. This allows a game to assign each object its own set of shaders and textures, resulting in a unique material.
  4. The raytracing pipeline state, a companion in spirit to today’s Graphics and Compute pipeline state objects, encapsulates the raytracing shaders and other state relevant to raytracing workloads.

You may have noticed that DXR does not introduce a new GPU engine to go alongside DX12’s existing Graphics and Compute engines. This is intentional – DXR workloads can be run on either of DX12’s existing engines. The primary reason for this is that, fundamentally, DXR is a compute-like workload. It does not require complex state such as output merger blend modes or input assembler vertex layouts. A secondary reason, however, is that representing DXR as a compute-like workload is aligned to what we see as the future of graphics, namely that hardware will be increasingly general-purpose, and eventually most fixed-function units will be replaced by HLSL code. The design of the raytracing pipeline state exemplifies this shift through its name and design in the API. With DX12, the traditional approach would have been to create a new CreateRaytracingPipelineState method. Instead, we decided to go with a much more generic and flexible CreateStateObject method. It is designed to be adaptable so that in addition to Raytracing, it can eventually be used to create Graphics and Compute pipeline states, as well as any future pipeline designs.

Anatomy of a DXR Frame

The first step in rendering any content using DXR is to build the acceleration structures, which operate in a two-level hierarchy. At the bottom level of the structure, the application specifies a set of geometries, essentially vertex and index buffers representing distinct objects in the world. At the top level of the structure, the application specifies a list of instance descriptions containing references to a particular geometry, and some additional per-instance data such as transformation matrices, that can be updated from frame to frame in ways similar to how games perform dynamic object updates today. Together, these allow for efficient traversal of multiple complex geometries.

Figure 3: Instances of 2 geometries, each with its own transformation matrix

The second step in using DXR is to create the raytracing pipeline state. Today, most games batch their draw calls together for efficiency, for example rendering all metallic objects first, and all plastic objects second. But because it’s impossible to predict exactly what material a particular ray will hit, batching like this isn’t possible with raytracing. Instead, the raytracing pipeline state allows specification of multiple sets of raytracing shaders and texture resources. Ultimately, this allows an application to specify, for example, that any ray intersections with object A should use shader P and texture X, while intersections with object B should use shader Q and texture Y. This allows applications to have ray intersections run the correct shader code with the correct textures for the materials they hit.

The third and final step in using DXR is to call DispatchRays, which invokes the ray generation shader. Within this shader, the application makes calls to the TraceRay intrinsic, which triggers traversal of the acceleration structure, and eventual execution of the appropriate hit or miss shader. In addition, TraceRay can also be called from within hit and miss shaders, allowing for ray recursion or “multi-bounce” effects.

Figure 4: an illustration of ray recursion in a scene

Note that because the raytracing pipeline omits many of the fixed-function units of the graphics pipeline such as the input assembler and output merger, it is up to the application to specify how geometry is interpreted. Shaders are given the minimum set of attributes required to do this, namely the intersection point’s barycentric coordinates within the primitive. Ultimately, this flexibility is a significant benefit of DXR; the design allows for a huge variety of techniques without the overhead of mandating particular formats or constructs.

PIX for Windows Support Available on Day 1

As new graphics features put an increasing array of options at the disposal of game developers, the need for great tools becomes increasingly important. The great news is that PIX for Windows will support the DirectX Raytracing API from day 1 of the API’s release. PIX on Windows supports capturing and analyzing frames built using DXR to help developers understand how DXR interacts with the hardware. Developers can inspect API calls, view pipeline resources that contribute to the raytracing work, see contents of state objects, and visualize acceleration structures. This provides the information developers need to build great experiences using DXR.

What Does This Mean for Games?

DXR will initially be used to supplement current rendering techniques such as screen space reflections, for example, to fill in data from geometry that’s either occluded or off-screen. This will lead to a material increase in visual quality for these effects in the near future. Over the next several years, however, we expect an increase in utilization of DXR for techniques that are simply impractical for rasterization, such as true global illumination. Eventually, raytracing may completely replace rasterization as the standard algorithm for rendering 3D scenes. That said, until everyone has a light-field display on their desk, rasterization will continue to be an excellent match for the common case of rendering content to a flat grid of square pixels, supplemented by raytracing for true 3D effects.

Project PICA PICA from SEED, Electronic Arts

And, our friends at EPIC, with collaboration from ILMxLAB and NVIDIA, have also put together a stunning technology demo with some characters you may recognize.

Of course, what new PC technology would be complete without support from Futuremark benchmark? Fortunately, Futuremark has us covered with their own incredible visuals.

In addition, while today marks the first public announcement of DirectX Raytracing, we have been working closely with hardware vendors and industry developers for nearly a year to design and tune the API. In fact, a significant number of studios and engines are already planning to integrate DXR support into their games and engines, including:

Electronic Arts, Frostbite

Electronic Arts, SEED

Epic Games, Unreal Engine

Unity Technologies, Unity Engine

And more will be coming soon.

What Hardware Will DXR Run On?

Developers can use currently in-market hardware to get started on DirectX Raytracing. There is also a fallback layer which will allow developers to start experimenting with DirectX Raytracing that does not require any specific hardware support. For hardware roadmap support for DirectX Raytracing, please contact hardware vendors directly for further details.

Available now for experimentation!

Want to be one of the first to bring real-time raytracing to your game? Start by attending our Game Developer Conference Session on DirectX Raytracing for all the technical details you need to begin, then download the Experimental DXR SDK and start coding! Not attending GDC? No problem! Click here to see our GDC slides.

Appendix – Primers on rasterization, raytracing and DirectX Raytracing

Intro to Rasterization

Of all the rendering algorithms out there, by far the most widely used is rasterization. Rasterization has been around since the 90s and has since become the dominant rendering technique in video games. This is with good reason: it’s incredibly efficient and can produce high levels of visual realism.

Rasterization is an algorithm that in a sense doesn’t do all its work in 3D. This is because rasterization has a step where 3D objects get projected onto your 2D monitor, before they are colored in. This work can be done efficiently by GPUs because it’s work that can be done in parallel: the work needed to color in one pixel on the 2D screen can be done independently of the work needed to color one the pixel next to it.

There’s a problem with this: in the real world the color of one object will have an impact on the objects around it, because of the complicated interplay of light. This means that developers must resort to a wide variety of clever techniques to simulate the visual effects that are normally caused by light scattering, reflecting and refracting off objects in the real world. The shadows, reflections and indirect lighting in games are made with these techniques.

Games rendered with rasterization can look and feel incredibly lifelike, because developers have gotten extremely good at making it look as if their worlds have light that acts in convincing way. Having said that, it takes an incredible deal of technical expertise to do this well and there’s also an upper limit to how realistic a rasterized game can get, since information about 3D objects gets lost every time they get projected onto your 2D screen.

Intro to Raytracing

Raytracing calculates the color of pixels by tracing the path of light that would have created it and simulates this ray of light’s interactions with objects in the virtual world. Raytracing therefore calculates what a pixel would look like if a virtual world had real light. The beauty of raytracing is that it preserves the 3D world and visual effects like shadows, reflections and indirect lighting are a natural consequence of the raytracing algorithm, not special effects.

Raytracing can be used to calculate the color of every single pixel on your screen, or it can be used for only some pixels, such as those on reflective surfaces.

How does it work?

A ray gets sent out for each pixel in question. The algorithm works out which object gets hit first by the ray and the exact point at which the ray hits the object. This point is called the first point of intersection and the algorithm does two things here: 1) it estimates the incoming light at the point of intersection and 2) combines this information about the incoming light with information about the object that was hit.

1) To estimate what the incoming light looked like at the first point of intersection, the algorithm needs to consider where this light was reflected or refracted from.

2) Specific information about each object is important because objects don’t all have the same properties: they absorb, reflect and refract light in different ways:

– different ways of absorption are what cause objects to have different colors (for example, a leaf is green because it absorbs all but green light)

– different rates of reflection are what cause some objects to give off mirror-like reflections and other objects to scatter rays in all directions

– different rates of refraction are what cause some objects (like water) to distort light more than other objects.

Often to estimate the incoming light at the first point of intersection, the algorithm must trace that light to a second point of intersection (because the light hitting an object might have been reflected off another object), or even further back.

Savvy readers with some programming knowledge might notice some edge cases here.

Sometimes light rays that get sent out never hit anything. Don’t worry, this is an edge case we can cover easily by measuring for how far a ray has travelled so that we can do additional work on rays that have travelled for too far.

The second edge case covers the opposite situation: light might bounce around so much that it’ll slow down the algorithm, or an infinite number of times, causing an infinite loop. The algorithm keeps track of how many times a ray gets traced after every step and gets terminated after a certain number of reflections. We can justify doing this because every object in the real world absorbs some light, even mirrors. This means that a light ray loses energy (becomes fainter) every time it’s reflected, until it becomes too faint to notice. So even if we could, tracing a ray an arbitrary number of times doesn’t make sense.

What is the state of raytracing today?

Raytracing a technique that’s been around for decades. It’s used quite often to do CGI in films and several games already use forms of raytracing. For example, developers might use offline raytracing to do things like pre-calculating the brightness of virtual objects before shipping their games.

No games currently use real-time raytracing, but we think that this will change soon: over the past few years, computer hardware has become more and more flexible: even with the same TFLOPs, a GPU can do more.

How does this fit into DirectX?

We believe that DirectX Raytracing will bring raytracing within reach of real-time use cases, since it comes with dedicated hardware acceleration and can be integrated seamlessly with existing DirectX 12 content.

This means that it’s now possible for developers to build games that use rasterization for some of its rendering and raytracing to be used for the rest. For example, developers can build a game where much of the content is generated with rasterization, but DirectX Raytracing calculates the shadows or reflections, helping out in areas where rasterization is lacking.

This is the power of DirectX Raytracing: it lets developers have their cake and eat it.

Что такое рейтрейсинг и как работает трассировка лучей в играх

Ray-Traycing (рейтрейсинг) или так называемая трассировка лучей (DXR), хоть и была известна до релиза видеокарт NVIDIA RTX, но после их выпуска на массовый рынок стала особо на слуху в игровом сообществе. NVIDIA удалось первой внедрить трассировку лучей в режиме реального времени в компьютерных играх, но разработчики этих самых игр не сильно-то и торопятся внедрять технологию RTX в свои проекты. Чтобы понять, кому и для чего нужна трассировка, для начала мы постараемся разъяснить, как работает рейтрейсинг, а также попробуем проанализировать рынок игр с поддержкой RTX и понять, стоит ли собирать игровой ПК для проектов с поддержкой DXR.

Что такое Ray-Traycing (рейтрейсинг)?

Как и в школьной программе по физике, перед изучением новой темы, начнем с определения термина. Рейтрейсинг – это техника рендеринга, которая использует принципы реальных физических процессов. Для того, чтобы построить трехмерную модель какого-либо объекта и применить к ней трассировку лучей, система отслеживает траекторию виртуального луча к этому объекту. При этом, системе нужно учитывать поверхность объекта и свойства его материала. Ну, и наконец, свет отслеживается с помощью нескольких лучей, имитирующих отраженный свет. Так и происходит трассировка лучей, которая учитывает преломления, отражения лучей, а также корректное взаимодействие света с любыми поверхностями, в том числе и зеркальными. К слову, после отражения света от объекта, свет, возможно, изменил свой цвет — и это системе тоже нужно учесть.

В теории, рейтрейсинг – простой процесс, корни которого идут из физики, а сама трассировка – далеко не новинка. Но всё просто только в теории. На практике, трассировка лучей – невероятно трудоемка с технической стороны, ведь часть лучей может не отразиться вообще, часть – отразиться всего пару раз, а некоторые лучи в рамках одной сцены могут отражаться бесконечное количество раз. И чтобы всё отражалось корректно, системе нужно обсчитать абсолютно каждый луч. Полностью точный и корректный рейтрейсинг требует очень высоких вычислительных мощностей железа, но даже в этом случае, это весьма длительный процесс.

К слову, «киношники» уже давно используют эту технологию при производстве фильмов. Вы могли видеть рейтрейсинг в кинематографе, к примеру, в фильме «Трон» 1982 года выпуска. Обычно, трассировка лучей в фильмах добавляется на стадии монтажа, поэтому создателям фильмов не нужно рассчитывать поведение источников света в реальном времени. Им достаточно это сделать один раз при рендеринге ленты. Но даже в таком случае, просчет лучей на одном кадре может занимать множество часов. А вот в играх разработчики никогда не смогут заранее предугадать, куда пойдет игрок и с какой стороны будет смотреть на объект, чтобы просчитать отражения и преломления лучей один раз, как это делают в кино. Поэтому в играх речь идет исключительно о трассировке лучей в реальном времени, а это невероятно трудоемкий процесс. Именно из-за сложности рейтрейсинга, его «приход» в игровую индустрию сильно задержался.

«Свет в конце тоннеля» или как NVIDIA принесла рейтрейсинг в игровую индустрию

Когда никто не ждал появления рейтрейсинга в играх ещё столько же, сколько его и не было, NVIDIA ворвалась на массовый потребительский рынок с видеокартами GeForce RTX на основе архитектуры Turing, которые помимо стандартного увеличения производительности в играх в рамках поколения привнесли технологию RTX в ряд совместимых игр. Видеокарты оснащены RT-ядрами, отвечающими за расчет трассировки лучей в режиме реального времени, и в дополнение поддерживают новую технологию сглаживания DLSS на основе машинного обучения. Итак, что произошло? NVIDIA первой внедрила аппаратную поддержку рейтрейсинга в компьютерных играх (RTX), а просчет лучей происходит в режиме реального времени с помощью специальных тензорных RT-ядер. Все новые карты основываются на архитектуре NVIDIA с кодовым названием Turing, созданной на 12-нм техническом процессе. Именно она позволяет в реальном времени обрабатывать отражения световых лучей, помогая сделать графику в играх в разы более реалистичной и кинематографичной.

Как работает трассировка лучей (DXR) в играх? На самом деле, немного по-хитрому. Трассирование лучей не предполагает применение на всю сцену, которая в теории может быть невероятно огромна. Поэтому здесь используется гибридный метод классических технологий освещения и непосредственно трассировки. Но когда рейтрейсинг активен, то отрабатывает он честно, выдавая шикарные эффекты отражений, теней и освещения. Также нельзя забывать, что графические настройки игры (низкие – средние – высокие – ультра) регулируют число проходов трассировщика и выбирают, где использовать обычные методы, а где DXR. Ну, и наконец, применяется такой прием, как сегментирование изображения. Он определяет, где нужно участие RT-ядер в обработке кадра. От этого зависит практически все, начиная от плотности лучей, заканчивая дальностью прорисовки отражений.

К слову, количество вышеупомянутых RT-ядер в видеокарте определяет производительность в играх при включенной трассировке. Логично, что RTX 2060, самая младшая видеокарта в линейке GeForce RTX, оснащена меньшим количеством RT-ядер, чем, например, RTX 2080, поэтому её производительность при включенной трассировке на тех же настройках и разрешении монитора заметно ниже. «Сгладить» этот момент призвана новая технология сглаживания NVIDIA DLSS, при включении которой можно повысить заветный fps (количество кадров в секунду).

Технология суперсэмплинга DLSS на основе машинного обучения

DLSS – это технология суперсэмплинга (сглаживания), которая работает и обучается при помощи нейросетей. Если и сейчас непонятно, то ничего страшного. Здесь всё очень просто. DLSS – это, по сути, самое обычное сглаживание краев на игровых объектах, но если обычное сглаживание использует мощности GPU (графического чипа) видеокарты, то для работы DLSS, NVIDIA выделила отдельный тензорный блок в чипе, оптимизированный для работы нейросетями. И чем больше данных доступно ИИ, тем лучше его производительность и результат в сглаживании. Разумеется, включение DLSS значительно уменьшает нагрузку с GPU видеокарты, поэтому он наиболее эффективен в играх на разрешении 4К, где обычное сглаживание потребляет невероятно много ресурсов видеочипа. Плюс, глубокое обучение нейросетей DLSS позволяет со временем еще больше увеличить производительность в играх, как при включенной трассировке лучей, так и без неё.

GeForce RTX SUPER – еще более производительная трассировка лучей в играх!

Недавно NVIDIA представила и выпустила на рынок новые видеокарты RTX с приставкой «SUPER» в названии. Обновление получили три модели – RTX 2060, RTX 2070 и RTX 2080. Все refresh-версии отличаются от «стандартных» более мощным графическим процессором, а также увеличенным количеством RT-ядер для обработки трассировки лучей. Всё это помогло увеличить производительность в играх в среднем на 15%, а в некоторых играх прирост доходит вплоть до 24%.

По всей видимости, NVIDIA, выпуская на рынок обычные GeForce RTX оставили скрытый запас мощности, который как раз-таки и пригодился для того, чтобы спустя определенное время полностью раскрыть видеокарты линейки RTX. К слову, компании AMD, главным конкурентам NVIDIA на рынке игровых видеокарт, не чем ответить на видеокарты GeForce RTX. NVIDIA первой удалось внедрить рейтрейсинг в массы, в то время как AMD только-только изучает возможности данной технологии. Именно поэтому игровые решения «красных» без поддержки RTX стоят дешевле, чем карты «зеленых», которые наделены тензорными RT-ядрами.

Главные проблемы рейтрейсинга в играх

«Ок, рейтрейсинг – это круто! Но неужели всё так гладко?» — резонно скажете Вы. Да, действительно, трассировка лучей – важная составляющая графики в играх. Она выводит качество картинки на совершенно новый уровень, добавляет кинематографичности для создания насыщенных визуальных эффектов, о которых раньше никто и мечтать не мог. Но всё-таки у рейтрейсинга есть несколько глобальных проблем:

Очень большая «нагрузка» на производительность.

Не так много игр с поддержкой трассировки лучей RTX

Рейтрейсинг, как мы уже упоминали ранее, требует больших вычислительных мощностей. Даже оптимизированные специально под эту задачу видеокарты GeForce RTX не всегда справляются с трассировкой в играх, особенно на высоких разрешениях. Разумеется, NVIDIA совместно с разработчиками игр регулярно выпускает обновления драйверов, улучшающих работу рейтрейсинга, но порой даже самая мощная видеокарта в линейке, RTX 2080 Ti, не всегда справляется с нагрузкой при включенном RTX, в 4К-разрешении и на максимальных графических настройках.

«Но там, где стол был яств, там гроб стоит» — если первая проблема решается усердной работой над оптимизацией игр, то вторая проблема куда более глобальная – на сегодняшний день существует не так много игр с полной реализацией рейтрейсинга. Мы специально подчеркнули слово «полной» т.к. на сегодня есть всего пара игр, где трассировка лучей представлена по максимуму. Остальным повезло чуть меньше. К примеру, в Battlefield V реализованы только отражения и эффекты преломления, в Shadow of the Tomb Raider есть только реалистичные тени, обрабатывающиеся по технологии RTX, а в Metro: Exodus – глобальное освещение и затенение.

Та самые игры, где рейтрейсинг представлен полностью и во всей красе – Control и Quake II RTX, которую разработчики выпустили совместно с NVIDIA. И если с Control всё более-менее ясно, ведь это относительно недавняя новинка, то с Quake II RTX ситуация интереснее. В значительно улучшенном переиздании легендарной классики, были обновлены не только текстуры и перерисованы все модели (не без помощи пользовательских модификаций), со стороны трассировки здесь есть и реалистичные отражения, и преломления, и тени с глобальным освещением. Т.е. полный набор, какой и должен быть по умолчанию во всех играх с поддержкой рейтрейсинга. К сожалению, сейчас количество игр, оснащенных трассировкой лучей можно пересчитать по пальцам одной руки, разумеется, если не учитывать технодемки, созданные исключительно для демонстрации технологии публике.

Будущее трассировки лучей и какие игры будут поддерживать рейтрейсинг?

Что ждет рейтрейсинг в будущем и какие у него перспективы? На самом деле, кто бы что ни говорил про трассировку, и в частности, про видеокарты GeForce RTX, будущее у этой технологии определенно есть. Для примера, достаточно вспомнить аналогичную ситуацию, когда был релиз DirectX 10. Многие утверждали, что и на DX9 неплохо «живется», а все эти новинки от лукавого, но двигатель прогресса не остановить. Сейчас это происходит и с DXR. Как говорится, «Назад пути нет», а количество игр с поддержкой рейтрейсинга будет только увеличиваться.

Анонсы главной игровой выставки года E3 2019 показали, что сейчас и в последующих годах количество игр будет неустанно увеличиваться. Среди самых ожидаемых проектов с поддержкой DXR числятся: Cyberpunk 2077, Call of Duty: Modern Warfare, Watch Dogs: Legion, Bloodlines 2 и Wolfenstein: Young Blood (игра уже вышла, но поддержку трассировки в неё добавят чуть позже). Среди проектов меньшего масштаба: Final Fantasy XV, PUBG, Remnant: From the Ashers, Serious Sam 4, We Happy Few, Atomic Hearth, Ark: Survival Evolved, Dauntless, MechWarrior V и др.

Quake II RTX также показал, что трассировка при возрождении классики имеет место быть, но мы бы не сильно надеялись на то, что разработчики массово побегут перевыпускать классические проекты, прикручивая к ним DXR. Всё-таки помимо рейтрейсинга, такие игры требуют куда большего обновления. Мы сейчас про графическую составляющую, где нужно полностью перерабатывать текстуры и модели. Эта работа по большей части «ручная» и требует достаточно много сил и времени. А вот, что действительно делается уже сейчас, так это пользовательские модификации для популярных игр, куда скажем так, «прикручивается» симуляция трассировки лучей. Моддеры и энтузиасты проделывают огромную работу. Взять, например, The Witcher 3: Wild Hunt и GTA 5, которые с помощью DXR и множества модов преобразились настолько, что от игр остался только костяк — геймплей, да сюжет.

Среди проектов, которые попали под улучшения и обновления моддеров: Star Wars: Battlefront 2, Dying Light, Portal 1+2, Bioshok 2 Remastered, Star Wars: The Force Unleashed 2, TES 5: Skyrim, Watch Dogs, Fallout 4, A Plague Tale, Crysis и др.

Возвращаясь к вопросу про будущее рейтрейсинга, технология уже показала, на что она способна в «правильных» руках, поэтому нам остается ждать большего количества игр с трассировкой лучей, чтобы сборка ПК на видеокартах GeForce RTX оправдывала себя целиком и полностью, а не стандартным 20-25 % — ым приростом производительности, которое наблюдается при релизе нового поколения видеокарт.

Собрать игровой компьютер на базе GeForce RTX или GeForce RTX SUPER, Вы можете в нашем конфигураторе игрового ПК:

DirectX raytracing — всплываем

В 2018 году компания Microsoft анонсировала raytracing API (DXR) как часть DirectX 12. Подход рейтрейсинга заставляет полностью переосмыслить способ ренедринга трехмерных сцен, смещающий классический подход растеризации на второй план. АПИ модернизируются, разрабатываются более производительные GPU, разработчики пакетов визуализации пробуют новые возможности. Однако даже на наиболее производительных видеокартах мощности хватает на генерирование всего нескольких лучей на пиксель для обеспечения стабильной частоты смены кадров. К тому же, производительность во многом зависит от сложности материалов и сцены. Но уже сегодня продвинутые алгоритмы шумоподавления и аккумуляции результата освещенности позволяют достичь высокой степени реализма. Все это мотивирует к экспериментам в данной области.

Возможность трассировки лучей на GPU стала возможна относительно недавно. В 2009 году вышел DirectX 11 с compute shaders — это дало толчок в развитии вычислений не связанных с графикой. Однако конструирование ускоряющих структур ложилось полностью на плечи программиста, что замедляло разработку. Получили распространение специализированные библиотеки по пересечению, например, Radeon Rays от AMD. В DXR ускоряющие структуры представлены по принципу черного ящика и пересечение происходит с помощью специальных аппаратных блоков. Трассировка лучей была так же добавлена в Vulkan в качестве расширения VK_NV_ray_tracing для карт Nvidia. В марте 2020 с небольшими изменениями вышло расширения VK_KHR_ray_tracing, перестало быть vendor-specific, возможно его включат в спецификацию Vulkan 1.3. Планируется полноценная работа трассировки лучей и в AMD до конца 2020. Повсеместная поддержка повышает перспективность технологии.

Концептуально DXR предоставляет возможность пересечения лучей с предварительно загруженными геометрическими объектами. В местах пересечений возможно выполнение определенных пользователем программ — шейдеров. Грубо говоря, объект это массив треугольников. Однако уточняющая форма, которая, например, говорит о прозрачности объекта может определяться и во время выполнения в отдельном шейдере. Такая возможность полезна, если степень прозрачности задается текстурой или в случае полностью процедурно сгенерированных объектов (облака, огонь). Любые события, которые возникают на пути луча (hit, miss, procedural hit, closest hit), подвержены программированию, например, в месте пересечений можно генерировать вторичные лучи, продолжающие движение. Такой pipeline похож на распространение света.

Окружение

Для запуска требуется DXR-совместимый GPU Nvidia RTX 2060 и выше. Windows SDK 19041 (для нашего примера подойдет и более раннее, но официальные Miscrosoft сэмплы ориентируются именно на эту версию), в качестве IDE используется Visual Studio 2019, язык C++.

Терминология

Как и в любой трассировке в DXR все начинается с генерирования необходимых лучей, за это отвечает отдельный raygen-шейдер. Глобально на стороне программы вызывается ID3D12GraphicsCommandList4::DispatchRays() c необходимым количеством лучей, а конкретные направления задает шейдер с помощью TraceRay(). Трассировка производится на определенной top level acceleration structure. Дальнейшее выполнение может происходить по разным сценариям, зависящим от сцены. Например, могут обрабатываться всевозможные пересечения на пути следования луча, либо вызываться отдельные шейдеры для процедурной геометрии, либо обрабатываться только ближайшее пересечение (closest hit). Для простоты мы рассмотрим последний случай, общий иллюстрирует следующая схема.

В процессе выполнение может передаваться разным miss и hit-шейдерам. Инстансы шейдеров для одного луча могут обмениваться небольшой областью памятью называемой payload — обычно это и есть результат вычислений. Ресурсы могут передаваться и быть видимым глобально для всех шейдеров с помощью стандартных средств DirectX, в этом случае создается global root signature. Либо локально per-shader ресурсы, в этом случае на каждый шейдер создается своя local root signature и передача параметров осуществляется с помощью Shader binding table. В такой ситуации надо следить, чтобы регистры глобальных ресурсов не пересекались с регистрами локальных.

Инициализация

На высоком уровне вся настройка делится на следующие этапы:

  • создание bottom-level, top-level acceleration structures
  • создание raytracing pipeline
  • создание shading binding table (SBT) — ассоциирование шейдеров и per-shader ресурсов с геометрией

Разберем подробно эти этапы.

Bottom-level acceleration structure (BLAS)

Объект представляет собой список геометрических объектов, где каждый объект — это массив треугольников. Один объект в BLAS для удобства в дальнейшем будем называть инстансом. Один BLAS может состоять из множества инстансов. Треугольники могут задаваться напрямую как тройки вершин либо индексироваться отдельным буфером. Генерирование BLAS происходит на GPU, и поэтому требует отдельного command list и небольших синхронизаций. Для генерирования требуется итоговый буфер, который и будет содержать BLAS а так же некоторое количество памяти для внутренних нужд (scratch-буфер). DirectX 12, как явное API, предоставляет возможность узнать необходимые размеры с помощью метода ID3D12Device5::GetRaytracingAccelerationStructurePrebuildInfo. В итоге создается буфер с флагом D3D12_RESOURCE_STATE_RAYTRACING_ACCELERATION_STRUCTURE — содержит все необходимые данные для эффективного пересечения лучей с треугольниками.

Основная структура здесь D3D12_RAYTRACING_GEOMETRY_DESC — описывает один инстанс в BLAS. Необходимо передать буфер вершин и их лэйаут (а так же index-buffer при наличии):

Заполняем общую информацию о BLAS:

И генерируем BLAS:

Top-level acceleration structure (TLAS)

TLAS представляется матрицей трансформации с уже созданными BLAS и флагами специфичными для данного инстанса. Она может инстанциировать один и тот же BLAS много раз, используя разные матрицы для рендеринга одинаковых моделей в разных позициях. Создание TLAS во многом похож на BLAS — здесь так же требуется дополнительный scratch-буфер. Более того, мы можем использовать один и тот же scratch-буфер, так как TLAS создается после BLAS. В нашем случае записываем в TLAS две одинаковые модели с разными матрицами трансформации:

Заполнение общей информации о TLAS (D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS и D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_DESC) производится аналогично BLAS.

Raytracing pipeline

Как и для graphic и compute нам требуется raytracing pipeline state object — это текущая конфигурация трассировки. RT pipeline состоит из множества подобъектов и объектов-ассоциаторов, которые связывают уже созданные подобъекты. Для удобства будем использовать вспомогательный класс CD3DX12_STATE_OBJECT_DESC и метод CreateSubobject(<тип подобъекта>).

  1. Библиотеки шейдеров. Необходимо скомпилировать либо заранее либо программно и заполнить поля BytecodeLength и pShaderBytecode структуры D3D12_SHADER_BYTECODE, затем передать в подобъект эту структуру с помощью SetDXILLibrary() и определить имя функции на исполнение DefineExport(). Такой алгоритм проделываем для 3-х шейдеров: raygen, hit, miss.
  2. Hit group (CD3DX12_HIT_GROUP_SUBOBJECT). Необходимо обозначить hit group-ы, которые будут участвовать в трассировке. Придумываем имя группы и устанавливаем с помощью SetHitGroupExport, а так же тип в нашем случае SetHitGroupType(D3D12_HIT_GROUP_TYPE_TRIANGLES). Текущий подобъект лишь указывает на наличие hit-group, конкретный шейдер мы уже добавили на первом шаге.
  3. Конфигурация шейдеров (CD3DX12_RAYTRACING_SHADER_CONFIG_SUBOBJECT). Размер payload — данные, которые возвращает TraceRay после обработки пересечения, и барицентрические координаты в closest hit — 2 float.
  4. Конфигурация пайплайна (CD3DX12_RAYTRACING_PIPELINE_CONFIG_SUBOBJECT). Устанавливаем максимальную глубина трассировки 1.
  5. Локальная root signature (CD3DX12_LOCAL_ROOT_SIGNATURE_SUBOBJECT). Описание аргументов, которые приходят в hit-шейдер. Конкретные аргументы передаются через SBT (об этом далее).
  6. Ассоциация local root signatore c hit group (CD3DX12_SUBOBJECT_TO_EXPORTS_ASSOCIATION_SUBOBJECT). Устанавливаем root signature SetSubobjectToAssociate() и имя группы для которой предназначаются параметры AddExport().
  7. Глобальная root signature (CD3DX12_GLOBAL_ROOT_SIGNATURE_SUBOBJECT). Описание аргументов, которые доступны во всех шейдерах. Аргументы устанавливаются непосредственно перед трассировкой с помощью стандартных методов SetComputeRootDescriptorTable, SetComputeRootShaderResourceView и SetComputeRoot32BitConstants.

Shader binding table (SBT)

SBT — это соединение геометрических данных и шейдеров вместе. Фактически таблица хранит информацию о том, какие нужно выполнить шейдеры и с какими аргументами для инстансов с которыми произошло пересечение, поэтому это часть подверженная активному изменению с точки зрения программиста. Технически это не является таблицей, она представляется размеченной GPU-памятью, в которой записаны идентификаторы шейдеров и аргументы по определенным правилам. Но для удобства продолжим называть ее таблицей.

Одна ячейка в таблице называется shader record. В нашем случае при конструировании TLAS мы указали что нулевой инстанс будет смотреть на нулевую запись, первый — на первую. Таким образом в рантайме придут разные константы. В общем случае формула расчета индекса в таблице может зависеть не только от номера геометрического инстанса в TLAS и BLAS, но и от типа лучей и передаваемых аргументов в TraceRay(), однако в данной статье мы рассматриваем самый простой случай.

Глобально все делится на 3 шейдера: ray generation, hit и miss, соответственно, можно сказать, что и таблиц буде тоже три. Мы можем разместить таблицы в разных буферах, либо в одном. В последнем случае нам нужно правильно рассчитать GPU-адрес на начало каждой из таблиц, которые принимает DispatchRays(). В таблице может быть любое количество shader record-ов.

Размер буфера который нам нужно аллоцировать для одной таблицы это размером одного shader record-a умноженный на их количество. Для raygen и miss у нас будет по одному шейдеру без каких либо локальных аргументов, поэтому размер shader record-a минимально возможный. Для глобальных аргументов, как мы уже знаем, которые видны всем шейдерам, мы создаем отдельную root signature, ее аргументы не записываются в SBT. Между shader record требуется выравнивание D3D12_RAYTRACING_SHADER_RECORD_BYTE_ALIGNMENT (сейчас 32 байта).

Идентификатор шейдера представляет собой void*, который возвращает GetShaderIdentifier() из объекта ID3D12StateObjectProperties, последний можно получить из COM-интерфейса созданного ранее raytracing pipeline. Для raygen-шейдера (miss аналогично) это выглядит примерно так:

Указатель мы записываем в начало нашего буфера. SBT для raygen и miss шейдеров сформированы.

Для hit мы передаем в шейдер float4 и здесь более интересная ситуация. Запись аргументов в SBT очень похожа на установку в root signature: константы записываются напрямую либо передается virtual GPU-address/GPU-handle. В нашей ситуации два инстанса необходимо обработать одним шейдером но с разными constant buffer, поэтому в hit SBT будет два shader record-а. Запись состоит из 32-байтного идентификатора и 4×4-байт константы, всего 48, но из-за выравнивания получится 64 байта. Расположение записей иллюстрируются следующей картинкой:

Шейдеры

В отличие от классического подхода vertex-fragment shader в трассировке требуется минимум 3: raygen, hit, miss.

raygen:

Задаем исходную точку и направление луча на основании позиции пикселя и системы координат камеры. Затем передаем TLAS, маски и набор параметров, отвечающих за расчет выполнения определенных шейдеров в SBT. TraceRay() возвращает payload после серии пересечений и результат записываем в выходой буфер. Идентификатор [shader(«raygeneration»)] говорит системе, что это именно шейдер, генерирующий лучи, а вот название функции «RayGen» может быть любое, его нужно будет экспортировать после компиляции.

closesthit

Выполняется только в случае ближайшего к камере пересечения. В результате мы должны записать что-нибудь в payload. В шейдер передается буфер вершин и нормалей и цвет текущей модели. Барицентрические координаты и номер треугольника передаются системой. Находим нормаль в точке пересечения с помощью барицентрических координат, и производим расчет освещения.

Наиболее просто выглядит miss.

В этом случае у нас нет пересечения — записываем цвет фона.

Main loop

Основная выдержка из main loop выглядит следующим образом:

Заключение

В статье мы рассмотрели основные объекты необходимые для начала работы с DXR, а так же применили эти знания на практике. Намеренно были пропущены вопросы инициализации DirectX, загрузки моделей, компиляции шейдеров, и т.д., которые не относятся к теме. В следующих статьях планируется сместить акцент на, собственно, графику, нежели работу с API.

Что такое DirectX Raytracing в Windows 10 и что это значит для игр

Игры

Microsoft наконец-то анонсировала DirectX Raytracing или DXR вкратце с обновлением Windows 10 v1809 за октябрь 2018 года. Начиная с первого поколения аппаратного обеспечения, геймеры смогут использовать Raytracing для создания теней, света и эффектов вокруг него в режиме реального времени. В этой статье мы рассмотрим DirectX Raytracing в Windows 10 и его значение для игр.

Что такое Raytracing?

Проще говоря, трассировка лучей означает вычисление того, как свет падает на объекты, и как он выглядит после того, как свет отражается от этого объекта, и влияние света, падающего на какой-то другой объект. Это помогает разработчикам создавать лучшую визуализацию своих персонажей и сценариев.

Тем не менее, в этом нет ничего нового, и это тоже не то, что было создано Microsoft. Разработчики использовали это с времен CGI, и это требовало предварительного расчета яркости виртуальных объектов перед выпуском их игр. Так что до сих пор не было Raytracing в реальном времени.

DirectX Raytracing в Windows 10

Есть две части Raytracing. Требуется поддержка как аппаратного, так и программного обеспечения. Начиная с обновления Windows 10 v1809, DirectX Raytracing будет работать на поддерживаемом оборудовании. Это означает, что вам нужно будет поменять видеокарту, которая поддерживает собственную трассировку лучей.

Microsoft позаботилась о том, чтобы DirectX Raytracing API был построен таким образом, чтобы он работал на оборудовании всех производителей. Лучшая часть всего этого – то, что Raytracing теперь в режиме реального времени. Разработчикам не нужно выполнять какой-либо предварительный расчет, поскольку разработчики игр теперь имеют доступ как к ОС, так и к аппаратному обеспечению для поддержки трассировки лучей в играх в реальном времени.

DirectX Raytracing работает с существующими двигателями

До настоящего времени индустрия использовала традиционную растеризацию для достижения более реалистичных сцен в играх. В нем отсутствовали отражения, тени и окклюзия окружающей среды. Все эти изменения с DirectX Raytracing с разработчиками API могут использовать наряду с основанными на растеризации игровыми конвейерами интеграцию поддержки DirectX Raytracing в их существующие движки. Это означает, что нет необходимости восстанавливать двигатели вообще.

Microsoft также поделилась тем, что несколько студий сотрудничают с NVIDIA, которая создала технологию RTX для максимально эффективной работы DirectX Raytracing на своем оборудовании. Вот несколько примеров изображений из таких игр, как Battlefield V, Shadow of the Tomb Raider и Metro Exodus.

На данный момент разработчики собираются создавать игры с использованием как растеризации, так и трассировки лучей. Последнее будет в основном использоваться для вычисления теней или отражений, в то время как большая часть контента генерируется с помощью первой технологии.

Directx 12/DirectX Raytracing API

Гигант Redmon также позаботился о том, чтобы DirectX Raytracing был ориентирован на будущее и хорошо соответствовал будущей эволюции графических процессоров: рабочие нагрузки DXR естественно вписываются в конвейеры графических процессоров будущего.

Помимо аппаратного обеспечения, недавно анонсированного публичного API, DirectML позволит разработчикам игр интегрировать выводы в свои игры с помощью низкоуровневого API. На более высоком уровне:

  • Структура ускорения: объект, представляющий полноценную трехмерную среду.
  • DispatchRays: это отправная точка для трассировки лучей в сцену.
  • Набор новых типов шейдеров HLSL, включая ray-generation , ближайший удар , любой удар и miss шейдеры.
  • Raytracing состояние трубопровода

Тем не менее, он не вводит никакого нового движка, но работает на любом из движков DirectX 12.

Microsoft делает большие ставки на DirectX Raytracing

По мере того, как игровая индустрия прогрессировала до более высокого разрешения, а человеческий глаз ищет более реалистичные представления, Microsoft ожидает, что даже небольшие проблемы могут быть разрешены. Небольшое отклонение от реального мира может быть замечено человеческим глазом, потому что оно не кажется правильным. DirectX Raytracing поможет разработчикам размыть грань между реальным и фальшивым.

Что вы думаете о DirectX Raytracing? Как вы думаете, мы увидим лучшие игры в ближайшие годы? Дайте нам знать в комментариях.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *