Характеристики света и методы визуализации теней. Построение теней при помощи теневых карт (shadow maps)

Оригинальный алгоритм теневых карт (shadow mapping) придумали уже достаточно давно. Принцип работы его заключается в следующем:
  1. Рисуем сцену в текстуру (теневую карту) из позиции источника света. Здесь важно отметить, что для разных типов источников света всё происходит немного по-разному.
    Направленные источники света (к таким в определённом приближении можно отнести солнечный свет) не имеют позиции в пространстве, однако для формирования карты теней эту позицию приходиться выбирать. Обычно её привязывают к положению наблюдателя, так чтобы в карту теней попадали объекты, находящиеся непосредственно в поле зрения наблюдателя. При рендеринге используют ортографическую проекцию .
    Проекционные источники света (лампы с непрозрачным абажуром, прожекторы) имеют определённое положение в пространстве и ограничивают распространение света определенными направлениями. При рендеринге карты теней в этом случае используется обычная перспективная проекционная матрица .
    Всенаправленные источники света (лампа накаливания, например) хоть и имеют определенное положение в пространстве, распространяют свет во всех направлениях. Чтобы корректно построить тени от такого источника света необходимо использовать кубические текстуры (cube maps), что, как правило, означает рисование сцены в карту теней 6 раз. Не всякая игра может позволить себе динамические тени от такого рода источников света, да и не всякой игре это необходимо. Если вам интересны принципы работы этого подхода, есть на эту тему.
    Кроме того, существует подкласс алгоритмов shadow mapping (LiSPSM , TSM , PSM и пр.), в которых используются нестандартные матрицы вида-проекции для улучшения качества теней и устранения недостатков оригинального подхода.
    Каким бы способом не формировалась карта теней, она неизменно содержит в себе расстояние от источника света до ближайшей видимой (из позиции источника света) точки или функцию от этого расстояния в более сложных разновидностях алгоритма.
  2. Рисуем сцену из основной камеры. Для того чтобы понять находится ли точка какого-либо объекта в тени, достаточно перевести координаты этой точки в пространство карты теней и произвести сравнение. Пространство карты теней определяется матрицей вида-проекции, которая использовалась при формировании этой карты. Переведя координаты точки объекта в это пространство и произведя преобразование координат из диапазона [-1;-1] в , получим текстурные координаты. Если полученные координаты получились вне диапазона , то эта точка не попала в карту теней, и её можно считать незатененной. Сделав выборку из карты теней по полученным текстурным координатам, мы получим расстояние между источником света и ближайшей к нему точкой какого-либо объекта. Если сравнить это расстояние с расстоянием между текущей точкой и источником света, то точка оказывается в тени, если значение в карте теней меньше. Это достаточно просто с логической точки зрения, если значение из карты теней меньше, значит, в этой точке есть какой-то объект, который находится ближе к источнику света, и мы находимся в его тени.
Shadow mapping на сегодняшний день является, наверное, самым распространенным алгоритмом для рендеринга динамических теней. Реализацию той или иной модификации алгоритма можно найти практически в любом графическом движке. Главным достоинством этого алгоритма является то, что он обеспечивает быстрое формирование теней от сколь угодно геометрически сложных объектов. Вместе с тем, существование широкого спектра вариаций алгоритма объясняется во многом его недостатками, которые могут приводить к очень неприятным графическим артефактам. Проблемы, характерные для PPSM, и пути их преодоления будут рассмотрены ниже.

Parallel-Split Shadow Mapping

Рассмотрим следующую задачу: необходимо рисовать динамические тени от объектов, находящихся на значительном удалении от игрока без ущерба для теней от близко расположенных объектов. Ограничимся направленным солнечным светом.
Задача такого рода может быть особенно актуальна в outdoor-играх, где в некоторых ситуациях игрок может видеть ландшафт на сотни метров перед собой. При этом, чем дальше мы хотим видеть тень, тем большее пространство должно попадать в теневую карту. Чтобы сохранить должное разрешение объектов в теневой карте, мы вынуждены увеличивать разрешение самой карты, что сначала приводит к снижению производительности, затем мы упираемся в ограничение на максимальный размер render target’а. В итоге, балансируя между производительностью и качеством тени, мы получим тени с хорошо заметным эффектом алиасинга, который плохо маскируется даже размытием. Понятно, что такое решение нас не может удовлетворить.
Для решения данной проблемы мы можем придумать такую матрицу проекции, чтобы близко расположенные к игроку объекты получали в карте теней площадь больше, чем объекты, которые расположены далеко. В этом заключается основная идея алгоритма Perspective Shadow Mapping (PSM) и ряда других алгоритмов. Главным преимуществом такого подхода является тот факт, что мы практически не изменили процесс рендеринга сцены, изменился лишь способ расчёта матрицы вида-проекции. Такой подход может быть легко встроен в существующую игру или движок без необходимости серьезных доработок последних. Главный недостаток такого рода подходов – граничные условия. Представим себе ситуацию, что мы рисуем тени от Солнца на закате. Когда Солнце приближается к горизонту, объекты в теневой карте начинают сильно перекрывать друг друга. В этом случае нетипичная проекционная матрица может усугубить ситуацию. Иными словами, алгоритмы класса PSM неплохо работают в определённых ситуациях, например, когда в игре рисуются тени от «неподвижного Солнца» близкого к зениту.
Принципиально другой подход предлагается в алгоритме PSSM. Некоторым данный алгоритм может быть известен под названием Cascaded Shadow Mapping (CSM). Формально, это разные алгоритмы, я бы даже сказал, что PSSM является частным случаем CSM. В этом алгоритме предлагается разделить пирамиду видимости (frustum) основной камеры на сегменты. В случае PSSM – с границами параллельными ближней и дальней плоскостям отсечения, в случае CSM – вид разделения жестко не регламентирован. Для каждого сегмента (split в терминологии алгоритма) строится своя теневая карта. Пример разделения приведен на рисунке ниже.


