Three.js随笔

1 篇文章 0 订阅
1 篇文章 0 订阅

CSS3DRenderer主要作用是能够将css中的节点转化为3dObject对象  能实现three.js中的常规操作
利用webgl做全景
利用webgl做天气预报   显示天气的动画效果 
利用webgl实现视屏全景 webgl_video_panorama_equirectangular

/-------------------------------------------------------

要想让摄像机随着鼠标移动设置而移动的实现方式
关键代码
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
var mouseX = 0, mouseY = 0;

在初始化方法init()中添加添加鼠标移动的监听  
document.addEventListener( 'mousemove', onDocumentMouseMove, false );

创建获取鼠标位置的方法及onDocumentMouseMove
function onDocumentMouseMove( event ) {
    mouseX = event.clientX - windowHalfX;
    mouseY = event.clientY - windowHalfY;
}

最后在animate()方法里  因为每秒会进行60次的渲染   所在在里面修改照相机的lookAt()
就能实现目标效果
camera.position.x += ( mouseX - camera.position.x ) * 0.05;
camera.position.y += ( - mouseY - camera.position.y ) * 0.05;
camera.lookAt( scene.position );

/----------------------注意事项---------------------------------

1、new THREE.TextureLoader().load('')取代了THREE.ImageUtils.loadTexture

2、如果使用了CSS3DObject  记得在init方法里面使用下面代码
renderer2 = new THREE.CSS3DRenderer();
renderer2.setSize( window.innerWidth, window.innerHeight );
renderer2.domElement.style.position = 'absolute';
renderer2.domElement.style.top = 0;
document.getElementById("WebGL-output").appendChild(renderer2.domElement);

3、var sprite = new THREE.TextureLoader().load( 'textures/sprites/disc.png' );
如果你要添加一些图片纹理   记得使用上面那种方式   然后再material材质的map里面加入sprite
如下
var starsMaterial = new THREE.PointsMaterial({size: 35,map:sprite});
var starField = new THREE.Points( starsGeometry, starsMaterial );

4、使用粒子或粒子系统时记得使用粒子材质  PointsMaterial

5、geometry为三维空间中的点集同点集闭合后的各个面的集合
Vector3 .velocityY .velocityY 主要用来设置点的x轴y轴位移速度
geom.vertices.push(particle);通过这种方式使得Vector3的点加入到geometry点集中  组成一个PointsSystem

6、当前的JSONLoader已经失效   如果要将以json格式存储在js文件上的模型粒子化  那么当前最新版本只能使用
var loader = new THREE.LegacyJSONLoader();
loader.load('textures/demo/game.js', function (geo, materials) {
    var colors = [];
    for (var i = 0; i < geo.vertices.length; i++) {
        colors.push(new THREE.Color("rgb(255, 255, 255)"))
    }
    geo.colors = colors;
    geo.center();
    geo.normalize();
    geo.scale(500, 500, 500)
    geo.rotateX(Math.PI / 4)
    geo.rotateY(-Math.PI / 8)
    glist.push(geo)
})

7、设置Mesh对象平移 大小伸缩 旋转角度 位置
Mesh.translateX=30 //设置Mesh对象在X轴的平移
Mesh.scale.set(1,1,1) //设置Mesh对象x、y、z方向上的比例大小 大小伸缩
Mesh.position.x //设置Mesh的x,y,z位置
Mesh.material = new THREE.MeshBasicMaterial();//设置Mesh对象的材质

8、three.js设置布局(div)的大小
renderer.setSize( 580, 510 );
通过渲染设置大小来达到控制div的大小,否则将会占据很大一个空间

9、世界坐标和屏幕坐标之间的转换

10、创建运动轨迹 
首先创建一条移动路径  然后在render循环中动态的从路径中取点,设置成相机的位置
        progress += 0.003;
        let point = path.getPointAt(progress);
        if(point){
          camera.position.set(point.x,point.y,300);
        }else{
          progress = 0;
        }

