马黑黑 发表于 2025-5-21 12:50

three.js几何体之边缘几何体

<p>边缘几何体 EdgesGeometry,和网格几何体 WireframeGeometry 一样,可以作为一个辅助对象用来查看其它实体几何体的边缘,不同的是,边缘几何体比网格几何体多了一个入参 thresholdAngle,用于控制两个相邻面之间的边是否需要绘制:如果两个面的法线小于该阈值,则边将不会被渲染,就是说,这个值越小,绘制的边就越多。其实现原理也是遍历Mesh几何体所有的三角面,再遍历三角面的边,若边没有被公用,则认为是边缘,会被收集。需要注意的是,作为辅助性质的几何体,边缘几何体和网格几何体一样,都需要借助其它几何体才能构图。构造器:</p>
<blockquote>EdgesGeometry( geometry : BufferGeometry, thresholdAngle : Integer )</blockquote>
<p> 其中:</p>
<blockquote>
        geometry — 任何一个Mesh几何体对象<br>
        thresholdAngle — 仅当相邻面的法线之间的角度(单位为角度)超过这个值时,才会渲染边缘。缺省时默认值为 1
</blockquote>
<p>为了对比,以下代码我们同时绘制了边缘几何体和网格几何体,效果见预览页面:</p>
<div id="hEdiv"><pre id="hEpre">
&lt;div&gt;左图: 边缘几何体&lt;br&gt;右图: 网格几何体&lt;br&gt;&lt;br&gt;点击页面可暂停、继续动画&lt;/div&gt;

&lt;script type="module"&gt;
        import * as THREE from 'https://638183.freep.cn/638183/web/ku/three.module.min.js';

        var scene = new THREE.Scene;
        var clock = new THREE.Clock();
        var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 1000);
        camera.position.set(0, 0, 5);
        var renderer = new THREE.WebGLRenderer({ antialias: true });
        renderer.setSize(window.innerWidth, window.innerHeight);
        document.body.appendChild(renderer.domElement);

        var geometry = new THREE.ExtrudeGeometry(); // 挤压缓冲几何体(默认参数)
       
        var edges = new THREE.EdgesGeometry(geometry, 1); // 边缘几何体
        var mesh_edges = new THREE.LineSegments(edges, new THREE.LineBasicMaterial()); // 构图
        mesh_edges.position.set(-1, 0, 0); // 往左靠
       
        var wireframe = new THREE.WireframeGeometry(geometry); // 网格几何体
        var mesh_wireframe = new THREE.LineSegments(wireframe, new THREE.LineBasicMaterial()); // 构图
        mesh_wireframe.position.set(1, 0, 0); // 往右靠

        scene.add(mesh_edges, mesh_wireframe); // 两个图形加入场景

        var animate = () => {
                requestAnimationFrame(animate);
                var delta = clock.getDelta();
                .forEach(mesh => mesh.rotation.y -= delta / 5);
                renderer.render(scene, camera);
        };

        document.onclick = () => clock.running ? clock.stop() : clock.start();

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

        animate();
&lt;/script&gt;

