WebGL three.js学习笔记 纹理贴图模拟太阳系运转
纹理贴图的应用以及实现一个太阳系的自转公转
点击查看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学习笔记 纹理贴图模拟太阳系运转的更多相关文章
- WebGL three.js学习笔记 6种类型的纹理介绍及应用
WebGL three.js学习笔记 6种类型的纹理介绍及应用 本文所使用到的demo演示: 高光贴图Demo演示 反光效果Demo演示(因为是加载的模型,所以速度会慢) (一)普通纹理 计算机图形学 ...
- WebGL three.js学习笔记 使用粒子系统模拟时空隧道(虫洞)
WebGL three.js学习笔记 使用粒子系统模拟时空隧道 本例的运行结果如图: 时空隧道demo演示 Demo地址:https://nsytsqdtn.github.io/demo/sprite ...
- WebGL three.js学习笔记 加载外部模型以及Tween.js动画
WebGL three.js学习笔记 加载外部模型以及Tween.js动画 本文的程序实现了加载外部stl格式的模型,以及学习了如何把加载的模型变为一个粒子系统,并使用Tween.js对该粒子系统进行 ...
- WebGL three.js学习笔记 法向量网格材质MeshNormalMaterial的介绍和创建360度全景天空盒的方法
WebGL学习----Three.js学习笔记(5) 点击查看demo演示 Demo地址:https://nsytsqdtn.github.io/demo/360/360 简单网格材质 MeshNor ...
- WebGL three.js学习笔记 创建three.js代码的基本框架
WebGL学习----Three.js学习笔记(1) webgl介绍 WebGL是一种3D绘图协议,它把JavaScript和OpenGL ES 2.0结合在一起,通过增加OpenGL ES 2.0的 ...
- JS学习笔记--轮播图效果
希望通过自己的学习收获哪怕收获一点点,进步一点点都是值得的,加油吧!!! 本章知识点:index this for if else 下边我分享下通过老师教的方式写的轮播图,基础知识实现: 1.css代 ...
- WebGL three.js学习笔记 自定义顶点建立几何体
自定义顶点建立几何体与克隆 Three.js本身已经有很多的网格模型,基本已经够我们的使用,但是如果我们还是想自己根据顶点坐标来建立几何模型的话,Three.js也是可以的. 基本效果如图: 点击查看 ...
- WebGL three.js学习笔记 阴影与实现物体的动画
实现物体的旋转.跳动以及场景阴影的开启与优化 本程序将创建一个场景,并实现物体的动画效果 运行的结果如图: 完整代码如下: <!DOCTYPE html> <html lang=&q ...
- WebGL学习之纹理贴图
为了使图形能获得接近于真实物体的材质效果,一般会使用贴图,贴图类型主要包括两种:漫反射贴图和镜面高光贴图.其中漫反射贴图可以同时实现漫反射光和环境光的效果. 实际效果请看demo:纹理贴图 2D纹理 ...
随机推荐
- Proxy SwitchyOmega配合Shawdowsocks使用的配置
国内环境如果想使用Shawdowsocks来FQ,几乎一定会装ProxyOmega来进行配合使用,简单讲讲ProxyOmega如何和Shawdowsocks进行协同. 准备 Google chrome ...
- 计算机的Cache和Memory访问时Write-back,Write-through及write allocate的区别
计算机的存储系统采用Register,Cache,Memory和I/O的方式来构成存储系统,无疑是一个性能和经济性的妥协的产物.Cache和Memory机制是计算机硬件的基础内容,这里就不再啰嗦.下面 ...
- Scala学习笔记:重要语法特性
1.变量声明 Scala 有两种变量, val 和 var val的值声明后不可变,var可变 val msg: String = "Hello yet again, world!&quo ...
- cas 4.1.4单点登录实战
使用工具 maven-3.3.9 cas-4.1.4 Tomcat-7.0.57-win-x64 cas-sample-Java-webapp 一.Hello cas 1.下载Tomcat,解压:修改 ...
- SSM-Spring-13:Spring中RegexpMethodPointcutAdvisor正则方法切入点顾问
------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- RegexpMethodPointcutAdvisor:正则方法切入点顾问 核心: <property ...
- sql server 分区(上)
分区发展历程 基于表的分区功能为简化分区表的创建和维护过程提供了灵活性和更好的性能.追溯到逻辑分区表和手动分区表的功能. 二.为什么要进行分区 为了改善大型表以及具有各种访问模式的表的可伸缩 ...
- VMware 非简易安装centos6(静态ip配置)
1.选择新建虚拟机 在弹出框中我选择推荐安装 然后点击下一步 2.选择稍后安装操作系统(不然会默认简易安装) 接着一直下一步就可以了,最后到这个页面 4.如下图选择事先下载好的安装文件 5.配置桥接模 ...
- JS奇淫巧技:防抖函数与节流函数
应用场景 实际工作中,我们经常性的会通过监听某些事件完成对应的需求,比如: 通过监听 scroll 事件,检测滚动位置,根据滚动位置显示返回顶部按钮 通过监听 resize 事件,对某些自适应页面调整 ...
- Android 手势检测实战 打造支持缩放平移的图片预览效果(下)
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/39480503,本文出自:[张鸿洋的博客] 上一篇已经带大家实现了自由的放大缩小图 ...
- 各位情人节快乐, Python帮忙撒狗粮, 我连夜做了这个程序!
阅读本文大概需要5分钟 码农的情人节 一年一度的情人节要来啦,这个浪漫温馨的节日,走在大街小巷,走在地铁里,走在商场里,走在电影院,姑娘们手里几乎都捧着一束花,心里都是乐滋滋的,一脸幸福的样子,忽然想 ...