纹理贴图的应用以及实现一个太阳系的自转公转

点击查看demo演示

demo地址:https://nsytsqdtn.github.io/demo/solar/solar

three.js中的纹理

纹理贴图是通过将图像应用到对象的一个或多个面,来为3D对象添加细节的一种方法。
可以使用TextureLoader类的load方法来加载纹理

function loadImgTexture(){
    var loader = new THREE.TextureLoader();
    loader.load("metal-rust.jpg",function(texture){
        var geometry = new THREE.BoxGeometry(10,10,10);
        var material = new THREE.MeshBasicMaterial({color:0x739783,map:texture});
        mesh = new THREE.Mesh(geometry,material);
        scene.add(mesh);
    })
}

实现效果如下:

八大行星的贴图资源网上到处都可以找到,这里给一个还不错的地址:
https://tieba.baidu.com/p/4876471245?red_tag=3235237836

完整太阳系代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Three.js</title>
    <script src="../../Import/three.js"></script>
    <script src="../../Import/stats.js"></script>
    <script src="../../Import/Setting.js"></script>
    <script src="../../Import/OrbitControls.js"></script>
    <style type="text/css">
        div#canvas-frame {
            border: none;
            cursor: pointer;
            width: 100%;
            height: 850px;
            background-color: #333333;
        }
    </style>
