На основе рекомендаций Tommy, Pivot и rotoglup я реализовал некоторые оптимизации, которые привели к удвоению скорости рендеринга как для генерации текстуры глубины, так и для всего конвейера рендеринга в приложении.
Во-первых, я снова включил предварительно рассчитанную глубину сферы и текстуру освещения, которые использовал раньше, с небольшим эффектом, только теперь я использую правильные значения точности lowp
при обработке цветов и других значений из этой текстуры.Эта комбинация, наряду с правильным mipmapping для текстуры, похоже, дает прирост производительности на ~ 10%.
Что еще более важно, я сейчас делаю проход, прежде чем рендерить мою текстуру глубины и конечные самозванцы с трассировкой лучей, где я лежунекоторая непрозрачная геометрия для блокировки пикселей, которые никогда не будут отображаться.Для этого я включаю тестирование глубины, а затем рисую квадраты, из которых состоят объекты в моей сцене, уменьшенные с помощью sqrt (2) / 2, с помощью простого непрозрачного шейдера.Это создаст вставленные квадраты, покрывающие область, которая, как известно, является непрозрачной в представленной сфере.
Затем я отключаю глубинную запись, используя glDepthMask(GL_FALSE)
, и визуализирую самозванца квадратной сферы в местоположении ближе к пользователю на один радиус.Это позволяет аппаратным средствам отложенного рендеринга на основе плиток в устройствах iOS эффективно вырезать фрагменты, которые никогда не будут отображаться на экране ни при каких условиях, но при этом обеспечивать плавные пересечения между самозванцами видимой сферы на основе значений глубины на пиксель.Это показано на моей грубой иллюстрации ниже:
В этом примере непрозрачные блокирующие квадраты для двух верхних самозванцев не препятствуют тому, чтобы какие-либо фрагменты из этих видимых объектов былиоказанные, все же они блокируют кусок фрагментов от самого низкого самозванца.Затем самые передние самозванцы могут использовать тесты для каждого пикселя, чтобы сгладить пересечение, в то время как многие пиксели от заднего самозванца не тратят циклы графического процессора при рендеринге.
Я не думал отключать записи глубины, но все же оставьте на глубинное тестирование при выполнении последней стадии рендеринга.Это является ключом к тому, чтобы помешать самозванцам просто накладывать друг на друга, но при этом использовать некоторые аппаратные оптимизации в графических процессорах PowerVR.
В моих тестах рендеринг тестовой модели, которую я использовал выше, дает время 18 -35 мс на кадр по сравнению с 35 - 68 мс, которые я получал ранее, почти вдвое увеличивая скорость рендеринга.Применение этой же непрозрачной предварительной визуализации геометрии к проходу трассировки лучей приводит к удвоению общей производительности рендеринга.
Как ни странно, когда я пытался уточнить это далее, используя вставные и описанные восьмиугольники, которые должны охватывать ~ 17На меньшее количество пикселей при рисовании и более эффективная блокировка фрагментов, производительность была на самом деле хуже, чем при использовании простых квадратов для этого.Использование тайлера в худшем случае было все еще менее 60%, поэтому, возможно, большая геометрия приводила к большему количеству промахов в кеше.
РЕДАКТИРОВАТЬ (31.05.2011):
Основываясь на предложении Pivot, я создал вписанные и описанные восьмиугольники для использования вместо своих прямоугольников, только я следовал рекомендациям здесь для оптимизации треугольников при растеризации.В предыдущем тестировании восьмиугольники давали худшую производительность, чем квадраты, несмотря на удаление многих ненужных фрагментов и более эффективную блокировку покрытых фрагментов.Отрегулировав рисунок треугольника следующим образом:
Я смог сократить общее время рендеринга в среднем на 14% в дополнение к вышеописанным оптимизациям, переключившись на восьмиугольники сквадраты.Текстура глубины теперь генерируется за 19 мс, со случайными провалами до 2 мс и скачками до 35 мс.
РЕДАКТИРОВАТЬ 2 (31.05.2011):
Я пересмотрел идею Томми об использовании функции шага, теперь, когда у меня меньше фрагментов, которые нужно выбросить из-за восьмиугольников.Это в сочетании с текстурой поиска глубины для сферы теперь приводит к тому, что среднее время рендеринга на iPad 1 составляет 2 мс для генерации текстуры глубины для моей тестовой модели.Я считаю, что это будет настолько хорошо, насколько я могу надеяться в этом случае рендеринга, и гигантское улучшение с того места, где я начал.Для потомков вот шейдер глубины, который я сейчас использую:
precision mediump float;
varying mediump vec2 impostorSpaceCoordinate;
varying mediump float normalizedDepth;
varying mediump float adjustedSphereRadius;
varying mediump vec2 depthLookupCoordinate;
uniform lowp sampler2D sphereDepthMap;
const lowp vec3 stepValues = vec3(2.0, 1.0, 0.0);
void main()
{
lowp vec2 precalculatedDepthAndAlpha = texture2D(sphereDepthMap, depthLookupCoordinate).ra;
float inCircleMultiplier = step(0.5, precalculatedDepthAndAlpha.g);
float currentDepthValue = normalizedDepth + adjustedSphereRadius - adjustedSphereRadius * precalculatedDepthAndAlpha.r;
// Inlined color encoding for the depth values
currentDepthValue = currentDepthValue * 3.0;
lowp vec3 intDepthValue = vec3(currentDepthValue) - stepValues;
gl_FragColor = vec4(1.0 - inCircleMultiplier) + vec4(intDepthValue, inCircleMultiplier);
}
Я обновил тестовый образец здесь , если вы хотите увидеть этот новый подход в действии по сравнениюк тому, что я делал изначально.
Я все еще открыт для других предложений, но это огромный шаг вперед для этого приложения.