joken-前端工程师

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: :: :: 管理 ::
  404 随笔 :: 39 文章 :: 8 评论 :: 20万 阅读

在Three.js中,GridHelper 是一个非常有用的工具,用于在3D场景中可视化地显示一个网格平面。它可以帮助开发者更好地理解场景中的空间关系和对象的位置。GridHelper 通常用于调试和设计阶段,以提供一种直观的方式来查看坐标系和物体的相对位置。

主要用途

  • 调试辅助:帮助开发者更直观地了解场景中的坐标系统。
  • 设计参考:作为参考网格,便于在设计和布局过程中对齐对象。
  • 教学工具:有助于解释3D空间概念,特别是在教育和演示中。

基本用法

创建 GridHelper

const size = 10; // 网格的总大小(宽度和高度)
const divisions = 10; // 每个方向上的分割数
const gridHelper = new THREE.GridHelper(size, divisions);

添加 GridHelper 到场景中

scene.add(gridHelper);

参数说明

  • size:网格的总大小,默认情况下是一个正方形网格,所以这个值既是宽度也是高度。
  • divisions:网格在每个方向上被分割成多少段。例如,如果 size 为10,divisions 为10,则每条线之间的距离为1单位。

示例代码

以下是一个完整的示例,展示如何使用 GridHelper 在 Three.js 场景中添加一个网格平面,并添加一些简单的几何体进行对比:

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Three.js GridHelper Example</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
    <style>
        body { margin: 0; }
        canvas { display: block; }
    </style>
</head>
<body>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r152/three.min.js"></script>
    <script>
        let scene, camera, renderer;

        init();
        animate();

        function init() {
            // 创建场景
            scene = new THREE.Scene();

            // 创建相机
            camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
            camera.position.z = 15;

            // 创建渲染器
            renderer = new THREE.WebGLRenderer();
            renderer.setSize(window.innerWidth, window.innerHeight);
            document.body.appendChild(renderer.domElement);

            // 创建并添加 GridHelper
            const size = 10;
            const divisions = 10;
            const gridHelper = new THREE.GridHelper(size, divisions);
            scene.add(gridHelper);

            // 创建并添加一些几何体作为参考
            const geometry = new THREE.BoxGeometry(1, 1, 1);
            const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
            const cube = new THREE.Mesh(geometry, material);
            cube.position.set(2, 2, 0); // 将立方体放置在网格上方
            scene.add(cube);

            const sphereGeometry = new THREE.SphereGeometry(0.5, 32, 32);
            const sphereMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000 });
            const sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);
            sphere.position.set(-2, -2, 0); // 将球体放置在网格下方
            scene.add(sphere);

            // 监听窗口调整大小事件
            window.addEventListener('resize', onWindowResize, false);
        }

        function onWindowResize() {
            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();
            renderer.setSize(window.innerWidth, window.innerHeight);
        }

        function animate() {
            requestAnimationFrame(animate);

            // 旋转几何体(可选)
            scene.children[1].rotation.x += 0.01;
            scene.children[1].rotation.y += 0.01;

            renderer.render(scene, camera);
        }
    </script>
</body>
</html>

详细解释

初始化部分

function init() {
    scene = new THREE.Scene();
    camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
    camera.position.z = 15;

    renderer = new THREE.WebGLRenderer();
    renderer.setSize(window.innerWidth, window.innerHeight);
    document.body.appendChild(renderer.domElement);
}
  • 创建场景、相机和渲染器,并将其添加到页面中。

创建 GridHelper

const size = 10;
const divisions = 10;
const gridHelper = new THREE.GridHelper(size, divisions);
scene.add(gridHelper);
  • 创建一个 GridHelper 实例,指定网格的大小和分割数。
  • GridHelper 添加到场景中。

添加几何体作为参考

const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const cube = new THREE.Mesh(geometry, material);
cube.position.set(2, 2, 0);
scene.add(cube);

const sphereGeometry = new THREE.SphereGeometry(0.5, 32, 32);
const sphereMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000 });
const sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);
sphere.position.set(-2, -2, 0);
scene.add(sphere);
  • 创建一个立方体和一个球体,并将它们分别放置在网格的不同位置。
  • 这些几何体可以帮助你更直观地看到网格的位置和比例。

动画循环

function animate() {
    requestAnimationFrame(animate);

    // 旋转几何体(可选)
    scene.children[1].rotation.x += 0.01;
    scene.children[1].rotation.y += 0.01;

    renderer.render(scene, camera);
}
  • 在每一帧中更新几何体的旋转角度(可选)。
  • 调用 renderer.render 渲染当前帧。

自定义 GridHelper

你可以通过传递额外的颜色参数来自定义 GridHelper 的外观:

const gridHelper = new THREE.GridHelper(size, divisions, colorCenterLine, colorGrid);
  • colorCenterLine:中心线的颜色(可选)。
  • colorGrid:网格线的颜色(可选)。

例如:

const gridHelper = new THREE.GridHelper(10, 10, 0x0000ff, 0x808080);

这将创建一个带有蓝色中心线和灰色网格线的 GridHelper

总结

GridHelper 是 Three.js 中一个非常实用的工具,能够帮助开发者更好地理解和调试3D场景中的空间关系。通过结合其他几何体和动画效果,可以创建出更加直观和丰富的可视化效果。希望这个示例和解释能帮助你更好地掌握 GridHelper 的使用方法。

设置位置

GridHelper 的位置是可以调整的。你可以通过修改 GridHelper 对象的位置属性(即 position)来改变它在场景中的位置。由于 GridHelper 是一个 Object3D 类的实例,因此它可以像其他 Three.js 对象一样进行平移、旋转和缩放等变换。

