以较低的分辨率渲染某些内容

时间:2019-02-11 15:38:38

标签: performance mobile three.js render resolution

我正在使用昂贵的海洋着色器(https://threejs.org/examples/webgl_shaders_ocean.html),它会破坏旧版移动设备中的用户体验(帧速率从60fps降至20fps)。如果在渲染器上设置较低的像素比率(2而不是3),则我可以获得两倍的FPS(约40fps)。我还将以编程方式将画布大小减小到50%,然后通过CSS将其增大以填充屏幕,但分辨率较低。

这两个动作是我现在可以提高性能的最佳方法。但是成本很高,因为不仅在海洋中,而且在场景中涉及的所有其他模型中,我都失去了很多分辨率。

我正在寻找一种方法来以低分辨率渲染昂贵的零件(例如此着色器材质),然后在渲染后还原它,我的意思是:在海洋网格平面上定义onBeforeRender,以便将分辨率降低到1 / 3,例如。然后,在渲染网格之后,我可以使用onAfterRender恢复原始像素比率。我可以毫无问题地降低onBeforeRender的分辨率,但是当我恢复onAfterRender的原始高质量分辨率时,屏幕变黑。这些是我对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.25dpi。可以,但是如果您取消第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 :(得分:1)

导致海洋渲染缓慢的部分原因是环境立方体贴图的每帧重建。如果您没有靠近水的物体在不断变化,那么您可能会偶尔或仅在切换天空或其他事物时更新一次环境地图而无法使用。

编辑:只需重新阅读您的问题即可,您可能会走上正确的道路。您将需要控制清除自己的帧缓冲区。设置renderer.autoClear = false,然后在渲染缩小的海洋之前调用renderer.clear()。否则,三者会在渲染海洋后自动清除缓冲区。 @spacorum

我的最初答案也可能仍然适用,如果不需要每帧完整的envmap重建,则可以以全分辨率渲染水。