Threejs 纹理贴图 UV 具有独立的 alphamap

tru*_*ru7 1 texture-mapping three.js

我有一个大纹理(一张照片)和一个小的简单网格,它们应该显示主纹理的区域。这些网格应该有一个 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,
});
Run Code Online (Sandbox Code Playgroud)

有没有办法只改变材质贴图的UV贴图,而让其他贴图(alphaMap和法线贴图)保持独立......或者还有其他方法吗?

Sci*_*ode 7

一种可能的选择是将第二组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 ) );
Run Code Online (Sandbox Code Playgroud)

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

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;

}
Run Code Online (Sandbox Code Playgroud)

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

JSFiddle 示例

  • 这些在内部被称为 [ShaderChunks](https://github.com/mrdoob/ Three.js/tree/dev/src/renderers/shaders/ShaderChunk)。现在每种材质都使用不同的着色器块组合,每种材质的实际着色器程序可以在 [ShaderLib](https://github.com/mrdoob/ Three.js/tree/master/src/renderers /着色器/ShaderLib)。 (2认同)
  • 事实证明,大多数材质都使用相同的 UV/Map ShaderChunk 设置,因此这种方法应该适用于大多数材质。这是一个优点,但当然,情况并非总是如此。 (2认同)