Three.js,自定义着色器和具有透明度的png纹理

时间:2015-06-24 21:15:57

标签: three.js png textures shader fragment-shader

我有一个非常简单的PNG纹理:一个带有透明背景的灰色圆圈。

PNG image with transparency

我将其用作.directive('ratehome',function(){ return { restrict:"E", template: "<div id='rateYo'></div>", link: function(scope, ele, attrs){ $scope.$watch('recentArtist',function(newValue,oldValue){ console.log("NEW",newValue) }); } } }) 的统一map

THREE.ShaderMaterial

这是我的片段着色器(只是其中的一部分):

var uniforms = THREE.UniformsUtils.merge( [basicShader.uniforms] );
uniforms['map'].value = THREE.ImageUtils.loadTexture( "img/particle.png" );
uniforms['size'].value = 100;
uniforms['opacity'].value = 0.5;
uniforms['psColor'].value = new THREE.Color( 0xffffff );

我将材质应用于某些粒子(gl_FragColor = vec4( psColor, vOpacity ); gl_FragColor = gl_FragColor * texture2D( map,vec2( gl_PointCoord.x, 1.0 - gl_PointCoord.y ) ); gl_FragColor = gl_FragColor * vec4( vColor, 1.0 ); 网格)并且效果很好:

Particles texture with transparency: OK!

但如果我将相机旋转超过180度,我会看到:

Particles texture without transparency

据我所知,片段着色器没有正确考虑PNG纹理的alpha值。

在这种情况下,为了获得正确的颜色和不透明度(来自自定义属性)并且仍然从PNG获得alpha权限,最佳方法是什么?

为什么一方面表现正常?

1 个答案:

答案 0 :(得分:10)

必须从后到前渲染透明对象 - 从最远到最近。这是因为深度缓冲区。

PointCloud粒子不会根据与相机的距离进行排序。那效率太低了。无论相机位置如何,粒子始终以相同的顺序渲染。

你有几种解决方法。

首先是丢弃alpha低的片段。你可以使用这样的模式:

if ( textureColor.a < 0.5 ) discard;

另一种选择是设置material.depthTest = falsematerial.depthWrite = false.您可能不喜欢副作用,但是,如果场景中有其他对象。

three.js r.71