马黑黑 发表于 2025-5-13 12:06

three.js几何体之圆锥缓冲几何体

<style>
        #btnPrev { box-shadow: 2px 2px 6px rgba(0,0,0,.5); }
        #btnPrev:hover { box-shadow: 2px 2px 12px rgba(0,0,0,.5); font-weight: bold; }
</style>

<p>圆锥缓冲几何体(ConeGeometry)是一个用于生成圆锥几何体的类。构造器:</p>
<blockquote>ConeGeometry(radius : Float, height : Float, radialSegments : Integer, heightSegments : Integer, openEnded : Boolean, thetaStart : Float, thetaLength : Float)</blockquote>
<p> 其中:</p>
<blockquote>
        radius — 圆锥底部的半径,默认值为 1<br>
        height — 圆锥的高度,默认值为 1<br>
        radialSegments — 圆锥侧面周围的分段数,默认为 32<br>
        heightSegments — 圆锥侧面沿着其高度的分段数,默认值为 1<br>
        openEnded — 一个Boolean值,指明该圆锥的底面是开放的还是封顶的。默认值为false,即其底面默认是封顶的<br>
        thetaStart — 第一个分段的起始角度,默认为 0(三点钟方向)<br>
        thetaLength — 圆锥底面圆扇区的中心角,通常被称为 θ(西塔)。默认值是 2*PI,这使其成为一个完整的圆锥
</blockquote>
<p>下面的示例,我们用圆锥几何体+基础材质画一对嵌套的圆锥立体图案:</p>
<div id="hEdiv"><pre id="hEpre">
&lt;script type="module"&gt;
        import * as THREE from 'https://esm.sh/three'; // three主库
        import { OrbitControls } from "https://esm.sh/three/examples/jsm/controls/OrbitControls"; // 轨道控制库

        const scene = new THREE.Scene; // 场景
        scene.background = new THREE.Color('rgba(40,40,40,0.5)'); // 场景背景色
        const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); // 相机
        camera.position.set(0, 0, 5); // 相机位置
        const renderer = new THREE.WebGLRenderer({ antialias: true }); // 渲染器
        renderer.setSize(window.innerWidth, window.innerHeight); // 渲染器范围
        document.body.appendChild(renderer.domElement); // 渲染器加入到body标签

        const controller = new OrbitControls(camera, renderer.domElement); // 实例化轨道控制器
        controller.autoRotate = true; // 开启自动旋转

        // 创建两个嵌套的圆锥体
        const geometry = new THREE.ConeGeometry(1, 2, 32); // 圆锥形几何体
        // 材质 1
        const material1 = new THREE.MeshBasicMaterial({
                color: 0x0a8ff6, // 颜色
                wireframe: true // 线框
        });       
        // 材质 2
        const material2 = new THREE.MeshBasicMaterial({
                color: 0x12ddf0, // 颜色
                transparent: true, // 开启透明度
                opacity: 0.5 // 不透明度(透明度 = 1 - opacity)
        });
        const cone1 = new THREE.Mesh(geometry, material1); // 圆锥 1
        const cone2 = new THREE.Mesh(geometry, material2); // 圆锥 2
        cone1.add(cone2); // 第 2 个圆锥加入到第 1 个圆锥
        scene.add(cone1); // 第 1 个圆锥加入到场景

        //renderer.render(scene, camera); // 至此已经可以将静态效果渲染出来

        // 动画函数
        const animate = () =&gt; {
                requestAnimationFrame(animate); // 请求关键帧动画递归调用函数自身
                controller.update(); // 更新轨道控制器
                renderer.render(scene, camera); // 渲染效果
        };

        animate(); // 运行动画
       
        window.onresize = () =&gt; renderer.setSize(window.innerWidth, window.innerHeight);
&lt;/script&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-13 12:14

锥体2(无线框、表面上色)作为锥体1(线框、表面透明)的子元素,严丝合缝嵌套在母体中,所以效果只看到一个锥体。实际上是两个锥体,里面的锥体负责表面颜色渲染,外面的锥体负责上线框。

有兴趣的朋友可以试着将子锥体挪开,方法是在 30 和 31 行之间插入一行:

cone2.position.set(4, 0, 0);

红影 发表于 2025-5-13 14:36

马黑黑 发表于 2025-5-13 12:14
锥体2(无线框、表面上色)作为锥体1(线框、表面透明)的子元素,严丝合缝嵌套在母体中,所以效果只看到一 ...

