Javascript (Three.js)自定义网格UV显示纹理
我基于平面几何体为Three.js创建了一个自定义几何体函数。 一切正常,只是我不知道如何正确显示UV。 我每平方使用4个三角形,而THREE.PlaneGeometry每平方仅使用2个三角形 PlaneGeometry UV的代码如下所示:Javascript (Three.js)自定义网格UV显示纹理,javascript,3d,three.js,texture-mapping,Javascript,3d,Three.js,Texture Mapping,我基于平面几何体为Three.js创建了一个自定义几何体函数。 一切正常,只是我不知道如何正确显示UV。 我每平方使用4个三角形,而THREE.PlaneGeometry每平方仅使用2个三角形 PlaneGeometry UV的代码如下所示: var uva = new THREE.Vector2( ix / gridX, 1 - iz / gridZ ); var uvb = new THREE.Vector2( ix / gridX, 1 - ( iz + 1 ) / gridZ ); va
var uva = new THREE.Vector2( ix / gridX, 1 - iz / gridZ );
var uvb = new THREE.Vector2( ix / gridX, 1 - ( iz + 1 ) / gridZ );
var uvc = new THREE.Vector2( ( ix + 1 ) / gridX, 1 - ( iz + 1 ) / gridZ );
var uvd = new THREE.Vector2( ( ix + 1 ) / gridX, 1 - iz / gridZ );
以及源代码中的我的代码:
var uva = new THREE.Vector2( a );
var uvb = new THREE.Vector2( b );
var uvc = new THREE.Vector2( c );
var uvd = new THREE.Vector2( d );
var uve = new THREE.Vector2( e );
显然,这是错误的。但是我试着使用PlaneGeometry代码,我得到了奇怪的变形,我不知道如何计算正确的位置。
这:
给我这个:
我在THREE.JS聊天室里得到了一些答案,但我不明白,那个人也没有详细说明
(Q) 所以。。UV的矢量2不应该与垂直方向处于同一位置吗
(A) 不,UV是映射到纹理的向量,如果
有一个512x512纹理和一个[0.25,0.75]的UV,它将映射到
纹理中256768处的像素每个顶点都有一个uv
这意味着该顶点映射到纹理中,如上文所述
这是为顶点的每个面以及顶点中的所有碎片执行的
然后使用这三个UV对面进行插值
所以这并没有消除我的困惑。。我不理解[0.25,0.75]部分。或者每个顶点都有一个纹理。点如何具有纹理
有人能给我指一下正确的方向吗?
我只需要知道紫外线是如何定位的。但举个例子就好了
如果您想看一看,以下是来源:
THREE.DiamondGeometry = function ( width, height, widthSegments, heightSegments ) {
THREE.Geometry.call( this );
this.width = width;
this.height = height;
this.widthSegments = widthSegments || 1;
this.heightSegments = heightSegments || 2;
var long_row = this.widthSegments + 1;
var short_row = this.widthSegments;
// First Row is the long_row, the ternary statement will toggle this.
var current_row = short_row;
var gridY = 0;
var vX = width / 2, vY = height / 2;
var ix, iz;
var width_half = width / 2;
var height_half = height / 2;
var gridX = this.widthSegments;
var gridZ = this.heightSegments;
var gridX1 = gridX + 1;
var gridZ1 = gridZ + ( gridZ - 2) + 1;
var segment_width = this.width / gridX;
var segment_height = this.height / gridZ;
var normal = new THREE.Vector3( 0, 0, 1 );
// Height Segments Verticies
for ( iz = 0; iz < (gridZ1 + 1) * 2; iz ++ ) {
// Ternary Operator:
current_row === long_row ? (current_row = short_row, vX = width_half - (segment_width / 2) ) : (current_row = long_row, vX = width_half );
// Width Segment Verticies
for ( ix = 0; ix < current_row; ix ++ ) {
var x = ix * segment_width - vX ;
var y = (iz * segment_height - vY) / 2 - (vY / 2);
this.vertices.push( new THREE.Vector3( x, - y, 0 ) );
}
}
for ( iz = 0; iz < gridZ ; iz ++ ) {
for ( ix = 0; ix < gridX; ix ++ ) {
var a = ix + gridX * iz + (iz * gridX1) ;
var b = a + 1;
var c = a + gridX1;
var d = c + gridX;
var e = d + 1;
// THIS IS THE BAD PART THAT I NEED TO CALCULATE THE UV POSITIONS FOR:
var uva = new THREE.Vector2( a );
var uvb = new THREE.Vector2( b );
var uvc = new THREE.Vector2( c );
var uvd = new THREE.Vector2( d );
var uve = new THREE.Vector2( e );
// UP
var face = new THREE.Face3( c, b, a );
face.normal.copy( normal );
face.vertexNormals.push( normal.clone(), normal.clone(), normal.clone() );
this.faces.push( face );
this.faceVertexUvs[ 0 ].push( [ uva, uvb, uvc ] );
// DOWN
face = new THREE.Face3( e, c, d );
face.normal.copy( normal );
face.vertexNormals.push( normal.clone(), normal.clone(), normal.clone() );
this.faces.push( face );
this.faceVertexUvs[ 0 ].push( [ uvd, uvc.clone(), uve ] );
// LEFT
face = new THREE.Face3( d, c, a );
face.normal.copy( normal );
face.vertexNormals.push( normal.clone(), normal.clone(), normal.clone() );
this.faces.push( face );
this.faceVertexUvs[ 0 ].push( [ uva.clone(), uvc.clone(), uvd.clone() ] );
// RIGHT
face = new THREE.Face3( e, b, c );
face.normal.copy( normal );
face.vertexNormals.push( normal.clone(), normal.clone(), normal.clone() );
this.faces.push( face );
this.faceVertexUvs[ 0 ].push( [ uvc.clone(), uvb.clone(), uve.clone() ] );
}
}
this.computeCentroids();
};
THREE.DiamondGeometry.prototype = Object.create( THREE.Geometry.prototype );
THREE.DiamondGeometry=函数(宽度、高度、宽度段、高度段){
三、几何学。叫(这个);
这个。宽度=宽度;
高度=高度;
this.widthSegments=widthSegments | | 1;
this.heightSegments=heightSegments | | 2;
var long_row=this.widthSegments+1;
var short_row=this.widthSegments;
//第一行是长_行,三元语句将对此进行切换。
var当前行=短行;
var-gridY=0;
var vX=宽度/2,vY=高度/2;
var ix,iz;
变量宽度_半=宽度/2;
变量高度_半=高度/2;
var gridX=this.widthSegments;
var gridZ=this.heightSegments;
var gridX1=gridX+1;
var gridZ1=gridZ+(gridZ-2)+1;
var段_宽度=this.width/gridX;
var段高度=this.height/gridZ;
var normal=新的三个向量3(0,0,1);
//垂直高度
对于(iz=0;iz<(gridZ1+1)*2;iz++){
//三元运算符:
当前行===长行?(当前行=短行,vX=宽度半-(段宽度/2)):(当前行=长行,vX=宽度半);
//宽段垂直
对于(ix=0;ix<当前行;ix++){
var x=ix*段宽度-vX;
变量y=(iz*段高度-vY)/2-(vY/2);
this.vertices.push(新的3.Vector3(x,-y,0));
}
}
对于(iz=0;iz
请参见此图:
如上所述,对于没有纹理重复的1个纹理,UV坐标在(0,0)到(1,1)的范围内。如果有一个四元平面,并将UV指定给图像中的顶点,则整个纹理将显示在四元平面上。如果添加边循环/细分四边形(例如在4个较小的四边形中),但仍希望在不重复的情况下完整显示纹理,则需要计算顶点在UV空间中的位置之间的值。例如,中间的顶点(由你的镶嵌产生)现在是UV(0.5,0.5)。
在中间的顶部的是(0,0.5)。了解PlaneGeometry是如何实现的,并尝试从中学习^^
THREE.DiamondGeometry = function ( width, height, widthSegments, heightSegments ) {
THREE.Geometry.call( this );
this.width = width;
this.height = height;
this.widthSegments = widthSegments || 1;
this.heightSegments = heightSegments || 2;
var long_row = this.widthSegments + 1;
var short_row = this.widthSegments;
// First Row is the long_row, the ternary statement will toggle this.
var current_row = short_row;
var gridY = 0;
var vX = width / 2, vY = height / 2;
var ix, iz;
var width_half = width / 2;
var height_half = height / 2;
var gridX = this.widthSegments;
var gridZ = this.heightSegments;
var gridX1 = gridX + 1;
var gridZ1 = gridZ + ( gridZ - 2) + 1;
var segment_width = this.width / gridX;
var segment_height = this.height / gridZ;
var normal = new THREE.Vector3( 0, 0, 1 );
// Height Segments Verticies
for ( iz = 0; iz < (gridZ1 + 1) * 2; iz ++ ) {
// Ternary Operator:
current_row === long_row ? (current_row = short_row, vX = width_half - (segment_width / 2) ) : (current_row = long_row, vX = width_half );
// Width Segment Verticies
for ( ix = 0; ix < current_row; ix ++ ) {
var x = ix * segment_width - vX ;
var y = (iz * segment_height - vY) / 2 - (vY / 2);
this.vertices.push( new THREE.Vector3( x, - y, 0 ) );
}
}
for ( iz = 0; iz < gridZ ; iz ++ ) {
for ( ix = 0; ix < gridX; ix ++ ) {
var a = ix + gridX * iz + (iz * gridX1) ;
var b = a + 1;
var c = a + gridX1;
var d = c + gridX;
var e = d + 1;
// THIS IS THE BAD PART THAT I NEED TO CALCULATE THE UV POSITIONS FOR:
var uva = new THREE.Vector2( a );
var uvb = new THREE.Vector2( b );
var uvc = new THREE.Vector2( c );
var uvd = new THREE.Vector2( d );
var uve = new THREE.Vector2( e );
// UP
var face = new THREE.Face3( c, b, a );
face.normal.copy( normal );
face.vertexNormals.push( normal.clone(), normal.clone(), normal.clone() );
this.faces.push( face );
this.faceVertexUvs[ 0 ].push( [ uva, uvb, uvc ] );
// DOWN
face = new THREE.Face3( e, c, d );
face.normal.copy( normal );
face.vertexNormals.push( normal.clone(), normal.clone(), normal.clone() );
this.faces.push( face );
this.faceVertexUvs[ 0 ].push( [ uvd, uvc.clone(), uve ] );
// LEFT
face = new THREE.Face3( d, c, a );
face.normal.copy( normal );
face.vertexNormals.push( normal.clone(), normal.clone(), normal.clone() );
this.faces.push( face );
this.faceVertexUvs[ 0 ].push( [ uva.clone(), uvc.clone(), uvd.clone() ] );
// RIGHT
face = new THREE.Face3( e, b, c );
face.normal.copy( normal );
face.vertexNormals.push( normal.clone(), normal.clone(), normal.clone() );
this.faces.push( face );
this.faceVertexUvs[ 0 ].push( [ uvc.clone(), uvb.clone(), uve.clone() ] );
}
}
this.computeCentroids();
};
THREE.DiamondGeometry.prototype = Object.create( THREE.Geometry.prototype );