На рисунке можно видеть разбиение пирамиды видимости на 3 сегмента. Каждый из сегментов выделен ограничивающим прямоугольником (в трёхмерном пространстве будет параллелепипед, bounding box). Для каждой из этих ограниченных частей пространства будет строиться своя теневая карта. Внимательный читатель обратит внимание, что здесь я использовал выравненные по осям ограничивающие параллелепипеды. Можно использовать и невыравненные, это добавит дополнительную сложность в алгоритм отсечения объектов и несколько изменит способ формирования матрицы вида из позиции источника света. Так как пирамида видимости расширяется, площадь сегментов более близких к камере может быть существенно меньше площади более дальних. При одинаковом разрешении теневых карт это означает большее разрешение для тени от близко расположенных объектов. В упомянутой выше статье в GPU Gems 3 предложена следующая схема для вычисления расстояний разбиения пирамиды видимости:



где i – индекс разбиения, m – количество разбиений, n – расстояние до ближней плоскости отсечения, f – расстояние до дальней плоскости отсечения, λ – коэффициент, определяющий интерполяцию между логарифмической и равномерной шкалой разбиения.

Общее в реализации
Алгоритм PSSM в реализации на Direct3D 11 и OpenGL имеет много общего. Для реализации алгоритма необходимо подготовить следующее:
  1. Несколько теневых карт (по числу разбиений). На первый взгляд, кажется, что для получения нескольких теневых карт необходимо нарисовать объекты несколько раз. На самом деле, делать это явным образом не обязательно, мы воспользуемся механизмом аппаратного инстансинга. Для этого нам потребуется так называемый массив текстур для рендеринга и простой геометрический шейдер.
  2. Механизм отсечения объектов. Объекты игрового мира могут быть разной геометрической формы и иметь разное положение в пространстве. Протяженные объекты могут быть видны в нескольких теневых картах, небольшие объекты – только в одной. Объект может оказаться прямо на границе соседних сегментов и должен быть нарисован минимум в 2 теневые карты. Таким образом, необходим механизм для определения, в какое подмножество теневых карт попадает тот или иной объект.
  3. Механизм для определения оптимального числа разбиений. Рендеринг теневых карт для каждого сегмента на каждый кадр может быть излишней тратой вычислительных ресурсов. Во многих ситуациях игрок видит перед собой лишь небольшой участок игрового мира (например, он смотрит себе под ноги, или его взгляд уперся в стену перед собой). Понятно, что это сильно зависит от вида обзора в игре, но иметь такую оптимизацию было бы неплохо.
