Three.js视频的一部分作为纹理

时间:2016-08-31 21:51:37

标签: javascript three.js

我试图将部分视频用作Three.js网格中的纹理。

视频在这里,http://video-processing.s3.amazonaws.com/example.MP4它是一个鱼眼镜头,我想只使用具有实际内容的部分,即中间的圆圈。

我想以某种方式遮罩,裁剪或定位并拉伸网格上的视频,以便只显示此部分并忽略黑色部分。

视频代码

var video = document.createElement( 'video' );
    video.loop = true;
    video.crossOrigin = 'anonymous';
    video.preload = 'auto';
    video.src = "http://video-processing.s3.amazonaws.com/example.MP4";
    video.play();

var texture = new THREE.VideoTexture( video );
    texture.minFilter = THREE.NearestFilter;
    texture.magFilter = THREE.LinearFilter;
    texture.format = THREE.RGBFormat;

var material   = new THREE.MeshBasicMaterial( { map : texture } );

然后将视频投影到220度球体上,以给出VR印象。

var geometry = new THREE.SphereGeometry( 200,100,100, 0, 220 * Math.PI / 180, 0, Math.PI); 

这是一支代码笔 http://codepen.io/bknill/pen/vXBWGv

任何人都可以让我知道我最好这样做吗?

2 个答案:

答案 0 :(得分:1)

您可以使用texture.repeat缩放纹理

http://threejs.org/docs/#Reference/Textures/Texture

例如,在两个轴上缩放2x texture.repeat.set(0.5,0.5);

答案 1 :(得分:1)

简而言之,您需要更新球体的UV-Map,以便将纹理的相关区域指定给球体的相应顶点。

每个顶点的UV坐标定义纹理中分配给该顶点的坐标(在[0..1]范围内,因此坐标(0,0)是左上角和(1,1) )视频的右下角)。 This example应该给你一个关于这是什么的想法。

这些UV坐标作为geometry.faceVertexUvs[0]存储在几何体中,这样每个面的每个顶点都有一个THREE.Vector2的UV坐标值。这是一个二维数组,第一个索引是面部索引,第二个索引是面部的顶点索引(参见示例)。

至于生成UV贴图,至少有两种方法可以做到这一点。可能更简单的方法(ymmv,但我总是走这条路)就是使用像blender这样的3D编辑软件创建UV贴图,并使用three.js导出器插件导出生成的对象。

另一种方法是手动计算值。我建议你首先尝试简单地使用球体的正交投影。所以基本上,如果你在原点有一个单位球体,只需删除顶点的z坐标,并使用u = x/2 + 0.5v = y/2 + 0.5作为UV坐标。

在JS中会是这样的:

// create the geometry (note that for simplicity, we're 
//   a) using a unit-sphere and 
//   b) use an exact half-sphere)
const geometry = new THREE.SphereGeometry(1, 18, 18, Math.PI, Math.PI)
const uvs = geometry.faceVertexUvs[0];
const vertices = geometry.vertices;

// compute the UV from the vertices of the sphere. You will probably need 
// something a bit more elaborate than this for the 220degree FOV, also maybe
// some lens-distorion, but it will boild down to something like this:
for(let i = 0; i<geometry.faces.length; i++) {
  const face = geometry.faces[i];
  const faceVertices = [vertices[face.a], vertices[face.b], vertices[face.c]];

  for(let j = 0; j<3; j++) {
    const vertex = faceVertices[j];
    uvs[i][j].set(vertex.x/2 + 0.5, vertex.y/2 + 0.5);
  }
}
geometry.uvsNeedUpdate = true;

(如果您需要更多信息,请发表评论,我会详细说明)