123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441 |
- import * as THREE from "../../../libs/three.js/build/three.module.js";
- import Common from '../utils/Common.js'
- import {Features} from "../../Features.js";
-
- const prefixVertex ="precision highp float;\nprecision highp int;\n\nuniform mat4 modelMatrix;\nuniform mat4 modelViewMatrix;\nuniform mat4 projectionMatrix;\nuniform mat4 viewMatrix;\nuniform mat3 normalMatrix;\nuniform vec3 cameraPosition;\nattribute vec3 position;\nattribute vec3 normal;\nattribute vec2 uv;\n"
- const prefixFragment ="precision highp float;\nprecision highp int;\n\nuniform mat4 viewMatrix;\nuniform vec3 cameraPosition;\n"
-
- let shader = {
-
- uniforms: {
-
- opacity: {
- type: "f",
- // value: 1
- },
- progress: {
- type: "f",
- value: 0
- },
-
- pano0Map: {
- type: "t",
- value: null
- },
- pano1Map: {
- type: "t",
- value: null
- },
- depthMap0: {
- type: "t",
- value: null
- },
- depthMap1: {
- type: "t",
- value: null
- },
- pano0Position: {
- type: "v3",
- value: new THREE.Vector3
- },
- pano0Matrix: {
- type: "m4",
- value: new THREE.Matrix4
- },
-
- pano1Position: {
- type: "v3",
- value: new THREE.Vector3
- },
- pano1Matrix: {
- type: "m4",
- value: new THREE.Matrix4
- },
- /* pano1Matrix2: {
- type: "m4",
- value: new THREE.Matrix4
- },
- */
-
- inverseProjectionMatrix: {
- value: new THREE.Matrix4
- },
- /* projectionMatrix:{//需要再写一遍吗
- value: new THREE.Matrix4
- }, */
- viewport: {
- value: new THREE.Vector4
- },
- //如 {x: 0, y: 0, z: 428, w: 969} xy应该是offset, zw是宽高
- cameraHeight0: {
- type: "f",
- value: 1
- },
- cameraHeight1: {
- type: "f",
- value: 1
- },
- ceilHeight0:{
- type: "f",
- value: 2
- },
- ceilHeight1:{
- type: "f",
- value: 2
- },
-
- },
-
- vertexShader: prefixVertex + `
- uniform vec3 pano0Position;
- uniform mat4 pano0Matrix;
-
- uniform vec3 pano1Position;
- uniform mat4 pano1Matrix;
- //uniform mat4 pano1Matrix2;
-
- varying vec2 vUv;
- varying vec3 vWorldPosition0;
- varying vec3 vWorldPosition1;
- varying vec3 vWorldPosition12;
-
- vec3 transformAxis( vec3 direction ) //navvis->4dkk
- {
- float y = direction.y;
- direction.y = direction.z;
- direction.z = -y;
- return direction;
- }
-
-
- void main() {
-
- vUv = uv;
- vec4 worldPosition = modelMatrix * vec4(position, 1.0);
-
-
-
- vec3 positionLocalToPanoCenter0 = worldPosition.xyz - pano0Position;
- vWorldPosition0 = (vec4(positionLocalToPanoCenter0, 1.0) * pano0Matrix).xyz;
- vWorldPosition0.x *= -1.0;
- vWorldPosition0 = transformAxis(vWorldPosition0);
-
- vec3 positionLocalToPanoCenter1 = worldPosition.xyz - pano1Position;
- vWorldPosition1 = (vec4(positionLocalToPanoCenter1, 1.0) * pano1Matrix).xyz;
- vWorldPosition1.x *= -1.0;
- vWorldPosition1 = transformAxis(vWorldPosition1);
-
- /*
- vec3 positionLocalToPanoCenter12 = worldPosition.xyz - pano1Position;
- vWorldPosition12 = (vec4(positionLocalToPanoCenter12, 1.0) * pano1Matrix2).xyz;
- vWorldPosition12.x *= -1.0;
- vWorldPosition12 = transformAxis(vWorldPosition12);
- */
-
-
-
- gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
-
- }
- `,
- fragmentShader: prefixFragment + `
- #extension GL_EXT_frag_depth : enable
- #define PI 3.141592653
-
-
- uniform float modelAlpha;
- uniform float opacity;
- uniform float progress;
- uniform int blackout;
- uniform vec3 pano0Position;
- uniform vec3 pano1Position;
- uniform float maxDistance;
- uniform float minDistance;
- uniform float minOpa;
-
-
-
- /* uniform sampler2D pano0Map;
- uniform sampler2D pano1Map; */
- uniform samplerCube pano0Map;
- uniform samplerCube pano1Map;
-
-
- varying vec2 vUv;
- varying vec3 vWorldPosition0;
- varying vec3 vWorldPosition1;
- //varying vec3 vWorldPosition12;
-
- /* vec2 getSamplerCoord( vec3 direction )
- {
- direction = normalize(direction);
- float tx=atan(direction.x,-direction.y)/(PI*2.0)+0.5;
- float ty=acos(direction.z)/PI;
- return vec2(tx,ty);
- } */
- vec2 getSamplerCoord2( vec3 direction )
- {
- direction = normalize(direction);
- float tx=atan(direction.x,direction.z)/(PI*2.0)+0.5;
- float ty=acos(direction.y)/PI;
- return vec2(tx,ty);
- }
-
-
- #if defined(GL_EXT_frag_depth) && defined(hasDepthTex)
- uniform sampler2D depthMap0;
- uniform sampler2D depthMap1;
- uniform mat4 inverseProjectionMatrix;
- uniform mat4 projectionMatrix;
- uniform vec4 viewport;
- uniform float cameraHeight0;
- uniform float cameraHeight1;
- uniform float ceilHeight0;
- uniform float ceilHeight1;
-
-
- vec2 getDepth(vec3 dir, sampler2D depthMap, float heightDown, float heightUp, vec4 eyePos){
- vec2 depthValue = vec2(0.0, 0.0);
- vec2 uv2 = getSamplerCoord2( dir.xyz); //暂时只用基于目标漫游点的方向
- uv2.x -= 0.25; //全景图和Cube的水平采样起始坐标相差90度,这里矫正 0.25 个采样偏移
- vec4 depth = texture2D(depthMap, uv2);
- //float distance = depth.r + 256. * (depth.g + 256. * depth.b);
- //distance *= 255. * .001; // distance is now in meters
-
- //更改
- float distance = (depth.g + depth.r / 256.) * 255.; //为什么要乘以255
-
- if(distance == 0.0){//漫游点底部识别不到的区域,给一个地板高度
- if(uv2.y < depthTexUVyLimit) distance = heightUp / dir.y;
- else if(uv2.y > 1.0 - depthTexUVyLimit) distance = heightDown / -dir.y;
- else distance = 100000.0;//给个超级远的值
- }
-
- if(distance == 0.0)distance = 100000.0;//给个超级远的值
-
- depthValue.x = distance;
-
- // return r[1] + r[0] / 256
- distance += .1; // add a safety margin
- vec4 eyePos2 = vec4(normalize(eyePos.xyz) * distance, 1.);
- vec4 clipPos2 = projectionMatrix * eyePos2;
- vec4 ndcPos2 = clipPos2 * 1. / clipPos2.w;
-
- depthValue.y = 0.5 * ((gl_DepthRange.far - gl_DepthRange.near) * ndcPos2.z
- + gl_DepthRange.near + gl_DepthRange.far);
- return depthValue;
- }
- //注:未加载好的话,depth为0,导致第一次漫游过去的时候许多mesh会立刻被遮挡,所以要确保加载完
- #endif
-
- void main()
- {
- vec3 vWorldPosition0N = normalize(vWorldPosition0);
- vec3 vWorldPosition1N = normalize(vWorldPosition1);
-
-
- vec4 colorFromPano0 = vec4(0.0,0.0,0.0,0.0);
- #if defined(usePanoMap0)
- //即progress < 1.0 通常是1
- colorFromPano0=textureCube(pano0Map,vWorldPosition0N.xyz);
- #endif
- vec4 colorFromPano1=textureCube(pano1Map,vWorldPosition1N.xyz);
-
- gl_FragColor=mix(colorFromPano0,colorFromPano1,progress);
-
-
-
-
- //深度图修改深度
-
- #if defined(GL_EXT_frag_depth) && defined(hasDepthTex)
- vec4 ndcPos;
- ndcPos.xy = ((2.0 * gl_FragCoord.xy) - (2.0 * viewport.xy)) / (viewport.zw) - 1.;
- ndcPos.z = (2.0 * gl_FragCoord.z - gl_DepthRange.near - gl_DepthRange.far) /
- (gl_DepthRange.far - gl_DepthRange.near);
- ndcPos.w = 1.0;
- vec4 clipPos = ndcPos / gl_FragCoord.w;
- vec4 eyePos = inverseProjectionMatrix * clipPos;
- vec2 depth0 = vec2(0.0,0.0);
- #if defined(usePanoMap0)
- depth0 = getDepth(vWorldPosition0N, depthMap0, cameraHeight0, ceilHeight0, eyePos);
- #endif
- vec2 depth1 = getDepth(vWorldPosition1N, depthMap1, cameraHeight1, ceilHeight1, eyePos);
-
-
- gl_FragDepthEXT = mix(depth0.y,depth1.y,progress);
-
-
-
- #endif
-
- }
- `
- }
-
- //注:gl_FragDepthEXT 修改了确实能像真实mesh那样遮挡住在后面的物体。但是为过渡时不能直接像有模型那样,和角度有关。
- export default class ModelTextureMaterial extends THREE.RawShaderMaterial {
- constructor( ){
-
- let defines = {depthTexUVyLimit: Potree.config.depthTexUVyLimit}
-
-
-
- super({
- fragmentShader: shader.fragmentShader,
- vertexShader: shader.vertexShader,
- uniforms: THREE.UniformsUtils.clone(shader.uniforms),
- side:THREE.DoubleSide,
- name: "ModelTextureMaterial",
- defines
- })
-
-
-
- let setSize = (e)=>{
- let viewport = e.viewport
- //let viewportOffset = viewport.offset || new Vector2()
- let resolution = viewport.resolution2
- //this.uniforms.viewport.value.set(viewportOffset.x, viewportOffset.y, resolution.x, resolution.y)
- this.uniforms.viewport.value.set(0,0, resolution.x, resolution.y);// xy是在viewport中的left和bottom,和整个窗口没有关系,所以不是viewportOffset。几乎都是0,0
-
- }
- let viewport = viewer.mainViewport;
-
- setSize({viewport})
- viewer.addEventListener('resize',(e)=>{
- if(e.viewport.name != "MainView")return
- setSize(e)
- })
-
-
- //var supportExtDepth = !!Features.EXT_DEPTH.isSupported()
- {
-
- //add
-
- viewer.addEventListener('camera_changed', (e)=>{
- if(e.viewport.name != "MainView")return
- //this.uniforms.projectionMatrix.value.copy(e.camera.projectionMatrix)
- e.camera && this.uniforms.inverseProjectionMatrix.value.copy(e.camera.projectionMatrixInverse)
- })
- }
- let progress = 0
- Object.defineProperty(this.uniforms.progress, 'value', {
- get: function () {
- return progress
- },
- set: e => {
- if (e < 1) {
- if (!('usePanoMap0' in this.defines)) {
- this.defines.usePanoMap0 = ''
- this.needsUpdate = true
- }
- } else {
- if ('usePanoMap0' in this.defines) {
- delete this.defines.usePanoMap0
- this.needsUpdate = true
- }
- }
- progress = e
- },
- })
- //-------------------------------------
- }
- /**
- *
- * @param {Panorama} pano0
- * @param {Panorama} pano1
- * @param {boolean} flag
-
- 更新全景图的材质uniforms
-
- */
-
-
-
- setProjectedPanos(pano0, pano1, progressValue ){
-
- progressValue!=void 0 && (this.uniforms.progress.value = progressValue);
- //pano0.ensureSkyboxReadyForRender();
-
-
- if(pano0){
- this.uniforms.pano0Map.value = pano0.getSkyboxTexture();//pano0.texture
- this.uniforms.pano0Position.value.copy(pano0.position)
- this.uniforms.pano0Matrix.value.copy(pano0.panoMatrix/* pano0.mesh.matrixWorld */ );
- //pano1.ensureSkyboxReadyForRender();
- }
-
-
- this.uniforms.pano1Map.value = pano1.getSkyboxTexture()//pano1.texture;
- this.uniforms.pano1Position.value.copy(pano1.position)
- this.uniforms.pano1Matrix.value.copy(pano1.panoMatrix /* pano1.mesh.matrixWorld */ );
-
-
-
- this.pano0 = pano0
- this.pano1 = pano1
-
- this.updateDepthTex(pano0)
- this.updateDepthTex(pano1)
-
-
- //console.log('setProjectedPanos', pano0&&pano0.id, pano1&&pano1.id)
- this.needsUpdate = true;
- }
-
-
-
- updateDepthTex(pano, extra){
- if( !Potree.settings.useDepthTex || !pano || !pano.depthTex || pano!=this.pano0 && pano!=this.pano1)return
- //console.log('updateDepthTex', pano.id, this.pano0 && this.pano0.id, this.pano1 && this.pano1.id)
-
-
- if(this.pano0){
- this.uniforms.depthMap0.value = this.pano0.entered ? this.pano0.depthTex : null; //dispose了就不要赋值否则dispose会失败
- this.uniforms.cameraHeight0.value = this.pano0.floorPosition.distanceTo(this.pano0.position)
- this.uniforms.ceilHeight0.value = this.pano0.getCeilHeight() - this.pano0.position.z
- }
- if(this.pano1){
- this.uniforms.depthMap1.value = this.pano1.depthTex //pano1还没entered时也需要,可能在飞入
- this.uniforms.cameraHeight1.value = this.pano1.floorPosition.distanceTo(this.pano1.position)
- this.uniforms.ceilHeight1.value = this.pano1.getCeilHeight() - this.pano1.position.z
- }
- this.updateDepthTexEnable()
- }
-
- updateDepthTexEnable(){
- let hasDepthTex = this.pano0 && this.pano1 && this.pano0.pointcloud.hasDepthTex && this.pano1.pointcloud.hasDepthTex //暂时不知道一个有图一个没图怎么写所以
-
- Potree.Utils.addOrRemoveDefine(this, 'hasDepthTex', hasDepthTex?'add':'remove' )
-
-
- }
-
- /* EnableDepthTex(){//开启DepthTex
- if(this.defines['hasDepthTex']){
- return
- }
- this.defines['hasDepthTex'] = ''
- this.needsUpdate = true;
- } */
- }
|