&lt;style&gt;
        /* 预览页面CSS */
        body { margin: 0; }
        div { margin: 10px; position: absolute; color: #eee; }
&lt;/style&gt;
</pre></div>
<blockquote><button id="btnPrev" name="btnPrev" type="button" value="prev">运行代码</button></blockquote>

<script type="module">
        import hlight from 'https://638183.freep.cn/638183/web/helight/helight1.js';
        hlight.hl(hEdiv, hEpre);

        btnPrev.onclick = () => {
                const value = hEpre.textContent + '<style>body {margin: 0; }</style>';
                const previewWindow = window.open('', 'preview1', 'width=1200,height=768,top=100,left=100');
                previewWindow.document.open();
                previewWindow.document.write(value);
                setTimeout(function() { previewWindow.document.title = "预览" }, 100);
                previewWindow.document.close();
        };
</script>

梦江南 发表于 2025-5-21 15:42

两只白色线条组成的方框体,右边一只方框多了几条线。自动旋转,一键暂停。{:4_187:}

马黑黑 发表于 2025-5-21 19:29

梦江南 发表于 2025-5-21 15:42
两只白色线条组成的方框体,右边一只方框多了几条线。自动旋转,一键暂停。

这只是外观。如果有余力,可以尝试理解

花飞飞 发表于 2025-5-21 20:55

两个几何体位置左靠右靠,是mesh_edges.position.set(-1, 0, 0);这个新的设置方法。。
Mesh几何体对象又是一个新名词,
乐,看得晕乎乎的。。{:4_170:}

马黑黑 发表于 2025-5-21 20:58

花飞飞 发表于 2025-5-21 20:55
两个几何体位置左靠右靠,是mesh_edges.position.set(-1, 0, 0);这个新的设置方法。。
Mesh几何体对象又是 ...

这个不新,之前用过,你看得不够细

花飞飞 发表于 2025-5-21 20:58

边缘几何体可查看其它实体几何体的边缘,也就是除了展示出的立方体,之前的网格几何体都可以适用么。
越来越多新名词,烧脑。。{:4_174:}

马黑黑 发表于 2025-5-21 20:59

花飞飞 发表于 2025-5-21 20:58
边缘几何体可查看其它实体几何体的边缘,也就是除了展示出的立方体,之前的网格几何体都可以适用么。
越来 ...

其实不烧脑的,只有头脑清晰

花飞飞 发表于 2025-5-21 21:01

马黑黑 发表于 2025-5-21 20:58
这个不新,之前用过,你看得不够细

好吧
之前只留意第9行的相机位置camera.position.set(0, 0, 5);
这个左右靠的确头一 次看到。。。
没认真学习。。

花飞飞 发表于 2025-5-21 21:02

马黑黑 发表于 2025-5-21 20:59
其实不烧脑的,只有头脑清晰

{:4_173:}这些名词跟你都是朋友,我都不认识他们。分不清谁是谁也正常不是

马黑黑 发表于 2025-5-21 21:03

花飞飞 发表于 2025-5-21 21:01
好吧
之前只留意第9行的相机位置camera.position.set(0, 0, 5);
这个左右靠的确头一 次看到。。。


东西太多,看不到位、看不懂正常

马黑黑 发表于 2025-5-21 21:03

花飞飞 发表于 2025-5-21 21:02
这些名词跟你都是朋友,我都不认识他们。分不清谁是谁也正常不是

都是常用的东东,初中英语基础得有

花飞飞 发表于 2025-5-21 21:05

马黑黑 发表于 2025-5-21 21:03
东西太多,看不到位、看不懂正常

{:4_170:}只看效果好看就好了。。
比如我会用冰箱就好了,工作原理就算了。。

花飞飞 发表于 2025-5-21 21:07

马黑黑 发表于 2025-5-21 21:03
都是常用的东东,初中英语基础得有

早说了我文盲,真的没有初中水平。。{:4_173:}

马黑黑 发表于 2025-5-21 21:49

花飞飞 发表于 2025-5-21 21:07
早说了我文盲,真的没有初中水平。。

英文方面很多人都是文盲

马黑黑 发表于 2025-5-21 21:51

花飞飞 发表于 2025-5-21 21:05
只看效果好看就好了。。
比如我会用冰箱就好了,工作原理就算了。。

原理不知道也会有问题,比方一年四季如何调整冰箱的工作档位,很多人就是看了介绍,过阵子还是会调错,原因之一是不懂其工作原理

红影 发表于 2025-5-21 23:16

这个很难理解,为什么法线之差越小,绘制的边缘越多,感觉应该是越大两个面更折,边缘应该越多啊。

红影 发表于 2025-5-21 23:18

如果两个相邻面的法线差是0,就是平面,怎么还会有边缘啊{:4_203:}

红影 发表于 2025-5-21 23:20

“再遍历三角面的边,若边没有被公用,则认为是边缘”这个好像也是反的,公用才有边缘?{:4_173:}

马黑黑 发表于 2025-5-22 07:31

红影 发表于 2025-5-21 23:20
“再遍历三角面的边,若边没有被公用,则认为是边缘”这个好像也是反的,公用才有边缘?

你比较一下网格几何体,试图领会。这是three.js设计好的东东,我们要做的是尽可能去理解,而非质疑,除非确实是错误(若此,可以提交官网或私聊作者)。

另外,有一些几何体可能并不常用,或者可能过于复杂使用难度较大。不论如何,作为介绍,我只是尽可能地不遗漏。

马黑黑 发表于 2025-5-22 07:32

红影 发表于 2025-5-21 23:16
这个很难理解,为什么法线之差越小,绘制的边缘越多,感觉应该是越大两个面更折,边缘应该越多啊。

具体进入three.js的殿堂之后,很多东东都会迎刃而解
页: [1] 2 3
查看完整版本: three.js几何体之边缘几何体