零基础学习three.js_第二天

137 阅读6分钟

第二天

一、几何体和网格

1.圆环几何体

  • 添加一个圆环几何体
  • radius - 圆环的半径,从圆环的中心到管道(横截面)的中心。默认值是1。
  • tube — 管道的半径,默认值为0.4。
  • radialSegments — 圆环的分段数,默认值为8。
  • tubularSegments — 管道的分段数,默认值为6。
  • arc — 圆环的中心角(单位是弧度),默认值为Math.PI * 2。

        var geometry = new THREE.TorusGeometry(10, 3, 16, 100); // 圆环几何体 
        var material = new THREE.MeshLambertMaterial({ color: 0xffff00 }); // 创建一个材质
        var torus = new THREE.Mesh(geometry, material); // 合并为网格
        torus.castShadow = true
        torus.position.x = 0
        torus.position.y = 10;
        torus.position.z = 0
        scene.add(torus);

2.圆柱几何体

参数:

  • 1.radiusTop — 圆柱的顶部半径,默认值是1。
  • 2.radiusBottom — 圆柱的底部半径,默认值是1。
  • 3.height — 圆柱的高度,默认值是1。
  • 4.radialSegments — 圆柱侧面周围的分段数,默认为8。
  • 5.heightSegments — 圆柱侧面沿着其高度的分段数,默认值为1。
  • 6.openEnded — 一个Boolean值,指明该圆锥的底面是开放的还是封顶的。默认值为false,即其底面默认是封顶的。
  • 7.thetaStart — 第一个分段的起始角度,默认为0。(three o'clock position)
  • 8.thetaLength — 圆柱底面圆扇区的中心角,通常被称为“θ”(西塔)。默认值是2 * Pi,这使其成为一个完整的圆柱。
var geometry = new THREE.CylinderGeometry(0, 5, 20, 32);// 圆柱几何体 
        var material = new THREE.MeshLambertMaterial({ color: 0xffff00 });// 创建一个材质
        var cylinder = new THREE.Mesh(geometry, material); // 合并为网格
        cylinder.castShadow = true
        cylinder.position.x = 30
        cylinder.position.y = 20;
        cylinder.position.z = 0
        scene.add(cylinder);

3.自定义几何体

		var geometry = new THREE.BufferGeometry();
        // 创建一个简单的矩形. 在这里我们左上和右下顶点被复制了两次。
        // 因为在两个三角面片里,这两个顶点都需要被用到。
        var vertices = new Float32Array([
            -1.0, -1.0, 1.0,
            10.0, -1.0, 10.0,
            10.0, 10.0, 10.0,

            10.0, 10.0, 10.0,
            10.0, -1.0, 10.0,
            -1.0, -1.0, 1.0,
        ]);

        // itemSize = 3 因为每个顶点都是一个三元组。
        geometry.addAttribute('position', new THREE.BufferAttribute(vertices, 3));
        var material = new THREE.MeshBasicMaterial({ color: 0xff0000 });
        var mesh = new THREE.Mesh(geometry, material);
        
        mesh.position.x = 0
        mesh.position.y = 30;
        mesh.position.z = 0
        // scene.add(mesh)

        // 添加线条
        // 网格几何体(WireframeGeometry)
        // 这个类可以被用作一个辅助物体,来对一个Geometry以线框的形式进行查看。
        var geometry = new THREE.SphereBufferGeometry(20, 20, 20);
        var wireframe = new THREE.WireframeGeometry(geometry);// 材质属性
        var line = new THREE.LineSegments(wireframe);
        line.material.depthTest = false; //深度测试
        line.material.opacity = 0.25; //控制透明度
        line.material.transparent = true;
        // scene.add(line);

4.克隆几何体

var crtl3 = new dat.GUI()
        crtl3.add(new function(){
            this.clone = function(){
                var cloneGeometry = mesh.geometry.clone();
                var clonematerial = new THREE.MeshBasicMaterial({
                    color:0xfff000,
                    side:THREE.DoubleSide
                })
                var cloneMesh = new THREE.Mesh(cloneGeometry,clonematerial)
                cloneMesh.translateZ(20)
                cloneMesh.name = "copy"
                scene.remove(scene.getChildByName("copy"));
                scene.add(cloneMesh)
            }
        },"clone")

        var findObj = scene.getObjectByName("cube2", false)
        console.log(findObj.position)

5.实现控制元素的位置等

1.创建一个参考的正方体

        var geometry2 = new THREE.BoxGeometry(10, 10, 10);
        // 创建该几何体的外观材质
        var material2 = new THREE.MeshLambertMaterial({ color: 0x00ffff });
        // 将几何体和材质合并为能够添加到场景中的网格
        var cube2 = new THREE.Mesh(geometry2, material2);
        //设置阴影效果
        cube2.castShadow = true
        cube2.position.x += 5;
        cube2.position.y += 10;
        cube2.position.z += 0;
        cube2.name = "cube2"
         scene.add(cube2)

2.创建一个控制的正方体

 //创建长宽高为4的几何体
        var showGeo = new THREE.BoxGeometry(10, 10, 10);
        // 创建该几何体的外观材质
        var showmaterial2 = new THREE.MeshLambertMaterial({ color: 0xffff00 });
        // 将几何体和材质合并为能够添加到场景中的网格
        var showcube2 = new THREE.Mesh(showGeo, showmaterial2);
        //设置阴影效果
        showcube2.castShadow = true
        showcube2.position.x += 5;
        showcube2.position.y += 10;
        showcube2.position.z += 0;
        showcube2.name = "cube2"
        scene.add(showcube2)

3.创建控制元素的方法集合

var ctrlshowGeo = {
    // 缩放
    scaleX :1,
    scaleY :1,
    scaleZ :1,
    // 位置
    positionX:0,
    positionY:10,
    positionZ:0,
    //旋转
    rotationX:0,
    rotationY:0,
    rotationZ:0,
    //显示隐藏
    visible:true,
    //平移
    translateX:0,
    translateY:0,
    translateZ:0,

}
var cart = new dat.GUI();
cart.add(ctrlshowGeo,"scaleX",0,5)
cart.add(ctrlshowGeo,"scaleY",0,5)
cart.add(ctrlshowGeo,"scaleZ",0,5)

cart.add(ctrlshowGeo,"positionX",-30,40)
cart.add(ctrlshowGeo,"positionY",-30,40)
cart.add(ctrlshowGeo,"positionZ",-30,40)

cart.add(ctrlshowGeo,"rotationX",-5,5)
cart.add(ctrlshowGeo,"rotationY",-5,5)
cart.add(ctrlshowGeo,"rotationZ",-5,5)

cart.add(ctrlshowGeo,'visible')

cart.add(ctrlshowGeo,"translateX",-30,40)
cart.add(ctrlshowGeo,"translateY",-30,40)
cart.add(ctrlshowGeo,"translateZ",-30,40)

5.刷新页面

function renderScene() {
            // 拉伸刷新
            showcube2.scale.set(ctrlshowGeo.scaleX,ctrlshowGeo.scaleY,ctrlshowGeo.scaleZ)
            // 位置刷新
            showcube2.position.set(ctrlshowGeo.positionX,ctrlshowGeo.positionY,ctrlshowGeo.positionZ)
            // 旋转刷新
            showcube2.rotation.set(ctrlshowGeo.rotationX,ctrlshowGeo.rotationY,ctrlshowGeo.rotationZ)
            showcube2.visible = ctrlshowGeo.visible
            // 平移刷新
            showcube2.translateX(ctrlshowGeo.translateX)
            showcube2.translateY(ctrlshowGeo.translateY)
            showcube2.translateZ(ctrlshowGeo.translateZ)
            requestAnimationFrame(renderScene);
            renderer.render(scene, camera);
        }

u78ob-x8jck.gif

二、透视摄像机和正交投影摄像机

1.正交相机(OrthographicCamera)

  • 这一摄像机使用orthographic projection(正交投影)来进行投影。
  • 在这种投影模式下,无论物体距离相机距离远或者近,在最终渲染的图片中物体的大小都保持不变。
  • 这对于渲染2D场景或者UI元素是非常有用的。

参数:

  • left — 摄像机视锥体左侧面。
  • right — 摄像机视锥体右侧面。
  • top — 摄像机视锥体上侧面。
  • bottom — 摄像机视锥体下侧面。
  • near — 摄像机视锥体近端面。
  • far — 摄像机视锥体远端面。
var camera = new THREE.OrthographicCamera(window.innerWidth / - 8, window.innerWidth / 8, window.innerHeight / 16, window.innerHeight / - 16, 1, 1000);

2.透视相机(PerspectiveCamera)

  • 这一摄像机使用perspective projection(透视投影)来进行投影。
  • 这一投影模式被用来模拟人眼所看到的景象,它是3D场景的渲染中使用得最普遍的投影模式。

参数:

  • fov — 摄像机视锥体垂直视野角度
  • aspect — 摄像机视锥体长宽比
  • near — 摄像机视锥体近端面
  • far — 摄像机视锥体远端面
var camera = new THREE.PerspectiveCamera( 45, width / height, 1, 1000 );
scene.add( camera );

三,光源AmbientLight、SpotLight

1.AmbientLight

  • 环境光会均匀的照亮场景中的所有物体。
  • 环境光不能用来投射阴影,因为它没有方向。

AmbientLight( color : Integer, intensity : Float ):

​ color - (参数可选)颜色的rgb数值。缺省值为 0xffffff。 ​ intensity - (参数可选)光照的强度。缺省值为 1。

var light = new THREE.AmbientLight( 0x404040 ); // soft white light
scene.add( light );

2.SpotLight聚光灯

聚光灯是从一个方向上的一个点发出,沿着一个圆锥体,它离光越远,它的尺寸就越大。

SpotLight( color : Integer, intensity : Float, distance : Float, angle : Radians, penumbra : Float, decay : Float )

  • color - (可选参数) 十六进制光照颜色。 缺省值 0xffffff (白色)。

  • intensity - (可选参数) 光照强度。 缺省值 1。

  • distance - 从光源发出光的最大距离,其强度根据光源的距离线性衰减。

  • angle - 光线散射角度,最大为Math.PI/2。

  • penumbra - 聚光锥的半影衰减百分比。在0和1之间的值。默认为0。

  • decay - 沿着光照距离的衰减量。

var spotLight = new THREE.SpotLight( 0xffffff );
spotLight.position.set( 100, 1000, 100 );

spotLight.castShadow = true;

spotLight.shadow.mapSize.width = 1024;
spotLight.shadow.mapSize.height = 1024;

spotLight.shadow.camera.near = 500;
spotLight.shadow.camera.far = 4000;
spotLight.shadow.camera.fov = 30;

scene.add( spotLight );

3.GUI控制场景灯光颜色

 //创建dat.GUI,传递并设置属性
        var gui = new dat.GUI();
        gui.add(controls, 'switchCamera').name("切换摄像机");
        gui.add(controls, 'perspective').listen();
        
        var crltObj ={
            intensity:1,
            ambientLightColor:0xfffffff,
        }
        var crtl = new dat.GUI()
        crtl.add(crltObj,"intensity",0,5)
        crtl.addColor(crltObj,"ambientLightColor").onChange(function (e) {
        ambientLight.color=new THREE.Color(e);
    });
var pos =0 ;
        //渲染场景
        function render() {
            // stats.update();
            pos += 0.01
            cube2.position.x = 10 + ( 20 * (Math.sin(pos)))
            camera.lookAt(cube2.position)
            ambientLight.intensity = crltObj.intensity
            //通过requestAnimationFrame方法在特定时间间隔重新渲染场景
            requestAnimationFrame(render);
            //渲染场景
            renderer.render(scene, camera);
        }

3.GUI控制聚光灯的数值

var crltObj = {
            // 环境光
            intensity: 1,
            ambientLightColor: 0xfffffff,
            // 聚光灯 SpotLight
            spotLightintensity: 1,
            spotLightColor: 0xfffffff,
            spotLightDistance: 0,
            spotLightangle: Math.PI / 3,
            // 聚光灯衰减
            spotLightPenumbra: 0,
            // 光照衰减量
            spotLightDecay: 0,
        }
        var crtl = new dat.GUI()
        crtl.add(crltObj, "intensity", 0, 5)
        crtl.addColor(crltObj, "ambientLightColor").onChange(function (e) {
            ambientLight.color = new THREE.Color(e);
        });
        // 从光源发出光的最大距离,其强度根据光源的距离线性衰减。
        crtl.add(crltObj, "spotLightintensity", 0, 5)
        // 聚光灯距离
        crtl.add(crltObj, "spotLightDistance",0,1000).onChange(function (e) {
            spotLight.distance = e;
        });
        // 光线散射角度,最大为Math.PI/2。
        crtl.add(crltObj, "spotLightangle", 0, 2 * Math.PI).onChange(function (e) {
            spotLight.angle = e;
        });
        //  聚光锥的半影衰减百分比。在0和1之间的值。默认为0。
        crtl.add(crltObj, "spotLightPenumbra", 0, 1).onChange(function (e) {
            spotLight.penumbra = e;
        });
        // 沿着光照距离的衰减量。
        crtl.add(crltObj, "spotLightDecay", 0, 1).onChange(function (e) {
            spotLight.decay = e;
        });

r.gif

de.gif

p.gif

视频学习地址