前言:该笔记用于记录阅读《three开发指南》遇到的问题,标题对应着书籍的标题,记录的问题大多是从书籍three版本0.69迁移到新版0.164做的调整。
Three官网地址:https://threejs.org/
书籍github源码地址:https://github.com/josdirksen/learning-threejs
1、渲染并展示三维对象
A、书籍有使用到方法setClearColorHex(),该方法在本地控制台显示错误:
有说法是新版的three.js已废弃该方法使用setClearColor替代,项目使用的three.js版本为0.161.0。
B、书籍有使用THREE.AxisHelper构造函数,该方法在本地控制台显示报错:
C、书籍有使用THREE.CubeGeometry构造函数,该方法在本地控制台显示报错:
看书籍的github网址中代码使用的是THREE.BoxGeometry,找了下,发现并没有THREE.CubeGeometry是three.js以前版本构造函数的说法。
D、通过向THREE.MeshBasicMaterial传递配置wireframe,值为true或false(wireframe的默认值是false),控制是以线条的方式绘制物体。根据立方体的线条绘制,可以发现three.js跟WebGL一样,通过绘制三角形来绘制平面。
2、添加材质、灯光和阴影
A、物体修改位置可以单个修改(如a.position.x = 20,只修改x轴的位置),也可以通过set多个修改(如a.position.set(1, 2, 3),同时修改x、y、z轴的位置)。
B、书籍说材质为MeshBasicMaterial的物体不会对光源有反应,three.js中有两种可以对光源产生反应的材质:MeshLambertMaterial和MeshPhongMaterial。按照github的写法,先加入光源,将MeshBasicMaterial材质改成MeshLambertMaterial,发现本地的物体都是黑色的:
看了下,控制台没有报错。以为是光源的位置问题,调整了光源x、y、z各个的方向和大小,发现还是一片黑。直接复制github的示例代码,发现其绘制也是和之前一样。将材质MeshLambertMaterial改成MeshPhongMaterial,绘制的物体也还是一样。
拉取github代码,运行HTML发现绘制正常。。。
看了书籍使用的three的版本是0.69.0,调整本地three的版本与书籍一致,发现还是一片黑。
冲浪发现一篇文章A,不是只有我自己有这个问题,按对方的说法只修改spotLight的decay也是一样漆黑。对方说需要修改WebGLRenderer.physicallyCorrectLights才可以,尝试一下将renderer.physicallyCorrectLights设置为true,发现可以正常绘制光源映射在物体上,修改spotLight的decay的值,发现渲染效果一样,将其去掉,发现也是一样。
将本地的three版本改成最新的0.164.1,此版本WebGLRnderer已没有physicallyCorrectLights属性,将physicallyCorrectLights改成useLegacyLights,发现也可以正常绘制光源映射在物体上,相较于旧版的physicallyCorrectLights,useLegacyLights的绘制效果总体要亮一些。在控制台上,有属性useLegacyLights将被弃用的信息:
文章A下有说修改spotLight的intensity属性,看了官网禁用后的解决方式,感觉也是让大家用intensity。
C、按照书籍的方式添加代码,发现物体的阴影没有绘制出来。。。后面发现renderer.shadowMapEnabled = true要改成renderer.shadowMap.enabled = true。不过本地绘制效果相较于书籍的平滑,有点像马赛克:
看参考,说将renderer.shadowMapType的值设置为THREE.PCFSoftShadowMap,尝试后发现效果一样。根据上面的调整将renderer.shadowMapType改为renderer.shadowMap.type,刷新页面后,感觉是要好上一点:
3、弹跳球
A、书籍能够使球体来回跳动的原因是cos和sin的值在[-1, 1]之间,因需要球体在x方向上来回移动,所以不用管cos的方向。在y方向的运动要始终保持为正值,否则会球体会显示在plane的下面,所以用到了Math.abs取绝对值:
对于x方向和y方向并不要求符合书籍sin和cos的绝对赋值,调整位置后,球体的运动方向改变(需删除Math.abs的方向矫正才看得出来)。将x方向和y方向同时设置为cos或sin,球体的运动轨迹将发生改变,由n变成v。
4、使用ASCII效果
A、直接使用new THREE.AsciiEffect会报错,说它不是一个构造函数,需要将AsciiEffect将其单独引入进来,在three的0.164.1的版本,其引入方式为”import {AsciiEffect} from ‘three/examples/jsm/effects/AsciiEffect.js’”。