Рендеринг некоторого содержимого в более низком разрешении - PullRequest
0 голосов
/ 11 февраля 2019

Я использую дорогой океанский шейдер (https://threejs.org/examples/webgl_shaders_ocean.html), который убивает пользовательский опыт на старых мобильных устройствах (частота кадров падает с 60 к / с до 20 к / с). Если для рендерера установлено более низкое соотношение пикселей (2 вместо3) я могу получить двойной FPS (около 40 кадров в секунду). Я также уменьшаю размер холста программно до 50%, позже увеличивая его с помощью CSS для заполнения экрана, но с более низким разрешением.

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

ЯПод поиском способа визуализации дорогих деталей (например, этого материала шейдера) с низким разрешением, чтобы восстановить его после рендеринга, я имею в виду: определим onBeforeRender на плоскости сетки океана, чтобы я мог уменьшить разрешение, например, до 1/3.Затем, после рендеринга сетки, я могу использовать onAfterRender для восстановления исходного соотношения пикселей. Я могу уменьшить разрешение на BeforeRender безпроблема, но когда я восстанавливаю оригинальное качественное разрешение на AfterFender, экран гаснет.Это мои изменения в https://threejs.org/examples/js/objects/Water.js

scope.onBeforeRender = function ( renderer, scene, camera ) {       
    (original onBeforeRender code)

    renderer.setPixelRatio( 0.5 );
    renderer.render( scene, mirrorCamera, renderTarget, false );
};


scope.onAfterRender = function ( renderer, scene, camera ) {
    renderer.setPixelRatio( 2 );
};

Я бы хотел знать, верна ли эта стратегия.Я на правильном пути, по крайней мере?Вот основной JSFiddle, чтобы проиллюстрировать проблему.Есть метод с именем "overrideFunctions ()", который переопределяет Water.js onBeforeRender (), чтобы уменьшить соотношение пикселей перед рендерингом океана.Затем мы определяем «onAfterRenderer ()», чтобы восстановить исходное качество, чтобы модели могли отображаться с высоким разрешением.

https://jsfiddle.net/spacorum/y5398gLm

Три комментария.Если вы раскомментируете строку 168, глобальное качество снизится до 0,25 точек на дюйм.Это нормально, но если вы затем раскомментируете строку 174, модели исчезнут, небо станет черным ... и холст будет слишком маленьким.Я также попробовал ваше предложение renderer.clear () перед рендерингом океана, но сейчас это не имеет значения.Так близко ..


РЕДАКТИРОВАТЬ 3: Это самое близкое, что я должен показать, что мне нужно.Изолированная версия океана с низким разрешением, включая отражения.Если бы мне удалось отобразить остаток в нормальном разрешении, это было бы сделано: https://jsfiddle.net/spacorum/f63z2ceg/

enter image description here


РЕДАКТИРОВАТЬ 4: Просто пытаюсь использовать другую технику: основную сцену и фоновую сцену.Я уже пробовал нечто подобное в последнее время, но я застрял.В этом тесте мне удалось отобразить версию моря с низким разрешением, визуализировав его фоновую сцену в WebGLRenderTarget (используя только 1/10 размера окна).Кажется, это улучшается, но я не уверен, что расчеты одинаковы, и я просто отображаю его в более низком разрешении.В любом случае, следуя этому пути, я не могу заставить сферу смотреть в море (я думаю, что это совершенно нормально, поскольку они находятся в разных сценах, верно?).Может ли renderer.clearDepth помочь здесь как-нибудь?https://jsfiddle.net/spacorum/wbtcx9re/

enter image description here


РЕДАКТИРОВАТЬ 5: Мой последний подход, смешивание EDIT3 и EDIT4.Есть две сцены: океан / солнце, добавленные к фоновой / вторичной сцене и сфера к основной.Не выполняя renderer.clear () и не устанавливая для Renderer.autoClear значение false, я могу отрендерить обе сцены, и сфера «входит» в океан, добавленный к вторичной сцене, пока что все хорошо.(Конечно, пока нет отражения, но я могу исправить это, добавив копию сферы во вторичную сцену).Затем я могу уменьшить разрешение перед рендерингом вторичной сцены (строка 166).Но если я восстановлю его позже, чтобы сфера визуализировалась в исходном разрешении (раскомментирующая строка 173), первая сцена исчезает и становится белой. Я не могу понять, почему изменение разрешения два раза вызывает это, я могу забыть обновитьчто-то после этого, но я не вижу этого: / https://jsfiddle.net/spacorum/o91se8fz/

enter image description here

1 Ответ

0 голосов
/ 11 февраля 2019

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

Редактировать: просто перечитайтевопросы .. и вы можете быть на правильном пути.Вам нужно будет контролировать очистку буфера кадров самостоятельно.Установите renderer.autoClear = false и вызовите renderer.clear (), прежде чем рендерить уменьшенный океан.В противном случае три автоматически очищает ваш буфер после рендеринга океана.@ spacorum

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

...