最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • React 优化技巧在 Web 版光线追踪里的应用(下)

    正文概述 掘金(工业聚)   2020-12-24   354

    在《React 优化技巧在 Web 版光线追踪里的应用(上)》中,我们介绍了 JS 中的操作符重载方案;在《React 优化技巧在 Web 版光线追踪里的应用(中)》中,我们介绍了 Time Slicing 和 Streaming Rendering 优化策略。

    代码里的公式不再难看,UI 线程不再卡顿。用渐进的方式进行第一次渲染,用户更快的看见内容。这些都是不错的优化。

    不过,我们还可以做更多。

    进阶方案:Schedule

    React 即将发布的 Concurrency Mode 特性,里面包含了 Suspense 和 Schedule 的功能。它们的作用是,让 UI 的渲染根据不同的触发来源和模块重要程度,划分出优先级。

    一个页面,并非所有模块都一样重要。总有一些模块,如标题,头图,价格等,比其它模块(如侧边栏,广告)重要。

    页面中触发更新的来源,也并非一样紧急。比如响应用户输入,就应该比其它任何渲染请求更重要。为此,Facebook 工程师还专门向 Chrome 团队,贡献了 isInputPending 这个 API,可以知道当前是否有用户输入。如果有,React 可以及时截断当前任务,处理用户请求。

    对于我们的光线追踪场景来说,这种优先级关系也可以划分出来。比如相比背景,物体,特别是聚焦的物体,显然更重要。我们可以更多地计算物体所在的像素里的光线采样情况。

    特别的,很多时候,背景不需要反复地去计算光线,它可能每次计算,都得到同一个值。我们可以探测到这种情况,直接跳过它们,把计算资源放到更重要的像素位置里。

    优先级划分的策略,根据场景和需求的不同而变化。在此,我采用了一个相对通用的处理办法,就是对比前后两张图片的像素的均方误差(Mean Squared Error),按照误差大小进行排序,误差大的排前面,误差小的排后面。每次取前 20000 个来计算光线追踪。

    如此,我们相当于为光线追踪添加了一个最优化算法。光线追踪里发射多条随机光线,本身就是使用蒙特卡罗方法去拟合渲染方程,它在用模拟出来的统计平均值,不断地逼近渲染方程计算出来的理论值(对蒙特卡罗方法感兴趣的同学,可以点击《40+行JS代码打造你的2048游戏AI》了解它在游戏 AI 场景里的应用)。

    我们按照像素误差来排列我们的蒙特卡洛采样位置,可以更高效地逼近理论值。

    React 优化技巧在 Web 版光线追踪里的应用(下)

    首先,我们不能在一个 render 函数里把所有点位计算出来,我们需要细化出一个 renderByPosition 函数,如上所示。这样我们可以用这个函数,对像素点按照优先级进行光线追踪,而不必在 for 循环里无脑依次追踪。

    React 优化技巧在 Web 版光线追踪里的应用(下)

    然后我们新增 3 个数组,renderCount ,prevImageData 和 currImageData。

    之前无脑依次渲染,一个数字变量 innerCount 对所有像素点通用,相除即可以得到平均值。如今,每个像素点被渲染的次数,因为优先级的关系,可能不一致了。所以需要专门的一一记录。

    我们用 prevImageData 记住上一个颜色值,用 currImageData 记住当前的颜色值,方便用来计算误差。

    React 优化技巧在 Web 版光线追踪里的应用(下)

    误差计算很简单,就是实现一个获取均方误差的函数,然后根据上一张图片,当前的图片,计算出每个位置前后两个颜色的误差值(每个颜色值包含 RGBA 四个数字)。根据误差从大到小排列即可。

    React 优化技巧在 Web 版光线追踪里的应用(下)

    我们在数据消费端,也实现了一个 renderByPosition 函数,把光线追踪 ray.renderByPosition 的结果,跟 renderCount, prevImageData, currImageData 和 imageData.data 进行数据记录和同步。

    React 优化技巧在 Web 版光线追踪里的应用(下)

    我们在 render 函数里依然使用了 innerCount,去记录整体渲染的次数。当它大于 2 时,说明我们起码有两张图片,可以对比误差。因此,我们不再递归地去 render,而是切换到 scheduleRender 函数,根据优先级追踪光线。

    React 优化技巧在 Web 版光线追踪里的应用(下)

    scheduleRender 函数,先去获得误差列表,取前 20000 个误差最大的像素点,依次渲染。同时它也做了 Time Slicing 和 Streaming Rendering 处理,让 UI 保持流畅。

    React 优化技巧在 Web 版光线追踪里的应用(下)

    在 scheduleRender 函数的底部,我们通过 count 记录 scheduleRender 的次数,大于 5 次后,将渲染模式切换回整体渲染的 render 函数。

    这是因为,蒙特卡罗模拟里带有随机性,只靠第一和第二张图片的误差来排优先级,会存在概率性的忽视,现象是图片变得不平整,仿佛有很多坏点。按照一定频次,进行整体渲染,可以让运气坏的像素点得到重新鉴定的机会。

    通过切换 scheduleRender 和 render,我们尽可能消除了统计偏差。既实现了优先级划分,又保持了渲染的整体平滑效果。

    React 优化技巧在 Web 版光线追踪里的应用(下)

    花 1000 秒时间,渲染结果如上。上半部分是渲染的图片,下半部分是每个像素点的渲染次数,次数越多,颜色越白。我们可以很直观地看到,我们的计算资源主要分配在哪些地方。

    从图中我们可以看到,交界和阴影里的光线情况相对复杂,因此我们着重去拟合了这些地方的光线情况(更白)。而背景跟天空,颜色比较单一,投入的光线计算资源就应该比较少(更黑)。

    React 优化技巧在 Web 版光线追踪里的应用(下)

    重复多次后,我们可以看到,误差列表里的 value 值,越来越接近 0。意味着对理论值的拟合变得更好了。

    如上所示,通过 Schedule + MSE 最优化策略,我们用更短的时间,就得到了一个局部高清的图像。而不必等很长时间,去得到一个全局高清的图像。

    进阶方案:心理加速

    渲染性能上的优化,并非唯一的优化途径。

    物理意义上的快,跟人类心理感受上的快,有时也不是一致的。

    我们之所以在更新阶段进行 Schedule 渲染,是因为我们起码需要两张图片来计算误差梯度。

    但是,仔细一想。第一次渲染,难道就分不出优先级吗?

    根据我们对人类创造的图片的浏览经验,很容易可以总结出:图片中心的内容,比图片边缘的内容,往往更重要。而我们的 Streaming Rendering,仿照的是 React SSR 渲染 HTML 的模式,从上到下。

    对于 HTML 文档来说,从上到下渲染,无可厚非。然而我们是图片,我们应该从中间开始,往上下两个方向展开。

    React 优化技巧在 Web 版光线追踪里的应用(下)

    如上所示,我们仅仅改变了一下渲染的起始位置和方向,用户就更大概率看到他们更感兴趣的东西。而不是首先看到空无一物的天空。

    此外,人类视觉有自动捕捉模式的能力。我们不必完整渲染,靠人眼对物体的模式匹配,也能让用户知道图片里大概包含什么内容。因此,我们可以按照一定间隙,渲染部分更粗略的图片。

    React 优化技巧在 Web 版光线追踪里的应用(下)

    上图只渲染了一半像素,只花了一半的时间。我们确实能识别出图片里的大概内容。如此,我们可以快速地生成粗略图,让用户有视觉占位;结合前面一招,从中间展开像素,细化内容,实现更好的视觉体验。

    React 优化技巧在 Web 版光线追踪里的应用(下)

    如上所示,现在用户不仅更快看到视觉中心的物体,还对图片的整体有了一定的把握。我们的 Schedule 优先级策略,在首次渲染阶段也得到了成功的应用。

    总结

    回顾一下,我们可以看到,React/Vue 里的渲染优化策略,在其它地方同样适用。

    +-*/编译成函数调用,跟 JSX 编译成 React.createElement 函数调用如出一辙。

    长时间渲染卡住 UI 主线程,都能采用 Time Slicing 的做法。

    长时间等待一次完整渲染,都可以采用 Streaming Rendering 的做法。

    模块之间存在优先级划分,都可以采用 Schedule 的做法。

    以上是我在学习光线追踪的过程中,顺手解决的问题。还没有把它们做成开源的 babel 插件和库的计划,故在此分享一下思路,希望能帮助到一些同学。

    值得一提的是,我们仍未穷尽可用的优化方案;这里呈现的优化措施,仅仅是其中一小部分。比如,考虑到每个像素点的光线追踪都是独立的,把这个过程并行化(Parallelization),放到 Web Worker 或者 GPU 里计算,即能得到效率的显著改善。感兴趣的同学,可以自行探索。

    点击查看上图的在线 DEMO。手机端也能体验噢。


    起源地下载网 » React 优化技巧在 Web 版光线追踪里的应用(下)

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元