如何在飞机的正面和背面放置两种不同的纹理?

Posted

技术标签:

【中文标题】如何在飞机的正面和背面放置两种不同的纹理?【英文标题】:How can I put two different textures on the front and back of a plane? 【发布时间】:2012-07-27 10:16:24 【问题描述】:

问题:我正在尝试创建(只是为了好玩)一张简单的扑克牌(背面有卡片,正面有卡片)。 我有两个不同的图像,用于背面和正面。 我很容易地为双方创建了一个带有单个纹理的平面几何图形,但我真的不知道如何为一侧分配一个纹理,为另一侧分配另一个纹理...... 我试过这个(没有成功:():

var textureBack = new THREE.ImageUtils.loadTexture( 'images/cardBack.png' );
var textureFront = new THREE.ImageUtils.loadTexture( 'images/cardFront.png' );      

var material1 = new THREE.MeshBasicMaterial(  map: textureBack  );
var material2 = new THREE.MeshBasicMaterial(  map: textureFront  );

var geometry = new THREE.PlaneGeometry( 90, 110, 1, 1 );            
geometry.faces[ 0 ].materials.push( material1 );
geometry.faces[ 1 ].materials.push( material2 );

var card = new THREE.Mesh( geometry, new THREE.MeshFaceMaterial());

有什么帮助吗? :)

【问题讨论】:

下面有一个更精简的解决方案,花了很长时间,所以我想我会分享! 【参考方案1】:

您需要将两个平面几何图形背靠背放置。

首先,为前面创建一个几何图形。

var geometry1 = new THREE.PlaneGeometry( 90, 110, 1, 1 );

现在为背部创建另一个几何体。

var geometry2 = new THREE.PlaneGeometry( 90, 110, 1, 1 );

旋转 180 度。

geometry2.applyMatrix( new THREE.Matrix4().makeRotationY( Math.PI ) );

加载材质后,创建网格,并将它们添加为“卡片”对象的子级。

// textures
var textureFront = new THREE.ImageUtils.loadTexture('images/cardFront.png' );      
var textureBack = new THREE.ImageUtils.loadTexture('images/cardBack.png' );

// material
var material1 = new THREE.MeshBasicMaterial(  color: 0xffffff, map: textureFront  );
var material2 = new THREE.MeshBasicMaterial(  color: 0xffffff, map: textureBack  );

// card
card = new THREE.Object3D();
scene.add( card );

// mesh
mesh1 = new THREE.Mesh( geometry1, material1 );
card.add( mesh1 );
mesh2 = new THREE.Mesh( geometry2, material2 );
card.add( mesh2 );

如果你使用WebGLRenderer,你会更轻松。

小提琴:http://jsfiddle.net/mdAb7/11/

更新到three.js r.69

【讨论】:

好的!我已经尝试了第一个解决方案,它成功了!!!!非常感谢:) 一点(也许可以避免浪费时间……):这段代码“geometry1.applyMatrix(new THREE.Matrix4().makeRotationX(Math.PI / 2));”不起作用,因为进行旋转的方法名称,虽然在文档中是 'makeRotationX',是 'setRotationX' :D 现在我也会尝试第二种解决方案;) 我尝试了第二种解决方案,它也可以工作...但我看到第二种解决方案所有动画都很慢...无论如何,再次感谢您!问题已解决:D setRotationX 来自旧版本的库。您需要更新到 r.49。 Ops:我真的确信我有正确的版本 oO 我会更新;) PS:对不起,但是......我怎么能接受这个答案?编辑:好的好的,我刚刚完成了! ;) 大家好,请看下面我的回答,以节省一些额外的内存/几何调用、更新或其他任何东西【参考方案2】:

正在寻找解决方案而不复制所有几何图形。

女士们,先生们,来吧……

var materials = [new THREE.MeshBasicMaterial(map: texture, side: THREE.FrontSide),
                 new THREE.MeshBasicMaterial(map: textureBack, side: THREE.BackSide)];

var geometry = new THREE.PlaneGeometry(width, height);

for (var i = 0, len = geometry.faces.length; i < len; i++) 
    var face = geometry.faces[i].clone();
    face.materialIndex = 1;
    geometry.faces.push(face);
    geometry.faceVertexUvs[0].push(geometry.faceVertexUvs[0][i].slice(0));


scene.add(new THREE.Mesh(geometry, new THREE.MeshFaceMaterial(materials)));

为你准备一个两面平面,循环也适用于具有更多面的几何图形,复制每个面并对其应用 BackSide 纹理。

享受吧!

【讨论】:

你能帮我翻转纹理吗?有镜面效果 您必须通过 UV 并翻转它们。使您的几何对象临时成为全局变量,然后运行您的应用程序。在 Chrome 中使用 javascript 控制台并输入几何对象的变量名(现在是全局的)并遍历它的内容。您应该会看到存储在那里的纹理 UV 坐标,按照您希望看到纹理出现的方式翻转它们的顺序。 这对于动态几何对象(例如,飘动的平面)很有用,因为您只需更新 1 个几何。可以通过使用此解决方案将镜像文件作为平面背面的输入来避免镜像问题。但是对于一个简单的标志,例如Stars & Stripes 只使用“DoubleSide”就可以了。 如何让它与 gltf 一起工作

以上是关于如何在飞机的正面和背面放置两种不同的纹理?的主要内容,如果未能解决你的问题,请参考以下文章

挤压形状的背面和正面的不同材料

导出到 DAE 时如何继承相同的纹理映射?

如何翻转正面带有标签而背面带有另一个标签的视图 - 参见图片

如何从 Blender 中导出 fbx 纹理以在 Monogame 中使用

在对象上添加图像/纹理的搅拌机未显示在 .obj 文档中

Cordova如何翻转整个屏幕正面到背面的3D效果