Threejs示例一

Posted FreeFly辉

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Threejs示例一相关的知识,希望对你有一定的参考价值。

Threejs是供js使用的webgl框架

threejs是开源免费的,当有了图形框架,我们便可以省去很多专业知识,而面向api编程,可以更快的构建3D效果。

git地址 : https://github.com/mrdoob/three.js.git

1、运行

可通过git直接执行 git clone https://github.com/mrdoob/three.js.git 拉取源码。
拉取源码后 进入项目目录执行 npm run dev 即可运行。
访问启动端口可看到如下页面:

点击 examples 目录即可进入查看示例:
点击 docs 查看文档,官方有如何引入项目安装,第一个示例、以及提供的各个api解释(新手很难看懂)

首个教程示例

一、介绍

threejs中进行构建画面时,有四个必须元素:

场景:scene, 摄像机:camera,renderer:渲染器,灯光:light

1、场景:场景相当于一个大舞台,你所有的东西都要放在这个舞台上用于展示
2、摄像机: 摄像机相当于你的眼睛,你想观看什么角度看到的东西,就要设置摄像机的位置,以及观看点
3、渲染器: 渲染器就是webgl的封装,用于显示在屏幕上。
4、灯光: 灯光属于一个辅助效果,像阴影,亮度都和灯光有关

二、起步

直接上代码,这里用的vue,所以文件格式为.vue格式,注意 vue 文件中,*

代码要放在 mounted()中,否则created中可能dom树还未加载完会报错。其次 场景 scene 变量要放在 script 标签最前面作为全局变量,不然也会报错,如图:

三、代码如下

	initDraw()
		//构建四要素中的场景,上图已声明为全局变量,所以无需用this指针
      	scene = new THREE.Scene(); 
      	//设置场景背景,这里的图片 根目录为 vue中的public目录,6张图片分辨率要一致,否则不显示
      	scene.background = new THREE.CubeTextureLoader()
                              .setPath('./img/skyBox6/')
                              .load([
                                'side.jpg',//前
                                'side.jpg',//后
                                'sky.JPEG',//上
                                'grass.JPEG',//下
                                'side.jpg',//右
                                'side.jpg',//左
                              ],()=>this.renderer.render(scene,this.camera));
      	//创建一个四要素中的辅助灯光                        
      	let ambientLight = new THREE.AmbientLight(0xffffff, 0.7);
      	scene.add(ambientLight);//灯光加入场景
      
		/*
		创建四要素中的相机,即人的视角,camera放在vue的data中用于 render()方法中使用
		参数分别是 角度(好比人睁眼不可能看到180度的平面,离眼睛越远处可视宽高越广),
		宽高比(可当作分辨率比),即能看到的宽高比值,
		可视最近距离,当摄像头距离物体小于这个值时,将不再显示,
		可视最远距离,当摄像头距离物体大于这个值时,将不再显示*/
      	this.camera = new THREE.PerspectiveCamera(45, window.innerWidth / (window.innerHeight), 0.1, 2000);
      	this.camera.position.set(-10, 10, 10);//摄像机坐标,threejs中心为0,0,0
      	//摄像机对准的坐标(俩点决定射线),摄像机坐标为起点,目标点决定的射线方向
      	this.camera.lookAt(new THREE.Vector3(0, 0, 0));
      
		/*
		*创建四要素中的渲染器,即人的视角,renderer放在vue的data中用于 render()方法中使用
		*四大要素最后一个渲染器,用于将摄像机看到的舞台显示在屏幕上*/
      	this.renderer = new THREE.WebGLRenderer(antialias:true);
      	this.renderer.setClearColor(0xffffff, 1.0);//用指定颜色先清屏
      	//渲染器的大小,相当于给 div标签设置宽,高
      	this.renderer.setSize(window.innerWidth,window.innerHeight);
      	//将渲染器加入htmldom树中
      	document.body.appendChild(document.createElement('div')).appendChild(this.renderer.domElement);
      	
      	//这是一个辅助器,用于允许通过鼠标旋转,放大,缩小摄像机看的位置,方便观察3D效果
      	let controls = new OrbitControls(this.camera, this.renderer.domElement);
      	controls.enableRotate =true; //启用旋转
      	controls.enablePan = true; //启用平移
      	controls.enableZoom =true;//启用缩放
      
      	//创建一个方块模型,用于放到场景中查看
      	let geometry = new THREE.BoxGeometry(3, 3, 3, 30, 30, 30);
      	//加载给方块贴图的图片
      	let map = new THREE.TextureLoader().load('img/skyBox6/sky.JPEG',()=>this.renderer.render(scene,this.camera));
      	//将贴图应用于纹理,纹理可以是普通颜色,也可是这里加载的图片,如果是颜色,将
      	//map:map换成color:'0xffffff'(16进制的rgb) 即可
      	let material = new THREE.MeshPhongMaterial(map:map);
      	//将纹理贴到方块上,形成一个可视的方块物体
      	let box = new THREE.Mesh(geometry, material);
      	scene.add(box);//物体加入 场景中
      	this.render();//所有工作完毕后进行渲染场景
    

