仅从纹理渲染Alpha值

时间:2018-04-22 07:27:15

标签: three.js

我想要做的是在使用材质的颜色渲染RGB时加载仅包含PNG图片的alpha值的纹理。为了给你一些上下文,我使用它来进行GPU选择以查找被点击的精灵。这样我就可以知道是否点击了精灵,或者用户是否点击了精灵的透明部分。

我尝试使用THREE.AlphaFormat格式,我尝试了所有类型但是 我得到的是具有正确alpha的精灵,但纹理的颜色与材质的颜色相结合。

这是我到目前为止尝试的代码

var type = THREE.UnsignedByteType;
var spriteMap = new THREE.TextureLoader().load( url );
spriteMap.format = THREE.AlphaFormat;
spriteMap.type = type;

var spriteMaterial = new THREE.SpriteMaterial( { map: spriteMap , color: idcolor.getHex() } ); //

var sprite = new THREE.Sprite( spriteMaterial );

sprite.position.set( this.position.x , this.position.y , this.position.z );
sprite.scale.set( this.scale.x , this.scale.y , this.scale.z );

Selection.GpuPicking.pickingScene.add( sprite );

关于如何实现这一目标的任何想法?

three.js r.91

1 个答案:

答案 0 :(得分:0)

我没有设法通过组合纹理和材料来做我想要的事情。我的解决方案是创建一个平面并添加我自己的自定义着色器来处理Sprite功能。我从three.js库复制了sprite的着色器并删除了我不需要的代码,因为我只需要正确的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;

}