ThreeJS 直管道
<style>.artBox { font-size: 18px; }
.artBox > p { margin: 10px 0; line-height: 30px; }
.artBox mark { padding: 4px 6px; background: lightblue; }
#prevBox { position: fixed; top: 0; right: 0; bottom: 0; left: 0; background: #eee; display: none; padding: 0; overflow: hidden; z-index: 1000; margin: 0; }
#prevBox::after { position: absolute; content: '关闭预览'; bottom: 10px; left: calc(50% - 40px); padding: 0 4px; width: 80px; height: 30px; line-height: 30px; text-align: center; border: 1px solid #efe; border-radius: 6px; background: #eee; font-size: 14px; box-shadow: 2px 2px 6px rgba(0,0,0,.25); cursor: pointer; }
iframe { position: relative; width: 100%; height: 100%; border: none; outline: none; box-sizing: border-box; margin: 0; }
</style>
<div id="prevBox"></div>
<div class="artBox">
<p>在 ThreeJS 中使用默认参数绘制一根管道是超简单的。下面我们演示一下如何在 basic3 创建的 ThreeJS 环境下实现绘制工作:</p>
<div class="hEdiv"><pre class="hEpre" id="pre1">
<script type="module">
import { THREE, scene, camera, renderer, clock, basic3 } from 'https://638183.freep.cn/638183/3dev/3/3basic.js';
basic3(); // 启动ThreeJS工作环境
const geometry = new THREE.TubeGeometry(); // 管道几何体
const material = new THREE.MeshNormalMaterial(); // 法线网格材质
const mesh = new THREE.Mesh(geometry, material); // 几何体+材质 => 管道图像
scene.add(mesh); // 图像添加到场景
renderer.render(scene, camera); // 渲染效果
</script>
</pre></div>
<blockquote><button id="btnPrev1">运行代码</button></blockquote>
<p>运行代码应该会看到一个相当于二通水管转接头的图像,其弯曲的形状是由二次贝塞尔路径创建而成。本文的任务是绘制一个直的管道,这需要复习一下<mark> TubeGeometry() </mark>的构造器即构成管道几何体所需的各个参数,总共五个:</p>
<blockquote>
① path : 路径,一个由基类Curve继承而来的3D路径,字符型,默认是二次贝塞尔路径曲线;<br>
② tubularSegments : 组成这一管道的分段数,整数型,默认值为64;<br>
③ radius : 管道的半径,浮点型,默认值为1;<br>
④ radialSegments : 管道横截面的分段数目,整数型,默认值为8<br>
⑤ closed : 管道的两端是否闭合,布尔值,默认值为false
</blockquote>
<p>可以看出,参数一 path 参数决定管道的形状、参数二 tubularSegments 影响管道的平滑度、参数三 radius 定义管道的大小、参数四 radialSegments 参与决定形状,即管道口呈现出来的结果是多边形还是圆形,参数五设置管道两个端口是开放的还是闭合的。借助第一个参数 path 路径参数,可以为管道几何体准备一个直线路径:</p>
<div class="hEdiv"><pre class="hEpre">
// 使用三维线段曲线 LineCurve3 将两个三维向量点连接成三维直线路径
const path = new THREE.LineCurve3(
new THREE.Vector3(-1, 0, 0), // 三维向量点 1
new THREE.Vector3(1, 0, 0) // 三维向量点 2
);
</pre></div>
<p><mark>Vector3 </mark>创建一个三维向量点 (x,y,z),表示三维空间上的一个点的三维坐标位置。直线需要两个点,所以,给 <mark>LineCurve3 </mark>三维线段曲线两个点,它能整出来的曲线就是直线。接下来将 path 变量作为参数用来构建管道,管道几何体所需的其它参数也做好相应的设计:</p>
<div class="hEdiv"><pre class="hEpre" id="pre2">
<script type="module">
import { THREE, scene, camera, renderer, clock, basic3 } from 'https://638183.freep.cn/638183/3dev/3/3basic.js';
basic3();
// 绘制直的管道
const path = new THREE.LineCurve3(new THREE.Vector3(-2, 0, 0), new THREE.Vector3(2, 0, 0));
const geometry = new THREE.TubeGeometry(path, 32, 0.2, 8, false);
const material = new THREE.MeshNormalMaterial({ side: THREE.DoubleSide }); // 双面渲染材质
const mesh = new THREE.Mesh(geometry, material);
mesh.rotateY(Math.PI / 3); // 在X轴上定位
scene.add(mesh);
renderer.render(scene, camera);
</script>
</pre></div>
<blockquote><button id="btnPrev2">运行代码</button></blockquote>
<p>这就完成了直管道的绘制工作。可以设计其它任意形状的管道,核心是 path 参数的设计。</p>
</div>
<script type="module">
import hlight from 'https://638183.freep.cn/638183/web/helight/helight1.js';
const pres = document.querySelectorAll('.hEpre');
const divs = document.querySelectorAll('.hEdiv');
divs.forEach( (div, key) => hlight.hl(div, pres));
const preView = (htmlCode, targetBox) => {
if (targetBox.innerHTML) return;
const iframe = document.createElement('iframe');
htmlCode = htmlCode + '<style>body {margin: 0; }</style>';
iframe.srcdoc = htmlCode;
targetBox.appendChild(iframe);
targetBox.style.display = 'block';
targetBox.onclick = () => {
targetBox.innerHTML = '';
targetBox.style.display = 'none';
}
};
const value1 = pre1.textContent;
const value2 = pre2.textContent;
btnPrev1.onclick = () => preView(value1, prevBox);
btnPrev2.onclick = () => preView(value2, prevBox);
</script> 原来默认的是完全的管道,想要得到直的管道,需要给它一个直线的路径,替代到默认路径。
学习了{:4_187:} 讲的真好,谢谢老师经典分享{:4_191:} 杨帆 发表于 2025-6-17 12:41
讲的真好,谢谢老师经典分享
{:4_190:} 红影 发表于 2025-6-17 12:32
原来默认的是完全的管道,想要得到直的管道,需要给它一个直线的路径,替代到默认路径。
学习了
这个再讲几何体是应该有讲过 马黑黑 发表于 2025-6-17 18:43
这个再讲几何体是应该有讲过
嗯嗯,应该是讲过的{:4_187:} 之前的管道几何体是线框化材质的,可以透视看到内部,
而这个是法线网格,外形颜色看上去不一样。。{:4_173:} 这个path 参数改变得到直管道,奇思妙想,黑神总能出奇迹。。{:4_199:} 花飞飞 发表于 2025-6-17 19:22
这个path 参数改变得到直管道,奇思妙想,黑神总能出奇迹。。
这个官网都有说到的 花飞飞 发表于 2025-6-17 19:20
之前的管道几何体是线框化材质的,可以透视看到内部,
而这个是法线网格,外形颜色看上去不一样。。{:4_17 ...
这个使用默认方式绘制 红影 发表于 2025-6-17 19:19
嗯嗯,应该是讲过的
是的 马黑黑 发表于 2025-6-17 19:38
这个官网都有说到的
一般不看管网的{:4_173:} 马黑黑 发表于 2025-6-17 19:38
这个使用默认方式绘制
{:4_173:}好哒,看到一种几何体老想换个材质看效果 花飞飞 发表于 2025-6-17 20:34
好哒,看到一种几何体老想换个材质看效果
{:4_190:} 花飞飞 发表于 2025-6-17 20:31
一般不看管网的
不看可惜 马黑黑 发表于 2025-6-17 19:38
是的
它默认的是二次贝塞尔路径,给它别的路径,就能绘制出别的管道了。 红影 发表于 2025-6-17 21:11
它默认的是二次贝塞尔路径,给它别的路径,就能绘制出别的管道了。
对,是这个意思 马黑黑 发表于 2025-6-17 22:23
对,是这个意思
其实也就直的和弯的两种吧? 红影 发表于 2025-6-18 16:49
其实也就直的和弯的两种吧?
管道嘛,不是直的就是弯的。弯的看怎么弯 马黑黑 发表于 2025-6-18 18:35
管道嘛,不是直的就是弯的。弯的看怎么弯
嗯,最复杂的弯会看得人眼花缭乱{:4_173:}