|
@@ -4,8 +4,13 @@
|
|
|
<script>
|
|
|
import * as THREE from 'three';
|
|
|
import Stats from 'three/addons/libs/stats.module.js';
|
|
|
- import {OrbitControls} from 'three/addons/controls/OrbitControls.js';
|
|
|
- import {getStorage} from '@/utils/localStorage';
|
|
|
+ import {
|
|
|
+ OrbitControls
|
|
|
+ } from 'three/addons/controls/OrbitControls.js';
|
|
|
+ import {RGBELoader} from 'three/examples/jsm/loaders/RGBELoader'
|
|
|
+ import {
|
|
|
+ getStorage
|
|
|
+ } from '@/utils/localStorage';
|
|
|
var requestId = "";
|
|
|
const util = require('@/utils/util.js').default;
|
|
|
import commonPageMethod from '@/mixins/commonPageMethod.js';
|
|
@@ -55,13 +60,13 @@
|
|
|
controlLastPosition: null, //观察点上一次移动到的位置
|
|
|
myLoadingStatus: false,
|
|
|
repeatFlag: false, //重复点击
|
|
|
- canvasHeight:'',
|
|
|
+ canvasHeight: '',
|
|
|
isIOS: false,
|
|
|
- videoUrl:'', //绿幕视频地址
|
|
|
- bgUrl:'',
|
|
|
- coordinate:'',
|
|
|
- hasOneTouch:false,
|
|
|
- muted:true,//视频是否静音
|
|
|
+ videoUrl: '', //绿幕视频地址
|
|
|
+ bgUrl: '',
|
|
|
+ coordinate: '',
|
|
|
+ hasOneTouch: false,
|
|
|
+ muted: true, //视频是否静音
|
|
|
}
|
|
|
},
|
|
|
beforeDestroy() {
|
|
@@ -104,7 +109,8 @@
|
|
|
console.warn("***webgl_rxdz_roam-options***", this.$route.query)
|
|
|
this.isIOS = !!navigator.userAgent.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);
|
|
|
this.videoUrl = this.$route.query.videoUrl || '';
|
|
|
- this.bgUrl = this.$route.query.bgUrl || 'https://dm.static.elab-plus.com/miniProgram/tears_of_steel_bridge_2k.jpg';
|
|
|
+ this.bgUrl = this.$route.query.bgUrl ||
|
|
|
+ 'https://dm.static.elab-plus.com/miniProgram/tears_of_steel_bridge_2k.jpg';
|
|
|
this.coordinate = this.$route.query.coordinate || '';
|
|
|
this.type = this.$route.query.type || '';
|
|
|
let screenWidth = window.screen.width;
|
|
@@ -132,14 +138,17 @@
|
|
|
let stats;
|
|
|
let videoMeshGroup = [];
|
|
|
let cubeCamera = null;
|
|
|
+ let lineMesh = null;
|
|
|
+ let radius = 30; //全景图半径-全景图是个球体
|
|
|
init();
|
|
|
// this.clearEvent = clearEvent;
|
|
|
// this.attendEvent = attendEvent;
|
|
|
this.starRender = starRender; //对外暴露启动渲染的方法
|
|
|
this.stopRender = stopRender; //对外暴露停止渲染的方法
|
|
|
- if(window.__wxjs_environment === 'miniprogram'){
|
|
|
+ if (window.__wxjs_environment === 'miniprogram') {
|
|
|
this.navbar.showCapsule = 0;
|
|
|
}
|
|
|
+
|
|
|
function init() {
|
|
|
// 创建相机位置
|
|
|
camera = new THREE.PerspectiveCamera(90, screenWidth / that.canvasHeight, 0.1, 10000);
|
|
@@ -159,13 +168,14 @@
|
|
|
// gridHelper.position.x = 0;
|
|
|
// scene.add(gridHelper);
|
|
|
//加载环境720贴图
|
|
|
- let loader = new THREE.TextureLoader();
|
|
|
- let texture = loader.load(that.bgUrl, () => {
|
|
|
- let rt = new THREE.WebGLCubeRenderTarget(texture.image.height);
|
|
|
- rt.fromEquirectangularTexture(renderer, texture);
|
|
|
- scene.background = rt.texture;
|
|
|
- });
|
|
|
- // makeInstance(),
|
|
|
+ // let loader = new THREE.TextureLoader();
|
|
|
+ // let texture = loader.load(that.bgUrl, () => {
|
|
|
+ // let rt = new THREE.WebGLCubeRenderTarget(texture.image.height);
|
|
|
+ // rt.fromEquirectangularTexture(renderer, texture);
|
|
|
+ // scene.background = rt.texture;
|
|
|
+ // });
|
|
|
+ makeShaderCube();
|
|
|
+ // makeInstance();
|
|
|
//antialias 这个值得设置为false,不然IOS上截图会失效
|
|
|
renderer = that.renderer = new THREE.WebGLRenderer({
|
|
|
canvas: canvas3d,
|
|
@@ -178,11 +188,11 @@
|
|
|
controls = new OrbitControls(camera, renderer.domElement);
|
|
|
controls.enableDamping = true; //启动缓动
|
|
|
controls.minDistance = 0.0001;
|
|
|
- controls.maxDistance = 30;
|
|
|
+ controls.maxDistance = radius;
|
|
|
// controls.minPolarAngle = 0; // 默认0
|
|
|
// controls.maxPolarAngle = Math.PI / 2; // 默认Math.PI,即可以向下旋转到的视角。
|
|
|
- controls.enableZoom = false; //启用/禁用摄像机的缩放
|
|
|
- controls.enablePan = false; //启用/禁用摄像机平移
|
|
|
+ controls.enableZoom = true; //启用/禁用摄像机的缩放
|
|
|
+ controls.enablePan = true; //启用/禁用摄像机平移
|
|
|
controls.enableRotate = true; //启用/禁用摄像机水平或垂直旋转
|
|
|
|
|
|
// 监听相机移动事件-限制只能在当前空间范围内移动
|
|
@@ -199,35 +209,84 @@
|
|
|
// // }
|
|
|
// });
|
|
|
// camera.lookAt(that.controlStarPosition.x, that.controlStarPosition.y, that.controlStarPosition.z);
|
|
|
- if(that.coordinate){
|
|
|
+ if (that.coordinate) {
|
|
|
let position = JSON.parse(that.coordinate);
|
|
|
// camera.lookAt(position.x, position.y, position.z);
|
|
|
}
|
|
|
starRender(); //启动渲染
|
|
|
- if(that.isIOS){
|
|
|
- document.addEventListener("WeixinJSBridgeReady", function (){
|
|
|
- if(that.type){
|
|
|
+ if (that.isIOS) {
|
|
|
+ document.addEventListener("WeixinJSBridgeReady", function() {
|
|
|
+ if (that.type) {
|
|
|
moreTest()
|
|
|
- }else{
|
|
|
- videoHandle({videoUrl:that.videoUrl,coordinate:that.coordinate,muted:that.muted});
|
|
|
+ } else {
|
|
|
+ videoHandle({
|
|
|
+ videoUrl: that.videoUrl,
|
|
|
+ coordinate: that.coordinate,
|
|
|
+ muted: that.muted
|
|
|
+ });
|
|
|
}
|
|
|
}, false)
|
|
|
}
|
|
|
var guideMask = document.querySelector('#guide-mask');
|
|
|
- document.addEventListener("touchend", function () {
|
|
|
+ document.addEventListener("touchend", function() {
|
|
|
guideMask.classList.add('guide-mask-hide');
|
|
|
- if(!that.isIOS && that.hasOneTouch==false){
|
|
|
+ if (!that.isIOS && that.hasOneTouch == false) {
|
|
|
that.hasOneTouch = true;
|
|
|
// setTimeout(()=>{
|
|
|
- if(that.type){
|
|
|
- moreTest()
|
|
|
- }else{
|
|
|
- videoHandle({videoUrl:that.videoUrl,coordinate:that.coordinate,muted:that.muted});
|
|
|
- }
|
|
|
+ if (that.type) {
|
|
|
+ moreTest()
|
|
|
+ } else {
|
|
|
+ videoHandle({
|
|
|
+ videoUrl: that.videoUrl,
|
|
|
+ coordinate: that.coordinate,
|
|
|
+ muted: that.muted
|
|
|
+ });
|
|
|
+ }
|
|
|
// },2000)
|
|
|
}
|
|
|
}, false);
|
|
|
}
|
|
|
+
|
|
|
+ function makeShaderCube() {
|
|
|
+ let loader = new THREE.TextureLoader();
|
|
|
+ let resultTexture = loader.load(that.bgUrl);
|
|
|
+ // 创建一个ShaderMaterial
|
|
|
+ var material = new THREE.ShaderMaterial({
|
|
|
+ uniforms: {
|
|
|
+ mytexture: {
|
|
|
+ value: resultTexture
|
|
|
+ }
|
|
|
+ },
|
|
|
+ vertexShader: `
|
|
|
+ varying vec3 vWorldPosition;
|
|
|
+ void main() {
|
|
|
+ vec4 worldPosition = modelMatrix * vec4(position, 1.0);
|
|
|
+ vWorldPosition = worldPosition.xyz;
|
|
|
+ gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
|
|
|
+ }
|
|
|
+ `,
|
|
|
+ fragmentShader: `
|
|
|
+ uniform sampler2D mytexture;
|
|
|
+ varying vec3 vWorldPosition;
|
|
|
+ void main() {
|
|
|
+ vec3 direction = normalize(vWorldPosition);
|
|
|
+ vec2 sampleUV = vec2(0.5 + atan(direction.z, direction.x) / (2.0 * 3.14159265359), 0.5 - asin(direction.y) / 3.14159265359);
|
|
|
+ gl_FragColor = texture2D(mytexture, sampleUV);
|
|
|
+ }
|
|
|
+ `,
|
|
|
+ side: THREE.BackSide
|
|
|
+ });
|
|
|
+ //创建一个球体几何体
|
|
|
+ var sphereGeometry = new THREE.SphereGeometry(radius, 60, 40);
|
|
|
+ //创建一个球体并应用材质
|
|
|
+ var sphere = new THREE.Mesh(sphereGeometry, material);
|
|
|
+ scene.add(sphere);
|
|
|
+ // 创建一个圆柱几何体
|
|
|
+ // var cylinderGeometry = new THREE.CylinderGeometry(50, 50, 100, 60, 1, true);
|
|
|
+ // var cylinder = new THREE.Mesh(cylinderGeometry, material);
|
|
|
+ // scene.add(cylinder);
|
|
|
+ }
|
|
|
+
|
|
|
function makeInstance() {
|
|
|
// let geometry = new THREE.BoxGeometry(10, 10, 10);
|
|
|
// //加载环境720贴图
|
|
@@ -255,48 +314,55 @@
|
|
|
'https://dm.static.elab-plus.com/miniProgram/neg-y.jpg',
|
|
|
'https://dm.static.elab-plus.com/miniProgram/pos-z.jpg',
|
|
|
'https://dm.static.elab-plus.com/miniProgram/neg-z.jpg',
|
|
|
- ], function (texture) {
|
|
|
- // 将Equirectangular map 应用到天空盒的材质上
|
|
|
- var material = new THREE.MeshBasicMaterial({ envMap: texture,side:THREE.BackSide });
|
|
|
- var geometry = new THREE.BoxGeometry(10, 10, 10);
|
|
|
- var skybox = new THREE.Mesh(geometry, material);
|
|
|
- scene.add(skybox);
|
|
|
+ ], function(texture) {
|
|
|
+ // 将Equirectangular map 应用到天空盒的材质上
|
|
|
+ //创建一个球体几何体
|
|
|
+ var sphereGeometry = new THREE.SphereGeometry(10, 60, 40);
|
|
|
+ const materials = new THREE.MeshStandardMaterial({
|
|
|
+ metalness:0.8, // 金属材质
|
|
|
+ roughness:0.1, // 粗糙度
|
|
|
+ envMap:texture, // 环境贴图
|
|
|
+ side: THREE.BackSide
|
|
|
+ })
|
|
|
+ const sphere = new THREE.Mesh(sphereGeometry,materials)
|
|
|
+ scene.add(sphere)
|
|
|
});
|
|
|
}
|
|
|
- function moreTest(){
|
|
|
- let data = [
|
|
|
- {
|
|
|
- videoUrl:'https://dm.static.elab-plus.com/miniProgram/002.mp4',
|
|
|
- coordinate:'{"x":6,"y":-5,"z":0}',
|
|
|
- muted:true,
|
|
|
+
|
|
|
+ function moreTest() {
|
|
|
+ let data = [{
|
|
|
+ videoUrl: 'https://dm.static.elab-plus.com/miniProgram/002.mp4',
|
|
|
+ coordinate: '{"x":6,"y":-5,"z":0}',
|
|
|
+ muted: true,
|
|
|
},
|
|
|
{
|
|
|
- videoUrl:'https://dm.static.elab-plus.com/miniProgram/004.mp4',
|
|
|
- coordinate:'{"x":-13,"y":16,"z":8}',
|
|
|
- muted:false,
|
|
|
+ videoUrl: 'https://dm.static.elab-plus.com/miniProgram/004.mp4',
|
|
|
+ coordinate: '{"x":-13,"y":16,"z":8}',
|
|
|
+ muted: false,
|
|
|
},
|
|
|
{
|
|
|
- videoUrl:'https://dm.static.elab-plus.com/miniProgram/005.mp4',
|
|
|
- coordinate:'{"x":13,"y":-14,"z":-35}',
|
|
|
- muted:true,
|
|
|
+ videoUrl: 'https://dm.static.elab-plus.com/miniProgram/005.mp4',
|
|
|
+ coordinate: '{"x":13,"y":-14,"z":-35}',
|
|
|
+ muted: true,
|
|
|
},
|
|
|
{
|
|
|
- videoUrl:'https://dm.static.elab-plus.com/miniProgram/007.mp4',
|
|
|
- coordinate:'{"x":0,"y":4,"z":25}',
|
|
|
- muted:true,
|
|
|
+ videoUrl: 'https://dm.static.elab-plus.com/miniProgram/007.mp4',
|
|
|
+ coordinate: '{"x":0,"y":4,"z":25}',
|
|
|
+ muted: true,
|
|
|
},
|
|
|
{
|
|
|
- videoUrl:'https://dm.static.elab-plus.com/miniProgram/008.mov',
|
|
|
- coordinate:'{"x":3,"y":-4,"z":-5}',
|
|
|
- muted:true,
|
|
|
+ videoUrl: 'https://dm.static.elab-plus.com/miniProgram/008.mov',
|
|
|
+ coordinate: '{"x":3,"y":-4,"z":-5}',
|
|
|
+ muted: true,
|
|
|
}
|
|
|
]
|
|
|
- data.forEach(it=>{
|
|
|
+ data.forEach(it => {
|
|
|
videoHandle(it);
|
|
|
})
|
|
|
}
|
|
|
+
|
|
|
function videoHandle(item) {
|
|
|
- if(!item.videoUrl){
|
|
|
+ if (!item.videoUrl) {
|
|
|
return false;
|
|
|
}
|
|
|
// 创建视频元素
|
|
@@ -311,46 +377,46 @@
|
|
|
video.setAttribute('webkit-playsinline', true);
|
|
|
video.setAttribute('playsinline', true);
|
|
|
video.load();
|
|
|
-
|
|
|
- console.warn("***video***",video,video.width);
|
|
|
-
|
|
|
- setTimeout(()=>{
|
|
|
+
|
|
|
+ console.warn("***video***", video, video.width);
|
|
|
+
|
|
|
+ setTimeout(() => {
|
|
|
video.play();
|
|
|
// 创建视频纹理
|
|
|
var videoTexture = new THREE.VideoTexture(video);
|
|
|
// videoTexture.minFilter = THREE.LinearFilter;
|
|
|
// videoTexture.format = THREE.RGBFormat;
|
|
|
-
|
|
|
+
|
|
|
var keyColorObject = new THREE.Color("#00ff05");
|
|
|
var myuniforms = {
|
|
|
- pointTexture: {
|
|
|
- type: "t",
|
|
|
- value: videoTexture
|
|
|
- },
|
|
|
- color: {
|
|
|
- type: "c",
|
|
|
- value: keyColorObject
|
|
|
- },
|
|
|
- videowidth: {
|
|
|
- type: "f",
|
|
|
- value: 501.0
|
|
|
- },
|
|
|
- videoheight: {
|
|
|
- type: "f",
|
|
|
- value: 1024.0
|
|
|
- },
|
|
|
- filterType: {
|
|
|
- type: "i",
|
|
|
- value: 0
|
|
|
- },
|
|
|
- lightLevel: {
|
|
|
- type: "f",
|
|
|
- value: 0.2
|
|
|
- },
|
|
|
- gridSize: {
|
|
|
- type: "f",
|
|
|
- value: 0.8
|
|
|
- }
|
|
|
+ pointTexture: {
|
|
|
+ type: "t",
|
|
|
+ value: videoTexture
|
|
|
+ },
|
|
|
+ color: {
|
|
|
+ type: "c",
|
|
|
+ value: keyColorObject
|
|
|
+ },
|
|
|
+ videowidth: {
|
|
|
+ type: "f",
|
|
|
+ value: 501.0
|
|
|
+ },
|
|
|
+ videoheight: {
|
|
|
+ type: "f",
|
|
|
+ value: 1024.0
|
|
|
+ },
|
|
|
+ filterType: {
|
|
|
+ type: "i",
|
|
|
+ value: 0
|
|
|
+ },
|
|
|
+ lightLevel: {
|
|
|
+ type: "f",
|
|
|
+ value: 0.2
|
|
|
+ },
|
|
|
+ gridSize: {
|
|
|
+ type: "f",
|
|
|
+ value: 0.8
|
|
|
+ }
|
|
|
};
|
|
|
// 创建绿幕着色器
|
|
|
let greenScreenShader = {
|
|
@@ -490,17 +556,27 @@
|
|
|
let geometry = new THREE.PlaneGeometry(9, 16);
|
|
|
// 应用绿幕材质到对象上
|
|
|
let mesh = new THREE.Mesh(geometry, greenScreenMaterial);
|
|
|
- if(item.coordinate){
|
|
|
+ if (item.coordinate) {
|
|
|
let position = JSON.parse(item.coordinate);
|
|
|
- mesh.position.set(position.x, position.y, position.z);//设置视频位置
|
|
|
- }else{
|
|
|
- mesh.position.set(0, 0, -10);//设置视频位置
|
|
|
+ mesh.position.set(position.x, position.y, position.z); //设置视频位置
|
|
|
+ } else {
|
|
|
+ mesh.position.set(0, 0, -10); //设置视频位置
|
|
|
}
|
|
|
// mesh.lookAt(camera.position);
|
|
|
scene.add(mesh);
|
|
|
videoMeshGroup.push(mesh);
|
|
|
- },1000)
|
|
|
-
|
|
|
+ // 创建一个PlaneGeometry
|
|
|
+ var planeGeometry = new THREE.PlaneGeometry(9, 16);
|
|
|
+ // 创建一个边框材质
|
|
|
+ var edgeMaterial = new THREE.LineBasicMaterial({ color: 0xffffff});
|
|
|
+ // 创建边框几何体
|
|
|
+ var edges = new THREE.EdgesGeometry(planeGeometry);
|
|
|
+ let line = new THREE.LineSegments(edges, edgeMaterial);
|
|
|
+ line.position.set(0, -10, -10);//设置视频位置
|
|
|
+ scene.add(line);
|
|
|
+ lineMesh = line;
|
|
|
+ }, 1000)
|
|
|
+
|
|
|
// videoMesh = mesh;
|
|
|
}
|
|
|
|
|
@@ -522,10 +598,16 @@
|
|
|
}
|
|
|
// stats.update();
|
|
|
controls.update();
|
|
|
- if(videoMeshGroup){
|
|
|
- videoMeshGroup.forEach(it=>{it.lookAt(camera.position)})
|
|
|
+ if (videoMeshGroup) {
|
|
|
+ videoMeshGroup.forEach(it => {
|
|
|
+ it.lookAt(camera.position)
|
|
|
+ })
|
|
|
+ if(lineMesh){
|
|
|
+ lineMesh.lookAt(camera.position);
|
|
|
+ lineMesh.position.copy(videoMeshGroup[0].position);
|
|
|
+ }
|
|
|
}
|
|
|
- if(cubeCamera){
|
|
|
+ if (cubeCamera) {
|
|
|
cubeCamera.update(renderer, scene);
|
|
|
}
|
|
|
// if(scene.background){
|