移开来后,一个就纯线框,一个纯色的了。还是套起来好看,否则纯色的都看不出圆锥体的感觉了{:4_173:}

红影 发表于 2025-5-13 14:37

用三角形拟合起来的图形,感觉圆锥体比球体看着更顺眼,也拟合得更好呢。

马黑黑 发表于 2025-5-13 18:11

红影 发表于 2025-5-13 14:36
移开来后,一个就纯线框,一个纯色的了。还是套起来好看,否则纯色的都看不出圆锥体的感觉了

纯色的话,画成不圆的应该是可以的

马黑黑 发表于 2025-5-13 18:11

红影 发表于 2025-5-13 14:37
用三角形拟合起来的图形,感觉圆锥体比球体看着更顺眼,也拟合得更好呢。

各种几何体图形都有自己的存在理由

花飞飞 发表于 2025-5-13 18:59

马黑黑 发表于 2025-5-13 12:14
锥体2(无线框、表面上色)作为锥体1(线框、表面透明)的子元素,严丝合缝嵌套在母体中,所以效果只看到一 ...

原来是两个嵌套在一起的,都是基础材质,
分开后,看到第二个没有线框,所以就是同色。
第二个换成MeshNormalMaterial材质虽然无线框但看着也很立体的了。。{:4_173:}
这个材质百搭,好用哎

马黑黑 发表于 2025-5-13 19:33

花飞飞 发表于 2025-5-13 18:59
原来是两个嵌套在一起的,都是基础材质,
分开后,看到第二个没有线框,所以就是同色。
第二个换成Mesh ...

Normal本来是正常的意思,挺好的

花飞飞 发表于 2025-5-13 20:39

刚才忙了一会,现在继续回来看看。{:4_173:}
缓冲几何体这个名词到是与众不同,是个专业名词吧。。很新奇。
这个教程里的嵌套,是否适用于胶囊几何体呢,那个应该也可以嵌套的吧
所以,three.js越来越厉害。。
或者是白老师这样由浅入深的讲解,揭开一层又一层的新功能。。。每天都有惊喜。

花飞飞 发表于 2025-5-13 20:39

马黑黑 发表于 2025-5-13 19:33
Normal本来是正常的意思,挺好的

基础的就是万能的,万能自然是好滴

马黑黑 发表于 2025-5-13 20:54

花飞飞 发表于 2025-5-13 20:39
基础的就是万能的,万能自然是好滴

是的吧

马黑黑 发表于 2025-5-13 20:54

花飞飞 发表于 2025-5-13 20:39
刚才忙了一会,现在继续回来看看。
缓冲几何体这个名词到是与众不同,是个专业名词吧。。很新奇 ...

很多几何体都是缓冲系列

红影 发表于 2025-5-13 21:41

马黑黑 发表于 2025-5-13 18:11
纯色的话,画成不圆的应该是可以的

哦,对的,分段少点,可能更清晰。

红影 发表于 2025-5-13 21:45

马黑黑 发表于 2025-5-13 18:11
各种几何体图形都有自己的存在理由

嗯嗯, three.js里的几何体都是标准几何体吧。

马黑黑 发表于 2025-5-13 22:10

红影 发表于 2025-5-13 21:45
嗯嗯, three.js里的几何体都是标准几何体吧。

它提供了不少内置封装的几何体,开箱即用

马黑黑 发表于 2025-5-13 22:11

红影 发表于 2025-5-13 21:41
哦,对的,分段少点,可能更清晰。

所以纹理贴图还是非常有必要的

红影 发表于 2025-5-13 22:41

马黑黑 发表于 2025-5-13 22:10
它提供了不少内置封装的几何体,开箱即用

这样真好,可以有无限可能,

红影 发表于 2025-5-13 22:42

马黑黑 发表于 2025-5-13 22:11
所以纹理贴图还是非常有必要的

让形体更明显{:4_173:}

马黑黑 发表于 2025-5-14 12:32

红影 发表于 2025-5-13 22:42
让形体更明显

或者加入光源。等下我做一个能控制每一个对象旋转的示例,里面就是用颜色做皮肤的,不穿花衣

花飞飞 发表于 2025-5-14 19:13

马黑黑 发表于 2025-5-13 20:54
很多几何体都是缓冲系列

原来如此,缓冲跟几何体联系在一起,这个也是需要适应的。{:4_173:}
页: [1] 2 3
查看完整版本: three.js几何体之圆锥缓冲几何体