【问题标题】:(Three.js) Custom Mesh UV Display Texture Properly(三.js)自定义Mesh UV正确显示纹理
【发布时间】:2013-11-06 17:28:48
【问题描述】:

我为 Three.js 创建了一个基于平面几何的自定义几何函数。 一切正常,除了我不知道如何正确显示紫外线。 我每个正方形使用 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 );
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 代码,但我得到了奇怪的扭曲,我不确定如何计算正确的位置。 这个:

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 ) / gridX) + gridX, 1 - iz / gridZ );
var uve = new THREE.Vector2( ( ix + 1 ) / gridX, 1 - iz / gridZ );

给我这个:BAD UV

我在THREE.JS聊天室里得到了某种答案,但我没看懂,那个人也没有细说……

(Q) 那么.. UV 的 Vector2 不应该与顶点的位置相同吗?

(A) 不,UV 是一个映射到纹理的向量,如果你 具有 512x512 纹理和 [0.25, 0.75] 的 UV,它将映射到 纹理中的像素 256, 768 每个顶点都有一个 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 );

【问题讨论】:

    标签: javascript 3d three.js texture-mapping


    【解决方案1】:

    看到这张图片: http://cgkit.sourceforge.net/tutorials/_images/uvmap.png 如上所述,对于没有纹理重复的 1 个纹理,UV 坐标在 (0,0) 到 (1,1) 的范围内。如果您有一个四边形并将 UV 分配给图像中的顶点,则整个纹理将显示在四边形上。如果您添加边缘循环/镶嵌您的四边形,例如在 4 个较小的四边形中,但仍然希望纹理完全显示而不重复,您需要计算顶点在 UV 空间中的位置之间的值。例如,中间的顶点(由您的镶嵌产生)现在是 UV (0.5, 0.5) 中间顶部的那个是 (0, 0.5)。看看PlaneGeometry是怎么做的,并尝试从中学习^^

    【讨论】:

      猜你喜欢
      • 2017-04-19
      • 2015-01-11
      • 2013-02-14
      • 2019-08-08
      • 1970-01-01
      • 2018-10-20
      • 1970-01-01
      • 2016-08-06
      • 2021-09-28
      相关资源
      最近更新 更多