• threeJS创建mesh,创建平面,设置mesh的平移,旋转、缩放、自传、透明度、拉伸


    这个小案例是当初我在学习的时候,小的一个小案例,代码还需要进一步优化;还请谅解~~;主要用到了threeJS创建mesh,创建平面,设置mesh的平移,旋转、缩放、自传、透明度、拉伸等这些小功能;

    (点击每个mesh,mesh的颜色会变为红色)

    点击

    1  需要加载这些相关的js文件

    2   下面是实现的一些小功能

    3   下面是相关代码,代码还没有优化,请谅解~~(具体的每一个小功能后面我都会进行一一讲解)

    <!DOCTYPE html>
    
    <html lang="en" xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta charset="utf-8" />
        <title></title>
        <style>
            body {
                margin: 0;
                overflow: hidden;
                /* 隐藏body窗口区域滚动条 */
            }
        </style>
        <!--引入three.js三维引擎-->
        <script src="js/three.js"></script>
        <!-- 引入threejs扩展控件OrbitControls.js -->
        <script src="js/OrbitControls.js"></script>
        <script src="js/stats.min.js"></script>
        <script src="js/jquery-1.9.0.js"></script>
        <script src="js/dat.gui.js"></script>
        <script src="js/stats.js"></script>
    </head>
    <body>
        <div id="Stats-output">
        </div>
        <div id="WebGL-output">
        </div>
        <script type="text/javascript">
    
            // once everything is loaded, we run our Three.js stuff.
            $(function () {
    
                var stats = initStats();
    
                // create a scene, that will hold all our elements such as objects, cameras and lights.
                var scene = new THREE.Scene();
    
                // create a camera, which defines where we're looking at.
                var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
    
                // create a render and set the size
                var renderer;
                var webGLRenderer = new THREE.WebGLRenderer();
                webGLRenderer.setClearColorHex(0xEEEEEE, 1.0);
                webGLRenderer.setSize(window.innerWidth, window.innerHeight);
                webGLRenderer.shadowMapEnabled = true;
    
                var canvasRenderer = new THREE.CanvasRenderer();
                canvasRenderer.setSize(window.innerWidth, window.innerHeight);
                renderer = webGLRenderer;
    
                var groundGeom = new THREE.PlaneGeometry(100, 100, 4, 4);
                var groundMesh = new THREE.Mesh(groundGeom, new THREE.MeshBasicMaterial({ color: 0x777777 }));
                groundMesh.rotation.x = -Math.PI / 2;
                groundMesh.position.y = -20;
                scene.add(groundMesh);
    
                var sphereGeometry = new THREE.SphereGeometry(14, 20, 20);
                var cubeGeometry = new THREE.CubeGeometry(15, 15, 15);
                var planeGeometry = new THREE.PlaneGeometry(14, 14, 4, 4);
    
    
                var meshMaterial = new THREE.MeshNormalMaterial({ color: 0x7777ff });
                var sphere = new THREE.Mesh(sphereGeometry, meshMaterial);
                var cube = new THREE.Mesh(cubeGeometry, meshMaterial);
                var plane = new THREE.Mesh(planeGeometry, meshMaterial);
    
                // position the sphere
                sphere.position.x = 0;
                sphere.position.y = 3;
                sphere.position.z = 2;
    
                for (var f = 0, fl = sphere.geometry.faces.length; f < fl; f++) {
                    var face = sphere.geometry.faces[f];
                    var arrow = new THREE.ArrowHelper(
                        face.normal,
                        face.centroid,
                        2,
                        0x3333FF);
                    sphere.add(arrow);
                }
    
    
                cube.position = sphere.position;
                plane.position = sphere.position;
    
    
                // add the sphere to the scene
                scene.add(cube);
    
                // position and point the camera to the center of the scene
                camera.position.x = -20;
                camera.position.y = 30;
                camera.position.z = 40;
                camera.lookAt(new THREE.Vector3(10, 0, 0));
    
                // add subtle ambient lighting
                var ambientLight = new THREE.AmbientLight(0x0c0c0c);
                scene.add(ambientLight);
    
                // add spotlight for the shadows
                var spotLight = new THREE.SpotLight(0xffffff);
                spotLight.position.set(-40, 60, -10);
                spotLight.castShadow = true;
                scene.add(spotLight);
    
                // add the output of the renderer to the html element
                $("#WebGL-output").append(renderer.domElement);
    
                // call the render function
                var step = 0;
                var oldContext = null;
    
                var controls = new function () {
                    this.rotationSpeed = 0.02;
                    this.bouncingSpeed = 0.03;
    
                    this.opacity = meshMaterial.opacity;
                    this.transparent = meshMaterial.transparent;
    
                    this.visible = meshMaterial.visible;
                    this.side = "front";
    
                    this.wireframe = meshMaterial.wireframe;
                    this.wireframeLinewidth = meshMaterial.wireframeLinewidth;
    
                    this.selectedMesh = "cube";
    
                    this.shadow = "flat";
    
                }
    
                var gui = new dat.GUI();
    
    
                var spGui = gui.addFolder("Mesh");
                spGui.add(controls, 'opacity', 0, 1).onChange(function (e) {
                    meshMaterial.opacity = e
                });
                spGui.add(controls, 'transparent').onChange(function (e) {
                    meshMaterial.transparent = e
                });
                spGui.add(controls, 'wireframe').onChange(function (e) {
                    meshMaterial.wireframe = e
                });
                spGui.add(controls, 'wireframeLinewidth', 0, 20).onChange(function (e) {
                    meshMaterial.wireframeLinewidth = e
                });
                spGui.add(controls, 'visible').onChange(function (e) {
                    meshMaterial.visible = e
                });
                spGui.add(controls, 'side', ["front", "back", "double"]).onChange(function (e) {
                    console.log(e);
                    switch (e) {
                        case "front":
                            meshMaterial.side = THREE.FrontSide;
                            break;
                        case "back":
                            meshMaterial.side = THREE.BackSide;
                            break;
                        case "double":
                            meshMaterial.side = THREE.DoubleSide
                            break;
                    }
                    meshMaterial.needsUpdate = true;
    
                });
                spGui.add(controls, 'shadow', ["flat", "smooth"]).onChange(function (e) {
                    switch (e) {
                        case "flat":
                            // https://github.com/mrdoob/three.js/issues/1929
                            meshMaterial.shading = THREE.FlatShading;
                            break;
                        case "smooth":
                            meshMaterial.shading = THREE.SmoothShading;
                            break;
                    }
    
                    var oldPos = sphere.position.clone();
                    scene.remove(sphere);
                    scene.remove(plane);
                    scene.remove(cube);
                    sphere = new THREE.Mesh(sphere.geometry.clone(), meshMaterial);
                    cube = new THREE.Mesh(cube.geometry.clone(), meshMaterial);
                    plane = new THREE.Mesh(plane.geometry.clone(), meshMaterial);
    
                    sphere.position = oldPos;
                    cube.position = oldPos;
                    plane.position = oldPos;
    
                    switch (controls.selectedMesh) {
                        case "cube":
                            scene.add(cube);
    
                            break;
                        case "sphere":
                            scene.add(sphere);
    
                            break;
                        case "plane":
                            scene.add(plane);
                            break;
    
                    }
    
                    meshMaterial.needsUpdate = true;
                    console.log(meshMaterial);
                });
    
                spGui.add(controls, 'selectedMesh', ["cube", "sphere", "plane"]).onChange(function (e) {
    
                    scene.remove(plane);
                    scene.remove(cube);
                    scene.remove(sphere);
    
    
                    switch (e) {
                        case "cube":
                            scene.add(cube);
    
                            break;
                        case "sphere":
                            scene.add(sphere);
    
                            break;
                        case "plane":
                            scene.add(plane);
                            break;
    
                    }
    
                    scene.add(e);
                });
    
                render();
    
                function render() {
                    stats.update();
    
                    cube.rotation.y = step += 0.01;
                    plane.rotation.y = step;
                    sphere.rotation.y = step;
    
    
                    // render using requestAnimationFrame
                    requestAnimationFrame(render);
                    renderer.render(scene, camera);
                }
    
                function initStats() {
    
                    var stats = new Stats();
    
                    stats.setMode(0); // 0: fps, 1: ms
    
    
                    // Align top-left
                    stats.domElement.style.position = 'absolute';
                    stats.domElement.style.left = '0px';
                    stats.domElement.style.top = '0px';
    
                    $("#Stats-output").append(stats.domElement);
    
                    return stats;
                }
            });
    
    
        </script>
        <script>
            /**
             * 创建场景对象Scene
             */
            var scene = new THREE.Scene();
            /**
             * 创建网格模型
             */
            //创建第一个方块
            var geometry = new THREE.BoxGeometry(100, 100, 100); //创建一个立方体几何对象Geometry
            var material = new THREE.MeshLambertMaterial({
                color: 0x0000ff
            }); //材质对象Material
            var mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh
            scene.add(mesh); //网格模型添加到场景中
            // 设置产生投影的网格模型
            mesh.castShadow = true;
    
            //创建第二个方块
            var geometry2 = new THREE.BoxGeometry(100, 100, 100); //创建一个立方体几何对象Geometry
            var material2 = new THREE.MeshLambertMaterial({
                color: 0x0000ff
            }); //材质对象Material
            var mesh2 = new THREE.Mesh(geometry2, material2); //网格模型对象Mesh
            mesh2.translateY(200);//方块二沿y轴正方向平移40
            scene.add(mesh2); //网格模型添加到场景中
    
            //创建第三个方块
            var geometry3 = new THREE.BoxGeometry(100, 100, 100); //创建一个立方体几何对象Geometry
            var material3 = new THREE.MeshLambertMaterial({
                color: 0x0000ff,
                transparent: true,//开启透明度
                opacity: 0.5,//设置透明度具体值
            }); //材质对象Material
            var mesh3 = new THREE.Mesh(geometry3, material3); //网格模型对象Mesh
            mesh3.translateY(400);//方块二沿y轴正方向平移80
            scene.add(mesh3); //网格模型添加到场景中
    
            //创建第四个方块
            var geometry4 = new THREE.BoxGeometry(100, 100, 100); //创建一个立方体几何对象Geometry
            var material4 = new THREE.MeshLambertMaterial({
                color: 0x0000ff,
                transparent: true,//开启透明度
                opacity: 0.5,//设置透明度具体值
            }); //材质对象Material
            var mesh4 = new THREE.Mesh(geometry4, material4); //网格模型对象Mesh
            mesh4.translateY(600);//方块二沿y轴正方向平移120
            scene.add(mesh4); //网格模型添加到场景中
    
            //创建第五个方块
            var geometry5 = new THREE.BoxGeometry(100, 100, 100); //创建一个立方体几何对象Geometry
            var material5 = new THREE.MeshLambertMaterial({
                color: 0x0000ff
            }); //材质对象Material
            var mesh5 = new THREE.Mesh(geometry5, material5); //网格模型对象Mesh
            mesh5.translateY(800);//方块二沿y轴正方向平移160
            scene.add(mesh5); //网格模型添加到场景中
    
            //创建第六个方块
            var geometry6 = new THREE.BoxGeometry(100, 100, 100); //创建一个立方体几何对象Geometry
            var material6 = new THREE.MeshLambertMaterial({
                color: 0x0000ff
            }); //材质对象Material
            var mesh6 = new THREE.Mesh(geometry6, material6); //网格模型对象Mesh
            mesh6.translateX(200);//方块二沿y轴正方向平移40
            scene.add(mesh6); //网格模型添加到场景中
            mesh6.castShadow = true;
    
            //创建第七个方块
            var geometry7 = new THREE.BoxGeometry(100, 100, 100); //创建一个立方体几何对象Geometry
            var material7 = new THREE.MeshLambertMaterial({
                color: 0x0000ff
            }); //材质对象Material
            var mesh7 = new THREE.Mesh(geometry7, material7); //网格模型对象Mesh
            mesh7.translateX(400);//方块二沿y轴正方向平移80
            scene.add(mesh7); //网格模型添加到场景中
            mesh7.castShadow = true;
    
            //创建第八个方块
            var geometry8 = new THREE.BoxGeometry(100, 100, 100); //创建一个立方体几何对象Geometry
            var material8 = new THREE.MeshLambertMaterial({
                color: 0x0000ff
            }); //材质对象Material
            var mesh8 = new THREE.Mesh(geometry8, material8); //网格模型对象Mesh
            mesh8.translateX(600);//方块二沿y轴正方向平移120
            scene.add(mesh8); //网格模型添加到场景中
            mesh8.castShadow = true;
    
            //创建第九个方块
            var geometry9 = new THREE.BoxGeometry(100, 100, 100); //创建一个立方体几何对象Geometry
            var material9 = new THREE.MeshLambertMaterial({
                color: 0x0000ff
            }); //材质对象Material
            var mesh9 = new THREE.Mesh(geometry9, material9); //网格模型对象Mesh
            mesh9.translateX(800);//方块二沿y轴正方向平移160
            scene.add(mesh9); //网格模型添加到场景中
            mesh9.castShadow = true;
    
            //创建第十个方块
            var geometry10 = new THREE.BoxGeometry(200, 200, 200); //创建一个立方体几何对象Geometry
            var material10 = new THREE.MeshLambertMaterial({
                color: 0x0000ff
            }); //材质对象Material
            var newMesh = new THREE.Mesh(geometry10, material10); //网格模型对象Mesh
            newMesh.copy(mesh);
            //相比mesh而言,在平移
            newMesh.translateX(-500);//方块二沿y轴正方向平移300
            scene.add(newMesh); //网格模型添加到场景中
    
            // 通过Path类的线条绘制方法方法定义轮廓
            var shape = new THREE.Shape();
            shape.moveTo(0, 0); //起点
            shape.lineTo(0, 100); //第2点
            shape.lineTo(100, 100); //第3点
            shape.lineTo(100, 0); //第4点
            shape.lineTo(0, 0); //第5点
            var geometry11 = new THREE.ExtrudeGeometry( //拉伸造型
                shape, //二维轮廓
                //拉伸参数
                {
                    amount: 300, //拉伸长度
                }
            );
            var material11 = new THREE.MeshPhongMaterial({
                color: 0x0000ff,
                side: THREE.DoubleSide, //两面可见
                // wireframe: true,
            }); //材质对象
            var mesh11 = new THREE.Mesh(geometry11, material11); //网格模型对象
            mesh11.translateY(-500);//方块二沿y轴正方向平移40
            scene.add(mesh11); //网格模型添加到场景中
    
    
            // 辅助坐标系
            var axisHelper = new THREE.AxisHelper(250);
            scene.add(axisHelper);
    
            /**
             * 光源设置
             */
            //点光源
            var point = new THREE.PointLight(0xffffff);
            point.position.set(40, 40, 30); //点光源位置
            scene.add(point); //点光源添加到场景中
            //环境光
            var ambient = new THREE.AmbientLight(0x444444);
            scene.add(ambient);
    
            //创建一个平面几何体作为投影面
            var planeGeometry = new THREE.PlaneGeometry(2000, 2000);
            var planeMaterial = new THREE.MeshLambertMaterial({
                color: 0x999999
            }); //材质对象Material
    
            // 平面网格模型作为投影面
            var planeMesh = new THREE.Mesh(planeGeometry, planeMaterial); //网格模型对象Mesh
            scene.add(planeMesh); //网格模型添加到场景中
            planeMesh.rotateX(-Math.PI / 2); //旋转网格模型
            planeMesh.position.y = -50; //设置网格模型y坐标
            // 设置接收阴影的投影面
            planeMesh.receiveShadow = true;
    
            // 方向光
            var directionalLight = new THREE.DirectionalLight(0xffffff, 1);
            // 设置光源位置
            directionalLight.position.set(60, 60, 60);
            scene.add(directionalLight);
            // 设置用于计算阴影的光源对象
            directionalLight.castShadow = true;
            // 设置计算阴影的区域,最好刚好紧密包围在对象周围
            // 计算阴影的区域过大:模糊  过小:看不到或显示不完整
            directionalLight.shadow.camera.near = 0.5;
            directionalLight.shadow.camera.far = 300;
            directionalLight.shadow.camera.left = -50;
            directionalLight.shadow.camera.right = 50;
            directionalLight.shadow.camera.top = 200;
            directionalLight.shadow.camera.bottom = -100;
            // 设置mapSize属性可以使阴影更清晰,不那么模糊
            // directionalLight.shadow.mapSize.set(1024,1024)
            console.log(directionalLight.shadow.camera);
    
            /**
             * 相机设置
             */
            var width = window.innerWidth; //窗口宽度
            var height = window.innerHeight; //窗口高度
            var k = width / height; //窗口宽高比
            var s = 1000; //三维场景显示范围控制系数,系数越大,显示的范围越大
            //创建相机对象
            var camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 2000);
            camera.position.set(200, 300, 200); //设置相机位置
            camera.lookAt(scene.position); //设置相机方向(指向的场景对象)
    
            //实现相机切换
            this.switchCamera = function () {
                if (camera instanceof THREE.PerspectiveCamera) {
                    camera = new THREE.OrthographicCamera(window.innerWidth / -16, window.innerWidth / 16, window.innerHeight / 16, window.innerHeight / -16, -200, 500);
                    camera.position.x = 120;
                    camera.position.y = 60;
                    camera.position.z = 180;
                    camera.lookAt(scene.position);
                    this.perspective = "Orthographic";
                } else {
                    camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
                    camera.position.x = 120;
                    camera.position.y = 60;
                    camera.position.z = 180;
    
                    camera.lookAt(scene.position);
                    this.perspective = "Perspective";
                }
            };//代码放入GUI工具中,可以在页面上动态切换相机
    
    
            //声明raycaster和mouse变量
            var raycaster = new THREE.Raycaster();
            console.log(raycaster);
            var mouse = new THREE.Vector2();
    
            function onMouseClick(event) {
    
                //通过鼠标点击的位置计算出raycaster所需要的点的位置,以屏幕中心为原点,值的范围为-1到1.
    
                mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
                mouse.y = - (event.clientY / window.innerHeight) * 2 + 1;
    
                // 通过鼠标点的位置和当前相机的矩阵计算出raycaster
                raycaster.setFromCamera(mouse, camera);
    
                // 获取raycaster直线和所有模型相交的数组集合
                var intersects = raycaster.intersectObjects(scene.children);
                console.log(intersects[i].object);
                console.log(intersects);
    
                //将所有的相交的模型的颜色设置为红色,如果只需要将第一个触发事件,那就数组的第一个模型改变颜色即可
                for (var i = 0; i < intersects.length; i++) {
                    //ransparent: true;//开启透明度
                    //acity: 0.5//设置透明度具体值
                    intersects[i].object.material.color.set(0xff0000);
                    // console.log(intersects[i].object);
                    // 因为sphereMaterial.opacity和sphere.material.opacity值是相等的,所以只判断一个
                    // if (sphereMaterial.opacity > 0) {
                    //     sphereMaterial.opacity -= 0.05;
                    //     sphere.material.opacity -= 0.05;
                    // }
                    // else {
                    //     sphere.material.transparent = true;
                    //     clearInterval(timer);
                    // }
    
                }
            }
    
            window.addEventListener('click', onMouseClick, false);
    
            //初始化dat.GUI简化试验流程
            var gui;
    
            function initGui() {
                //声明一个保存需求修改的相关数据的对象
                controls = {
    
                };
    
                var gui = new dat.GUI();
    
            }
    
            //初始化性能插件
            var stats;
    
            function initStats() {
                stats = new Stats();
                document.body.appendChild(stats.dom);
            }
    
            //用户交互插件 鼠标左键按住旋转,右键按住平移,滚轮缩放
            var controls;
    
            function initControls() {
                controls = new THREE.OrbitControls(camera, renderer.domElement);
                // 如果使用animate方法时,将此函数删除
                //controls.addEventListener( 'change', render );
                // 使动画循环使用时阻尼或自转 意思是否有惯性
                controls.enableDamping = true;
                //动态阻尼系数 就是鼠标拖拽旋转灵敏度
                //controls.dampingFactor = 0.25;
                //是否可以缩放
                controls.enableZoom = true;
                //是否自动旋转
                controls.autoRotate = false;
                //设置相机距离原点的最远距离
                controls.minDistance = 50;
                //设置相机距离原点的最远距离
                controls.maxDistance = 1000;
                //是否开启右键拖拽
                controls.enablePan = true;
            }
    
            //窗口变动触发的函数
            function onWindowResize() {
    
                camera.aspect = window.innerWidth / window.innerHeight;
                camera.updateProjectionMatrix();
                render();
                renderer.setSize(window.innerWidth, window.innerHeight);
    
            }
    
            function animate() {
                //更新控制器
                render();
    
                //更新性能插件
                stats.update();
    
                //controls.update();
    
                requestAnimationFrame(animate);
            }
    
            function draw() {
                initGui();
                initControls();
                initStats();
                animate();
                window.onresize = onWindowResize;
            }
    
    
            /**
             * 创建渲染器对象
             */
            var renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
            renderer.setSize(width, height);//设置渲染区域尺寸
            renderer.setClearColor(0xb9d3ff, 1); //设置背景颜色
            renderer.shadowMapEnabled = true;
            document.body.appendChild(renderer.domElement); //body元素中插入canvas对象
            scene.add(ambient);
            //执行渲染操作   指定场景、相机作为参数
            renderer.render(scene, camera);
            // 渲染函数
            function render() {
                renderer.render(scene, camera); //执行渲染操作
                mesh8.rotateY(0.01);//每次绕y轴旋转0.01弧度
                requestAnimationFrame(render); //请求再次执行渲染函数render,渲染下一帧
            }
            render();
    
            //通过x,y,z指定旋转中心,obj是要旋转的对象
            //function changePivot(x, y, z, obj) {
            //  let wrapper = new THREE.Object3D();
            //wrapper.position.set(250, 250, 250);
            //wrapper.add(mesh8);
            //mesh8.position.set(x, y, z);
            //return wrapper;
            //}
            //changePivot();
    
    
            //创建控件对象  相机对象camera作为参数   控件可以监听鼠标的变化,改变相机对象的属性
            var controls = new THREE.OrbitControls(camera);
    
            // onresize 事件会在窗口被调整大小时发生
            window.onresize = function () {
                // 重置渲染器输出画布canvas尺寸
                renderer.setSize(width, height);
                // 重置相机投影的相关参数
                k = window.innerWidth / window.innerHeight;//窗口宽高比
                camera.left = -s * k;
                camera.right = s * k;
                camera.top = s;
                camera.bottom = -s;
                // 渲染器执行render方法的时候会读取相机对象的投影矩阵属性projectionMatrix
                // 但是不会每渲染一帧,就通过相机的属性计算投影矩阵(节约计算资源)
                // 如果相机的一些属性发生了变化,需要执行updateProjectionMatrix ()方法更新相机的投影矩阵
                camera.updateProjectionMatrix();
            };
    
    
            // onresize 事件会在窗口被调整大小时发生
            window.onresize = function () {
                // 重置渲染器输出画布canvas尺寸
                renderer.setSize(width, height);
                // 全屏情况下:设置观察范围长宽比aspect为窗口宽高比
                camera.aspect = window.innerWidth / window.innerHeight;
                // 渲染器执行render方法的时候会读取相机对象的投影矩阵属性projectionMatrix
                // 但是不会每渲染一帧,就通过相机的属性计算投影矩阵(节约计算资源)
                // 如果相机的一些属性发生了变化,需要执行updateProjectionMatrix ()方法更新相机的投影矩阵
                camera.updateProjectionMatrix();
            };
    
            //创建控件对象  相机对象camera作为参数   控件可以监听鼠标的变化,改变相机对象的属性
            var control = new THREE.OrbitControls(camera);
    
            //监听鼠标事件,触发渲染函数,更新canvas画布渲染效果
            control.addEventListener('change', render);
        </script>
    </body>
    </html>
    

      相关学习群

     

  • 相关阅读:
    Oracle性能调整ASH,AWR,ADDM
    子网掩码、子网划分详解
    10046事件sql_trace跟踪
    find详解
    date详解
    touch详解
    [转]lsof详解
    iftop、ifstat详解
    iotop详解
    关于Unity的入门游戏飞机大战的开发(上)
  • 原文地址:https://www.cnblogs.com/yaosusu/p/11269908.html
Copyright © 2020-2023  润新知