Лучшие практики для настройки параметров эффектов в XNA

13

Я хочу спросить, есть ли лучшая практика для настройки Effectпараметров в XNA. Или, другими словами, что именно происходит, когда я звоню pass.Apply(). Я могу представить несколько сценариев:

  1. Каждый раз, когда Applyвызывается, все параметры эффекта передаются в графический процессор, и это не влияет на частоту установки параметра.
  2. При каждом Applyвызове передаются только параметры, которые были сброшены. Поэтому следует избегать кэширования Set-операций, которые фактически не устанавливают новое значение.
  3. При каждом Applyвызове передаются только измененные параметры. Так что кеширование Set-операций бесполезно.
  4. Весь этот вопрос бесполезен, потому что ни один из упомянутых способов не оказывает сколько-нибудь заметного влияния на производительность игры.

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

private Matrix _world;
public Matrix World
{
    get{ return _world; }
    set 
    {
        if (value == world) return;
        _effect.Parameters["xWorld"].SetValue(value);
        _world = value;
    }
}

Благодарим вас заранее.

0xBADF00D
источник
Я добавил тег DirectX, исходя из того, что это функциональность более низкого уровня, чем XNA.
Эндрю Рассел
Я нашел доказательство того, что данная тема ОЧЕНЬ жизнеспособна. Похоже, если вы умны в настройке параметров эффектов, вы можете увеличить количество вызовов отрисовки (то есть, насколько быстро они обрабатываются в ЦП) более чем в два раза. Я все еще в процессе тестирования, вы можете прочитать мой вопрос здесь: gamedev.stackexchange.com/questions/66932/…
cubrman

Ответы:

8

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

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

(Поскольку сценарий № 2 возможен, вероятно, лучше не бегать намеренно, переустанавливая параметры, которые не меняются.)

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

Конечно, не начинайте реализовывать оптимизацию, подобную этой, не измеряя свою производительность и не понимая, что происходит.

Кроме того, сравнение Matrixс ==плохим вуду. A Matrixсостоит из floats, и сравнения равенства с плавающей точкой во многих случаях склонны к сбою.

И, вообще говоря, картина if(x != y) x = y;медленнее, чем просто x = y.

Эндрю Рассел
источник
Интересный момент, что водитель должен заботиться об этом. Спасибо за ссылку (и повторные ссылки).
0xBADF00D
Недавно я наткнулся на пример создания геометрии из msdn . Сброс одного и того же рендеринга (с одинаковыми значениями) несколько раз за кадр значительно замедляет процесс рендеринга в два или три раза. Таким образом, государственное пакетирование является полезным. К сожалению, я не уверен, что эта ситуация применима и к настройке параметров эффекта. Но я хотел бы поделиться своей информацией.
0xBADF00D
4

Одна интересная вещь, которую я нашел в этой теме.

Из MSDN:

Вы можете использовать индексированное свойство Parameters в Effect для доступа к любому параметру эффекта, но это медленнее, чем при использовании EffectParameters. По этой причине вы должны создать EffectParameter для каждого параметра эффекта, который часто изменяется.

и

Создание и назначение экземпляра EffectParameter для каждого метода в вашем эффекте значительно быстрее, чем использование индексированного свойства «Параметры» в Effect.

Это означает, что _effect.Parameters["xWorld"].SetValue(value);это заметно медленнее, чемwordlParam.SetValue(value);

Таким образом, вы, вероятно, должны кэшировать такие параметры:

public EffectParameter wordlParam;
wordlParam = _effect.Parameters["xWorld"];

Но я не нашел никаких реальных ориентиров.

Источники:

http://msdn.microsoft.com/en-us/library/Microsoft.Xna.Framework.Graphics.EffectParameter%28v=xnagamestudio.40%29.aspx http://msdn.microsoft.com/en-us/library /bb976060%28v=xnagamestudio.31%29.aspx

зигзаг
источник
Только что проверил это на Monogame и WP эмуляторе - я могу подтвердить, что действительно есть существенная разница (между 5-15% в моем случае). Есть ли еще такие приемы, которые помогают в производительности?
Конрад