【问题标题】:Texturing a Cylinder in Three.js在 Three.js 中对圆柱体进行纹理化
【发布时间】:2012-01-09 01:48:12
【问题描述】:

我已经照顾了很长时间了。 我只是在任何地方都找不到任何解决方案。 我正在尝试在圆柱体上应用 3 种不同的纹理(2 顶盖和侧面) 但我完全不知道如何实现这一目标。 你能给我定位吗? 这是我现在正在做的事情:

var coin1_geo = new THREE.CylinderGeometry( 100, 100, 10, 100, 100, false );
var coin1_texture = THREE.ImageUtils.loadTexture("./assets/avers.png");
var coin1_mat = new THREE.MeshLambertMaterial({map:coin1_texture});
var coin1 = new THREE.Mesh( coin1_geo, coin1_mat );
coin1.rotation.x = 20;
coin1.position.set(0,0,0);
coin1.castShadow = true;
coin1.receiveShadow = false;
scene.add( coin1 );

正如您在此处看到的,我只在所有面上应用一种纹理。 但即使在大写字母上,它也没有真正显示出来,我只有一个完整的圆圈。 请帮忙,我正在实现硬币,如果你没有弄清楚。 即使你只是给我一个教程的链接,我也会非常感激。 我什么也找不到,而且我在 3D/OpenGL 编程方面的知识非常有限。 非常感谢。

【问题讨论】:

  • 我认为你需要的不仅仅是一个硬币的圆柱体,你应该在顶部和底部添加两个“环”(内半径 = 0)。
  • 为什么? three.js 的最后一个版本为 Cylinders 提供了一个布尔值 (openEnded),可以用大写或不用大写来关闭末端。 THREE.CylinderGeometry 的最后一个参数。或者我不明白为什么我应该添加“戒指”......那为什么呢? ;)

标签: javascript html webgl three.js


【解决方案1】:

[编辑] 由于上限 UV 是伪造的,因此三个圆柱体无法工作。 您需要滚动自己的帽几何形状。工作量不大,就是烦。以下是如何使用自定义瓶盖制作无盖圆柱体:

var coin_sides_geo =
  new THREE.CylinderGeometry( 10.0, 10.0, 1.0, 100.0, 10.0, true );
var coin_cap_geo = new THREE.Geometry();
var r = 10.0;
for (var i=0; i<100; i++) {
  var a = i * 1/100 * Math.PI * 2;
  var z = Math.sin(a);
  var x = Math.cos(a);
  var a1 = (i+1) * 1/100 * Math.PI * 2;
  var z1 = Math.sin(a1);
  var x1 = Math.cos(a1);
  coin_cap_geo.vertices.push(
    new THREE.Vertex(new THREE.Vector3(0, 0, 0)),
    new THREE.Vertex(new THREE.Vector3(x*r, 0, z*r)),
    new THREE.Vertex(new THREE.Vector3(x1*r, 0, z1*r))
  );
  coin_cap_geo.faceVertexUvs[0].push([
    new THREE.UV(0.5, 0.5),
    new THREE.UV(x/2+0.5, z/2+0.5),
    new THREE.UV(x1/2+0.5, z1/2+0.5)
  ]);
  coin_cap_geo.faces.push(new THREE.Face3(i*3, i*3+1, i*3+2));
}
coin_cap_geo.computeCentroids();
coin_cap_geo.computeFaceNormals();

var coin_sides_texture =
  THREE.ImageUtils.loadTexture("./coin_sides.png");
var coin_cap_texture =
  THREE.ImageUtils.loadTexture("./coin_face.png");

var coin_sides_mat =
  new THREE.MeshLambertMaterial({map:coin_sides_texture});
var coin_sides =
  new THREE.Mesh( coin_sides_geo, coin_sides_mat );