</head>
<body onload="threeStart()">
<script>
    let renderer;
    function initThree() {
        width = document.getElementById('canvas-frame').clientWidth;
        height = document.getElementById('canvas-frame').clientHeight;
        renderer = new THREE.WebGLRenderer({
            antialias : true
        });
        renderer.setSize(width,height);
        document.getElementById("canvas-frame").appendChild(renderer.domElement);
        renderer.setClearColor(0x333333, 1.0);

    }
    let camera;
    function initCamera() {
        camera = new THREE.PerspectiveCamera(45, width / height, 1, 10000);
        camera.position.x = 0;
        camera.position.y = 500;
        camera.position.z = 2000;
        camera.up.x = 0;
        camera.up.y = 1;
        camera.up.z = 0;
        camera.lookAt(0,0,0);
    }

    let scene;
    function initScene() {
        scene = new  THREE.Scene();
        let bgTexture = new THREE.TextureLoader().load("../../Image/universe.jpg");//背景贴图
        scene.background = bgTexture;//把场景的背景设置为一张图片
    }
    let light;
    function initLight() {
        light = new THREE.PointLight(0xffffff,1);//点光源,模拟太阳
        light.position.set(0,0,0);
        scene.add(light);
        light = new THREE.AmbientLight(0xffffff,0.3);//环境光
        scene.add(light);
    }
    let sun;
    let earth;
    let tuxing;
    let shuixing;
    let jinxing;
    let huoxing;
    let muxing;
    let tianwangxing;
    let haiwangxing;

    function initObject() {
        let geometry = new THREE.SphereGeometry(15, 50, 50);
        let texture = THREE.ImageUtils.loadTexture("../../Image/shuixing.jpg");//定义一个贴图,并从本地文件中加载
        let material = new THREE.MeshBasicMaterial({map:texture});//把上面定义的texture设置为星球的纹理材质
        shuixing = new THREE.Mesh(geometry,material);
        shuixing.position.set(0,0,150);//3
        scene.add(shuixing);

        geometry = new THREE.SphereGeometry(25, 50, 50);
        texture = THREE.ImageUtils.loadTexture("../../Image/jinxing.jpg");
        material = new THREE.MeshBasicMaterial({map:texture});
        jinxing = new THREE.Mesh(geometry,material);
        jinxing.position.set(0,0,200);//4
        scene.add(jinxing);

        geometry = new THREE.SphereGeometry(30, 50, 50);
        texture = THREE.ImageUtils.loadTexture("../../Image/earth.jpg");
        material = new THREE.MeshBasicMaterial({map:texture});
        earth = new THREE.Mesh(geometry,material);
        earth.position.set(0,0,300);//6
        scene.add(earth);

        geometry = new THREE.SphereGeometry(20, 50, 50);
        texture = THREE.ImageUtils.loadTexture("../../Image/huoxing.jpg");
        material = new THREE.MeshBasicMaterial({map:texture});
        huoxing = new THREE.Mesh(geometry,material);
        huoxing.position.set(0,0,400);//8
        scene.add(huoxing);

        geometry = new THREE.SphereGeometry(65, 50, 50);
        texture = THREE.ImageUtils.loadTexture("../../Image/muxing.jpg");
        material = new THREE.MeshBasicMaterial({map:texture});
        muxing = new THREE.Mesh(geometry,material);
        muxing.position.set(0,0,600);//500 12
        scene.add(muxing);
        geometry = new THREE.TorusGeometry(80,6,20,20);
        texture = THREE.ImageUtils.loadTexture("../../Image/muxinghuan.jpg");
        material = new THREE.MeshBasicMaterial({map:texture});
        let muxinghuan = new THREE.Mesh(geometry,material);
        muxinghuan.rotation.x = 1.4;//木星环
        muxing.add(muxinghuan);

        geometry = new THREE.SphereGeometry(55, 50, 50);
        texture = THREE.ImageUtils.loadTexture("../../Image/tuxing.jpg");
        material = new THREE.MeshBasicMaterial({map:texture});
        tuxing = new THREE.Mesh(geometry,material);
        tuxing.position.set(0,0,800);//16
        scene.add(tuxing);
        geometry = new THREE.TorusGeometry(65,8,20,20);
        texture = THREE.ImageUtils.loadTexture("../../Image/tuxinghuan.jpg");
        material = new THREE.MeshBasicMaterial({map:texture});
        let tuxinghuan = new THREE.Mesh(geometry,material);
        tuxinghuan.rotation.x = 1.4;
        tuxing.add(tuxinghuan);

        geometry = new THREE.SphereGeometry(45, 50, 50);
        texture = THREE.ImageUtils.loadTexture("../../Image/tianwangxing.jpg");
        material = new THREE.MeshBasicMaterial({map:texture});
        tianwangxing = new THREE.Mesh(geometry,material);
        tianwangxing.position.set(0,0,950);//19
        scene.add(tianwangxing);

        geometry = new THREE.SphereGeometry(40, 50, 50);
        texture = THREE.ImageUtils.loadTexture("../../Image/haiwangxing.jpg");
        material = new THREE.MeshBasicMaterial({map:texture});
        haiwangxing = new THREE.Mesh(geometry,material);
        haiwangxing.position.set(0,0,1100);//22
        scene.add(haiwangxing);

        geometry = new THREE.SphereGeometry(120, 50, 50);
        texture = THREE.ImageUtils.loadTexture("../../Image/sun.jpg");
        material = new THREE.MeshBasicMaterial({map:texture,
            emissive: 0xffffff,side: THREE.DoubleSide,});
        sun = new THREE.Mesh(geometry,material);
        sun.position.set(0,0,0);
        scene.add(sun);

        //在太阳外面设置一层透明的罩,看上去更像太阳
        let canvas = document.createElement( 'canvas' );
        canvas.width = 256;
        canvas.height = 256;
        let context = canvas.getContext( '2d' );
        let gradient = context.createRadialGradient( canvas.width / 2, canvas.height / 2, 0, canvas.width / 2, canvas.height / 2, canvas.width / 2 );//创建一个圆形渐变对象
        gradient.addColorStop( 0.1, 'rgba(255,60,0,0.01)' );//内圈的颜色
        gradient.addColorStop( 1, 'rgba(255,125,0,0.5)' );//最外面的颜色
        context.fillStyle = gradient;
        context.fillRect( 0, 0, canvas.width, canvas.height );//将一个画布使用圆形渐变对象进行填充
        let shadowTexture = new THREE.CanvasTexture( canvas );//把刚刚画好的画布拿来作为画布贴图
        let shadowMaterial = new THREE.MeshBasicMaterial( { map: shadowTexture,transparent:true } );//用此贴图来当材质
        let shadowGeo = new THREE.SphereGeometry( 130,50,50);
        let shadowMesh;
        shadowMesh = new THREE.Mesh( shadowGeo, shadowMaterial );
        shadowMesh.position.y = 0;
        shadowMesh.position.x = 0;
        sun.add( shadowMesh );

        //画线,把太阳系每个星球运行轨迹画出来
        for(let j=3;j<=22;j++) {
            if (j==3||j==4||j==6||j==8||j==12||j==16||j==19||j==22){
                let radius = 50 * j;
                let lineGeometry2 = new THREE.Geometry();
                for (let i = 0; i <= 2 * Math.PI; i += Math.PI / 30) {
                    lineGeometry2.vertices.push(new THREE.Vector3(radius * Math.cos(i), 0, radius * Math.sin(i), 0))
                }
                let material2 = new THREE.LineBasicMaterial({color: 0x8f6cab})
                let cycleMesh = new THREE.Line(lineGeometry2, material2);
                cycleMesh.position.set(0, 0, 0);
                scene.add(cycleMesh);
            }
            }
    }
    //每个星球的自转函数
    function zizhuan() {
        sun.rotation.y = sun.rotation.y+0.008>=2*Math.PI?0:sun.rotation.y+0.008;
        shuixing.rotation.y = shuixing.rotation.y+0.005>=2*Math.PI?0:shuixing.rotation.y+0.005;
        jinxing.rotation.y = jinxing.rotation.y+0.003>=0?2*Math.PI:jinxing.rotation.y+0.003;
        earth.rotation.y = earth.rotation.y+0.012>=2*Math.PI?0:earth.rotation.y+0.012;
        huoxing.rotation.y = huoxing.rotation.y+0.01>=2*Math.PI?0:huoxing.rotation.y+0.01;
        tuxing.rotation.y = tuxing.rotation.y+0.04>=2*Math.PI?0:tuxing.rotation.y+0.06;
        muxing.rotation.y = muxing.rotation.y+0.03>=2*Math.PI?0:muxing.rotation.y+0.08;
        tianwangxing.rotation.z = tianwangxing.rotation.z+0.015>=2*Math.PI?0:tianwangxing.rotation.z+0.015;
        haiwangxing.rotation.y = haiwangxing.rotation.y+0.02>=2*Math.PI?0:haiwangxing.rotation.y+0.02;
    }

    let shuixingAngle = 0;
    let jinxingAngle = 0;
    let earthAngle = 0;
    let huoxingAngle = 0;
    let tuxingAngle = 0;
    let muxingAngle = 0;
    let tianwangxingAngle = 0;
    let haiwangxingAngle = 0;
    //每个星球的公转函数
    function gongzhuan() {
        shuixingAngle = shuixingAngle+0.03>=2*Math.PI?0:shuixingAngle +0.03;
        shuixing.position.set(150*Math.sin(shuixingAngle)
            ,0,150*Math.cos(shuixingAngle));

        jinxingAngle = jinxingAngle-0.02>=0?2*Math.PI:jinxingAngle -0.02;
        jinxing.position.set(200*Math.sin(jinxingAngle)
            ,0,200*Math.cos(jinxingAngle));

        earthAngle = earthAngle+0.015>=2*Math.PI?0:earthAngle +0.015;
        earth.position.set(300*Math.sin(earthAngle)
            ,0,300*Math.cos(earthAngle));

        huoxingAngle = huoxingAngle+0.01>=2*Math.PI?0:huoxingAngle +0.01;
        huoxing.position.set(400*Math.sin(huoxingAngle)
            ,0,400*Math.cos(huoxingAngle));

        muxingAngle = muxingAngle+0.006>=2*Math.PI?0:muxingAngle +0.006;
        muxing.position.set(600*Math.sin(muxingAngle)
            ,0,600*Math.cos(muxingAngle));

        tuxingAngle = tuxingAngle+0.004>=2*Math.PI?0:tuxingAngle +0.004;
        tuxing.position.set(800*Math.sin(tuxingAngle)
            ,0,800*Math.cos(tuxingAngle));

        tianwangxingAngle = tianwangxingAngle+0.003>=2*Math.PI?0:tianwangxingAngle +0.003;
        tianwangxing.position.set(950*Math.sin(tianwangxingAngle)
            ,0,950*Math.cos(tianwangxingAngle));

        haiwangxingAngle = haiwangxingAngle+0.002>=2*Math.PI?0:haiwangxingAngle +0.002;
        haiwangxing.position.set(1100*Math.sin(haiwangxingAngle)
            ,0,1100*Math.cos(haiwangxingAngle));
    }
    function initSetting() {
        loadAutoScreen(camera,renderer);
        loadFullScreen();
        loadStats();
    }
    let controller;
    function threeStart() {
        initThree();
        initCamera();
        initScene();
        initLight();
        initObject();
        initSetting();
        controller = new THREE.OrbitControls(camera,renderer.domElement);
        controller.target = new THREE.Vector3(0,0,0);
        controller.autoRotate = true;
        animation();
    }
    function animation() {
        zizhuan();
        gongzhuan();
        renderer.clear();
        renderer.render(scene,camera);
        requestAnimationFrame(animation);
        stats.update();
    }

