当前位置: 首页 > news >正文

说说Babylon.js中scene.deltaTime的大坑

诡异的问题      

        下面是给一个材质设置发光颜色周期变化和纹理偏移的代码,你能感觉到这里面可能出现的问题吗?

        var passTime = 0;var uOffset = 0;var deltaTime = 0;function SetEmissiveColor() {passTime += scene.deltaTime * 0.05;if(passTime > 6.2832) passTime -= 6.2832;var multi = (Math.sin(passTime) + 1) * 0.5;material.emissiveColor = new BABYLON.Color3(9 * multi, 2.75 * multi, 0);var offset = scene.deltaTime * 0.001;material.diffuseTexture.uOffset -= offset;material.opacityTexture.uOffset -= offset;}scene.onBeforeRenderObservable.add(SetEmissiveColor);

        实际在浏览器中运行时,你会发现有可能完全没有实现预期的效果。如果你打印一下passTime的值,可能是一直都是NaN,所以最终会导致material.emissiveColor 的值完全不可用。

        这是咋回事呢?原来scene.deltaTime  在场景的第一帧渲染之前是  undefined,这导致 passTime变量在下面这行代码

passTime += scene.deltaTime * 0.05;

执行的时候就变成了NaN,然后NaN的自增就一直是NaN了,所以计算得到的颜色值也就一直错了,哈哈。

       下面说说解决方法。

解决方法一

        添加if语句检查scene.deltaTime的值是否可用,参考代码如下:

        var passTime = 0;var uOffset = 0;var deltaTime = 0;function SetEmissiveColor() {if (scene.deltaTime !== void 0 && !isNaN(scene.deltaTime)){passTime += scene.deltaTime * 0.05;if(passTime > 6.2832) passTime -= 6.2832;var multi = (Math.sin(passTime) + 1) * 0.5;material.emissiveColor = new BABYLON.Color3(9 * multi, 2.75 * multi, 0);var offset = scene.deltaTime * 0.001;material.diffuseTexture.uOffset -= offset;material.opacityTexture.uOffset -= offset;}}scene.onBeforeRenderObservable.add(SetEmissiveColor);

        上述代码在执行passTime的自增的之前通过 if 语句对scene.deltaTime进行了检查,这样就不会在scene.deltaTime不可用的时候进行计算了。

        知识点:scene.deltaTime !== void 0 这个判断里面也可以写成 scene.deltaTime !== undefined,但是这里为啥用的是 void 0 而没有用undefined 呢,下面这个链接讲了这个问题:

 关于void 0 与 undefined。

解决方法二

        使用定时器,由于scene.deltaTime只是在第一帧渲染完成之前有问题,就没有必要每帧判断,下面的代码在定时器中判断scene.deltaTime的值,待其合理之后再把SetEmissiveColor方法添加到scene.onBeforeRenderObservable事件中,与此同时移除了这个定时器,这样就避免了每帧都要检查scene.deltaTime的合理性。参考代码如下:

        var passTime = 0;var uOffset = 0;var deltaTime = 0;function SetEmissiveColor() {passTime += scene.deltaTime * 0.05;if(passTime > 6.2832) passTime -= 6.2832;var multi = (Math.sin(passTime) + 1) * 0.5;material.emissiveColor = new BABYLON.Color3(9 * multi, 2.75 * multi, 0);var offset = scene.deltaTime * 0.001;material.diffuseTexture.uOffset -= offset;material.opacityTexture.uOffset -= offset;}var checkDeltaTime = setInterval(function () {if (scene.deltaTime !== void 0 && !isNaN(scene.deltaTime)) {scene.onBeforeRenderObservable.add(SetEmissiveColor);//scene.deltaTime可用之后再添加到事件中clearInterval(checkDeltaTime); // 清除定时器}}, 20); // 每20毫秒检查一次

解决方法三

        不使用scene.deltaTime,改用engine.getDeltaTime()方法,参考代码如下:

        var passTime = 0;var uOffset = 0;var deltaTime = 0;function SetEmissiveColor() {passTime += engine.getDeltaTime() * 0.05;console.log(engine.getDeltaTime());if(passTime > 6.2832) passTime -= 6.2832;var multi = (Math.sin(passTime) + 1) * 0.5;material.emissiveColor = new BABYLON.Color3(9 * multi, 2.75 * multi, 0);var offset = engine.getDeltaTime() * 0.001;material.diffuseTexture.uOffset -= offset;material.opacityTexture.uOffset -= offset;}scene.onBeforeRenderObservable.add(SetEmissiveColor);

        这里的engine.getDeltaTime()在第一帧渲染完成之前会被赋值为0,不会出现值为NaN的情况(scene.deltaTime为啥就不能这么干呢???)。

        好了,就到这里,通过这个问题又学会了一些东西,大家共勉。

http://www.lryc.cn/news/522087.html

相关文章:

  • 【React】win系统环境搭建
  • ThinkPHP 8的一对一关联
  • Linux 下配置 Golang 环境
  • 爬虫后的数据处理与使用(使用篇--实现分类预测)
  • arcgis提取不规则栅格数据的矢量边界
  • python milvus 如何检查有多少个collection 以及多少个index,多少个database
  • 2006-2020年各省工业增加值数据
  • 【MySQL】使用C语言链接
  • Vue篇-07
  • 使用 LLaMA-Factory 微调大模型
  • 数据仓库的复用性:模型层面通用指标体系、参数化模型、版本化管理
  • Web APP 阶段性综述
  • 某国际大型超市电商销售数据分析和可视化
  • 电子杂志制作平台哪个好
  • Django Admin 实战:实现 ECS 集群批量同步功能
  • 虚拟拨号技术(GOIP|VOIP)【基于IP的语音传输转换给不法分子的境外来电披上一层外衣】: Voice over Internet Protocol
  • 迅为RK3576开发板Android 多屏显示
  • cmake + vscode + mingw 开发环境配置
  • nginx 配置代理,根据 不同的请求头进行转发至不同的代理
  • 类模板的使用方法
  • 高级Python Web开发:FastAPI的前后端集成与API性能优化
  • 期权懂|期权的溢价率和杠杆率有什么区别?
  • 分布式ID的实现方案
  • Py之cv2:cv2(OpenCV,opencv-python)库的简介、安装、使用方法(常见函数、图像基本运算等)
  • 如何学习网络安全?有哪些小窍门?
  • Dart语言的数据结构
  • TabPFN - 表格数据基础模型
  • AOF日志:宕机了Redis如何避免数据丢失?
  • MAC上安装Octave
  • C 语言中二维数组的退化