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和法线贴图)保持独立......或者还有其他方法吗?
一种可能的选择是将第二组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 集时都需要不同的几何体。这可能会对性能产生影响,具体取决于您的应用程序。