В итоге, получим следующий алгоритм формирования матриц вида-проекции для рендеринга карт теней:
  1. Вычисляем расстояния для разбиения пирамиды видимости для наихудшего случая. Наихудший случай здесь – мы видим тени до дальней плоскости отсечения камеры.

    Код

    void calculateMaxSplitDistances() { float nearPlane = m_camera.getInternalCamera().GetNearPlane(); float farPlane = m_camera.getInternalCamera().GetFarPlane(); for (int i = 1; i < m_splitCount; i++) { float f = (float)i / (float)m_splitCount; float l = nearPlane * pow(farPlane / nearPlane, f); float u = nearPlane + (farPlane - nearPlane) * f; m_maxSplitDistances = l * m_splitLambda + u * (1.0f - m_splitLambda); } m_farPlane = farPlane + m_splitShift; }

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

    Код

    float calculateFurthestPointInCamera(const matrix44& cameraView) { bbox3 scenebox; scenebox.begin_extend(); for (size_t i = 0; i < m_entitiesData.size(); i++) { if (m_entitiesData[i].isShadowCaster) { bbox3 b = m_entitiesData[i].geometry.lock()->getBoundingBox(); b.transform(m_entitiesData[i].model); scenebox.extend(b); } } scenebox.end_extend(); float maxZ = m_camera.getInternalCamera().GetNearPlane(); for (int i = 0; i < 8; i++) { vector3 corner = scenebox.corner_point(i); float z = -cameraView.transform_coord(corner).z; if (z > maxZ) maxZ = z; } return std::min(maxZ, m_farPlane); }

  3. На основе полученных на шагах 1 и 2 значений определяем количество сегментов, которое нам действительно необходимо и расстояния разбиения для них.

    Код

    void calculateSplitDistances() { // calculate how many shadow maps do we really need m_currentSplitCount = 1; if (!m_maxSplitDistances.empty()) { for (size_t i = 0; i < m_maxSplitDistances.size(); i++) { float d = m_maxSplitDistances[i] - m_splitShift; if (m_furthestPointInCamera >= d) m_currentSplitCount++; } } float nearPlane = m_camera.getInternalCamera().GetNearPlane(); for (int i = 0; i < m_currentSplitCount; i++) { float f = (float)i / (float)m_currentSplitCount; float l = nearPlane * pow(m_furthestPointInCamera / nearPlane, f); float u = nearPlane + (m_furthestPointInCamera - nearPlane) * f; m_splitDistances[i] = l * m_splitLambda + u * (1.0f - m_splitLambda); } m_splitDistances = nearPlane; m_splitDistances = m_furthestPointInCamera; }

  4. Для каждого сегмента (границы сегмента определяются ближним и дальним расстояниями) вычисляем ограничивающий параллелепипед.

    Код

    bbox3 calculateFrustumBox(float nearPlane, float farPlane) { vector3 eye = m_camera.getPosition(); vector3 vZ = m_camera.getOrientation().z_direction(); vector3 vX = m_camera.getOrientation().x_direction(); vector3 vY = m_camera.getOrientation().y_direction(); float fov = n_deg2rad(m_camera.getInternalCamera().GetAngleOfView()); float aspect = m_camera.getInternalCamera().GetAspectRatio(); float nearPlaneHeight = n_tan(fov * 0.5f) * nearPlane; float nearPlaneWidth = nearPlaneHeight * aspect; float farPlaneHeight = n_tan(fov * 0.5f) * farPlane; float farPlaneWidth = farPlaneHeight * aspect; vector3 nearPlaneCenter = eye + vZ * nearPlane; vector3 farPlaneCenter = eye + vZ * farPlane; bbox3 box; box.begin_extend(); box.extend(vector3(nearPlaneCenter - vX * nearPlaneWidth - vY * nearPlaneHeight)); box.extend(vector3(nearPlaneCenter - vX * nearPlaneWidth + vY * nearPlaneHeight)); box.extend(vector3(nearPlaneCenter + vX * nearPlaneWidth + vY * nearPlaneHeight)); box.extend(vector3(nearPlaneCenter + vX * nearPlaneWidth - vY * nearPlaneHeight)); box.extend(vector3(farPlaneCenter - vX * farPlaneWidth - vY * farPlaneHeight)); box.extend(vector3(farPlaneCenter - vX * farPlaneWidth + vY * farPlaneHeight)); box.extend(vector3(farPlaneCenter + vX * farPlaneWidth + vY * farPlaneHeight)); box.extend(vector3(farPlaneCenter + vX * farPlaneWidth - vY * farPlaneHeight)); box.end_extend(); return box; }

  5. Вычисляем теневую матрицу вида-проекции для каждого сегмента.

    Код

    matrix44 calculateShadowViewProjection(const bbox3& frustumBox) { const float LIGHT_SOURCE_HEIGHT = 500.0f; vector3 viewDir = m_camera.getOrientation().z_direction(); vector3 size = frustumBox.size(); vector3 center = frustumBox.center() - viewDir * m_splitShift; center.y = 0; auto lightSource = m_lightManager.getLightSource(0); vector3 lightDir = lightSource.orientation.z_direction(); matrix44 shadowView; shadowView.pos_component() = center - lightDir * LIGHT_SOURCE_HEIGHT; shadowView.lookatRh(shadowView.pos_component() + lightDir, lightSource.orientation.y_direction()); shadowView.invert_simple(); matrix44 shadowProj; float d = std::max(size.x, size.z); shadowProj.orthoRh(d, d, 0.1f, 2000.0f); return shadowView * shadowProj; }

Отсечение объектов реализуем при помощи простого теста на пересечение двух ограничивающих параллелепипедов (объекта и сегмента пирамиды видимости). Здесь есть одна особенность, которую важно учесть. Мы можем не видеть объект, но видеть тень от него. Нетрудно догадаться, что при описанном выше подходе мы отсечём все объекты, которые не видны в основной камере, и теней от них не будет. Чтобы этого не происходило, я использовал довольно распространенный приём – вытянул ограничивающий параллелепипед объекта вдоль направления распространения света, что дало грубое приближение области пространства, в которой видна тень от объекта. В итоге, для каждого объекта был сформирован массив индексов теневых карт, в которые необходимо рисовать этот объект.

Код

void updateShadowVisibilityMask(const bbox3& frustumBox, const std::shared_ptr& entity, EntityData& entityData, int splitIndex) { bbox3 b = entity->getBoundingBox(); b.transform(entityData.model); // shadow box computation auto lightSource = m_lightManager.getLightSource(0); vector3 lightDir = lightSource.orientation.z_direction(); float shadowBoxL = fabs(lightDir.z) < 1e-5 ? 1000.0f: (b.size().y / -lightDir.z); bbox3 shadowBox; shadowBox.begin_extend(); for (int i = 0; i < 8; i++) { shadowBox.extend(b.corner_point(i)); shadowBox.extend(b.corner_point(i) + lightDir * shadowBoxL); } shadowBox.end_extend(); if (frustumBox.clipstatus(shadowBox) != bbox3::Outside) { int i = entityData.shadowInstancesCount; entityData.shadowIndices[i] = splitIndex; entityData.shadowInstancesCount++; } }


Теперь рассмотрим процесс рендеринга и специфичные для Direct3D 11 и OpenGL 4.3 части.
Реализация на Direct3D 11
Для реализации алгоритма на Direct3D 11 нам понадобятся:
  1. Массив текстур для рендеринга теневых карт. Для создания такого рода объекта в структуре D3D11_TEXTURE2D_DESC есть поле ArraySize . Таким образом, в коде на C++ у нас не будет ничего похожего на ID3D11Texture2D* array[N] . С точки зрения Direct3D API массив текстур слабо отличается от единственной текстуры. Важной особенностью при использовании такого массива в шейдере является то, что мы можем определить, в какую именно текстуру в массиве будем рисовать тот или иной объект (семантика SV_RenderTargetArrayIndex в HLSL). В этом заключается и главное отличие этого подхода от MRT (multiple render targets), при котором один объект рисуется сразу во все заданные текстуры. Для объектов, которые необходимо нарисовать сразу в несколько теневых карт, мы воспользуемся аппаратным инстансингом, позволяющим клонировать объекты на уровне GPU. При этом объект может быть нарисован в одну текстуру в массиве, а его клоны в другие. В картах теней мы будем хранить только значение глубины, поэтому воспользуемся текстурным форматом DXGI_FORMAT_R32_FLOAT .
  2. Специальный текстурный сэмплер. В Direct3D API можно задать специальные параметры для выборки из текстуры, которые позволят производить сравнение значения в текстуре с заданным числом. Результатом в этом случае будет 0 или 1, а переход между этими значениями может быть сглажен линейным или анизотропным фильтром. Для создания сэмплера в структуре D3D11_SAMPLER_DESC зададим следующие параметры:

    SamplerDesc.Filter = D3D11_FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT; samplerDesc.ComparisonFunc = D3D11_COMPARISON_LESS; samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_BORDER; samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_BORDER; samplerDesc.BorderColor = 1.0f; samplerDesc.BorderColor = 1.0f; samplerDesc.BorderColor = 1.0f; samplerDesc.BorderColor = 1.0f;
    Таким образом, у нас будет билинейная фильтрация, сравнение функцией «меньше», а выборка из текстуры по координатам вне диапазона вернет 1 (т.е. отсутствие тени).

Рендеринг будем осуществлять по следующей схеме:

Реализация на OpenGL 4.3
Для реализации алгоритма на OpenGL 4.3 нам понадобится все то же самое, что и для Direct3D 11, однако есть тонкости. В OpenGL мы можем делать совмещённую со сравнением выборку только для текстур, содержащих значение глубины (например, в формате GL_DEPTH_COMPONENT32F). Следовательно, рендеринг мы будем осуществлять только в буфер глубины, а запись в цвет уберём (точнее, привяжем к framebuffer’у только массив текстур для хранения буфера глубины). Это, с одной стороны, немного сэкономит нам видеопамять и облегчит графический конвейер, с другой, вынудит работать с нормализованными значениями глубины.
Параметры выборки в OpenGL можно привязать прямо к текстуре. Они будут идентичны тем, что были рассмотрены ранее для Direct3D 11.

Const float BORDER_COLOR = { 1.0f, 1.0f, 1.0f, 1.0f }; glBindTexture(m_shadowMap->getTargetType(), m_shadowMap->getDepthBuffer()); glTexParameteri(m_shadowMap->getTargetType(), GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(m_shadowMap->getTargetType(), GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(m_shadowMap->getTargetType(), GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); glTexParameteri(m_shadowMap->getTargetType(), GL_TEXTURE_COMPARE_FUNC, GL_LESS); glTexParameteri(m_shadowMap->getTargetType(), GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); glTexParameteri(m_shadowMap->getTargetType(), GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); glTexParameterfv(m_shadowMap->getTargetType(), GL_TEXTURE_BORDER_COLOR, BORDER_COLOR); glBindTexture(m_shadowMap->getTargetType(), 0);
Интересен процесс создания массива текстур, который внутри OpenGL представлен трёхмерной текстурой. Для его создания не сделали специальной функции, и то и другое создается при помощи glTexStorage3D . Аналогом SV_RenderTargetArrayIndex в GLSL является встроенная переменная gl_Layer .
Схема рендеринга также осталась прежней:

Проблемы

Проблем у алгоритма shadow mapping и его модификаций много. Зачастую алгоритм приходится тщательно настраивать под конкретную игру или даже конкретную сцену. Список наиболее частых проблем и путей их решения можно найти . При реализации PSSM я столкнулся со следующим:

Производительность

Замеры производительности велись на компьютере следующей конфигурации: AMD Phenom II X4 970 3.79GHz, 16Gb RAM, AMD Radeon HD 7700 Series, под управлением ОС Windows 8.1.

Среднее время кадра. Direct3D 11 / 1920x1080 / MSAA 8x / полный экран / маленькая сцена (~12к полигонов в кадре, ~20 объектов)

Среднее время кадра. OpenGL 4.3 / 1920x1080 / MSAA 8x / полный экран / маленькая сцена (~12к полигонов в кадре, ~20 объектов)

Среднее время кадра. 4 разбиения / 1920x1080 / MSAA 8x / полный экран / большая сцена (~1000к полигонов в кадре, ~1000 объектов, ~500 инстансов объектов)

Результаты показали, что на больших и малых сценах реализация на OpenGL 4.3 работает, в целом, быстрее. С увеличением нагрузки на графический конвейер (увеличение количества объектов и их инстансов, увеличение размера карт теней) разница по скорости работы между реализациями сокращается. Преимущество реализации на OpenGL я связываю с отличным от Direct3D 11 способом формирования карты теней (мы использовали только буфер глубины без записи в цвет). Ничего нам не мешает сделать то же самое на Direct3D 11, смирившись при этом с использованием нормализованных значений глубины. Однако такой подход будет работать только до тех пор, пока мы не захотим хранить в карте теней какие дополнительные данные или функцию от значения глубины вместо значения глубины. И некоторые улучшения алгоритма (например, Variance Shadow Mapping) окажутся для нас сложно реализуемыми.

Выводы

Алгоритм PSSM является одним их самых удачных способов для создания теней на больших открытых пространствах. В его основе лежит простой и понятный принцип разбиения, который можно легко масштабировать, увеличивая или уменьшая качество теней. Данный алгоритм можно объединять с другими алгоритмами shadow mapping для получения более красивых мягких теней или физически более правильных. Вместе с тем, алгоритмы класса shadow mapping часто приводят к появлению неприятных графических артефактов, которые необходимо устранять путем тонкой настройки алгоритма под конкретную игру.

Теги:

  • Shadow mapping
  • PSSM
  • Direct3D 11
  • OpenGL 4
Добавить метки

Карта теней вероятно, самая трудная часть в создания визуального представления объекта. Мы используем их, чтобы получить запеченные свет и тень.
Они должны быть однозначно развернуты, так что каждая часть модели имеет свое собственное место в UV пространстве, чтобы в итоге получать корректную информацию о свете и тени.
Важно помнить, что разрешение карты теней крошечное по сравнению с размером UV пространства.
Важно также понимать, что чем больше уровень должен быть оптимизирован тем ниже дизайнер уровней должен использовать разрешение на лайтмапах, иногда доходя до 8 на 8 или 16 на 16 в случае с более мелкими объектами.
Эта тенденция требует, чтобы мы оставили много дополнительного пространства вокруг каждой секции из развертки объекта так, чтобы области, которые являются темными,
не воздействовали на светлые и не уничтожали иллюзию визуальной корректности теней в игре.

Есть 3 основных способа создания такой развертки:

BOX UNWRAP

Часто это самый надежный метод создания развертки объекта, поскольку большинство моделей окружающей среды близки по форме к блокам, которые объединены в некую структуру.
Непрерывный меш (меш в которой нет отстоящих от основной частей) часто бывает очень полезным решением при построении развертки,
это решение поможет обеспечить более эффективное распределение сетки геометрии в UV пространстве.
Это так же будет хорошо работать даже при низком разрешении карты теней, поскольку тогда она образует единый градиент от темного к светлому.
В отличии от фрагментированной развертки где результат покажется более неоднозначным и может потребоваться повысить разрешение карты теней для парирования эффекта резких переходов.
Мы должны стараться избегать этого там где мы можем. К сожалению иногда нет возможности использовать пониженное разрешение или единую развертку геометрии.

PLANAR UNWRAP

Этот способ особенно полезен для плоских конструкций, таких как стены с несколькими фасками или выдавливаниями. Это также очень полезно для больших частей фасадов зданий, таких как, например, многоквартирные дома.
Planar будет разворачивать значительно лучше если использовать неразрывную геометрию, потому что здесь вопрос будет стоять лишь в “расслаблении” сетки развертки.
Иногда так же хорошее правило заключается в том, чтобы убедиться, что на подобной развертке больше места по горизонтали, чем по вертикали, так как отбрасывание теней, как правило, происходит со стороны при слегка повышенном угле,
а не прямо вниз. Так, большее горизонтальное пространство даёт более широкие возможности для построения более резкой тени, из-за тенденции выбора дизайнерами освещения под углом,
чтобы создать более интересные тени, чем при освещении сверху вниз.

CYLINDRICAL UNWRAP

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

Примеры

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


Этот метод развертки позволяет нам иметь почти идеальную карту теней в игре с разрешением 32 на 32. У геометрии нет никаких швов. Там где должна быть тень мы видим тонкие черные линии, а где не должна, там её и нет.


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


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


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


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


У некоторых проектов не выходит следовать этим простым правилам, как на скриншоте ниже.


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


Иногда развернуть объект легко, достаточно разбить его на несколько обоснованных частей. А затем просто “расслабить” развертку. Отличный пример объект ниже.


Такая конструкция является по существу цилиндром с плоским основанием поэтому здесь используются эти два основных метода развертки объекта.
Planar разворачивает части геометрии вниз по оси Z, а затем применяется модификатор “расслабления” и немного регулируется положение вершин чтобы убедиться, что ничего не получает слишком мало покрытия.
В середине схожий с основанием случай, здесь центральная часть разделена и использован Planar вместо Cylindrical для того что бы обеспечить большую зону покрытия.
Как всегда, мы больше озабочены охватом, чем чем соотношением сторон 1 на 1. Большим преимуществом будет располагать швы в их реальных местах, это позволит выглядеть теням более естественно.
Если на вашем объекте есть глубокие вырезы, крайне резкие стыки геометрии то это отличное место что бы здесь проложить шов, если конечно он требуется.

Lightmap Coordinates Index

По умолчанию, первый набор UV (индекс 0) статик меша будет использоваться при создании карты теней для статического освещения.
Это означает, что один и тот же набор координат, который используется для нанесения материалов на меш, так же будет использован для статического освещения.
Этот метод довольно часто не является идеальным. Одной из причин этого является то, что UV, используемые для генерации карты теней должны быть уникальными,
а это означает, что каждая грань сетки не должна перекрывать любую другую поверхность в UV пространстве. Причина этого достаточно очевидна: если фейсы перекрывают друг друга на UV развертке,
часть карты теней, соответствующая этому пространству будет применяться к обеим граням. Это приведет к неправильному освещению, появлению теней там где их в принципе быть не должно.
Статик меши имеют свойство LightmapCoordinateIndex , которое позволяет использовать заданную UV развертку под карту теней. Установите это свойство, чтобы указать на набор UV, который правильно настроен для освещения.

UV чарты и отступы

Группы обособленных треугольников с сопредельными UVs называются UV чарты (charts).

Разделять развертку на чарты и располагать их отдельно следует если вы хотите исключить воздействие теней одного чарта на другой. Так же делая отступ следует помнить о простом правиле:
Размер отступа должен быть больше чем 4х4 текселя, так как DXT сжатие работает с блоками именно такого размера.

  1. Потраченный впустую отступ
  2. Необходимый отступ

Это означает, что для карты теней разрешением 32, отступы между частями UV развертки должны быть 12,5% от всего UV-пространства.
Однако, имейте в виду, что использование слишком больших отступов между частями UV развертки приведет к трате памяти, отведенной на карту теней, впустую на более высоких разрешениях.
Чем ближе ближе вы сможете расположить UV чарты, тем лучше. Это позволит уменьшить количество растраченной впустую памяти.


Это далеко не идеальная развертка.

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


Лучший способ создания развертки для карты теней является моделирование всего меша как одного непрерывного элемента или создание развертки вручную.


Это даст единую развертку, на которой почти нет швов и которая гораздо более эффективна.

Конечным результатом является меш, который освещается должным образом без каких — либо артефактов.


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


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

Колода Теней карт Таро относится к категории оккультных. Она появилась на свет в 2003 году , благодаря талантливому сотрудничеству известного в России таролога Скляровой В.А. и художнику Васильченко О.

Эти карты уникальны и по своей характеристике и по стилистике. Гадание на картах Теней под силу знатокам карт Таро, начинать с этой колодой будет сложно.

Колода карт Теней Таро

Вера Склярова, автор колоды, опытный таролог, на счету которого несколько работ по технике гадания на картах Таро и изданных под ее авторством новых колод. Колода Теней позволяет точно ответить на волнующие вопросы, понять причины преследующих человека неудач, установить воздействие темных сил на судьбу человека.

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

Автор вложил в карты весь свой опыт и знания в этой области. Колода состоит из 78 арканов и не делится по мастям, как это происходит в классическом варианте Таро. На самом деле, колоду карт Теней сложно сравнивать с классическим Таро.

Младшие арканы

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

Каждая карта в колоде имеет уникальное изображение и уникальное толкование. В колоде карт Таро многие арканов из колоды карт Теней вы найдете. Карты Таро Теней являются на сегодняшний день уникальной колодой, сразу же получившей популярность среди профессионалов.

Расклады на личность и ситуацию

Рассмотрим значение нескольких старших арканов, для того, чтобы понять, насколько похожи карты Теней на обычные карты Таро и в чем их очевидное отличие.

  • Карта “Сатана” – если расклад проводится на личность человека, то перед вами удачливый и привлекательный человек. Он может произвести приятное впечатление практически всегда. Он успешен и вызывает у окружающих уважение и зависть. Но это лишь внешнее проявление личности человека, на самом деле он вспыльчив и неуравновешен, может быть жестоким и проявлять приступы агрессии. Если карта выпадает в раскладе на ситуации, то она предупреждает вас об осторожности в отстаивании своей позиции. Возможно вы выступаете слишком жестко и вам стоит подумать о том, чтобы в чем-то уступить или согласиться на компромисс. Карта также может указывать на то, что над человеком был произведен обряд разрушения на что именно можно будет понять по другим картам в раскладе. Обряд может быть проведен на разрушение отношений, карьеры и даже здоровья. В раскладе на отношения карта говорит о том, что вы под властью более сильного партнера. Может также являться предвестником болезненного разрыва.
  • Аркан под номером два – Лилит. Эта карта обычно олицетворяет сильную женщину. Эта женщина умеет добиваться своего и в делах любовных и в делах материальных. Она красива, влиятельна, ее отличает сильный характер. Если карта выпадает мужчине, то она указывает на зависимость от женщины в любой возможной форме. Это может быть зависимость страстная от любимой женщины, может быть зависимость от материнской любви. В раскладе на отношения указывает на то, что доминирует в них женщина. В раскладе на дела и ситуацию карта обещает удачу и успех женщине, а вот для мужчины означает что ему пора стать жестче, его позиция слишком мягкая и не внятная.
  • Третья карта колоды Теней – это Геката . Эта карта также говорит о стремлении к независимости, но движет этим стремлением вовсе не сильный характер волевой женщины, а потворство своим желаниям и эгоизм. Часто карта может указывать на ветреность натуры. Олицетворяя женщину, карта указывает на ее привлекательность, но при этом говорит о ее несерьезности и стремлению к выгоде. Возможно, что алчность проявляется конкретно в данной ситуации. Если карта выпадает в раскладе мужчине, то это является предупреждением. В ближайшем будущем вам не стоит конкурировать или вступать в серьезный спор с особой женского пола. Вас ожидает проигрыш. Если карта выпадает женщине, то она предвещает победу и удачу. В раскладе на отношения карта говорит о потребительском отношении одного из партнеров к другому. Подчеркивает несерьезность связи и поверхностность чувств.
  • Четвертый аркан Люцифер предостерегает от поспешности в любых ситуациях. Если вы примете решение необдуманно, то рискуете иметь неприятные последствия. Лучше остановиться, потянуть время, подумать несколько раз, посоветоваться с близкими людьми и только затем сделать свой выбор. В спешке таится опасность. При раскладе на личность карта указывает на уравновешенного, логичного, твердого в своих убеждениях человека. Этот человек кажется сильным и надежным. Он способен контролировать свои эмоции, хотя по своей сути является человеком темпераментным. В раскладах на отношения может указывать на наличие серьезного покровителя, на то, что вторая половинка является для вас надежной опорой во всех делах и невзгодах.
  • Аркан под номером пять носит название “Ариман” . Аркан очень интересен в том плане, что носит магический отпечаток. Эта карта может выпадать в раскладе человеку, который в настоящий период своей жизни расплачивается за свое поведение. Иначе говоря, карта несет отпечаток возмездия, кары судьбы за неверные поступки или плохие черты характера. Но при этом, в сочетании с некоторыми картами может указывать на то, что на человека была наведена порча или был проведен обряд мести. В раскладах на личность эта карта выпадает тем людям, которые отличаются особенно низкими поступками или наделены низкими качествами характера. Карта указывает на подлость, лицемерие, агрессию, излишнюю подверженность страстям, азартным играм, эгоизм. В целом крайне негативный аркан. Он предвещает провал в любых начинаниях, проблемы в делах, появление болезни, финансовую несостоятельность. В раскладах на отношения говорит о болезненной любви или страсти, разрыве, потере любимого.
  • Шестой аркан тоже можно назвать удивительным и уникальным. Речь идет о карте “Ваалверит, Владыка соглашений” . Эта карта выпадает в раскладе на личность, указывая на крайнюю степень подавленности человека. Возможно, что человек подвержен суицидальным мыслям. Может говорить о недавней утрате близкого человека, крупной финансовой потере, близкой к банкротству. Карта выпадает в том случае, когда в сложившейся бедственной ситуации виновен сам человек.

Расклады для карт Теней Таро

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

Расклад можно усложнить, например, добавить пятую карту, которая расскажет о том, что человек любит больше всего в жизни. Шестая карта может говорить о мечтах человека, а седьмая укажет на источник раздражения.

Можно заранее подготовить список вопросов , ответы на которые вам необходимо узнать и таким образом создать собственный расклад.

Четвертый блог разработчиков: Новые возможности графики

В первом дневнике про обновление графического движка, мы вкратце рассказали о некоторых новых графических улучшениях, которые вскоре будут добавлены в игру. Кроме того, мы заявляли, что большинство этих улучшений будут соответствовать уровню современных игровых движков, таких как Unity 5, Unreal 4 или CryEngine 3. Но что это на самом деле означает?

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

Стоит отметить, что применение многих из этих графических возможностей для работы на таком старом движке, в то же время, сохраняя обратную совместимость со старым графическим режимом и ресурсами, потребовало от нас очень много интересных и, местами, сумасшедших обходных решений, ограничиваясь возможностями DirectX 9. Это было очень весело!

Динамическое освещение и тени

Оригинальный движок Lithitech Jupiter имел ограниченную поддержку динамического освещения и теней, хотя то, что предлагалось движком, было достаточно передовым для той эпохи, в которой он был разработан. В основном в оригинальном графическом движке Lithtech Jupiter освещение и затенение были полностью статичными, что означает, что они предварительно вычисляются и сохраняются как текстура, которая используется при рендеринге геометрии карты. Тем не менее, даже статическое освещение в некоторых моментах позволяли ним создавать динамически освещаемые сцены на некоторых объектах, таких как, например, модели персонажей и оружия. Поскольку динамическое освещение использовало на объектах вершинный метод (per-vertex), различные дополнительные детали и выпуклости также должны были быть предварительно вычислены и запечены непосредственно на диффузных текстурах. А поскольку они запечены, они не могут динамически взаимодействовать с различными источниками света и часто не вписываются в условия освещения. Это делает картинку очень плоской и устаревшей на 2017 год.

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

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

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

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

С учетом всех этих оптимизаций мы смогли реализовать сложный физический шейдер освещения. Затем мы провели всестороннее тестирование этой модели освещения, сравнив ее с тем, как похожие сцены будут отображаться в других современных игровых движках, таких как Unity 5 и Unreal 4, а также с полностью прорисованными лучами сценами, создаваемыми с использованием профессионального автономного рендеринга. Мы ограничились только тем, что мы могли бы реализовать в реальном времени с современным графическим оборудованием, используя современные осветительные шейдеры. Результаты вполне сопоставимы с визуализацией лучей, основные различия заключаются в точности отражения и ослаблении освещения.

Новые динамические шейдеры освещения в Combat Arms:

Версия сцены с отслеживанием лучей:

Теневая карта

При реализации динамических теней перед нами стоял целый ряд задач, чтобы получить современное полностью динамическое затенение в Combat Arms. В оригинальном движке Lithtech большинство теней запекается в текстурах статического освещения, используемых при рендеринге геометрии карты. Вот почему не все объекты отбрасывают тени, особенно динамические объекты, потому что тень фиксирована и не может изменяться. Хотя у Lithtech и есть функция, позволяющая создавать динамические тени на определенных объектах, она практически не использовалась в Combat Arms. Кроме того, эта функция слишком сильно ограничена в области своего применения, а сами динамические объекты не могут получать тени.

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

А вообще, что же такое Теневая карта? По сути, это очень хитрый трюк, который игры и программы для рендеринга используют для имитации динамического затенения с ускорением при помощи графического процессора. https://en.wikipedia.org/wiki/Shadow_mapping .

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

В игре текстура теневой карты выглядит так:

Обратите внимание, что на этой текстуре не 1, а 4 теневых карты. Каждая из этих теневых карт называется каскадом теневой карты. С увеличением расстояния до наблюдаемой поверхности используется больший каскад, но с более низким разрешением. Это позволяет теням простираться очень далеко, но по-прежнему вписываться в одну текстуру фиксированного размера. При этом тени рядом с наблюдателем будут обладать более высоким разрешением. Разрешение карты теней напрямую связано с тем, насколько резкими и точными могут быть тени.

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

Вот как выглядит решение теневой карты при фильтрации.

Фильтрация карты теней

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

В реальном мире тени не всегда жесткие или мягкие, они изменяются в зависимости от размера источника света и удаленности от освещаемого предмета. Примеры вы можете увидеть на фото:

Обратите внимание, как на этих фото тени становятся мягче при удалении от объектов, которые их отбрасывают. В большинстве других современных игр по-прежнему используется простейший метод фильтрации затенения, называемый Percentage Closer Filtering или PCF который применяет фиксированное значение твердости или мягкости ко всем теням.

Это скиншоты из вполне современных игр Doom и Overwatch показывают, как большинство игр делают простую теневую фильтрацию с использованием PCF.

Однако в Combat Arms мы решили реализовать более совершенную технологию фильтрации теней, которая будет более приближена к тому, что мы видим в реальной жизни. В игре мы симулируем это, используя разработанную NVidia технологию под названием Closer Soft Shadows (PCSS).

Хотя эта технология была представлена в далеком 2005 году, только сейчас графическое оборудование стало достаточно мощным, чтобы использовать этот метод, и современные игры лишь в последние годы начали интенсивно использовать его для фильтрации карты теней. На момент написания этого блога эта технология все еще недоступна в Unreal 4 или Unity 5. Хотя в техническом плане Unreal 4 предоставляет альтернативное решение, называемое функцией трассировки лучей на расстоянии, но она ограничена только разрешением статической геометрии для отбрасывания теней.

PCSS выключен:

PCSS Включен:

Тонкая фильтрация с помощью PCSS будет применяться при установке высоких настроек качества теней. Также, в настоящее время PCSS используется только для основного направленного солнечного света на всех уровнях качества. К сожалению, PCSS не совместим с аппаратной ускоренной теневой фильтрацией. Shader Model 3 DirectX 9 не поддерживает инструкции шейдера Gather4, которые обычно используются в пиксельных шейдерах DirectX 10 + / Shader Model 4+ для фильтрации карты теней. Из-за эксплуатационной нагрузки PCSS с использованием пиксельного шейдера Shader Model 3, используется сглаженная фильтрация для уменьшения нагрузки на GPU.

Всенаправленное отображение теней

С всенаправленными источниками света все немного сложнее. Так как они отбрасывают тени во все стороны, сделать для них карты теней не так то просто поскольку сцену нужно отображать с помощью какой-то 360°камеры. Обычно это связано с визуализацией сцены в нескольких направлениях от положения источника света. Однако сцену сложно масштабировать, когда таких источников света много. Поэтому для этого мы применили предварительно вычисленную карту теней, где она вычисляется только один раз, когда карта загружается вместо каждого кадра. Предварительно вычисленная карта теней может отбрасывать тени на динамические объекты в сцене, но динамические объекты внутри сцены не будут отбрасывать тени. Чтобы обойти это ограничение, используется собственная теневая функция для объектов из движка Lithtech, чтобы дать тени для объектов из заранее рассчитанных всенаправленных карт теней. Мы также комбинируем это с трассировкой Screen-Space Shadows, чтобы дать объектам подробные собственные тени и контактные тени.

Интересный пример, как теневая карта используется для проецирования всенаправленной карты теней в одну текстуру:

Здесь используется полностью 360°-проекционный метод, известный как сферическая параметризация октаэдра, или иногда он называется «октаэдровое картирование», где сфера отображается на одиночную текстуру, основанную на ее проекции на грани октаэдра.

Традиционно всенаправленные карты теней используют карту-куб, для которой требуется, по меньшей мере 6 различных текстур, чтобы представлять полную всенаправленную 360° карту теней, но с применением этой картографической проекции используется только 1 текстура. Этот метод также обеспечивает меньшие искажения, чем большинство других методов сферического 2D-проектирования, и в отличие от развернутой карты куба, он идеально вписывается в одну квадратную текстуру. Многие существующие в игре карты используют большое количество всенаправленных источников в качестве первичных источников света, и это позволяет многим им также поддерживать динамическое затенение в реальном времени.

Подводим итоги

Мы полагаем, что эта комбинация технологий освещения и затенения придаст игре вполне современный вид на 2017 год, а также что наши решения вполне конкурентоспособны с тем, что предлагают другие игровые движки на сегодняшний день. Хотя одних только этих изменений недостаточно, чтобы «осовременить» игру, нам еще предстоит большая работа по улучшению текстур и ресурсов, которые будут в полной мере использовать преимущества новых функций.

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

Я должен также напомнить, что обновленные параметры графики являются необязательными, и вы сможете переключаться между версиями движков после выхода обновления. Мы разрабатываем эти графические улучшения, ориентируясь на возможности современных средних и высокопроизводительных графических аппаратов, актуальных на 2016 год. Мы хотим, чтобы движок игры мог в полной мере использовать возможности современных графических процессоров, чтобы обеспечить наилучшее качество картинки. Мы по-прежнему постоянно проводим бенчмаркинг и оптимизацию новых графических функций, но стоит быть готовыми к тому, что немного устаревшее или более дешевое оборудование сможет работать с новыми графическими опциями лишь с пониженными настройками или разрешением. Мы по-прежнему будем поддерживать старый графический движок, так что игроки с устаревшим или менее мощным оборудованием или же те, кто просто предпочитает классический стиль Combat Arms, смогут продолжать наслаждаться игрой, как и раньше.

С уважением, команда Combat Arms!

Loading...Loading...