11、three.js 加载模型  模型的中心点偏离原点的解决方案
new THREE.OBJLoader()
.setMaterials( materials )
.setPath( 'textures/demo4/' )
.load( '消防设备.obj', function ( object ) {
    object.children[0].geometry.computeBoundingBox();//这两行代码最关键
    object.children[0].geometry.center();//这两行代码最关键          
    helper = new THREE.BoundingBoxHelper(object, 0xff0000);
    helper.update();
    //scene.add(helper);
    //object.rotation.y = 2 * Math.PI;
    console.log(object);
    scene.add( object );

});


12、three.js 记载纹理重复映射
给平面加载纹理  并且重复映射
首先创建纹理  加载贴图
var textureLoader = new THREE.TextureLoader();
texture = textureLoader.load('textures/demo4/sngz.jpg');
然后创建平面给平面贴图
var planeGeometry = new THREE.PlaneGeometry(1000, 1000);//创建一个宽60  长20的平面
var planeMaterial = new THREE.MeshBasicMaterial({
    map: texture,
});
var plane = new THREE.Mesh(planeGeometry, planeMaterial);//创建该平面
添加平面设置平面的纹理重复映射以及他的值
scene.add(plane);//将创建的平面对象放到scene容器里面
plane.material.map.wrapT = THREE.RepeatWrapping;
plane.material.map.wrapS = THREE.RepeatWrapping;
plane.material.map.repeat.set(70,70);

13、如何给一个平面正反面添加不同的纹理
var geometry1 = new THREE.PlaneGeometry( 90, 110, 1, 1 );
var geometry2 = new THREE.PlaneGeometry( 90, 110, 1, 1 );
geometry2.applyMatrix( new THREE.Matrix4().makeRotationY( Math.PI ) );
var textureFront = new THREE.ImageUtils.loadTexture('textures/demo4/标识-男性.png' );      
var textureBack = new THREE.ImageUtils.loadTexture('textures/demo4/标识-男性.png' );
// material
var material1 = new THREE.MeshBasicMaterial( { color: 0xffffff, map: textureFront } );
var material2 = new THREE.MeshBasicMaterial( { color: 0xffffff, map: textureBack } );
// card
card = new THREE.Object3D();
scene.add( card );
// mesh
mesh1 = new THREE.Mesh( geometry1, material1 );
card.add( mesh1 );
mesh2 = new THREE.Mesh( geometry2, material2 );
card.add( mesh2 );
这样在实现效果上看上去就好像是一个平面与两个材质

14、threejs里继承了Object3D的类都可以加载事件。这些类包含mesh,camera,group等等。
15、如何给three.js line对象的定点设置颜色
//定义直线纹理
var material = new THREE.LineBasicMaterial({
    opacity: 1.0, //设置透明度
    linewidth: 1, //设置线的宽度
    vertexColors: THREE.VertexColors //设置这个可以给每个顶点指定一种颜色
});
/-------------------------------------------------------

                            如何生成粒子模型
var loader = new THREE.OBJLoader();
loader.load('models/obj/female02/female02.obj', function (object) {
    console.log(object);
    group = createPointsCloud(object);
    group.position.y=-40;
    scene.add(group);
});

