我没有设法通过结合纹理和材料来做我想做的事。我的解决方案是创建一个平面并添加我自己的自定义着色器来处理 Sprite 功能。我从 three.js 库中复制了精灵的着色器并删除了我不需要的代码,因为我只需要正确的 alpha 和一种可见的颜色。
我的代码用于创建一个精灵,颜色来自材质,alpha 值来自纹理
//Create the position, scale you want for your sprite and add the url to your texture
var spriteMap = new THREE.TextureLoader().load( url , function( texture ){
var geometry = new THREE.PlaneGeometry( 1.0, 1.0 );
uniforms = {
color: {type:"v3", value: color },
map: {value: texture },
opacity: {type:"f", value: 1.0 },
alphaTest: {type:"f", value: 0.0 },
scale: {type:"v3", value: scale }
};
var material = new THREE.ShaderMaterial(
{
uniforms: uniforms,
vertexShader: vertexShader, //input the custom shader here
fragmentShader: fragmentShader, //input the custom shader here
transparent: true,
});
var mesh = new THREE.Mesh( geometry, material );
mesh.position.set( position.x , position.y , position.z );
mesh.scale.set( scale.x , scale.y ,sprite.scale.z );
scene.add(mesh);
} );
这是我的顶点着色器:
uniform vec3 scale;
varying vec2 vUV;
void main() {
float rotation = 0.0;
vUV = uv;
vec3 alignedPosition = position * scale;
vec2 rotatedPosition;
rotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;
rotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;
vec4 mvPosition;
mvPosition = modelViewMatrix * vec4( 0.0, 0.0 , 0.0 , 1.0 );
mvPosition.xy += rotatedPosition;
gl_Position = projectionMatrix * mvPosition;
}
我的片段着色器:
varying vec2 vUV;
uniform vec3 color;
uniform sampler2D map;
uniform float opacity;
uniform float alphaTest;
void main() {
vec4 texture = texture2D( map, vUV );
//showing the color from material, but uses alpha from texture
gl_FragColor = vec4( color , texture.a * opacity );
if ( gl_FragColor.a < alphaTest ) discard;
}