three.js webgl 自定义着色器:如何使用新的偏移量共享纹理

7
我正在将一个1024 x 1024的纹理切割成32x32的32个瓦片,我不确定是否能够使用偏移量共享纹理,还是需要为每个瓦片创建一个具有偏移量的新纹理。
为了创建偏移量,我使用一个统一值= 32 * i,并通过每个循环实例更新统一值以创建瓦片。但所有的瓦片似乎都具有相同的偏移量?因为我想要的是在图像上看起来像是一个图像,而不是分解成小的瓦片。但当前输出中的所有32个瓦片都具有相同的x,y偏移量。我正在使用three.js r71中的顶点着色器...
我是否需要为每个带有偏移量的瓦片创建一个新的纹理呢?
      for ( j = 0; j < row; j ++ ) {

           for ( t = 0; t < col; t ++ ) {

                customUniforms.tX.value = tX; 
                customUniforms.tY.value = tY;
                console.log(customUniforms.tX.value);
                customUniforms.tX.needsUpdate = true;
                customUniforms.tY.needsUpdate = true;
                mesh = new THREE.Mesh( geometry,mMaterial);// or new material
           }
       }

       //vertex shader :
       vec2 uvOffset = vUV + vec2( tX, tY) ;    

图片示例:

在此输入图片描述

每个图像应该有10或20像素的偏移量,但它们都是一样的...这是由于使用一个纹理造成的。

如建议所述,我已经尝试操作每个对象上的UV,但没有成功,似乎会使所有相同的顶点具有相同的位置,例如10×10细分平面所有面都将相同。

    var geometry = [
    [ new THREE.PlaneGeometry( w, w ,64,64),50 ],
    [ new THREE.PlaneGeometry( w, w ,40,40), 500 ],
    [ new THREE.PlaneGeometry( w, w ,30,30), 850 ],
    [ new THREE.PlaneGeometry( w, w,16,16 ), 1200 ]
];

    geometry[0][0].faceVertexUvs[0] = [];

    for(var p = 0; p < geometry[0][0].faces.length; p++){ 
        geometry[0][0].faceVertexUvs[0].push([
        new THREE.Vector2(0.0, 0.0),
        new THREE.Vector2(0.0, 1),
        new THREE.Vector2( 1, 1 ), 
        new THREE.Vector2(1.0, 0.0)]);  
    }

如果您查看此结果的图像,您会注意到所有顶点都相同,而它们不应该是相同的。

enter image description here

再次更新: 我必须检查每个面的顶点,因为两个三角形组成一个四边形,以避免上述问题,我认为我可能已经解决了这个问题...将进行更新

最后一次更新: 下面是源代码,但我迷失在使算法按预期显示纹理方面。

            /*
            j and t are rows & columns looping by 4x4 grid
            row = 4 col = 4;
            */

            for( i = 0; i < geometry.length; i ++ ) {
            var mesh = new THREE.Mesh( geometry[ i ][ 0 ], customMaterial);
            mesh.geometry.computeBoundingBox();
            var max     =  mesh.geometry.boundingBox.max;
            var min     =  mesh.geometry.boundingBox.min;
            var offset  = new THREE.Vector2(0 - min.x*t*j+w, 0- min.y*j+w);//here is my issue
            var range   = new THREE.Vector2(max.x - min.x*row*2, max.y - min.y*col*2);
            mesh.geometry.faceVertexUvs[0] = [];
            var faces =  mesh.geometry.faces;

            for (p = 0; p <  mesh.geometry.faces.length ; p++) {
                var v1 =  mesh.geometry.vertices[faces[p].a];
                var v2 =  mesh.geometry.vertices[faces[p].b];
                var v3 =  mesh.geometry.vertices[faces[p].c];
                mesh.geometry.faceVertexUvs[0].push([
                new THREE.Vector2( ( v1.x + offset.x ) / range.x , ( v1.y + offset.y ) / range.y ),
                new THREE.Vector2( ( v2.x + offset.x ) / range.x , ( v2.y + offset.y ) / range.y ),
                new THREE.Vector2( ( v3.x + offset.x ) / range.x , ( v3.y + offset.y ) / range.y )
                ]);

            }

你会注意到下面这张红色的图片边缘是无缝连接的,而其他贴图没有与其对齐。 enter image description here

32个瓷砖,但都带有偏移量,我会上传一张图片... - Careen
每个瓷砖都有单独的材质吗?如果它们使用相同的材质,您需要在渲染循环中设置偏移量,而不是在创建时设置。 - Brendan Annable
偏移量似乎发生了变化,但对纹理本身没有影响。很难调试。 - Careen
我会尝试翻译,然后将结果发送给您。 - Careen
你有什么想法吗?因为循环在一个页面上,而渲染在另一个页面上。我该如何告诉渲染器每个瓷砖都要更新内部的uniforms呢? - Careen
显示剩余10条评论
1个回答

3

这里是答案:

      var offset  = new THREE.Vector2(w - min.x-w+(w*t), w- min.y+w+(w*-j+w));
      var range   = new THREE.Vector2(max.x - min.x*7, max.y - min.y*7);

如果您能简化答案,我们会给予 bounty 奖励:

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接