欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Threejs学习笔记(一) 基础篇

程序员文章站 2024-03-16 19:55:16
...

基本概念


一个完整的3D环境包含以下元素:

1.场景(Scene):是物体、光源等元素的容器,
2.相机(Camera):控制视角的位置、范围以及视觉焦点的位置,一个3D环境中只能存在一个相机
3.物体对象(Mesh):包括二维物体(点、线、面)、三维物体、粒子
4.光源(Light):包括全局光、平行光、点光源
5.渲染器(Renderer):指定渲染方式,如webGL\canvas2D\Css2D\Css3D等。
6.控制器(Control): 相机控件,可通过键盘、鼠标控制相机的移动

场景(Scene)
物体、光源、控制器的添加必须使用secen.add(object)添加到场景中才能渲染出来。
一个3D项目中可同时存在多个scene,通过切换render的scene来切换显示场景
var scene = new THREE.Scene();
var mesh=scene.getObjectByName(“sky”);//获取场景中name=sky的物体;
相机(Camera)
基本概念
相机根据投影方式分两种:正交投影相机和透视投影相机

正交投影相机:THREE.OrthographicCamera(left, right, top, bottom, near, far),大小不因远近而变化
透视投影相机:THREE.PerspectiveCamera(fov, aspect, near, far),遵循近大远小的空间规则

一般情况下,我们使用的是透视投影相机,其参数为:

fov: 垂直方向夹角
aspect:可视区域长宽比 width/height
near:渲染区域离摄像机最近的距离
far:渲染区域离摄像机最远的距离,3仅在距离摄像机near和far间的区域会被渲染到 canvas中

相机有两个重要的参数:

camera.position:控制相机在整个3D环境中的位置(取值为3维坐标对象-THREE.Vector3(x,y,z))
camera.lookAt:控制相机的焦点位置,决定相机的朝向(取值为3维坐标对象-THREE.Vector3(x,y,z))

以下代码创建一个垂直夹角为45度、渲染区域为距离镜头1px到1000000px的透视投影相机,设置其位置为x:500px,y:0,z:500px,镜头朝向空间坐标轴原点x:0,y:0,z:0

var camera = new THREE.PerspectiveCamera( 45, 1920 / 1000, 1, 1000000 );
camera.position.set(500, 0, 500);
camera.lookAt(new THREE.Vector3(0,0,0));

主要应用
1.设置相机焦点位置为原点坐标或某物体的位置坐标:camera.lookAt(new THREE.Vector3(0,0,0)),循环改变camera.position的位置,可以实现围绕物体旋转 360度观看物体的动画。
2.同时循环设置camera.lookAt和camera.position,可以实现以第一人称视角在空间*移动的动画
物体(Mesh)
一个完整的物体对象mesh包括形状Geometry和材质Material
Mesh:三维物体,包括Geometry、Material,设置其name属性可以通过scene.getObjectByName(name)获取该物体对象;
Geometry:包括平面Plane、圆形Circle、立方体Cube、球体Sphere、圆柱Cylinder、多面体Polyhedron等,拥有以下属性:
Material:包括基础材质MeshBasicMaterial,深度材质MeshDepthMaterial、法向材质MeshNormalMaterial、面材质MeshFacelMaterial、朗柏材质MeshLambertMaterial、phone材质MeshPhongMaterial、着色器材质ShaderMaterial
以下代码以创建name为sky一个立方体为例,使用6张图片作为材质贴到立方体内部
pointlight = new THREE.PointLight(0xffffff, 1, 3000);
pointlight.position.set(0, 0, 2000);//设置点光源位置
scene.add( pointlight );
var pointlight2 = new THREE.PointLight(0xffffff, 1, 2000);
pointlight2.position.set(-1000, 1000, 1000);
scene.add( pointlight2 );
var pointlight_back = new THREE.PointLight(0xffffff, 1, 2000);
pointlight_back.position.set(0, 0, -2000);
scene.add( pointlight_back );
var pointlight_left = new THREE.PointLight(0xffffff, 1, 2000);
pointlight_left.position.set( -2000, 0,0);
scene.add( pointlight_left );
var pointlight_right = new THREE.PointLight(0xffffff, 1, 2000);
pointlight_right.position.set(0, -2000, 0);
scene.add( pointlight_right );
渲染器(Renderer)
一般情况下我们使用的是WebGL渲染器,

var renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio( window.devicePixelRatio );//设置canvas的像素比为当前设备的屏幕像素比,避免高分屏下模糊
renderer.setSize( _container.offsetWidth, _container.offsetHeight );//设置渲染器大小,即canvas画布的大小
container.appendChild( renderer.domElement );//在页面中添加canvas
控制器(Controls)
FlyControls:飞行控制,用键盘和鼠标控制相机的移动和转动
OrbitControls::轨道控制器,模拟轨道中的卫星,绕某个对象旋转平移,用键盘和鼠标控制相机位置
PointerLockControls:指针锁定,鼠标离开画布依然能被捕捉到鼠标交互,主要用于游戏
TrackballControls:轨迹球控制器,通过键盘和鼠标控制前后左右平移和缩放场景
TransformControls:变换物体控制器,可以通过鼠标对物体的进行拖放等操作