//创建点云   通过循环的方式将模型的所有Mesh对象的geometry都点化  形成PointsSystems
function createPointsCloud(object) {
    var sprite = new THREE.TextureLoader().load( 'textures/gradient.png' );
    /* 精灵材质 */
    let spriteMaterial = new THREE.PointsMaterial({
        color: 0xffffff,
        size:0.23,
        transparent: true,
        map: sprite,blending: THREE.AdditiveBlending,
        depthTest: false,
    });
    var group = new THREE.Group();
    for(var i=0 ; i< object.children.length ;i++){
        var geometry = object.children[i].geometry;
        var points = new THREE.Points(geometry, spriteMaterial);
        group.add(points);
    }
    return group;

/-------------------------------------------------------
wbgl设置线条粗细 虚线 设置线模型Line对应线材质LineBasicMaterial的线宽属性.lineWidth,可能是无效果
故这里使用了一个新的对象Line2  使用该对象  需要引入一下几个js脚本    

<script src='/js/lines/LineSegmentsGeometry.js'></script>
<script src='/js/lines/LineGeometry.js'></script>
<script src='/js/lines/LineMaterial.js'></script>
<script src='/js/lines/LineSegments2.js'></script>
<script src='/js/lines/Line2.js'></script>
var geometry = new THREE.LineGeometry();  
// 顶点坐标构成的数组pointArr
var pointArr = [-1000,0,0,
                1000,0,0,
                ]
// 几何体传入顶点坐标
geometry.setPositions( pointArr);
// 自定义的材质
var material  = new THREE.LineMaterial( {
  color: 0x33FF00,
  // 线宽度
  linewidth: 8,
  dashed: false,
} );
// 把渲染窗口尺寸分辨率传值给材质LineMaterial的resolution属性
// resolution属性值会在着色器代码中参与计算
material.resolution.set(window.innerWidth,window.innerHeight);
var line = new THREE.Line2(geometry, material);
line.computeLineDistances();
scene.add(line);
line.position.y=10;
material.dashed=true;
material.defines.USE_DASH = "";
material.dashScale = 0.5;
material.needsUpdate = true;


设置管道流动
var curve = new THREE.CatmullRomCurve3([
  new THREE.Vector3(-100, 0, 0),
  new THREE.Vector3(100, 0, 0),
  new THREE.Vector3(100, 0, 50),
  new THREE.Vector3(100, 0, 50),
 // new THREE.Vector3(70, 40, 0),
  //new THREE.Vector3(80, -40, 0)
],false/*是否闭合*/);


var tubeGeometry = new THREE.TubeGeometry(curve, 100, 1, 50, false);
var textureLoader = new THREE.TextureLoader();
texture = textureLoader.load('textures/demo4/run.png');
// 设置阵列模式为 RepeatWrapping
texture.wrapS = THREE.RepeatWrapping;
texture.wrapT=THREE.RepeatWrapping;
// 设置x方向的偏移(沿着管道路径方向),y方向默认1
//等价texture.repeat= new THREE.Vector2(20,1)
texture.repeat.x = -20;
var tubeMaterial = new THREE.MeshBasicMaterial( { 
    map:texture,
    color: 0x2292dd ,
    transparent: true,
    opacity: 0.7
});

var tube = new THREE.Mesh(tubeGeometry, tubeMaterial);
scene.add(tube);
tube.position.y=10;

然后再animation()方法里面设置纹理的偏移
texture.offset.x -= 0.06;

/-------------------------------------------------------

three.js  demo的大概框架
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script src="../build/three.js"></script>
    <script src="js/controls/OrbitControls.js"></script>
    <script src="js/jquery-3.3.1.min.js"></script>
</head>
<body>
    <div id="WebGL-output"></div>
    <script type="text/javascript">
        
        var scene,camera,renderer,controls;

        init();
        animate();


        function init(){
            scene = new THREE.Scene();
            scene.background = new THREE.Color( 0x000000);
            
            camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000);
            camera.position.set( 200, 200, 200 );
           
        
            //---------------------------------------------------------------------------    
            具体内容

            
            //-----------------------------------------------------------------------------------
            renderer = new THREE.WebGLRenderer( { antialias: true } );
            renderer.setPixelRatio( window.devicePixelRatio );
            renderer.setSize( window.innerWidth, window.innerHeight );
            document.getElementById("WebGL-output").appendChild(renderer.domElement);

            controls = new THREE.OrbitControls( camera );
           
        }

        function animate() {        
            controls.update();
            requestAnimationFrame( animate );
            renderer.render(scene, camera);
        }

    
    </script>
</body>
</html>

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值