</script>
<div id="canvas-frame"></div>
</body>
</html>

注意从本地读取图片或者其他文件时,浏览器一般是不允许的,所以会出现加载不了纹理或者背景图片的情况,只能在Chrome浏览器的属性--目标的最后,加上 --allow-file-access-from-files(前面有一个空格),就可以从这个打开的快捷方式中去读取到本地文件,如果是Edge浏览器似乎就直接可以。也可以使用npm或者tomcat搭建一个本地服务器,然后把图片放进去就可以直接读取了。

WebGL three.js学习笔记 纹理贴图模拟太阳系运转的更多相关文章

  1. WebGL three.js学习笔记 6种类型的纹理介绍及应用

    WebGL three.js学习笔记 6种类型的纹理介绍及应用 本文所使用到的demo演示: 高光贴图Demo演示 反光效果Demo演示(因为是加载的模型,所以速度会慢) (一)普通纹理 计算机图形学 ...

  2. WebGL three.js学习笔记 使用粒子系统模拟时空隧道(虫洞)

    WebGL three.js学习笔记 使用粒子系统模拟时空隧道 本例的运行结果如图: 时空隧道demo演示 Demo地址:https://nsytsqdtn.github.io/demo/sprite ...

  3. WebGL three.js学习笔记 加载外部模型以及Tween.js动画

    WebGL three.js学习笔记 加载外部模型以及Tween.js动画 本文的程序实现了加载外部stl格式的模型,以及学习了如何把加载的模型变为一个粒子系统,并使用Tween.js对该粒子系统进行 ...

  4. WebGL three.js学习笔记 法向量网格材质MeshNormalMaterial的介绍和创建360度全景天空盒的方法

    WebGL学习----Three.js学习笔记(5) 点击查看demo演示 Demo地址:https://nsytsqdtn.github.io/demo/360/360 简单网格材质 MeshNor ...

  5. WebGL three.js学习笔记 创建three.js代码的基本框架

    WebGL学习----Three.js学习笔记(1) webgl介绍 WebGL是一种3D绘图协议,它把JavaScript和OpenGL ES 2.0结合在一起,通过增加OpenGL ES 2.0的 ...

  6. JS学习笔记--轮播图效果

    希望通过自己的学习收获哪怕收获一点点,进步一点点都是值得的,加油吧!!! 本章知识点:index this for if else 下边我分享下通过老师教的方式写的轮播图,基础知识实现: 1.css代 ...

  7. WebGL three.js学习笔记 自定义顶点建立几何体

    自定义顶点建立几何体与克隆 Three.js本身已经有很多的网格模型,基本已经够我们的使用,但是如果我们还是想自己根据顶点坐标来建立几何模型的话,Three.js也是可以的. 基本效果如图: 点击查看 ...

  8. WebGL three.js学习笔记 阴影与实现物体的动画

    实现物体的旋转.跳动以及场景阴影的开启与优化 本程序将创建一个场景,并实现物体的动画效果 运行的结果如图: 完整代码如下: <!DOCTYPE html> <html lang=&q ...

  9. WebGL学习之纹理贴图

    为了使图形能获得接近于真实物体的材质效果,一般会使用贴图,贴图类型主要包括两种:漫反射贴图和镜面高光贴图.其中漫反射贴图可以同时实现漫反射光和环境光的效果. 实际效果请看demo:纹理贴图 2D纹理 ...