项目中使用的是轨道控制器OrbitControls,并限制了上下旋转的角度范围和滚轮控制相机离中心点的最大距离和最小距离

var controls = new THREE.OrbitControls(camera,_container);
controls.maxPolarAngle=1.5;//上下两极的可视区域的最大角度
controls.minPolarAngle=1;//上下两极的可视区域最小角度
controls.enableDamping=true;//允许远近拉伸
controls.enableKeys=false;//禁止键盘控制
controls.enablePan=false;//禁止平移
controls.dampingFactor = 0.1;//鼠标滚动一个单位时拉伸幅度
controls.rotateSpeed=0.1;//旋转速度
// controls.enabled = false;//禁用控制器
controls.minDistance=1000;//离中心物体的最近距离
controls.maxDistance=3000;//离中心物体的最远距离
示例:

<script src="../js/lib/threejs/OrbitControls.js"></script>
<script>
     

        var container, stats;

        var camera, scene, renderer;

        var mouseX = 0, mouseY = 0;

        var windowHalfX = window.innerWidth / 2;
        var windowHalfY = window.innerHeight / 2;


        init();
        animate();
        var mesh;

        function init() {

            container = document.getElementById("space")
            camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 5000 );
            camera.position.set(0, 0, 1500);
             
            scene = new THREE.Scene();

            var ambient = new THREE.AmbientLight( 0xffffff );
            scene.add( ambient );
             
             
            var directionalLight = new THREE.DirectionalLight( 0xffffff );
            directionalLight.position.set( -5, 5, 5).normalize();
            scene.add( directionalLight );

            var pointlight = new THREE.PointLight(0x63d5ff, 1, 200); 
            pointlight.position.set(0, 0, 200);
            scene.add( pointlight );                
            var pointlight2 = new THREE.PointLight(0xffffff, 1, 200); 
            pointlight2.position.set(-200, 200, 200);
            scene.add( pointlight2 );
            var pointlight3 = new THREE.PointLight(0xffffff, 1.5, 200); 
            pointlight3.position.set(-200, 200, 0);
            scene.add( pointlight3 );

            var controls = new THREE.OrbitControls(camera,container);
        //controls.maxPolarAngle=1.5;
        //controls.minPolarAngle=1;
        controls.enableDamping=true;
        controls.enableKeys=false;
        controls.enablePan=false;
        controls.dampingFactor = 0.1;
        controls.rotateSpeed=0.1;
//      controls.enabled = false;
        //controls.minDistance=1000;
        //controls.maxDistance=3000;
             
             
             
            var path = "../resource/sky/";
            var format = '.jpg';
            var urls = [
                    path + 'px' + format, path + 'nx' + format,
                    path + 'py' + format, path + 'ny' + format,
                    path + 'pz' + format, path + 'nz' + format
                ];
            var skyMaterials = []; 
            for (var i = 0; i < urls.length; ++i) {
                var loader = new THREE.TextureLoader();
                loader.setCrossOrigin( this.crossOrigin );
                var texture = loader.load( urls[i], function(){}, undefined, function(){} );
                 
                skyMaterials.push(new THREE.MeshBasicMaterial({
                    //map: THREE.ImageUtils.loadTexture(urls[i], {},function() { }), 
                    map: texture, 
                    overdraw: true,
                    side: THREE.BackSide,
                    //transparent: true,
                    //needsUpdate:true,
                    premultipliedAlpha: true
                    //depthWrite:true,
                     
    //              wireframe:false,
                })
                ); 
                 
            } 
             
            var cube = new THREE.Mesh(new THREE.CubeGeometry(500, 500,500), new THREE.MeshFaceMaterial(skyMaterials)); 
            cube.name="sky";
            scene.add(cube);
            renderer = new THREE.WebGLRenderer();
            renderer.setPixelRatio( window.devicePixelRatio );
            renderer.setSize( window.innerWidth, window.innerHeight );
            container.appendChild( renderer.domElement );

            document.addEventListener( 'mousemove', onDocumentMouseMove, false );
            window.addEventListener( 'resize', onWindowResize, false );

        }

        function onWindowResize() {

            windowHalfX = window.innerWidth / 2;
            windowHalfY = window.innerHeight / 2;

            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();
            renderer.setSize( window.innerWidth, window.innerHeight );

        }

        function onDocumentMouseMove( event ) {

            mouseX = ( event.clientX - windowHalfX ) / 2;
            mouseY = ( event.clientY - windowHalfY ) / 2;

        }

        //

        function animate() {

            requestAnimationFrame( animate );
            render();

        }

        function render() {

// camera.position.x += ( mouseX - camera.position.x ) ;
// camera.position.y += ( mouseY - camera.position.y ) ;

            camera.lookAt( scene.position );

            renderer.render( scene, camera );

        }

</script>
</body>
相关标签: 笔记 three.js