MonkeyFirst / urho3d-post-process-dof

urho3d-post-process-dof
MIT License
9 stars 3 forks source link

ДОФ не работает, если в сцене нет физики #1

Open 1vanK opened 8 years ago

1vanK commented 8 years ago

Просто размытый экран, так как событие FixedUpdate компонента SmoothFocus не вызывается. Может лучше использовать USE_POSTUPDATE? С ним у меня работает.

1vanK commented 8 years ago

Также папку CoreData/RenderPath надо переименовать в CoreData/RenderPaths, а то я CoreData скопировал и не сразу понял, почему не находит :)

1vanK commented 8 years ago

Да и вообще Update не нужен, все можно в постапдейте сделать. Еще заметил проблему, что фокус скачком меняется. Особенно заметно при большом значении FocusTIme.

1vanK commented 8 years ago

void SmoothFocus::PostUpdate(float timeStep)
{
    if (!vp | !rp) return;

    float targetFocus = GetNearestFocus(camera->GetFarClip());

    smoothFocus = Lerp(smoothFocus, targetFocus, timeStep * 10.0f / smoothTimeSec);
    rp->SetShaderParameter("SmoothFocus", Variant(smoothFocus));
}
MonkeyFirst commented 8 years ago

float targetFocus = GetNearestFocus(camera->GetFarClip());

Рейкастить в каждом кадре?) Все-таки рейкаст не сильно часто то нужен. Поэтому ему самое место в "физическом тике" (60 раз в сек). В промежутке значения интерполируются. Хз почему он у тебя не вызывается.

И почему-то у меня твой вариант просто блюр, без каких либо намеков на четкость в какой либо части кадра. Или так задумано?) Там же условия для того чтобы - лерпить в зависимости от того какой "сырой каст"(smoothFocusRawLast) придет в зависимости от предыдущего "сырого фокуса". Своеобразный пинпонг для значения smoothFocus. И представь себе ситуацию когда фокус с 10м почти дошел до 500м за время (smoothTimeElapsed / smoothTimeSec) (чутку еще осталось) а потом меняется ветка с условиями потомучто камера переехала на новый фокус 20м, а время лерпа осталось еще меньше - smoothTimeElapsed / smoothTimeSec. Вот он и скачет. Как-то нужно по другому сделать, но я пока не думал над этим )

ДОФ не работает, если в сцене нет физики

И возвращаясь к заголовку, это очень странно, поскольку "физика" ему нафиг не нужна :) Рейкасты же из octree по рисуeмым объектам идут.

1vanK commented 8 years ago

FixedUpdate вызывается только если у сцены есть компонент PhysicsWorld (смотри LogicComponent.cpp). Когда ты в сцену добавляешь любой объект с компонентом RigidBody у сцены автоматом создается компонент PhysicsWorld.

Один рейкаст каждый кадр это очень мало, на производительности это не скажется.

1vanK commented 8 years ago

По поводу Lerpa, есть хитрый трюк )

Представь что при каждом вызове PostUpdate(float timeStep) этот самый timeStep равен к примеру 0.1 (от частоты кадров зависит).

И вот вызывается

smoothFocus = Lerp(smoothFocus, targetFocus, 0.1); smoothFocus = Lerp(smoothFocus, targetFocus, 0.1); smoothFocus = Lerp(smoothFocus, targetFocus, 0.1);

то есть на каждом кадре берется текущее значение и немного изменяется в строну целевого. Чтобы изменить скорость данного изменения нужны коэффициенты.

То есть не просто smoothFocus = Lerp(smoothFocus, targetFocus, timeStep); а smoothFocus = Lerp(smoothFocus, targetFocus, timeStep * 10.f); к примеру

Ну а так как у тебя задается скорость фокусировки параметром, то я его в коэффициент вставил.

smoothFocus = Lerp(smoothFocus, targetFocus, timeStep * 10.0f / smoothTimeSec);

Такой способ много где используется, например position = position.Lerp(targetPosition_, constant); в файле SmoothedTransform.cpp

Почему у тебя не работает не знаю, вот мой работающий пример https://gist.github.com/1vanK/5abb23c0d092616e8142

1vanK commented 8 years ago

Кстати, у тебя может не работать фокусировка, если ты забыл включить событие PostUpdate SetUpdateEventMask(USE_POSTUPDATE | USE_UPDATE);

MonkeyFirst commented 8 years ago

Кстати да, я забыл убрать в маске Update и оставить просто один - пост-апдейт

SetUpdateEventMask(USE_POSTUPDATE);

Теперь твой пример заработал )

FixedUpdate вызывается только если у сцены есть компонент PhysicsWorld

Я чет не подумал об этом, но это же issue в чистом виде. А что же делать, если у меня нет физики вообще, но мне нужен фиксированный вызов по времени? И я не хочу делать костыль и аккумулировать время по timeStep )

1vanK commented 8 years ago

Таймер вроде был в движке

MonkeyFirst commented 8 years ago

Нет, ты не так меня понял, я хотел бы дальше юзать FixedUpdate() Зачем её привязали "к наличию" того или иного компонента. Может в моей игре физика своя будет, на пальцах ) Кстати я обновил репозиторий с твоими правками.

1vanK commented 8 years ago

Кстати шейдер DOF из блендера, может будет интересно https://git.blender.org/gitweb/gitweb.cgi/blender.git/tree/refs/heads/master:/source/blender/gpu/shaders

MonkeyFirst commented 8 years ago

Да, наверное пригодится т.к. в части реконструкции Z буфера у меня вообще как мне кажется не правильно сейчас сделано.

1vanK commented 8 years ago

Fog по идее буфер глубины использует, может там чего-то можно поглядеть