随机推荐

  1. JavaScript高级程序设计(一)

    一.三种常见的著名的命名规则: 1.Camel(驼峰式命名):首字母是小写的,接下来的单词都以大写字母开头.例如:var  myTestValue=0; 2.Pascal(帕斯卡命名):首字母是大写的 ...

  2. MySQL数据库主从分离的配置方法

    1.介绍 MySQL数据库设置读写分离,可以使对数据库的写操作和读操作在不同服务器上执行,提高并发量和响应速度.现在的网站一般大点的,都采用有数据库主从分离.读写分离,既起到备份作用也可以减轻数据库的 ...

  3. android获取手机机型、厂商、deviceID基本信息

    /** * 系统工具类 */ public class SystemUtil { /** * 获取当前手机系统语言. * * @return 返回当前系统语言.例如:当前设置的是"中文-中国 ...

  4. vue项目 构建 打包 发布 三部曲

    一.vue项目的创建 1.首先第一肯定是要有Node.js及npm这个不多说了2.安装脚手架 此时可以直接浏览-但是现在肯定有很多小白想将他发布到gitHub上并可以浏览,使用vue全家桶制作自己的博 ...

  5. TCP连接和 time_wait、close_waite

    TCP连接和 time_wait.close_waite tags:time_wait close_waite RST TCP 引言:前两天朋友公司的服务器垮掉了,最后查出的原因是发现大量的time_ ...

  6. ubuntu18.04 & Windows10 双系统关机缓慢

    1.Windows与Ubuntu双系统关机缓慢并不少见,有时单系统下的Linux mint或Ubuntu都会出现这个现象.主要原因是还有没有关闭的进程或者是软件兼容的原因,所以导致每次关机都有一个90 ...

  7. 数据结构和算法总结(一):广度优先搜索BFS和深度优先搜索DFS

    前言 这几天复习图论算法,觉得BFS和DFS挺重要的,而且应用比较多,故记录一下. 广度优先搜索 有一个有向图如图a 图a 广度优先搜索的策略是: 从起始点开始遍历其邻接的节点,由此向外不断扩散. 1 ...

  8. spring+activemq中多个consumer同时处理消息时遇到的性能问题

    最近在做数据对接的工作,用到了activemq,我需要从activemq中接收消息并处理,但是我处理数据的步骤稍微复杂,渐渐的消息队列中堆的数据越来越多,就想到了我这边多开几个线程来处理消息. 可是会 ...

  9. SSM-MyBatis-10:Mybatis中SqlSession的getMapper()和简单的工具类MyBatisUtils

    ------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- getMapper的作用,获取到接口,直接通过点的方式调用方法,以免直接手打的方式写错方法名,(强类型的方式) ...

  10. Windows Server 2008取消登录前的Ctrl+Alt+Delete组合键操作

    前言: 在Windows Server 2008服务器中,为了防止人们登录服务器时错误的将账户和密码输入其他地方导致信息泄漏,所以在我们登录Windows Server 2008服务器操作系统时会要求 ...