|
|
@@ -1,11 +1,11 @@
|
|
|
// Author: Fyrestar https://mevedia.com (https://github.com/Fyrestar/THREE.InfiniteGridHelper)
|
|
|
import * as THREE from "../../../libs/three.js/build/three.module.js";
|
|
|
-
|
|
|
+import math from "../utils/math.js";
|
|
|
|
|
|
|
|
|
class InfiniteGridHelper extends THREE.Mesh{
|
|
|
|
|
|
- constructor(size1, size2, color, distance, opacity1=0.2, opacity2=1){
|
|
|
+ constructor(size1, size2, color, distance, opacity1=0.2, opacity2=1, viewer){
|
|
|
|
|
|
color = color || new THREE.Color('white');
|
|
|
size1 = size1 || 10;
|
|
|
@@ -13,7 +13,7 @@ class InfiniteGridHelper extends THREE.Mesh{
|
|
|
|
|
|
distance = distance || 8000; //可视距离?越远越模糊
|
|
|
|
|
|
- const geometry = new THREE.PlaneBufferGeometry(2, 2, 1, 1);
|
|
|
+ const geometry = new THREE.PlaneGeometry(2, 2, 1, 1);
|
|
|
|
|
|
const material = new THREE.ShaderMaterial({
|
|
|
|
|
|
@@ -39,24 +39,28 @@ class InfiniteGridHelper extends THREE.Mesh{
|
|
|
},
|
|
|
uDistance: {
|
|
|
value: distance
|
|
|
+ },
|
|
|
+ staticCamPos :{
|
|
|
+ value: new THREE.Vector3(0,0,0)
|
|
|
+ },
|
|
|
+ staticModelViewMatrix:{
|
|
|
+ value: new THREE.Matrix4()
|
|
|
}
|
|
|
},
|
|
|
transparent: true,
|
|
|
vertexShader: `
|
|
|
|
|
|
varying vec3 worldPosition;
|
|
|
-
|
|
|
+ uniform vec3 staticCamPos;
|
|
|
uniform float uDistance;
|
|
|
-
|
|
|
+ uniform mat4 staticModelViewMatrix;
|
|
|
void main() {
|
|
|
|
|
|
- vec3 pos = position.xyz * uDistance;
|
|
|
- pos.xy += cameraPosition.xy;
|
|
|
+ vec3 pos = position.xyz * uDistance;
|
|
|
+ pos.xy += staticCamPos.xy; //pos.xy += cameraPosition.xy;
|
|
|
+ worldPosition = pos;
|
|
|
|
|
|
- worldPosition = pos;
|
|
|
-
|
|
|
- gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0);
|
|
|
-
|
|
|
+ gl_Position = projectionMatrix * staticModelViewMatrix/* modelViewMatrix */ * vec4(pos, 1.0);
|
|
|
}
|
|
|
`,
|
|
|
|
|
|
@@ -64,7 +68,7 @@ class InfiniteGridHelper extends THREE.Mesh{
|
|
|
fragmentShader: `
|
|
|
|
|
|
varying vec3 worldPosition;
|
|
|
-
|
|
|
+ uniform vec3 staticCamPos;
|
|
|
uniform float uSize1;
|
|
|
uniform float uSize2;
|
|
|
uniform float opacity1;
|
|
|
@@ -78,7 +82,6 @@ class InfiniteGridHelper extends THREE.Mesh{
|
|
|
|
|
|
vec2 r = worldPosition.xy / size;
|
|
|
|
|
|
-
|
|
|
vec2 grid = abs(fract(r - 0.5) - 0.5) / fwidth(r);
|
|
|
float line = min(grid.x, grid.y);
|
|
|
|
|
|
@@ -89,21 +92,20 @@ class InfiniteGridHelper extends THREE.Mesh{
|
|
|
|
|
|
void main() {
|
|
|
|
|
|
-
|
|
|
- float d = 1.0 - min(distance(cameraPosition.xy, worldPosition.xy) / uDistance, 1.0);
|
|
|
-
|
|
|
- float g1 = getGrid(uSize1);
|
|
|
- float g2 = getGrid(uSize2);
|
|
|
+
|
|
|
+ float d = 1.0 - min(distance(staticCamPos/* cameraPosition */.xy, worldPosition.xy) / uDistance, 1.0);
|
|
|
+
|
|
|
+ float g1 = getGrid(uSize1);
|
|
|
+ float g2 = getGrid(uSize2);
|
|
|
|
|
|
|
|
|
- gl_FragColor = vec4(uColor.rgb, mix(g2, g1, g1) * pow(d, 3.0));
|
|
|
- //gl_FragColor.a = mix(0.5 * gl_FragColor.a, gl_FragColor.a, g2);
|
|
|
- gl_FragColor.a = mix(opacity1 * gl_FragColor.a, opacity2 * gl_FragColor.a, g2);
|
|
|
+ gl_FragColor = vec4(uColor.rgb, mix(g2, g1, g1) * pow(d, 3.0));
|
|
|
+ //gl_FragColor.a = mix(0.5 * gl_FragColor.a, gl_FragColor.a, g2);
|
|
|
+ gl_FragColor.a = mix(opacity1 * gl_FragColor.a, opacity2 * gl_FragColor.a, g2);
|
|
|
|
|
|
|
|
|
- if ( gl_FragColor.a <= 0.0 ) discard;
|
|
|
-
|
|
|
-
|
|
|
+ if ( gl_FragColor.a <= 0.0 ) discard;
|
|
|
+
|
|
|
}
|
|
|
|
|
|
`,
|
|
|
@@ -119,7 +121,45 @@ class InfiniteGridHelper extends THREE.Mesh{
|
|
|
|
|
|
super(geometry, material)
|
|
|
this.frustumCulled = false;
|
|
|
-
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ //当视角移动到百万米以后线会变虚闪烁,所以提前计算下相对位置再传入shader,不要把大数字直接传入:
|
|
|
+
|
|
|
+ //暂只在mainViewport绘制
|
|
|
+
|
|
|
+ viewer.addEventListener('camera_changed',(e)=>{
|
|
|
+ if(e.viewport != viewer.mainViewport || e.changeInfo && !e.changeInfo.positionChanged ) return
|
|
|
+
|
|
|
+ let { staticCamPos, staticModelViewMatrix} = this.material.uniforms
|
|
|
+
|
|
|
+
|
|
|
+ let camera = viewer.mainViewport.camera
|
|
|
+ staticCamPos.value.copy(camera.position)
|
|
|
+
|
|
|
+
|
|
|
+ if(math.closeTo(camera.position, new THREE.Vector3(0,0,0), 50000)){//没有超过这个范围就用原本的
|
|
|
+ staticModelViewMatrix.value = this.modelViewMatrix //用copy会延迟,要先更新矩阵
|
|
|
+ }else{
|
|
|
+
|
|
|
+ staticCamPos.value.x %= size2
|
|
|
+ staticCamPos.value.y %= size2 //只要余数。不过之前我的大格子设置为和整个大小一致,以隐藏大格子,如果要求恢复隐藏,就用size1
|
|
|
+
|
|
|
+ let camM = camera.matrixWorld.clone()
|
|
|
+ camM.elements[12] = staticCamPos.value.x
|
|
|
+ camM.elements[13] = staticCamPos.value.y
|
|
|
+ camM.invert()
|
|
|
+ staticModelViewMatrix.value = new THREE.Matrix4().multiplyMatrices( camM, this.matrixWorld );
|
|
|
+ }
|
|
|
+
|
|
|
+ })
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
}
|
|
|
|
|
|
|