从零开始搭建开源智慧城市项目(一)初始化场景

4,080 阅读2分钟

前言

本篇文章是从零开始仿写一个智慧城市系列文章的第一篇,这一篇主要实现一下项目的初始化,添加一下Three场景的三大组件:场景(scene)、相机(camera)和渲染器(renderer),加一个控制器可以通关鼠标控制移动场景,把模型数据加载到场景里面。

初始化项目

初始化项目 然后创建一个scens的vue文件 创建一个div

<template>
  <div id="scene"></div>
</template>

然后引入three模块 ,然后引入这次需要的几个文件.

import * as THREE from "three";//引入three模块
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";//控制器模块
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";//gltf模型加载模块

初始化Three三要素

  1. 场景: three中创建场景只需要new一个THREE.Scene就行了
      scene = new THREE.Scene();
  1. 相机: 相机在three中分成透视相机和正投影相机 这里用的是透视相机PerspectiveCamera
      const width = window.innerWidth; // 窗口宽度
      const height = window.innerHeight; // 窗口高度
      /** 透视投影相机对象 */
      camera = new THREE.PerspectiveCamera(60, width / height, 1, 100000);
      camera.position.set(6000, 9000, 6000); // 树上面观察
      // camera.position.set(200, 30, 200); //树下面观察
      camera.lookAt(this.scene.position); // 设置相机方向(指向的场景对象)
  1. 渲染器: 渲染器决定了渲染的结果应该画在元素的什么元素上面,这里采用的是WebGLRenderer
      const container = document.getElementById("scene");//或者Dom元素,前面需要创建一个id为scene的div。
      renderer = new THREE.WebGLRenderer({ alpha: true });//新建一个WebGLRenderer
      renderer.setSize(container.clientWidth, container.clientHeight); // 设置渲染区域尺寸
      container.appendChild(renderer.domElement); // body元素中插入canvas对象

加载场景控制器并导入模型,添加光照

  1. 模型控制器: 只需要创建一个OrbitControls并且把相机和渲染器中绑定的Dom元素传进去就行
      controls = new OrbitControls(camera, renderer.domElement);
  1. 导入模型: 导入模型需要实例化一个GLTFLoader,然后调用lod方法,把模型地址加进去,然后把数据加载到scene中。
const loader = new GLTFLoader();
     loader.load("shanghai.gltf", (gltf) => {
       scene.add(gltf.scene);
     });
      controls = new OrbitControls(camera, renderer.domElement);

3.加载光照: 现在模型已经能显示在场景里面了但是没有光照 现在需要加一下光照

       //创建点光源和环境光源
        const point = new THREE.PointLight(0xffffff);
        point.position.set(6000, 9000, 6000); // 点光源位置
        scene.add(point); // 点光源添加到场景中
        // 环境光
        const ambient = new THREE.AmbientLight(0x888888);
        scene.add(ambient);

效果图

SDGIF_Rusult_1.gif

上完整代码

<template>
  <div id="scene"></div>
</template>
<script>
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
let scene; //场景
let camera; //相机
let renderer; //创建渲染器
// eslint-disable-next-line no-unused-vars
let controls; //控制器
export default {
  mounted() {
    this.init();
    this.createControls();
    this.render();
      this.addGLTF();
  },
  methods: {
    init() {
      //创建场景
      scene = new THREE.Scene();
      /**
       * 透视投影相机设置
       */
      const width = window.innerWidth; // 窗口宽度
      const height = window.innerHeight; // 窗口高度

      /** 透视投影相机对象 */
      camera = new THREE.PerspectiveCamera(60, width / height, 1, 100000);
      camera.position.set(6000, 9000, 6000); // 树上面观察
      camera.lookAt(scene.position); // 设置相机方向(指向的场景对象)
      // 创建渲染器对象
      const container = document.getElementById("scene");
      renderer = new THREE.WebGLRenderer({ alpha: true });
      renderer.setSize(container.clientWidth, container.clientHeight); // 设置渲染区域尺寸
      container.appendChild(renderer.domElement); // body元素中插入canvas对象

        //创建点光源和环境光源
        const point = new THREE.PointLight(0xffffff);
        point.position.set(6000, 9000, 6000); // 点光源位置
        scene.add(point); // 点光源添加到场景中
        // 环境光
        const ambient = new THREE.AmbientLight(0x888888);
        scene.add(ambient);
    },
    createControls() {
      controls = new OrbitControls(camera, renderer.domElement);
    },
    render() {
      renderer.render(scene, camera);
      requestAnimationFrame(this.render); // 请求再次执行渲染函数render
    },
    addGLTF() {
      const loader = new GLTFLoader();
      loader.load("shanghai.gltf", (gltf) => {
        scene.add(gltf.scene);
      });
    },
  },
};
</script>
<style scoped>
html,
body,
#scene {
  width: 100%;
  height: 100vh;
  z-index: 2;
  position: absolute;
  top: 0%;
}
</style>

项目地址:github.com/lixiaochjaj…

最后

这是第一篇创建场景,接下几篇我会介绍添加自定义材质,后处理实现模型材质替换,辉光效果,流动线,扫描线,扩散效果等使其看起来炫酷一些,并争取通过多种方式实现以上效果,添加天空盒并解决天空盒和后处理冲突问题,还有什么比较炫酷的效果欢迎大家提意见。