var coin_cap_mat = new THREE.MeshLambertMaterial({map:coin_cap_texture});
var coin_cap_top = new THREE.Mesh( coin_cap_geo, coin_cap_mat );
var coin_cap_bottom = new THREE.Mesh( coin_cap_geo, coin_cap_mat );
coin_cap_top.position.y = 0.5;
coin_cap_bottom.position.y = -0.5;
coin_cap_top.rotation.x = Math.PI;

var coin = new THREE.Object3D();
coin.add(coin_sides);
coin.add(coin_cap_top);
coin.add(coin_cap_bottom);

【讨论】:

  • 我明天肯定会测试这个。但是帽子的纹理应该是什么样子的,它是帽子的简单 png(透明背景上的圆形硬币)吗?还是我必须为此搞砸UV纹理?事实上,这是我最初的问题。但我们会看到它是如何做到的。还是谢谢。
  • 啊,我想这是帽子的简单 png。但是让我先试试看。做你自己的自定义帽几何形状也不是太难,如果帽纹理对我来说很奇怪,我可以给你一个例子。
  • 好吧,帽子的纹理很奇怪。必须使用自己的 UV。
  • 哇,你在这方面做了很多...这是我最初的问题(UV)。我不知道如何处理这些,请赐教。非常感谢。
【解决方案2】:

在现代 Three.js 中,您可以创建一个包含 3 种材质数组的圆柱体:

const materials = [
  sideMaterial,
  topMaterial,
  bottomMaterial
]
const geometry = new THREE.CylinderGeometry(5, 5, 0.5, 100)
const mesh= new THREE.Mesh(geometry, materials)

【讨论】:

  • 谢谢一堆,这就像一个魅力,拯救了我的一天。
  • 投了赞成票,所以它会登上顶峰!这是完美的!
【解决方案3】:

TypeScript 函数变体,创建具有 3 个网格的 Object3D:side、topCap 和 bottomCap。
适用于 lib 版本:
“三”:“0.102.1”

 import capTop from './textures/capTopTexture.png';
 import capBottom from './textures/capBottomTexture.png';
 import capSide from './textures/sideTexture.png';

 function createCylinder (
        radiusTop: number,
        radiusBottom: number,
        height: number,
        radialSegments: number,
        heightSegments: number,
    ): Object3D {
        const cylinder = new THREE.Object3D();

        const sidesGeo = new THREE.CylinderGeometry(
            radiusTop,
            radiusBottom,
            height,
            radialSegments,
            heightSegments,
            true,
        );
        const sideTexture = new THREE.TextureLoader().load(capSide, this.reRender);
        const sidesMat =
            new THREE.MeshLambertMaterial({map: sideTexture});
        const sidesMesh =
            new THREE.Mesh( sidesGeo, sidesMat );
        cylinder.add(sidesMesh);

        const capTopGeo = new THREE.CircleGeometry(radiusTop, radialSegments);
        const capTopTexture = new THREE.TextureLoader().load(capTop, this.reRender);
        const capTopMat =
            new THREE.MeshLambertMaterial({map: capTopTexture});
        const capTopMesh =
            new THREE.Mesh( capTopGeo, capTopMat );
        capTopMesh.position.y = height / 2;
        capTopMesh.rotation.x = - Math.PI / 2;
        cylinder.add(capTopMesh);

        const capBottomGeo = new THREE.CircleGeometry(radiusBottom, radialSegments);
        const capBottomTexture = new THREE.TextureLoader().load(capBottom, this.reRender);
        const capBottomMat =
            new THREE.MeshLambertMaterial({map: capBottomTexture});
        const capBottomMesh =
            new THREE.Mesh( capBottomGeo, capBottomMat );
        capBottomMesh.position.y = -height / 2;
        capBottomMesh.rotation.x = Math.PI / 2;
        cylinder.add(capBottomMesh);

        return cylinder;
    };


【讨论】:

    猜你喜欢
    • 2013-12-23
    • 2019-09-22
    • 1970-01-01
    • 1970-01-01
    • 2014-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-30
    相关资源
    最近更新 更多