Three.js 无限网格效果 | 三维可视化 / AI 提示词

📋 AI 提示词

prompt
1
创建一个无限延伸的3D网格系统,随着距离增加网格逐渐淡出,支持自定义网格间距、颜色和最大可见距离。

🖼️ 效果预览

无限网格效果

🎮 案例演示

立即体验


效果描述

这是一个高级的3D无限网格辅助类,通过自定义着色器实现随距离增加逐渐淡出的网格效果,适用于大场景的参考网格。

效果特性

  • 无限延伸:基于着色器的网格系统,理论上可以无限延展
  • 距离衰减:随距离增加透明度逐渐降低
  • 双层网格:主网格和次网格分层显示
  • 天空盒集成:集成Sky对象创造逼真的大气效果
  • 阴影系统:支持方向光阴影投射

核心参数

参数 默认值 说明
次要网格间距 15 次要网格线之间的距离
主要网格间距 150 主要网格线之间的距离
网格颜色 #607d8b 网格线的颜色
最大可见距离 12000 网格完全消失的距离

核心代码解析

自定义网格辅助类

javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class AdvancedGridHelper extends THREE.Mesh {
    constructor(
        minorSize = 10,
        majorSize = 100,
        color = new THREE.Color(0x8899aa),
        maxDistance = 10000,
        axes = 'xzy'
    ) {
        const geometry = new THREE.PlaneGeometry(2, 2, 1, 1);
        const planeAxes = axes.substring(0, 2);

        const material = new THREE.ShaderMaterial({
            side: THREE.DoubleSide,
            uniforms: {
                uMinorSize: { value: minorSize },
                uMajorSize: { value: majorSize },
                uColor: { value: color },
                uMaxDistance: { value: maxDistance }
            },
            transparent: true,
            // ... 着色器代码
        });

        super(geometry, material);
        this.frustumCulled = false;
    }
}

顶点着色器

glsl
1
2
3
4
5
6
7
8
9
10
varying vec3 vWorldPos;
uniform float uMaxDistance;

void main() {
    // 计算世界空间位置
    vec3 pos = position.xzy * uMaxDistance;
    pos.xzy += cameraPosition.xzy;
    vWorldPos = pos;

    // 计算最终顶点位置
    gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0);
}

片段着色器

glsl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
varying vec3 vWorldPos;
uniform float uMinorSize;
uniform float uMajorSize;
uniform vec3 uColor;
uniform float uMaxDistance;

// 计算网格线函数
float getGridLine(float size) {
    vec2 gridCoords = vWorldPos.xzy / size;
    vec2 grid = abs(fract(gridCoords - 0.5) - 0.5) / fwidth(gridCoords);
    return 1.0 - min(min(grid.x, grid.y), 1.0);
}

void main() {
    // 计算距离衰减因子
    float distanceFactor = 1.0 - min(
        distance(cameraPosition.xzy, vWorldPos.xzy) / uMaxDistance,
        1.0
    );

    // 计算网格线
    float minorGrid = getGridLine(uMinorSize);
    float majorGrid = getGridLine(uMajorSize);

    // 混合网格线并应用衰减
    float gridAlpha = mix(majorGrid, minorGrid, minorGrid) * pow(distanceFactor, 3.0);

    // 主要网格线更粗
    gridAlpha = mix(gridAlpha * 0.5, gridAlpha, majorGrid);

    gl_FragColor = vec4(uColor, gridAlpha);

    if (gl_FragColor.a <= 0.0) discard;
}

天空盒配置

javascript
1
2
3
4
5
6
7
8
9
10
11
const sky = new Sky();
sky.scale.setScalar(450000);

const skyUniforms = sky.material.uniforms;
skyUniforms.sunPosition.value = new THREE.Vector3().setFromSphericalCoords(
    1,
    THREE.MathUtils.degToRad(70),
    THREE.MathUtils.degToRad(190)
);
skyUniforms.rayleigh.value = 3.2;
skyUniforms.mieCoefficient.value = 0.005;
skyUniforms.mieDirectionalG.value = 0.8;

技术亮点

  1. 着色器驱动:使用自定义着色器实现网格渲染,避免了大面积几何体的性能问题
  2. 抗锯齿网格线:利用fwidth函数实现平滑的网格线边缘
  3. 距离衰减:使用立方衰减函数创造自然的淡出效果
  4. 轴向配置:支持不同轴向配置,适应不同场景需求
  5. 视锥体剔除禁用:确保网格始终可见

调试技巧

  1. 距离调节:增大maxDistance可扩大网格可见范围
  2. 网格密度:减小minorSize增加网格密度
  3. 颜色搭配:深色背景搭配浅色网格更易辨识
  4. 性能优化:可根据需要禁用主要网格线
  5. Axes配置:修改axes参数可改变网格所在平面

扩展方向

  1. 动态网格:添加时间维度让网格产生波动效果
  2. 热力图网格:根据高度或距离改变网格颜色
  3. 交互式网格:鼠标悬停显示网格坐标信息
  4. 导航网格:扩展为寻路导航网格系统

本文档由 ThreeLab 编辑整理,专注 Three.js 着色器、Web 3D、GIS 可视化技术分享。如需转载,请注明出处。