修改 GridHelper 位置

平移(Translation)

你可以直接设置 GridHelperposition 属性来移动它:

const size = 10;
const divisions = 10;
const gridHelper = new THREE.GridHelper(size, divisions);

// 设置网格的位置
gridHelper.position.set(5, 5, 0); // 将网格移动到 (5, 5, 0)

scene.add(gridHelper);

旋转(Rotation)

你也可以对 GridHelper 进行旋转操作:

// 绕 X 轴旋转 45 度
gridHelper.rotation.x = Math.PI / 4;

// 绕 Y 轴旋转 45 度
gridHelper.rotation.y = Math.PI / 4;

缩放(Scaling)

虽然不太常见,但你也可以对 GridHelper 进行缩放:

// 放大两倍
gridHelper.scale.set(2, 2, 2);

示例代码

以下是一个完整的示例,展示如何创建并调整 GridHelper 的位置、旋转和缩放:

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Three.js GridHelper Example</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
    <style>
        body { margin: 0; }
        canvas { display: block; }
    </style>
</head>
<body>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r152/three.min.js"></script>
    <script>
        let scene, camera, renderer;

        init();
        animate();

        function init() {
            // 创建场景
            scene = new THREE.Scene();

            // 创建相机
            camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
            camera.position.z = 15;

            // 创建渲染器
            renderer = new THREE.WebGLRenderer();
            renderer.setSize(window.innerWidth, window.innerHeight);
            document.body.appendChild(renderer.domElement);

            // 创建并添加 GridHelper
            const size = 10;
            const divisions = 10;
            const gridHelper = new THREE.GridHelper(size, divisions);
            
            // 设置网格的位置
            gridHelper.position.set(5, 5, 0); // 将网格移动到 (5, 5, 0)
            
            // 设置网格的颜色
            gridHelper.material.color.set(0x808080); // 网格线颜色为灰色
            
            // 可选:绕 X 轴旋转 45 度
            gridHelper.rotation.x = Math.PI / 4;
            
            // 可选:放大两倍
            gridHelper.scale.set(2, 2, 2);

            scene.add(gridHelper);

            // 添加一些几何体作为参考
            const geometry = new THREE.BoxGeometry(1, 1, 1);
            const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
            const cube = new THREE.Mesh(geometry, material);
            cube.position.set(2, 2, 0); // 将立方体放置在网格上方
            scene.add(cube);

            const sphereGeometry = new THREE.SphereGeometry(0.5, 32, 32);
            const sphereMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000 });
            const sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);
            sphere.position.set(-2, -2, 0); // 将球体放置在网格下方
            scene.add(sphere);

            // 监听窗口调整大小事件
            window.addEventListener('resize', onWindowResize, false);
        }

        function onWindowResize() {
            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();
            renderer.setSize(window.innerWidth, window.innerHeight);
        }

        function animate() {
            requestAnimationFrame(animate);

            // 旋转几何体(可选)
            scene.children[1].rotation.x += 0.01;
            scene.children[1].rotation.y += 0.01;

            renderer.render(scene, camera);
        }
    </script>
</body>
</html>

详细解释

初始化部分

function init() {
    scene = new THREE.Scene();
    camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
    camera.position.z = 15;

    renderer = new THREE.WebGLRenderer();
    renderer.setSize(window.innerWidth, window.innerHeight);
    document.body.appendChild(renderer.domElement);
}
  • 创建场景、相机和渲染器,并将其添加到页面中。

创建并配置 GridHelper

const size = 10;
const divisions = 10;
const gridHelper = new THREE.GridHelper(size, divisions);

// 设置网格的位置
gridHelper.position.set(5, 5, 0); // 将网格移动到 (5, 5, 0)

// 设置网格的颜色
gridHelper.material.color.set(0x808080); // 网格线颜色为灰色

// 可选:绕 X 轴旋转 45 度
gridHelper.rotation.x = Math.PI / 4;

// 可选:放大两倍
gridHelper.scale.set(2, 2, 2);

scene.add(gridHelper);
  • 创建一个 GridHelper 实例,指定网格的大小和分割数。
  • 设置网格的位置、颜色、旋转和缩放。
  • GridHelper 添加到场景中。

添加几何体作为参考

const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const cube = new THREE.Mesh(geometry, material);
cube.position.set(2, 2, 0); // 将立方体放置在网格上方
scene.add(cube);

const sphereGeometry = new THREE.SphereGeometry(0.5, 32, 32);
const sphereMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000 });
const sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);
sphere.position.set(-2, -2, 0); // 将球体放置在网格下方
scene.add(sphere);
  • 创建一个立方体和一个球体,并将它们分别放置在网格的不同位置。
  • 这些几何体可以帮助你更直观地看到网格的位置和比例。

动画循环

function animate() {
    requestAnimationFrame(animate);

    // 旋转几何体(可选)
    scene.children[1].rotation.x += 0.01;
    scene.children[1].rotation.y += 0.01;

    renderer.render(scene, camera);
}
  • 在每一帧中更新几何体的旋转角度(可选)。
  • 调用 renderer.render 渲染当前帧。

总结

通过调整 GridHelperpositionrotationscale 属性,你可以灵活地控制其在场景中的位置和方向。这对于调试和设计阶段非常有用,能够帮助你更好地理解场景中的空间关系。希望这个示例和解释能帮助你更好地掌握 GridHelper 的使用方法及其变换操作。

官方案例参考

https://threejs.org/examples/#webgl_interactive_voxelpainter
image

posted on   joken1310  阅读(9)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
历史上的今天:
2018-03-05 centos 支持安装libsodium
点击右上角即可分享
微信分享提示