从零开始搭建开源智慧城市项目(五)背景天空盒、扩散墙、扩散圆 |
您所在的位置:网站首页 › 天空盒子贴图下载 › 从零开始搭建开源智慧城市项目(五)背景天空盒、扩散墙、扩散圆 |
前言
上一节实现了颜色渐变效果和扩散扫光效果,这一节来添加背景天空盒、扩散墙、扩散圆。 添加天空盒思路three添加天空盒有两种格式,一种是需要上下左右前后六张图来组成天空盒,一种是创建一个足够大的球,把这个球表面贴上一张图 场景在球里面组成天空球。 六张图:这种方式是通关three的THREE.CubeTextureLoader().load方法,吧六张图地址数据添加到该对象里面去然后把场景的背景设置为这个对象。原理图如下所示我这里天空盒实现选的是第一种方式(因为数据是六张图的),代码如下 const textureCube = new THREE.CubeTextureLoader().load(['1.jpg', '2.jpg', '3.jpg', '4.jpg', '5.jpg', '6.jpg'],); scene.background = textureCube; // 作为背景贴图数据如下 效果 通过THREE.RingGeometry创建一个圆,然后给这个圆添加想要实现效果的贴图,然后再render循环里面每一帧都改变这个圆的大小。 扩散圆实现通过创建THREE.TextureLoader()来进行读取图片纹理数据其中this.img为图片地址,创建THREE.RingGeometry模型,把读出来的纹理赋给THREE.MeshBasicMaterial材质,然后再render循环里面改变这个模型的缩放比例来进行扩散效果模拟。 代码如下 /* eslint-disable */ import * as THREE from 'three'; /** * 波纹散射图层 * @param options.img 照片地址 * @param options.speed 流动速度 * @param options.scene three场景 * @param options.radius 圆的半径 * @param options.thing 圆的位置 * @param options.meshrings 存储圆形数据 * @example */ class RunRing { constructor(option) { this.img = option.img || ''; this.speed = option.speed / 100 || 0.01; this.scene = option.scene; this.radius = option.radius || 100; this.position = option.position || [0, 0, 0]; this.meshrings = []; this.CreatRing(); } CreatRing() { //创建对象读取照片纹理 const textureLoader = new THREE.TextureLoader(); textureLoader.load(this.img, (texture) => { //创建圆圈结构 const geometry = new THREE.RingGeometry(0, this.radius, 500); //创建材质 把读取到的图片赋给材质 const material2 = new THREE.MeshBasicMaterial({ color: 0xffffff, side: THREE.DoubleSide, depthTest: true, blending: THREE.AdditiveBlending, map: texture, }); //传入的多点的话生成多个模型 for (let i = 0; i < this.position.length; i += 1) { //组合生成模型 this.meshring = new THREE.Mesh(geometry, material2); //设置模型的X轴偏移量,让模型平铺再X面上 this.meshring.rotateX(Math.PI / 2); //设置初始状态模型缩放比例 this.meshring.scale.set(0.1, 0.1, 0.1); //设置模型位置 this.meshring.position.set(this.position[i][0], this.position[i][1], this.position[i][2]); //储存模型对象,用于render改变属性和销毁对象 this.meshrings.push(this.meshring) //添加到场景里面 this.scene.add(this.meshrings[i]); } }); //创建render,每一帧进行模型改变 this.thing = setInterval(() => { //循环所有创建的模型,进行改变 for (let i = 0; i < this.position.length; i += 1) { //如果模型已经创建 if (this.meshrings[i]) { //当模型缩放比例小于1的时候,模型进行放大 if (this.meshrings[i].scale.x < 1) { this.meshrings[i].scale.set( this.meshrings[i].scale.x + 0.01, this.meshrings[i].scale.x + 0.01, this.meshrings[i].scale.x + 0.01, ); } else { //当模型比例大于1的时候,模型重置 this.meshrings[i].scale.set(0.1, 0.1, 0.1); } } } }, 50); } delete() { //删除scene中对应的模型 for (let i = 0; i < this.position.length; i += 1) { if (this.meshrings[i]) { this.scene.remove(this.meshrings[i]); } } if (this.thing) { //清除render事件 clearInterval(this.thing); } } } export default RunRing;数据格式 { img: "clice.png", scene: scene, speed: 1, radius: 400, position: [ [400, 30, 400], [100, 30, 1200], ], }
扩散墙和上一节一样 是通过ShaderMaterial来实现的,要实现的效果是墙面随着高度增加透明度也增加,所以模型点位的透明度和高度呈反比。模型的扩散效果是把模型点位的位置通过mod函数来进行取余运算(%),把计算结果限制再0-1之间。 扩散墙实现 /* eslint-disable */ import * as THREE from "three"; /** * 波动墙 * @param options.scene three场景 * @param options.radius 中心 * @param options.height 墙高度 * @param options.opacity 墙透明度 * @param options.color 墙颜色 * @example */ class Wall { constructor(option) { this.scene = option.scene; this.radius = option.radius || 420; this.height = option.height || 120; this.opacity = option.opacity || 0.5; this.color = option.color || "#efad35"; this.speed = option.speed || 0.5; this.mesh = ""; //生成的模型数据 this.CreatRing(); } CreatRing() { const vertexShader = ` uniform vec3 u_color; uniform float time; uniform float u_height; varying float v_opacity; void main() { //模型点位置乘以一个0.0-1.0的系数,来模拟扩散效果。 vec3 vPosition = position * mod(time/20.0, 1.0); //模型的透明度和模型的高度呈反比 v_opacity =1.0- position.y / u_height; gl_Position = projectionMatrix * modelViewMatrix * vec4(vPosition, 1.0); } `; const fragmentShader = ` uniform vec3 u_color; uniform float u_opacity; varying float v_opacity; void main() { //u_color是颜色 v_opacity * u_opacity是高度所产生的透明效果和模型传入的透明度的乘积。 gl_FragColor = vec4(u_color, v_opacity * u_opacity); } `; //获取参数 const { radius, height, opacity, color, speed, renderOrder } = this; //生成模型结构 const geometry = new THREE.CylinderGeometry( radius, radius, height, 32, 1, true ); //模型位置设置 geometry.translate(0, height / 2, 0); //自定义模型材质 const material = new THREE.ShaderMaterial({ uniforms: { u_height: { value: height, }, u_opacity: { value: opacity, }, u_color: { value: new THREE.Color(color), }, time: { value: 0, }, }, transparent: true, depthWrite: false, depthTest: false, side: THREE.DoubleSide, vertexShader: vertexShader, fragmentShader: fragmentShader, }); //组合材质和结构生成对象 const mesh = new THREE.Mesh(geometry, material); //设置模型遮挡,把这个模型放到最前面防止遮挡 mesh.renderOrder = renderOrder || 1; this.mesh = mesh; } } export default Wall;效果图 项目地址: github.com/lixiaochjaj… |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |