在编辑器上显示顶点和三角形计数的统计数据

问题描述 投票:0回答:1

在示例编辑器中,Three.js 如何渲染显示顶点和三角形数量的图例以及 3 轴辅助图例,我添加了带有这些图例的场景屏幕截图。

Three.js editor scene

我想在我的场景中显示,但找不到如何添加这些。是否有此类东西的插件或自定义几何形状?

javascript three.js 3d geometry
1个回答
0
投票

基本上你可以看看这个thread,但是那里的一些信息需要更新。

可以使用 .info 属性,但要注意:

  • 如果在全局范围内使用此属性,您将得到总和 顶点,当你有多个顶点时就会出现问题 场景中的物体。
  • 另请注意,如果您有
    wireframe: true
    ,您将获得
    0
    顶点, 您必须将其设置为
    false

此外,正如 pailhead 正确指出的那样,由于

non-indexed
indexed
的几何形状,获得统一的值可能很困难。在第一个中,三角形之间不共享顶点,这意味着它们的数量会更多,而在第二个中,顶点更少,因为它们共享它们。

至于

rStats
,它将不再起作用,因为
WebGL1
标准自
r117/153
以来已被弃用,并在
r163
中完全删除。如果您将使用(不太可能)带有
WebGL1
的旧版本,那么您可以使用它,在最新版本中,由于使用
WebGL2
,它将无法工作。

迁移指南

您可以使用 TextGeometry 创建一个

quasi
-rStat:

对于这个相机助手,您可以使用一些库(例如

GSAP
TWEEN
)来制作视图之间的过渡动画

body { margin: 0; }
#cameraSwitcher {
        position: fixed;
        bottom: 10px;
        right: 10px;
        display: flex;
        flex-direction: column;
      }
.camera-button {
        width: 40px;
        height: 40px;
        margin: 5px;
        background-color: #800080;
        color: white;
        border: none;
        border-radius: 5px;
        cursor: pointer;
        font-size: 16px;
        display: flex;
        align-items: center;
        justify-content: center;
      }
<script type="importmap">
  {
"imports": {
  "three": "https://unpkg.com/[email protected]/build/three.module.js",
  "three/addons/": "https://unpkg.com/[email protected]/examples/jsm/"
}
  }
</script>

<div id="cameraSwitcher">
<button class="camera-button" id="camera1">1</button>
<button class="camera-button" id="camera2">2</button>
</div>

<script type="module">
import * as THREE from "https://esm.sh/three";
import { OrbitControls } from "https://esm.sh/three/addons/controls/OrbitControls.js";
import { FontLoader } from "https://esm.sh/three/addons/loaders/FontLoader.js";
import { TextGeometry } from "https://esm.sh/three/addons/geometries/TextGeometry.js";

        const scene = new THREE.Scene();
        const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
        camera.position.z = 5;

        const camera2 = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
        camera2.position.set(5, 5, 5);
        camera2.lookAt(new THREE.Vector3(0, 0, 0));

        const renderer = new THREE.WebGLRenderer({ antialias: true });
        renderer.setSize(window.innerWidth, window.innerHeight);
        renderer.setPixelRatio(2);
        document.body.appendChild(renderer.domElement);

        const indexedGeometry = new THREE.ConeGeometry(1, 2, 32);
        const indexedMaterial = new THREE.MeshBasicMaterial({ color: 0x00ff00, wireframe: true });
        const indexedCone = new THREE.Mesh(indexedGeometry, indexedMaterial);
        scene.add(indexedCone);
        indexedCone.position.x = 2;

        const nonIndexedGeometry = indexedGeometry.toNonIndexed();
        const nonIndexedMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000, wireframe: true });
        const nonIndexedCone = new THREE.Mesh(nonIndexedGeometry, nonIndexedMaterial);
        scene.add(nonIndexedCone);
        nonIndexedCone.position.x = -2;

        function getVertexCount(geometry) {
            return geometry.attributes.position.count;
        }

        function getTriangleCount(geometry) {
            if (geometry.index) {
                return geometry.index.count / 3;
            } else {
                return geometry.attributes.position.count / 3;
            }
        }

        const fontLoader = new FontLoader();
        fontLoader.load('https://threejs.org/examples/fonts/helvetiker_regular.typeface.json', (font) => {
            const indexedVertexCount = getVertexCount(indexedGeometry);
            const indexedTriangleCount = getTriangleCount(indexedGeometry);
            const indexedTextGeometry = new TextGeometry(`Indexed Cone: Vertices: ${indexedVertexCount} Triangles: ${indexedTriangleCount}`, {
                font: font,
                size: 0.2,
                depth: 0.01
            });
            const indexedTextMaterial = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
            const indexedTextMesh = new THREE.Mesh(indexedTextGeometry, indexedTextMaterial);
            indexedTextMesh.position.set(-2, 3, 0);
            scene.add(indexedTextMesh);

            const nonIndexedVertexCount = getVertexCount(nonIndexedGeometry);
            const nonIndexedTriangleCount = getTriangleCount(nonIndexedGeometry);
            const nonIndexedTextGeometry = new TextGeometry(`Non-Indexed Cone: Vertices: ${nonIndexedVertexCount} Triangles: ${nonIndexedTriangleCount}`, {
                font: font,
                size: 0.2,
                depth: 0.01
            });
            const nonIndexedTextMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000 });
            const nonIndexedTextMesh = new THREE.Mesh(nonIndexedTextGeometry, nonIndexedTextMaterial);
            nonIndexedTextMesh.position.set(-2, 2, 0);
            scene.add(nonIndexedTextMesh);
        });
        
        //const controls = new OrbitControls( camera, renderer.domElement );
        //controls.enableDamping = true

        let currentCamera = camera;

        document.getElementById('camera1').addEventListener('click', () => {
            currentCamera = camera;
        });

        document.getElementById('camera2').addEventListener('click', () => {
            currentCamera = camera2;
        });

        function animate() {
            requestAnimationFrame(animate);
            indexedCone.rotation.x += 0.01;
            indexedCone.rotation.y += 0.01;
            nonIndexedCone.rotation.x += 0.01;
            nonIndexedCone.rotation.y += 0.01;
            //controls.update();
            renderer.render(scene, currentCamera);
        }

        animate();

        window.addEventListener('resize', () => {
            renderer.setSize(window.innerWidth, window.innerHeight);
            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();
            camera2.aspect = window.innerWidth / window.innerHeight;
            camera2.updateProjectionMatrix();
        });

</script>

或者你可以使用 HTML layer

body { margin: 0; }
        canvas { display: block; }
        #hud {
            position: absolute;
            top: 10px;
            left: 10px;
            color: white;
            font-family: Arial, sans-serif;
            font-size: 16px;
            z-index: 1;
        }
        button {
            position: absolute;
            top: 10px;
            background-color: #800080;
            color: white;
            border: none;
            border-radius: 5px;
            padding: 10px;
            font-size: 16px;
            cursor: pointer;
            z-index: 2;
        }
        #camera1 {
            right: 120px;
        }
        #camera2 {
            right: 10px;
        }
      
<script type="importmap">
  {
"imports": {
  "three": "https://unpkg.com/[email protected]/build/three.module.js",
  "three/addons/": "https://unpkg.com/[email protected]/examples/jsm/"
}
  }
</script>

<div id="hud">
<div id="indexed-info"></div>
<div id="non-indexed-info"></div>
</div>
<button id="camera1">Camera 1</button>
<button id="camera2">Camera 2</button>

<script type="module">
import * as THREE from "https://esm.sh/three";
import { OrbitControls } from "https://esm.sh/three/addons/controls/OrbitControls.js";

const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 5;

const camera2 = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera2.position.set(5, 5, 5);
camera2.lookAt(new THREE.Vector3(0, 0, 0));

const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(2);
document.body.appendChild(renderer.domElement);

const indexedGeometry = new THREE.ConeGeometry(1, 2, 32);
const indexedMaterial = new THREE.MeshBasicMaterial({ color: 0x00ff00, wireframe: true });
const indexedCone = new THREE.Mesh(indexedGeometry, indexedMaterial);
scene.add(indexedCone);
indexedCone.position.x = 2;

const nonIndexedGeometry = indexedGeometry.toNonIndexed();
const nonIndexedMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000, wireframe: true });
const nonIndexedCone = new THREE.Mesh(nonIndexedGeometry, nonIndexedMaterial);
scene.add(nonIndexedCone);
nonIndexedCone.position.x = -2;

function getVertexCount(geometry) {
    return geometry.attributes.position.count;
}

function getTriangleCount(geometry) {
    if (geometry.index) {
        return geometry.index.count / 3;
    } else {
        return geometry.attributes.position.count / 3;
    }
}

function updateHUD() {
    const indexedVertexCount = getVertexCount(indexedGeometry);
    const indexedTriangleCount = getTriangleCount(indexedGeometry);
    const nonIndexedVertexCount = getVertexCount(nonIndexedGeometry);
    const nonIndexedTriangleCount = getTriangleCount(nonIndexedGeometry);

    document.getElementById('indexed-info').textContent = `Indexed Cone: Vertices: ${indexedVertexCount} Triangles: ${indexedTriangleCount}`;
    document.getElementById('non-indexed-info').textContent = `Non-Indexed Cone: Vertices: ${nonIndexedVertexCount} Triangles: ${nonIndexedTriangleCount}`;
}

const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;

let currentCamera = camera;

document.getElementById('camera1').addEventListener('click', () => {
    currentCamera = camera;
});

document.getElementById('camera2').addEventListener('click', () => {
    currentCamera = camera2;
});

function animate() {
    requestAnimationFrame(animate);
    indexedCone.rotation.x += 0.01;
    indexedCone.rotation.y += 0.01;
    nonIndexedCone.rotation.x += 0.01;
    nonIndexedCone.rotation.y += 0.01;
    controls.update();
    updateHUD();
    renderer.render(scene, currentCamera);
}

animate();

window.addEventListener('resize', () => {
    renderer.setSize(window.innerWidth, window.innerHeight);
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();
    camera2.aspect = window.innerWidth / window.innerHeight;
    camera2.updateProjectionMatrix();
});


</script>

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.