WebGL three.js學習筆記 紋理貼圖模擬太陽系運轉

紋理貼圖的應用以及實現一個太陽系的自轉公轉

點擊查看demo演示

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

three.js中的紋理

紋理貼圖是經過將圖像應用到對象的一個或多個面,來爲3D對象添加細節的一種方法。
能夠使用TextureLoader類的load方法來加載紋理javascript

1function loadImgTexture(){
2    var loader = new THREE.TextureLoader();
3    loader.load("metal-rust.jpg",function(texture){
4        var geometry = new THREE.BoxGeometry(10,10,10);
5        var material = new THREE.MeshBasicMaterial({color:0x739783,map:texture});
6        mesh = new THREE.Mesh(geometry,material);
7        scene.add(mesh);
8    })
9}
複製代碼

實現效果以下:
css

太陽系
太陽系

八大行星的貼圖資源網上處處均可以找到,這裏給一個還不錯的地址:
https://tieba.baidu.com/p/4876471245?red_tag=3235237836html

完整太陽系代碼:java

 1<!DOCTYPE html>
2<html lang="en">
3<head>
4    <meta charset="UTF-8">
5    <title>Three.js</title>
6    <script src="../../Import/three.js"></script>
7    <script src="../../Import/stats.js"></script>
8    <script src="../../Import/Setting.js"></script>
9    <script src="../../Import/OrbitControls.js"></script>
10    <style type="text/css">
11        div#canvas-frame {
12            border: none;
13            cursor: pointer;
14            width100%;
15            height850px;
16            background-color#333333;
17        }
18    
</style>
19</head>
20<body onload="threeStart()">
21<script>
22    let renderer;
23    function initThree({
24        width = document.getElementById('canvas-frame').clientWidth;
25        height = document.getElementById('canvas-frame').clientHeight;
26        renderer = new THREE.WebGLRenderer({
27            antialias : true
28        });
29        renderer.setSize(width,height);
30        document.getElementById("canvas-frame").appendChild(renderer.domElement);
31        renderer.setClearColor(0x3333331.0);
32
33    }
34    let camera;
35    function initCamera({
36        camera = new THREE.PerspectiveCamera(45, width / height, 110000);
37        camera.position.x = 0;
38        camera.position.y = 500;
39        camera.position.z = 2000;
40        camera.up.x = 0;
41        camera.up.y = 1;
42        camera.up.z = 0;
43        camera.lookAt(0,0,0);
44    }
45
46    let scene;
47    function initScene({
48        scene = new  THREE.Scene();
49        let bgTexture = new THREE.TextureLoader().load("../../Image/universe.jpg");//背景貼圖
50        scene.background = bgTexture;//把場景的背景設置爲一張圖片
51    }
52    let light;
53    function initLight({
54        light = new THREE.PointLight(0xffffff,1);//點光源,模擬太陽
55        light.position.set(0,0,0);
56        scene.add(light);
57        light = new THREE.AmbientLight(0xffffff,0.3);//環境光
58        scene.add(light);
59    }
60    let sun;
61    let earth;
62    let tuxing;
63    let shuixing;
64    let jinxing;
65    let huoxing;
66    let muxing;
67    let tianwangxing;
68    let haiwangxing;
69
70    function initObject({
71        let geometry = new THREE.SphereGeometry(155050);
72        let texture = THREE.ImageUtils.loadTexture("../../Image/shuixing.jpg");//定義一個貼圖,並從本地文件中加載
73        let material = new THREE.MeshBasicMaterial({map:texture});//把上面定義的texture設置爲星球的紋理材質
74        shuixing = new THREE.Mesh(geometry,material);
75        shuixing.position.set(0,0,150);//3
76        scene.add(shuixing);
77
78        geometry = new THREE.SphereGeometry(255050);
79        texture = THREE.ImageUtils.loadTexture("../../Image/jinxing.jpg");
80        material = new THREE.MeshBasicMaterial({map:texture});
81        jinxing = new THREE.Mesh(geometry,material);
82        jinxing.position.set(0,0,200);//4
83        scene.add(jinxing);
84
85        geometry = new THREE.SphereGeometry(305050);
86        texture = THREE.ImageUtils.loadTexture("../../Image/earth.jpg");
87        material = new THREE.MeshBasicMaterial({map:texture});
88        earth = new THREE.Mesh(geometry,material);
89        earth.position.set(0,0,300);//6
90        scene.add(earth);
91
92        geometry = new THREE.SphereGeometry(205050);
93        texture = THREE.ImageUtils.loadTexture("../../Image/huoxing.jpg");
94        material = new THREE.MeshBasicMaterial({map:texture});
95        huoxing = new THREE.Mesh(geometry,material);
96        huoxing.position.set(0,0,400);//8
97        scene.add(huoxing);
98
99        geometry = new THREE.SphereGeometry(655050);
100        texture = THREE.ImageUtils.loadTexture("../../Image/muxing.jpg");
101        material = new THREE.MeshBasicMaterial({map:texture});
102        muxing = new THREE.Mesh(geometry,material);
103        muxing.position.set(0,0,600);//500 12
104        scene.add(muxing);
105        geometry = new THREE.TorusGeometry(80,6,20,20);
106        texture = THREE.ImageUtils.loadTexture("../../Image/muxinghuan.jpg");
107        material = new THREE.MeshBasicMaterial({map:texture});
108        let muxinghuan = new THREE.Mesh(geometry,material);
109        muxinghuan.rotation.x = 1.4;//木星環
110        muxing.add(muxinghuan);
111
112        geometry = new THREE.SphereGeometry(555050);
113        texture = THREE.ImageUtils.loadTexture("../../Image/tuxing.jpg");
114        material = new THREE.MeshBasicMaterial({map:texture});
115        tuxing = new THREE.Mesh(geometry,material);
116        tuxing.position.set(0,0,800);//16
117        scene.add(tuxing);
118        geometry = new THREE.TorusGeometry(65,8,20,20);
119        texture = THREE.ImageUtils.loadTexture("../../Image/tuxinghuan.jpg");
120        material = new THREE.MeshBasicMaterial({map:texture});
121        let tuxinghuan = new THREE.Mesh(geometry,material);
122        tuxinghuan.rotation.x = 1.4;
123        tuxing.add(tuxinghuan);
124
125        geometry = new THREE.SphereGeometry(455050);
126        texture = THREE.ImageUtils.loadTexture("../../Image/tianwangxing.jpg");
127        material = new THREE.MeshBasicMaterial({map:texture});
128        tianwangxing = new THREE.Mesh(geometry,material);
129        tianwangxing.position.set(0,0,950);//19
130        scene.add(tianwangxing);
131
132        geometry = new THREE.SphereGeometry(405050);
133        texture = THREE.ImageUtils.loadTexture("../../Image/haiwangxing.jpg");
134        material = new THREE.MeshBasicMaterial({map:texture});
135        haiwangxing = new THREE.Mesh(geometry,material);
136        haiwangxing.position.set(0,0,1100);//22
137        scene.add(haiwangxing);
138
139        geometry = new THREE.SphereGeometry(1205050);
140        texture = THREE.ImageUtils.loadTexture("../../Image/sun.jpg");
141        material = new THREE.MeshBasicMaterial({map:texture,
142            emissive0xffffff,side: THREE.DoubleSide,});
143        sun = new THREE.Mesh(geometry,material);
144        sun.position.set(0,0,0);
145        scene.add(sun);
146
147        //在太陽外面設置一層透明的罩,看上去更像太陽
148        let canvas = document.createElement( 'canvas' );
149        canvas.width = 256;
150        canvas.height = 256;
151        let context = canvas.getContext( '2d' );
152        let gradient = context.createRadialGradient( canvas.width / 2, canvas.height / 20, canvas.width / 2, canvas.height / 2, canvas.width / 2 );//建立一個圓形漸變對象
153        gradient.addColorStop( 0.1'rgba(255,60,0,0.01)' );//內圈的顏色
154        gradient.addColorStop( 1'rgba(255,125,0,0.5)' );//最外面的顏色
155        context.fillStyle = gradient;
156        context.fillRect( 00, canvas.width, canvas.height );//將一個畫布使用圓形漸變對象進行填充
157        let shadowTexture = new THREE.CanvasTexture( canvas );//把剛剛畫好的畫布拿來做爲畫布貼圖
158        let shadowMaterial = new THREE.MeshBasicMaterial( { map: shadowTexture,transparent:true } );//用此貼圖來當材質
159        let shadowGeo = new THREE.SphereGeometry( 130,50,50);
160        let shadowMesh;
161        shadowMesh = new THREE.Mesh( shadowGeo, shadowMaterial );
162        shadowMesh.position.y = 0;
163        shadowMesh.position.x = 0;
164        sun.add( shadowMesh );
165
166        //畫線,把太陽系每一個星球運行軌跡畫出來
167        for(let j=3;j<=22;j++) {
168            if (j==3||j==4||j==6||j==8||j==12||j==16||j==19||j==22){
169                let radius = 50 * j;
170                let lineGeometry2 = new THREE.Geometry();
171                for (let i = 0; i <= 2 * Math.PI; i += Math.PI / 30) {
172                    lineGeometry2.vertices.push(new THREE.Vector3(radius * Math.cos(i), 0, radius * Math.sin(i), 0))
173                }
174                let material2 = new THREE.LineBasicMaterial({color0x8f6cab})
175                let cycleMesh = new THREE.Line(lineGeometry2, material2);
176                cycleMesh.position.set(000);
177                scene.add(cycleMesh);
178            }
179            }
180    }
181    //每一個星球的自轉函數
182    function zizhuan({
183        sun.rotation.y = sun.rotation.y+0.008>=2*Math.PI?0:sun.rotation.y+0.008;
184        shuixing.rotation.y = shuixing.rotation.y+0.005>=2*Math.PI?0:shuixing.rotation.y+0.005;
185        jinxing.rotation.y = jinxing.rotation.y+0.003>=0?2*Math.PI:jinxing.rotation.y+0.003;
186        earth.rotation.y = earth.rotation.y+0.012>=2*Math.PI?0:earth.rotation.y+0.012;
187        huoxing.rotation.y = huoxing.rotation.y+0.01>=2*Math.PI?0:huoxing.rotation.y+0.01;
188        tuxing.rotation.y = tuxing.rotation.y+0.04>=2*Math.PI?0:tuxing.rotation.y+0.06;
189        muxing.rotation.y = muxing.rotation.y+0.03>=2*Math.PI?0:muxing.rotation.y+0.08;
190        tianwangxing.rotation.z = tianwangxing.rotation.z+0.015>=2*Math.PI?0:tianwangxing.rotation.z+0.015;
191        haiwangxing.rotation.y = haiwangxing.rotation.y+0.02>=2*Math.PI?0:haiwangxing.rotation.y+0.02;
192    }
193
194    let shuixingAngle = 0;
195    let jinxingAngle = 0;
196    let earthAngle = 0;
197    let huoxingAngle = 0;
198    let tuxingAngle = 0;
199    let muxingAngle = 0;
200    let tianwangxingAngle = 0;
201    let haiwangxingAngle = 0;
202    //每一個星球的公轉函數
203    function gongzhuan({
204        shuixingAngle = shuixingAngle+0.03>=2*Math.PI?0:shuixingAngle +0.03;
205        shuixing.position.set(150*Math.sin(shuixingAngle)
206            ,0,150*Math.cos(shuixingAngle));
207
208        jinxingAngle = jinxingAngle-0.02>=0?2*Math.PI:jinxingAngle -0.02;
209        jinxing.position.set(200*Math.sin(jinxingAngle)
210            ,0,200*Math.cos(jinxingAngle));
211
212        earthAngle = earthAngle+0.015>=2*Math.PI?0:earthAngle +0.015;
213        earth.position.set(300*Math.sin(earthAngle)
214            ,0,300*Math.cos(earthAngle));
215
216        huoxingAngle = huoxingAngle+0.01>=2*Math.PI?0:huoxingAngle +0.01;
217        huoxing.position.set(400*Math.sin(huoxingAngle)
218            ,0,400*Math.cos(huoxingAngle));
219
220        muxingAngle = muxingAngle+0.006>=2*Math.PI?0:muxingAngle +0.006;
221        muxing.position.set(600*Math.sin(muxingAngle)
222            ,0,600*Math.cos(muxingAngle));
223
224        tuxingAngle = tuxingAngle+0.004>=2*Math.PI?0:tuxingAngle +0.004;
225        tuxing.position.set(800*Math.sin(tuxingAngle)
226            ,0,800*Math.cos(tuxingAngle));
227
228        tianwangxingAngle = tianwangxingAngle+0.003>=2*Math.PI?0:tianwangxingAngle +0.003;
229        tianwangxing.position.set(950*Math.sin(tianwangxingAngle)
230            ,0,950*Math.cos(tianwangxingAngle));
231
232        haiwangxingAngle = haiwangxingAngle+0.002>=2*Math.PI?0:haiwangxingAngle +0.002;
233        haiwangxing.position.set(1100*Math.sin(haiwangxingAngle)
234            ,0,1100*Math.cos(haiwangxingAngle));
235    }
236    function initSetting({
237        loadAutoScreen(camera,renderer);
238        loadFullScreen();
239        loadStats();
240    }
241    let controller;
242    function threeStart({
243        initThree();
244        initCamera();
245        initScene();
246        initLight();
247        initObject();
248        initSetting();
249        controller = new THREE.OrbitControls(camera,renderer.domElement);
250        controller.target = new THREE.Vector3(0,0,0);
251        controller.autoRotate = true;
252        animation();
253    }
254    function animation({
255        zizhuan();
256        gongzhuan();
257        renderer.clear();
258        renderer.render(scene,camera);
259        requestAnimationFrame(animation);
260        stats.update();
261    }
262
263
</script>
264<div id="canvas-frame"></div>
265</body>
266</html>
複製代碼

注意從本地讀取圖片或者其餘文件時,瀏覽器通常是不容許的,因此會出現加載不了紋理或者背景圖片的狀況,只能在Chrome瀏覽器的屬性--目標的最後,加上 --allow-file-access-from-files(前面有一個空格),就能夠從這個打開的快捷方式中去讀取到本地文件,若是是Edge瀏覽器彷佛就直接能夠。也能夠使用npm或者tomcat搭建一個本地服務器,而後把圖片放進去就能夠直接讀取了。git

相關文章
相關標籤/搜索