渲染函数如下:

	render()
      requestAnimationFrame(this.render);//相当于setInterval计时器一直循环渲染
      //调用渲染器的渲染方法,渲染指定的场景,从指定摄像机角度看到的图像
      this.renderer.render(scene, this.camera)
    

四、最后效果如图:

全部代码如下

可直接复制到新建的 .vue文件中运行(图片文件注意目录放在 vue项目public/img/skyBox6目录下:)
<template>
</template>
<script>
import * as THREE from 'three'
import  OrbitControls  from 'three/examples/jsm/controls/OrbitControls.js'
let scene = undefined
export default 
  name: 'HomeView',
  data()
    return
      renderer:null,
      camera:null
    
  ,
  methods:
    initDraw()
      scene = new THREE.Scene();
      scene.background = new THREE.CubeTextureLoader()
                              .setPath('./img/skyBox6/')
                              .load([
                                'side.jpg',
                                'side.jpg',
                                'sky.JPEG',//天空
                                'grass.JPEG',
                                'side.jpg',
                                'side.jpg',
                              ],()=>this.renderer.render(scene,this.camera));
      let ambientLight = new THREE.AmbientLight(0xffffff, 0.7);
      scene.add(ambientLight);
      

      this.camera = new THREE.PerspectiveCamera(45, window.innerWidth / (window.innerHeight), 0.1, 2000);
      this.camera.position.set(-10, 10, 10);
      this.camera.lookAt(new THREE.Vector3(0, 0, 0));
      

      this.renderer = new THREE.WebGLRenderer(antialias:true);
      this.renderer.setClearColor(0xffffff, 1.0);
      this.renderer.setSize(window.innerWidth,window.innerHeight);
      document.body.appendChild(document.createElement('div')).appendChild(this.renderer.domElement);
      
      let controls = new OrbitControls(this.camera, this.renderer.domElement);
      controls.enableRotate =true; //启用旋转
      controls.enablePan = true; //启用平移
      controls.enableZoom =true;//启用缩放
      
      
      let geometry = new THREE.BoxGeometry(3, 3, 3, 30, 30, 30);
      let map = new THREE.TextureLoader().load('img/skyBox6/sky.JPEG',()=>this.renderer.render(scene,this.camera));
      let material = new THREE.MeshPhongMaterial(map:map);
      let box = new THREE.Mesh(geometry, material);
      scene.add(box);
      this.render()
    ,
    render()
      requestAnimationFrame(this.render);
      this.renderer.render(scene, this.camera)
    
  ,
  mounted()
    this.initDraw()
  

</script>
<style lang="less">
  .about
    
  
</style>

以上是关于Threejs示例一的主要内容,如果未能解决你的问题,请参考以下文章

Threejs - 灯光?投影?? 有光的地方就会有影子

Threejs中用于无线光线追踪的自定义渲染器和灯光?

Threejs物联网,养殖场3D可视化

Threejs示例一

Threejs示例一

THREEJS案例(11)- 光照阴影