(Three.js)自定义网UV贴图显示正确 [英] (Three.js) Custom Mesh UV Display Texture Properly

查看:5611
本文介绍了(Three.js)自定义网UV贴图显示正确的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个自定义的几何函数Three.js的基础上,平面几何。 一切正常,只是我不知道如何正确地使UV显示。 我用每平方4个三角形,而THREE.PlaneGeometry只用2个三角形每平方米。

在$ C $下PlaneGeometry紫外线的长相是这样的:

  VAR UVA =新THREE.Vector2(IX /为gridx,1  -  IZ / gridZ);
VAR UVB =新THREE.Vector2(IX /为gridx,1  - (IZ + 1)/ gridZ);
变种UVC =新THREE.Vector2((九+ 1)/的gridx,1  - (IZ + 1)/ gridZ);
VAR UVD =新THREE.Vector2((IX + 1)/为gridx,1  -  IZ / gridZ);
 

和我的code的来源$ C ​​$ C:

  VAR UVA =新THREE.Vector2(一);
VAR UVB =新THREE.Vector2(B);
VAR UVC =新THREE.Vector2(C);
VAR UVD =新THREE.Vector2(D);
VAR UVE =新THREE.Vector2(E);
 

显然,这是错误的。但我曾尝试使用PlaneGeometry code,我也得到奇怪的扭曲,我不知道如何计算正确的位置。 这:

  VAR UVA =新THREE.Vector2(IX /为gridx,1  -  IZ / gridZ);
VAR UVB =新THREE.Vector2(IX /为gridx,1  - (IZ + 1)/ gridZ);
变种UVC =新THREE.Vector2((九+ 1)/的gridx,1  - (IZ + 1)/ gridZ);
VAR UVD =新THREE.Vector2(((九)/为gridx)+的gridx,1  -  IZ / gridZ);
VAR UVE =新THREE.Vector2((IX + 1)/为gridx,1  -  IZ / gridZ);
 

给我这个: BAD UV

我得到了某种形式的THREE.JS聊天室的答案,但我不明白,而该人并没有详细说明......

  

(Q)所以..是在Vector2用于UV不是应该是相同的位置verticies?

     

(一)无紫外线是映射到你的纹理矢量   有一个512×512的质地,并且与[0.25,0.75]紫外线,这将映射到   在纹理256象素,768每个顶点有一个紫外线   这意味着,这个顶点映射到纹理像上面说明    这为顶点的每个面进行,而在所有片段   脸,然后用内插这三个乌布苏

所以,这并不能消除我的困惑。我不明白[0.25,0.75]部分。或者说,每个顶点有纹理。如何才能点有质感。

有人能指出我朝着正确的方向吗? 所有我需要的是知道UV如何定位。但是,一个例子将是巨大的。

下面是如果你想看看源:

  THREE.DiamondGeometry =功能(宽度,高度,widthSegments,heightSegments){

    THREE.Geometry.call(本);

    this.width =宽度;
    this.height =身高;

    this.widthSegments = widthSegments || 1;
    this.heightSegments = heightSegments || 2;

    变种long_row = this.widthSegments + 1;
    VAR short_row = this.widthSegments;
    //第一行是long_row,三元语句将切换此。
    VAR current_row = short_row;
    变种gridY = 0;
    VAR VX =宽度/ 2,VY =身高/ 2;

    VAR IX,IZ;
    变种width_half =宽度/ 2;
    VAR height_half =身高/ 2;

    VAR的gridx = this.widthSegments;
    VAR gridZ = this.heightSegments;

    VAR gridX1 =为gridx + 1;
    变种gridZ1 = gridZ +(gridZ  -  2)+ 1;

    VAR segment_width = this.width /为gridx;
    VAR segment_height = this.height / gridZ;

    变种正常=新THREE.Vector3(0,0,1);
                     //高度分段Verticies
    为(IZ = 0; IZ≤(gridZ1 + 1)* 2; IZ ++){
        //三元运算符:
        current_row === long_row? (current_row = short_row,VX = width_half  - (segment_width / 2)):(current_row = long_row,VX = width_half);
                        //宽段Verticies
        对于(九= 0;九< current_row;九++){

            VAR X = IX * segment_width  -  VX;
            变种Y =(IZ * segment_height  -  VY)/ 2  - (VY / 2);

            this.vertices.push(新THREE.Vector3(X, -  Y,0));
        }
    }

    为(IZ = 0; IZ&所述; gridZ; IZ ++){

            对于(九= 0;九<为gridx;九++){
                VAR一个= IX +的gridx * IZ +(IZ * gridX1);
                变种B = A + 1;
                变种C = A + gridX1;
                变种D = C +的gridx;
                变种E = D + 1;

                //这是我需要计算UV职位坏的部分:
                VAR UVA =新THREE.Vector2(一);
                VAR UVB =新THREE.Vector2(B);
                VAR UVC =新THREE.Vector2(C);
                VAR UVD =新THREE.Vector2(D);
                VAR UVE =新THREE.Vector2(E);



                // 向上
                VAR面=新THREE.Face3(C,B,A);
                face.normal.copy(正常);
                face.vertexNormals.push(normal.clone(),normal.clone(),normal.clone());

                this.faces.push(面);
                this.faceVertexUvs [0] .push([UVA,UVB,UVC]);

                // 向下
                FACE =新THREE.Face3(E,C,D);
                face.normal.copy(正常);
                face.vertexNormals.push(normal.clone(),normal.clone(),normal.clone());

                this.faces.push(面);
                this.faceVertexUvs [0] .push([UVD,uvc.clone(),UVE]);

                // 剩下
                FACE =新THREE.Face3(D,C,A);
                face.normal.copy(正常);
                face.vertexNormals.push(normal.clone(),normal.clone(),normal.clone());

                this.faces.push(面);
                this.faceVertexUvs [0] .push([uva.clone(),uvc.clone(),uvd.clone()]);

                // 对
                FACE =新THREE.Face3(E,B,C);
                face.normal.copy(正常);
                face.vertexNormals.push(normal.clone(),normal.clone(),normal.clone());

                this.faces.push(面);
                this.faceVertexUvs [0] .push([uvc.clone(),uvb.clone(),uve.clone()]);

            }

    }

    this.computeCentroids();

};

