Отсроченное рендеринг с использованием концепции концепции выборки на основе плитки. Отложенное освещение и затенение



Отложенное освещение и затенение , отложенный рендеринг (англ. deferred shading ) - программная техника (методика) в трёхмерной компьютерной графике, которая обрабатывает освещение и затенение визуальной сцены. В результате работы алгоритма отложенного освещения и затенения процесс вычисления разбивается на меньшие части, которые записываются в промежуточную буферную память и объединяются потом. Главным отличием отложенного освещения и затенения от стандартных методов освещения является то, что эти методы немедленно записывают результат работы шейдера во фреймбуфер цвета. Реализации в современных аппаратных средствах по обработке графики имеют тенденцию использовать множественные цели рендеринга (англ. multiple render targets - MRT ) для избежания избыточных трансформаций вершин. Обычно, как только построены все необходимые буферы, они затем считываются (обычно как вводная текстура) из шейдерного алгоритма (например, уравнение освещения) и объединяются для создания результата. В этом случае вычислительная сложность и полоса пропускания памяти, необходимые для рендеринга сцены, уменьшаются до видимых частей, таким образом уменьшая сложность освещаемой сцены.

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

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

Другим довольно важным недостатком отложенного рендеринга является несовместимость со сглаживанием. Так как стадия освещения отделена от стадии геометрии, то аппаратный анти-алиасинг не приводит к правильным результатам. Хотя первый проход, используемый при рендеринге базовых свойств (диффузная обработка, карта высот), может использовать сглаживание, к полному освещению сглаживание неприменимо. Одной из стандартных методик для преодоления этого ограничения является метод выделения границ (en:edge detection) финального изображения и затем применения размытия к граням (границам).

Методика отложенного рендеринга всё более часто используется в компьютерных играх, так как допускает использование неограниченного количества источников света и уменьшает сложность необходимых шейдерных инструкций. В частности, «Advanced Technology Group», команда специалистов компании Sony Computer Entertainment, исследовала эту область и помогает разработчикам встраивать эту технологию в графические движки. PhyreEngine, бесплатный графический движок разработки Sony Computer Entertainment, имеет поддержку отложенного освещения и затенения. Примерами игр, использующих отложенный рендеринг и разработку которых поддержала Sony Computer Entertainment, являются Killzone 2 разработки Guerrilla Games, LittleBigPlanet разработки Media Molecule и inFamous разработки Sucker Punch Productions. К играм, использующим отложенный рендеринг, но в разработке которых Sony не принимала участие, являются серия игр S.T.A.L.K.E.R. разработки GSC Game World, Dead Space разработки Electronic Arts и Tabula Rasa разработки NCSoft. Технология отложенного освещения и затенения используется в игровом движке CryEngine 3 разработки Crytek.


История

Идея отложенного освещения и затенения изначально была представлена Майклом Дирингом (en:Michael Deering) и его коллегами в работе под названием «The triangle processor and normal vector shader: a VLSI system for high performance graphics», опубликованной в 1988 году. Хотя в работе нигде не используется слово «отложенный», концепция, представленная там, только недавно нашла практическое применение в таких приложениях, как компьютерные игры.


Примечания

  1. NVIDIA SDK 9.51 - Featured Code Samples - download.nvidia.com/developer/SDK/Individual_Samples/featured_samples.html. NVIDIA (2007-01-17).
  2. Deferred shading tutorial - www710.univ-lyon1.fr/~jciehl/Public/educ/GAMA/2007/Deferred_Shading_Tutorial_SBGAMES2005.pdf. Pontifical Catholic University of Rio de Janeiro.
  3. Dead Space by Electronic Arts - nzone.com/object/nzone_deadspace_feature.html. NVIDIA.
  4. Deferred shading in Tabula Rasa - developer.nvidia.com/GPUGems3/gpugems3_ch19.html. NVIDIA.
  5. Deering, Michael; Stephanie Winner, Bic Schediwy, Chris Duffy, Neil Hunt. «The triangle processor and normal vector shader: a VLSI system for high performance graphics». ACM SIGGRAPH Computer Graphics 22 (4): 21–30.
  6. Deferred Shading - download.nvidia.com/developer/presentations/2004/6800_Leagues/6800_Leagues_Deferred_Shading.pdf (PDF). NVIDIA.
  7. Klint, Josh. «Deferred Rendering in Leadwerks Engine - www.leadwerks.com/files/Deferred_Rendering_in_Leadwerks_Engine.pdf».
