threejs-入坑

threejs-入坑, 官网GitHub:


前篇


tomcat运行官方examples

  1. 安装好tomcat

  2. 直接在 D:\apache-tomcat-8.5.32\conf\server.xml 文件中将这个路径改为 threejs clone 下来的仓库即可

    1
    2
    3
    4
    5
    <Connector port="80" protocol="HTTP/1.1" # 端口也改成80

    <Host name="localhost" appBase="webapps"
    unpackWARs="true" autoDeploy="true">
    <Context path="" docBase="E:\workplace_threejs\threejs" /> # 改成 threejs 路径
  3. 启动tomcat, 访问: http://localhost/examples/


动画库


参考


3dmax 导出模型

方式一: 全部导出到一个fbx

模型加载

  • FBXLoader

    1
    2
    <script src="./lib/inflate.min.js"></script>
    <script src="./lib/FBXLoader.js"></script>

    其中出现了个inflate.min.js,是FBXLoader在使用时所必须的插件。

    • 在 web端 只需如上 src 进来
    • 在 微信小游戏中 , 需要 inflate.min.js , 及 zlib

render target 使用

  • 和unity中的概念差不多. 不过unity中的使用是通过 layercull 决定摄像机是否照射某个物体, 而 threejs 中则是 将一个 摄像机所照射的某个场景 渲染到一个 THREE.WebGLRenderTarget 对象中, 如

    1
    2
    3
    4
    5
    6
    7
    const RenderTarget = new THREE.WebGLRenderTarget( RT_SIZE, RT_SIZE);
    const RTScene = new THREE.Scene();
    const Camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 1000 );
    const Renderer = new THREE.WebGLRenderer( {
    antialias: true // 开启消除锯齿
    } );
    Renderer.render(RTScene, Camera, RenderTarget); // 离屏渲染并存放到 RenderTarget 里

    所以 threejs 中需要 单独一个scene 用来装需要被摄像机照射的物体

  • 渲染源码:

    WebGLRenderer.js

    1
    2
    3
    4
    5
    6
    7
    this.render = function ( scene, camera, renderTarget, forceClear ) {
    this.setRenderTarget( renderTarget );
    }

    this.setRenderTarget = function ( renderTarget ) {
    ...
    }
  • 参考


shader

自定义shader材质球

  • 源码中绘制 cubeTexture 就是使用

    WebGLBackground.js

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    new ShaderMaterial( {
    uniforms: UniformsUtils.clone( ShaderLib.background.uniforms ),
    vertexShader: ShaderLib.background.vertexShader,
    fragmentShader: ShaderLib.background.fragmentShader,
    side: FrontSide,
    depthTest: true,
    depthWrite: false,
    fog: false
    } )
    );
  • 参考


传递 uniform 变量

从 cpu 传递参数到 gpu 中

  1. 在 fragment 中定义一个 uniform 变量

    1
    2
    3
    4
    5
    uniform float time22;
    void main() {
    ...
    float a = time22 * 40.0; // 使用这个变量
    }
  2. js 中程序中定义一个所有 uniform 的 object.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    var uniforms = {
    "time11": { value: 1.0 },
    "time22": { value: 1.0 }
    };

    var material = new THREE.ShaderMaterial( {
    uniforms: uniforms, // 复制给自定义材质球的 uniforms 字段
    vertexShader: document.getElementById( 'vertexShader' ).textContent,
    fragmentShader: document.getElementById( 'fragmentShader' ).textContent

    } );
  3. js 中动态修改 uniform 值

    1
    uniforms[ "time22" ].value = timestamp / 10000;

模板测试


后处理

使用了组合


opengl api


显示线框

1
2
3
4
5
6
7
8
9
10
11
var postPlane = new THREE.PlaneBufferGeometry( 2, 2 );
var postQuad = new THREE.Mesh( postPlane, postMaterial );
postScene = new THREE.Scene();
// postScene.add( postQuad );

// 线框显示
var lineMaterial = new THREE.LineBasicMaterial( { color: 0x00ff00, transparent: true, opacity: 1 } );
var group = new THREE.Group();
group.add( new THREE.LineSegments( postPlane, lineMaterial ) );
group.add( postQuad );
postScene.add( group );

适配微信小游戏

参考

采坑

  • 加入 threejs 相关库 比如 FBXLoader.js 是, 报错 ReferenceError: THREE is not defined

    临时处理方法只要在 FBXLoader.js` 第一行粗暴的添加这行代码引入即可:

    1
    var THREE = require('three.min');

    参考: https://www.indienova.com/indie-game-development/wechat-mini-game-notes-threejs-load-model-and-interaction/

  • 使用 FBXLoader.js 的 load 函数时报错 TypeError: n.addEventListener is not a function

    weapp-adapter.js 中找到 XMLHttpRequest 的定义部分,为其增加一个新的 key

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    {
    key: 'addEventListener',
    value: function addEventListener(type, listener) {
    if (typeof listener === 'function') {
    let event = { target: this }
    let that = this
    this['on' + type] = function () {
    listener.call(that, event)
    }
    }
    }
    }
  • 加载相关

    • 模型加载 FBXLoader 和 JSONLoader 貌似只能通过 http或https 远程下载加载.
    • TextureLoader 可以本地加载


采坑


TODO:

  • 2D sprite 显示
  • ui 展示
  • 3d model 显示
  • 动画