THREE.DiamondGeometry.prototype = Object.create(THREE.Geometry.prototype);
 

解决方案

看到这样的图片: http://cgkit.sourceforge.net/tutorials/_images/uvmap.png 如上所述那里,为1的质地而没有纹理重复,紫外坐标是在范围从(0,0)至(1,1)。如果你有一个四平面和分配的UV到顶点的形象,整机质感被显示在四。如果添加边循环/ tesselate的四例如在4小四边形,但仍希望有纹理不重复compeltely显示,您需要计算的值,其中顶点是在紫外线的空间。例如顶点在中间(从镶嵌的结果)现在是UV(0.5,0.5) 和一个在在MIDDL的顶部是(0,0.5)。见PlaneGeometry是怎么做的,并尝试从中吸取教训^ ^

I have created a custom Geometry function for Three.js, based on the Plane Geometry. Everything works fine, except that I don't know how to make the UV display correctly. I use 4 triangles per Square, while the THREE.PlaneGeometry is only using 2 triangles per square.

The code for PlaneGeometry UV's looks like this:

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 );

And my Code in the Source Code:

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 );

Obviously that is wrong. But I have tried to use the PlaneGeometry code, and I get odd distortions, and I am not sure how to calculate the proper positions. This:

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 );

Gives me this: BAD UV

I got some sort of answer in the THREE.JS ChatRoom, but I did not understand it, and the person did not elaborate...

(Q) So.. are the Vector2 for UV's not supposed to be the same position as the verticies ?

(A) no an UV is a vector that maps into a texture if you have a 512x512 texture, and an UV with [0.25, 0.75], it would map to the pixel in the texture at 256, 768 each vertex has an uv this means that this vertex maps into the texture like explained above this is done for each face of a vertex, and all fragments in the face are then interpolated using those three uvs

So that did not remove my confusion.. I did not understand the [0.25, 0.75] part. Or that every vertex has a texture. How can a point have a texture.

Could someone point me in the right direction please ? All I need is to know how the UV is positioned. But an example would be great.

Here is the source if you would like to take a look:

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 );

解决方案

see this image: http://cgkit.sourceforge.net/tutorials/_images/uvmap.png As noted there, for 1 texture without texture repeat, UV coordinates are in the range from (0,0) to (1,1). If you have a quad-plane and assign the UVs to the vertices as in the image, the whole texture gets displayed on the quad. if you add edge loops/ tesselate your quad for example in 4 smaller quads but still want to have the texture compeltely displayed without repetition, you need to calculate values in between for where the vertices are in UV-space. for example the vertex in the middle (resulting from your tesselation) is now UV (0.5, 0.5) and the one at the top in the middl is (0, 0.5). See how PlaneGeometry does it and try to learn from it^^

这篇关于(Three.js)自定义网UV贴图显示正确的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