带有独立alphamap的3个js纹理贴图UV

问题描述 投票:0回答:2

我有一个大的纹理-照片-和小的简单网格物体,应该显示主要纹理的区域。这些网格物体应具有alphaMap,例如圆形。

在网格材质的纹理(PlaneBufferGeometry)中,我更改了UV贴图,因此它将显示主纹理的正确区域。问题是UV贴图也应用于alphaMap,但我希望它独立。

const planeGeometry = new THREE.PlaneBufferGeometry(sz.x, sz.y);
let uvs= planeGeometry.attributes.uv;
for (let ix = 0; ix< uvs.array.length; ix++){
    let x = uvs.getX(ix);
    let y = uvs.getY(ix);
    uvs.setXY(ix, x*.5, y*.75);   // just testing
}

const planeMaterial = new THREE.MeshPhongMaterial({
    map: imageTexture,
    transparent: true,      
    alphaMap ,
    normalMap,
});

是否有一种方法可以仅更改材质贴图的UV贴图,而使其他贴图(alphaMap和normalMap)保持独立...或者还有其他方法?

three.js texture-mapping
2个回答
2
投票

出于所有意图和目的,@ Marquizzo的回答是正确的。但是,我个人发现使用内置的纹理属性确实很尴尬,并且可能导致UV无法正确对齐的情况。

一个可能的选择是将第二组uv坐标添加到几何中:

// setup new attribute uvs
var uvb = new Float32Array( [
    0.25, 0.75,
    0.75, 0.75,
    0.25, 0.25,
    0.75, 0.25
] );

planeGeometry.setAttribute( 'uvB', new THREE.BufferAttribute( uvb, 2 ) );

并修改材质着色器以使用该组坐标用于颜色贴图纹理:

var planeMaterial = new THREE.MeshPhongMaterial( {
    side: THREE.DoubleSide,
    transparent: true,
    map: colorTex,
    alphaMap: alphaTex,
} );

planeMaterial.onBeforeCompile = function( shader ) {

    // vertex modifications
    var vertex_pars = 'attribute vec2 uvB;\nvarying vec2 vUvB;\n';
    var vertex_uv = shader.vertexShader.replace(
        '#include <uv_vertex>',
        [
            '#include <uv_vertex>',
            'vUvB = uvB;'
        ].join( '\n' )
    );

    shader.vertexShader = vertex_pars + vertex_uv;


    // fragment modifications
    var frag_pars = 'varying vec2 vUvB;\n';
    var frag_uv = shader.fragmentShader.replace(
        '#include <map_fragment>',
        [
            'vec4 texelColor = texture2D( map, vUvB );',
            'texelColor = mapTexelToLinear( texelColor );',
            'diffuseColor *= texelColor;'
        ].join( '\n' )
    );

    shader.fragmentShader = frag_pars + frag_uv;

}

此方法的缺点是,每次要使用不同的uv时,您都需要不同的几何形状。这可能会影响性能,具体取决于您的应用程序。

JSFiddle Example


2
投票

最简单的方法是不使用几何图形uvs,而是在照片纹理上使用一些内置的纹理变换属性。它们是.offset.repeat.rotation。和.center。您可以阅读说明in the docs。例如,如果要将照片纹理缩放到200%,可以使用

imageTexture.repeat.set(0.5, 0.5);

如果您要移动它:

imageTexture.offset.set(0.0, 0.7);

这只会影响imageTexture,而不会留下您的alphaMap纹理。

[.rotation.center一起使用,如果您想更改旋转原点。

© www.soinside.com 2019 - 2024. All rights reserved.