微信小程序集成three.js--VR全景项目源码

1.实例演示

小程序集成Three.js,展示不同贴图材质的运用

2.源码

(1)引入库文件

import * as THREE from '../../libs/three.weapp.js'
import gLTF from '../../jsm/loaders/GLTFLoader'
import {
    OrbitControls
} from '../../jsm/controls/OrbitControls'
const app = getApp()

(2)在onLoad声明周期函数中初始化场景

onLoad: function () {
        initScene()
    },

(3)initScene()函数源码

initScene() {
        wx.createSelectorQuery()
            .select('#webgl')
            .node()
            .exec((res) => {
                let canvasId = String(res[0].node.id)
                const canvas = THREE.global.registerCanvas(canvasId, res[0].node)
                this.setData({
                    canvasId: canvasId
                })
                //相机
                const camera = new THREE.PerspectiveCamera(70, canvas.width / canvas.height, 1, 1000);
                //场景
                const scene = new THREE.Scene();
                scene.background = new THREE.Color(0xffffff);
                const renderer = new THREE.WebGLRenderer({
                    antialias: true
                });
                //设置相机位置
                camera.position.set(0, 0, 5);
                //控制器
                const controls = new OrbitControls(camera, renderer.domElement);
                controls.enableDamping = true;
                controls.update();

                //添加灯光
                const spotLight = new THREE.SpotLight(0xffffff);
                spotLight.position.set(-40, 60, -10)
                //设置点光源投射阴影
                spotLight.castShadow = true;
                scene.add(spotLight)

                //加入环境光
                let ambiColor = "#33322b";
                let ambientLight = new THREE.AmbientLight(ambiColor);
                scene.add(ambientLight)
                //定义图片
                let backurl = 'https://mmbiz.qpic.cn/mmbiz_png/DWsjgNA1bNg0SfFX1Od4SLicD89xz919XU0mgSlH2YKCnumENibq57JOhSuVPunNLmtUDXXicibfvwP6MsaEPQ3D8Q/0?wx_fmt=png'
                let fronturl = 'https://mmbiz.qpic.cn/mmbiz_png/DWsjgNA1bNg0SfFX1Od4SLicD89xz919XicHLxnM9wvgdrhNzHoK9aibicWZ5ice7NIVZxf9ict6MiaahHJdoCGRiaOhYw/0?wx_fmt=png'
                let lefturl = 'https://mmbiz.qpic.cn/mmbiz_png/DWsjgNA1bNg0SfFX1Od4SLicD89xz919XFTA6ZwMg4wp7nibYfMVUflicbQEJAhxicwvqlXLhY300JB9icWUo7USpeg/0?wx_fmt=png'
                let righturl = 'https://mmbiz.qpic.cn/mmbiz_png/DWsjgNA1bNg0SfFX1Od4SLicD89xz919XZ1V9ibeFdp9iaw1icWD6rl4YOxQXNaqJyIFShtBKDu5veNNmC1j3kW1tw/0?wx_fmt=png'
                let topurl = 'https://mmbiz.qpic.cn/mmbiz_png/DWsjgNA1bNg0SfFX1Od4SLicD89xz919Xia5ot5lPeiaDUHT9UPvJhUZobL9Wl4lEgBrna7zI0GdCwEE7B2sCCExw/0?wx_fmt=png'
                let bottomurl = 'https://mmbiz.qpic.cn/mmbiz_png/DWsjgNA1bNg0SfFX1Od4SLicD89xz919X26hbtubv0f43zOr2zqZQ0tUlFJwIONKzRoVqgdcTWnur113McB3XNA/0?wx_fmt=png'

                //正方体1
                wx.showLoading({
                  title: '纹理加载中',
                })
                const geometry = new THREE.BoxBufferGeometry(20, 20, 20);
                const textureb = new THREE.TextureLoader().load(backurl)
                textureb.minFilter = THREE.LinearFilter
                const material1 = new THREE.MeshBasicMaterial({map:textureb})
                
                const texturef = new THREE.TextureLoader().load(fronturl)
                texturef.minFilter = THREE.LinearFilter
                const material2 = new THREE.MeshBasicMaterial({map:texturef})

                const texturel = new THREE.TextureLoader().load(lefturl)
                texturel.minFilter = THREE.LinearFilter
                const material3 = new THREE.MeshBasicMaterial({map:texturel})

                const texturer = new THREE.TextureLoader().load(righturl)
                texturer.minFilter = THREE.LinearFilter
                const material4 = new THREE.MeshBasicMaterial({map:texturer})

                const textureu = new THREE.TextureLoader().load(topurl)
                textureu.minFilter = THREE.LinearFilter
                const material5 = new THREE.MeshBasicMaterial({map:textureu})

                const textured = new THREE.TextureLoader().load(bottomurl)
                textured.minFilter = THREE.LinearFilter
                const material6 = new THREE.MeshBasicMaterial({map:textured})
                wx.hideLoading({
                })
                //1:左侧 2:前册 3 顶部 4 底部 5前
                var boxMaterials = [material4,material3,material5,material6,material2,material1]

                const cube = new THREE.Mesh(geometry,boxMaterials)
                cube.geometry.scale(1,1,-1)
                cube.rotation.y = Math.PI
                scene.add(cube)
                
                //设置cube纹理加载器
                const cubeTextureLoader = new THREE.CubeTextureLoader()
                const envMapTexture = cubeTextureLoader.load([
                    backurl,
                    fronturl,
                    righturl,
                    lefturl,
                    topurl,
                    bottomurl
                ])
                envMapTexture.minFilter = THREE.LinearFilter
                const sphereGeomtry = new THREE.SphereGeometry(1,20,20)
                const sphereMaterial = new THREE.MeshStandardMaterial({
                    metalness:0.7,
                    roughness:0.1,
                    envMap:envMapTexture    //设置环境贴图
                })
                const sphere = new THREE.Mesh(sphereGeomtry,sphereMaterial)
                scene.add(sphere)

                //辅助线
                /* const axesHelper = new THREE.AxesHelper(500);
                scene.add(axesHelper) */

                renderer.setPixelRatio(wx.getSystemInfoSync().pixelRatio);
                renderer.setSize(canvas.width, canvas.height);

                function render() {
                    canvas.requestAnimationFrame(render);
                    //更新控制器
                    controls.update();
                    renderer.render(scene, camera);
                }
                render()
            })
    },

(4)源码解读

实现VR全景效果的部分,主要实现步骤如下:

<1> 创建一个正方体

<2>加载6个不同面的图片作为正方体的材质

<3>设置正方体属性 cube.geometry.scale(1,1,-1),即完成了正方体面的反转

<4>将camera的位置设置在正方体内部,即实现了从内部观察正方体的全景效果

源码中还添加了一个金属球,来反射周围的环境,这里主要就是在给金属球设置材质时,将材质的envMap属性设置为想要的环境贴图

3.实例小程序

ThreeJS开发指南及模型下载 

猜你喜欢

转载自blog.csdn.net/weixin_39318421/article/details/128493881