скачать
Данный реферат составлен на основе статьи из русской Википедии . Синхронизация выполнена 19.07.11 17:46:16
Похожие рефераты:
  • Алгоритмы
    • Tutorial

    Привет, друг! В этот раз я опять подниму вопрос о графике в ААА -играх. Я уже разобрал методику HDRR (не путать с HDRI) и чуть-чуть поговорил о коррекции цвета. Сегодня я расскажу, что такое SSLR (так же известная как SSPR, SSR): . Кому интересно - под кат.

    Введение в Deferred Rendering

    Для начала введу такое понятие как Deferred Rendering (не путать с Deferred Shading , т.к. последнее относится к освещению). В чем суть Deferred Rendering ? Дело в том, что все эффекты (такие как освещение, глобальное затенение, отражения, DOF ) можно отделить от геометрии и реализовать эти эффекты как особый вид постпроцессинга. К примеру, что нужно, чтобы применить DOF (Depth Of Field , размытие на дальних расстояниях) к нашей сцене? Иметь саму сцену (Color Map ) и иметь информацию о позиции текселя (другими словами на сколько пиксель далеко от камеры). Далее - все просто. Применяем Blur к Color Map , где радиус размытия будет зависеть от глубины пикселя (из Depth Map ). И если взглянуть на результат - чем дальше объект, тем сильнее он будет размыт. Так что же делает методика Deferred Rendering ? Она строит так называемый GBuffer , который, обычно, в себя включает три текстуры (RenderTarget ):

    В случае с Color map , Normal map вроде все понятно, это обычные Surface.Color текстуры: пожалуй, за исключением того, что вектор нормали может лежать в пределах [-1, 1] (используется простая упаковка вектора в формат ).

    А вот ситуация с Depth map становится непонятной. Как же Depth map хранит в себе информацию о позиции пикселя, да еще и одним числом? Если говорить сильно упрощенно, трансформация примитива:

    Float4 vertexWVP = mul(vertex, World*View*Projection);

    Дает нам экранные координаты:

    Float2 UV = vertexWVP.xy;

    И некоторую информацию о том, насколько “далеко” от камеры пиксель:

    Float depth = vertexWVP.z / vertexWVP.w;

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

    В дальнейшем мы сможем реконструировать позицию пикселя очень простым способом:

    Float3 GetPosition(float2 UV, float depth) { float4 position = 1.0f; position.x = UV.x * 2.0f - 1.0f; position.y = -(UV.y * 2.0f - 1.0f); position.z = depth; //Transform Position from Homogenous Space to World Space position = mul(position, InverseViewProjection); position /= position.w; return position.xyz; }

    Напомню, что для построения GBuffer необходима такая методика как MRT (Multiple Render Targets ), которая рисует модель сразу в несколько Render Target (причем в каждом RT содержится разная информация). Одно из правил MRT - размерность всех Render Target должна быть одинаковой . В случае Color Map , Normal Map - Surface.Color : 32-ух битная RT , где на каждый канал ARGB приходится по 8 бит, т.е. 256 градаций от 0 до 1.

    Благодаря такому подходу мы можем применять сложные эффекты к любой геометрии, например самый популярный Screen Space эффект: SSAO (Screen Space Ambient Occlusion). Этот алгоритм анализирует буферы глубины и нормали, считая уровень затенения. Весь алгоритм я описывать не буду, он уже на хабре, скажу лишь то, что задача алгоритма сводится к трассировки карты глубины: у нас есть набор случайных векторов, направленных из считаемого “пикселя” и нам нужно найти кол-во пересечений с геометрией.

    Пример эффекта (слева без SSAO, справа с SSAO):

    Так же Deferred Shading является Screen Space эффектом. Т.е. для каждого источника света на экране (без всяких оптимизаций) мы рисуем квад в режиме Additive в так называемый RenderTarget : Light Map . И зная мировую позицию “пикселя”, его нормаль, позицию источника света - мы можем посчитать освещенность этого пикселя.

    Пример Deferred Shading (освещение выполнено отложено, после отрисовки геометрии):

    Достоинства и проблемы Screen Space эффектов
    Самый главный плюс Screen Space эффектов - независимость сложности эффекта от геометрии.

    Самый главный минус - локальность всех эффектов. Дело в том, что мы постоянно будем сталкиваться с Information Lost , во многих случаях это сильно зависит обзора, поскольку SSE зависит от смежных глубин текселей, которые могут быть сгенерированы любой геометрией.

    Ну и стоит отменить, что Screen Space эффекты выполняются полностью на GPU и являются пост-процессингом.

    Наконец SSLR

    После всей теории мы подошли к такому эффекту, как Screen Space Local Reflections : локальные отражения в экранном пространстве.

    Для начала разберемся с перспективной проекцией:

    Горизонтальный и вертикальный угол зрения задается FOV (обычно 45 градусов, я предпочитаю 60 градусов), в виртуальной камере они разные т.к. учитывается еще и Aspect Ratio (соотношение сторон).

    Окно проекции (там, где мы оперируем UV-space данными) - это, что мы видим, на то мы проецируем нашу сцену.
    Передняя и задняя плоскости отсечения это соответственно Near Plane, Far Plane , задаются так же в проекцию как параметры. Делать в случае Deferred Rendering слишком большим значением Far Plane стоит, т.к. точность Depth Buffer сильно упадет: все зависит от сцены.

    Теперь, зная матрицу проекции и позицию на окне проекции (а так же глубину) для каждого пикселя мы вычисляем его позицию следующим образом:

    Float3 GetPosition(float2 UV, float depth) { float4 position = 1.0f; position.x = UV.x * 2.0f - 1.0f; position.y = -(UV.y * 2.0f - 1.0f); position.z = depth; position = mul(position, InverseViewProjection); position /= position.w; return position.xyz; }

    После нам нужно найти вектор взгляда на этот пиксель:

    Float3 viewDir = normalize(texelPosition - CameraPosition);
    В качестве CameraPosition выступает позиция камеры.
    И найти отражение этого вектора от нормали в текущем пикселе:

    Float3 reflectDir = normalize(reflect(viewDir, texelNormal));
    Далее задача сводится к трассировке карты глубины. Т.е. нам нужно найти пересечение отраженного вектора с какой-либо геометрией. Понятное дело, что любая трассировка производится через итерации. И мы в них сильно ограниченны. Т.к. каждая выборка из Depth Map стоит времени. В моем варианте мы берем некоторое начальное приближение L и динамически меняем его исходя из расстояния между нашим текселем и позицией, которую мы “восстановили”:

    Float3 currentRay = 0; float3 nuv = 0; float L = LFactor; for(int i = 0; i < 10; i++) { currentRay = texelPosition + reflectDir * L; nuv = GetUV(currentRay); // проецирование позиции на экран float n = GetDepth(nuv.xy); // чтение глубины из DepthMap по UV float3 newPosition = GetPosition2(nuv.xy, n); L = length(texelPosition - newPosition); }

    Вспомогательные функции, перевод мировой точки на экранное пространство:

    Float3 GetUV(float3 position) { float4 pVP = mul(float4(position, 1.0f), ViewProjection); pVP.xy = float2(0.5f, 0.5f) + float2(0.5f, -0.5f) * pVP.xy / pVP.w; return float3(pVP.xy, pVP.z / pVP.w); }

    После завершения итераций мы имеет позицию “пересечения с отраженной геометрией”. А наше значение nuv будет проекцией этого пересечения на экран, т.е. nuv.xy – это UV координаты в экранном нашем пространстве, а nuv.z это восстановленная глубина (т.е. abs(GetDepth(nuv.xy)-nuv.z) должен быть очень маленьким) .

    В конце итераций L будет показывать расстояние отраженного пикселя. Последний этап - собственно добавление отражения к Color Map :

    Float3 cnuv = GetColor(nuv.xy).rgb; return float4(cnuv, 1);

    Разбавим теорию иллюстрациями, исходное изображение (содержание Color Map из GBuffer):

    После компиляции шейдера (отражения) мы получим следующую картину (Color Map из GBuffer + результат шейдера SSLR):

    Не густо . И тут стоит еще раз напомнить, что Space-Screen эффекты это сплошной Information Lost (примеры выделены в красные рамки).

    Дело в том, что если вектор отражения выходит за пределы Space-Screen – информация о Color -карте становится недоступной и мы видим Clamping нашего UV .

    Чтобы частично исправить эту проблему, можно ввести дополнительный коэффициент, который будет отражать “дальность” отражения. И далее по этому коэффициенту мы будем затенять отражение, проблема частично решается:

    L = saturate(L * LDelmiter); float error *= (1 - L);

    Результат, отражение умноженное на error (попытка убрать артефакт SSLR - information lost):

    Уже лучше, но мы замечаем еще одну проблему, что будет, если вектор отразится в направлении камеры? Clamping ’а UV происходить не будет, однако, несмотря на актуальность UV (x > 0, y > 0, x < 1, y < 1) он будет неверным:

    Эту проблему так же можно частично решить, если как-нибудь ограничить углы допустимых отражений. Для этого идеально подходит фишка с углами от эффекта Френеля :

    Float fresnel = dot(viewDir, texelNormal);
    Чуть-чуть модифицируем формулу:

    Float fresnel = 0.0 + 2.8 * pow(1+dot(viewDir, texelNormal), 2);
    Значения Френеля, с учетом Normal-маппинга (значения fresnel-переменной для SSLR-алгоритма).

    If you"re a developer of 3D games, then you"ve probably come across the terms forward rendering and deferred rendering in your research of modern graphics engines. And, often, you"ll have to choose one to use in your game. But what are they, how do they differ, and which one should you pick?

    Deferred Rendering for many lights (Image courtesy of Hannes Nevalainen)

    Modern Graphics Pipelines

    To begin, we need to understand a little bit about modern, or programmable, graphics pipelines.

    Back in the day, we were limited in what the video card graphics pipeline had. We couldn"t change how it drew each pixel, aside from sending in a different texture, and we couldn"t warp vertices once they were on the card. But times have changed, and we now have programmable graphics pipelines . We can now send code to the video card to change how the pixels look, giving them a bumpy appearance with normal maps , and adding reflection (and a great deal of realism).

    This code is in the form of geometry , vertex , and fragment shaders , and they essentially change how the video card renders your objects.



    Simplified view of a programmable graphics pipeline

    Forward Rendering

    Forward rendering is the standard, out-of-the-box rendering technique that most engines use. You supply the graphics card the geometry, it projects it and breaks it down into vertices, and then those are transformed and split into fragments, or pixels, that get the final rendering treatment before they are passed onto the screen.



    Forward rendering: Geometry shader to vertex shader to fragment Shader

    It is fairly linear, and each geometry is passed down the pipe one at a time to produce the final image.

    Deferred Rendering

    In deferred rendering, as the name implies, the rendering is deferred a little bit until all of the geometries have passed down the pipe; the final image is then produced by applying shading at the end.

    Now, why would we do that?



    Deferred rendering: Geometry to vertex to fragment shaders. Passed to multiple render targets, then shaded with lighting.

    Deferred lighting is a modification of deferred rendering that reduces the size of the G-buffer by using more passes on the scene.

    Lighting Performance

    Lighting is the main reason for going one route versus the other. In a standard forward rendering pipeline, the lighting calculations have to be performed on every vertex and on every fragment in the visible scene, for every light in the scene.

    If you have a scene with 100 geometries, and each geometry has 1,000 vertices, then you might have around 100,000 polygons (a very rough estimate). Video cards can handle this pretty easily. But when those polygons get sent to the fragment shader, that"s where the expensive lighting calculations happen and the real slowdown can occur.

    Developers try to push as many lighting calculations into the Vertex shader as possible to reduce the amount of work that the fragment shader has to do.

    The expensive lighting calculations have to execute for each visible fragment of every polygon on the screen, regardless if it overlaps or is hidden by another polygon"s fragments. If your screen has a resolution of 1024x768 (which is, by all means, not very high-res) you have nearly 800,000 pixels that need to be rendered. You could easily reach a million fragment operations every frame. Also, many of the fragments will never make it to the screen because they were removed with depth testing, and thus the lighting calculation was wasted on them.

    If you have a million of those fragments and suddenly you have to render that scene again for each light, you have jumped to x 1,000,000 fragment operations per frame! Imagine if you had a town full of street lights where each one is a point-light source...

    The formula for estimating this forward rendering complexity can be written, in big O notation , as O(num_geometry_fragments * num_lights) . You can see here that the complexity is directly related to the number of geometries and number of lights.

    Fragments are potential pixels that will end up on the screen if they do not get culled by the depth test.

    Now, some engines optimize this, by cutting out lights that are far away, combining lights, or using light maps (very popular, but static). But if you want dynamic lights and a lot of them, we need a better solution.

    Deferred Rendering to the Rescue

    Deferred Rendering is a very interesting approach that reduces the object count, and in particular the total fragment count, and performs the lighting calculations on the pixels on the screen, thereby using the resolution size instead of the total fragment count.

    The complexity of deferred rendering, in big O notation, is: O(screen_resolution * num_lights) .

    You can see that it now doesn"t matter how many objects you have on the screen that determines how many lights you use, so you can happily increase your lighting count. (This doesn"t mean you can have unlimited objects-they still have to be drawn to the buffers to produce the final rendering result.)

    Let"s see how it works.

    The Guts of Deferred Rendering

    Every geometry is rendered, but without light shading, to several screen space buffers using multiple render targets . In particular, the depth, the normals, and the color are all written to separate buffers (images). These buffers are then combined to provide enough information for each light to light the pixels.



    Color , Depth , and Normal buffers. (Images by astrofa, via Wikimedia Commons.)

    Final lighting (shading) result generated using the three buffers. (Image by astrofa , via Wikimedia Commons.)

    By knowing how far away a pixel is, and its normal vector, we can combine the color of that pixel with the light to produce our final render.

    Which to Pick?

    The short answer is, if you are using many dynamic lights then you should use deferred rendering. However, there are some significant drawbacks:

    • This process requires a video card with multiple render targets. Old video cards don"t have this, so it won"t work on them. There is no workaround for this.
    • It requires high bandwidth. You"re sending big buffers around and old video cards, again, might not be able to handle this. There is no workaround for this, either.
    • You can"t use transparent objects. (Unless you combine deferred rendering with Forward Rendering for just those transparent objects; then you can work around this issue.)
    • There"s no anti-aliasing. Well, some engines would have you believe that, but there are solutions to this problem: edge detection , FXAA .
    • Only one type of material is allowed, unless you use a modification of deferred rendering called Deferred Lighting .
    • Shadows are still dependent on the number of lights, and deferred rendering does not solve anything here.

    If you don"t have many lights or want to be able to run on older hardware, then you should stick with forward rendering and replace your many lights with static light maps. The results can still look amazing.

    Conclusion

    I hope that has shed some light on the subject. Your options are there to solve your rendering problems, but it is very important to choose the right one at the start of your game development to avoid difficult changes later on.

    Deferred Lighting (отложенного освещения). См. для технической информации об отложенном освещении.

    Note : Deferred Lighting is considered a legacy feature starting with Unity 5.0, as it does not support some of the rendering features (e.g. Standard shader, reflection probes). New projects should consider using Deferred Shading rendering path instead.

    NOTE: Deferred rendering is not supported when using Orthographic projection. If the camera’s projection mode is set to Orthographic, the camera will always use Forward rendering.

    Обзор

    Тип рендеринга Deferred Lighting имеет высочайшее качество освещения и теней. При таком типе не существует ограничений на количество источников света, влияющих на один объект и всё источники света просчитывается попиксельно, что позволяет им корректно работать с картами нормалей и т.д. Кроме того, все источники света могут иметь тени и cookie текстуры.

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

    С другой стороны, отложенное освещение не имеет настоящей поддержки anti-aliasing’а (сглаживание изображения) и не может обрабатывать полупрозрачные объекты (такие объекты должны отрисовываться с помощью упреждающего рендеринга). Также не поддерживается опция Receive Shadows (получать тени) компонента Mesh Renderer и culling masks (маски выборочного рендеринга по слоям) поддерживаются только в ограниченной форме. Если быть точнее, то вы можете использовать не более четырёх culling масок. Следовательно, culling маска слоёв должна содержать как минимум все слои минус 4 произвольных слоя, то есть, к примеру, должно быть установлено 28 слоёв из 32. Иначе могут появиться графические артефакты.

    Требования

    It requires a graphics card with Shader Model 3.0 (or later), support for Depth render textures and two-sided stencil buffers. Most PC graphics cards made after 2004 support deferred lighting, including GeForce FX and later, Radeon X1300 and later, Intel 965 / GMA X3100 and later. On mobile, all OpenGL ES 3.0 capable GPUs support deferred lighting, and some of OpenGL ES 2.0 capable ones support it too (the ones that do support depth textures).

    Вопросы производительности

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

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

    Детали реализации

    При включенном отложенном освещении, процесс отрисовки в Unity происходит в 3 прохода:-

    1. Базовый проход: объекты рендерятся для создания буферов экранного пространства с глубиной, нормалями и степенью зеркальности.
    2. Проход освещения: буферы, созданные на предыдущем шаге, используются для расчёта освещения в другой буфер экранного пространства.
    3. Финальный проход: объекты снова рендерятся. Они получают рассчитанное освещение, объединяют его с цветными текстурами и добавляют любое излучаемое освещение или освещение окружения.

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

    Базовый проход

    Базовый проход рендерит каждый объект один раз. Нормали экранного пространства и степень зеркальности рендерятся в одну ARDB32 Render Texture (с нормалями в RGB каналах и степенью зеркальности в A). Если платформа и оборудование позволяют считывать содержимое Z-буфера в виде текстуры, тогда глубина рендерится неявно. Если к Z-буферу нет доступа в качестве текстуры, тогда глубина рендерится в дополнительном проходе рендеринга с помощью замены шейдера .

    Результатом базового прохода является Z-буфер, заполненный содержимым сцены и Render Texture с нормалями и степенью зеркальности.

    Проход освещения

    Проход освещения рассчитывает освещение, основанное на глубине, нормалях и степени зеркальности. Освещение рассчитывается в экранном пространстве, так что время, требуемое на расчёты не зависит от сложности сцены. Буфер освещения - это одна ARGB32 Render Texture, с диффузным освещением в RGB каналах и монохромным зеркальным освещением в канале A. Значения освещения кодируются логарифмически, для обеспечения большего динамического диапазона, чем обычно доступно при использовании ARGB32 текстуры. Единственная модель освещения, доступная при отложенном освещении - это Blinn-Phong.

    Точечные и прожекторные источники света, не пересекающие ближайшую плоскость камеры, рендерятся как 3D формы, с включенным тестом Z-буфера против сцены. Это позволяет тратить немного ресурсов на рендеринг частично или полностью скрытых точечных и прожекторных источников света. Если направленные источники света и точечные/прожекторные источники света пересекают ближайшую плоскость камеры, то они рендерятся в виде полноэкранных квадов.

    The above doesn’t apply to directional lights, which are always rendered as fullscreen quads.

    Если у источника света включены тени, то они тоже рендерятся и применяются в этом проходе. Учтите, что тени не даются “даром”; требуется рендеринг отбрасывающих тень объектов и к ним должен применяться шейдер с более сложным расчётом освещения.

    Единственная доступная модель освещения - Blinn-Phong. Если вы желаете использовать другую модель, вы можете изменить шейдер прохода освещения, разместив изменённую версию файла Internal-PrePassLighting.shader из набора в папке с именем “Resources” в вашей папке “Assets”.

    Финальный проход

    Финальный проход производит итоговое отрисованное отображение. Здесь все объекты отрисовываются ещё раз шейдерами, которые получают освещение, совмещают его с текстурами и добавляют излучаемое освещение. Карты освещения также применяются в финальном проходе. Вблизи камеры используется динамическое освещение и добавляется только запечённое непрямое освещение. Это переходит в полностью запечённое освещение вдали от камеры.

    Детали упреждающего типа рендеринга

    Подробности способа рендеринга вершинного освещения