Three.js,自定义着色器和具有透明性的png纹理 [英] Three.js, custom shader and png texture with transparency

查看:864
本文介绍了Three.js,自定义着色器和具有透明性的png纹理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have an extremely simple PNG texture: a grey circle with a transparent background.

我将它用作THREE.ShaderMaterial的统一map:

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 );

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

Here is my fragment shader (just part of it):

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 );

我将材料应用于一些粒子(THREE.PointCloud网格),并且效果很好:

I applied the material to some particles (THREE.PointCloud mesh) and it works quite well:

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

But if i turn the camera of more than 180 degrees I see this:

我知道片段着色器没有正确考虑PNG纹理的alpha值.

I understand that the fragment shader is not correctly taking into account the alpha value of the PNG texture.

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

What is the best approach in this case, to get the right color and opacity (from custom attributes) and still get the alpha right from the PNG?

为什么它的一侧表现正确?

And why is it behaving correctly on one side?

推荐答案

透明对象必须从后到前呈现-从最远到最远.这是因为有深度缓冲.

Transparent objects must be rendered from back to front -- from furthest to closest. This is because of the depth buffer.

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

But PointCloud particles are not sorted based on distance from the camera. That would be too inefficient. The particles are always rendered in the same order, regardless of the camera position.

您有几种解决方法.

第一个是丢弃alpha值较低的片段.您可以使用类似这样的模式:

The first is to discard fragments for which the alpha is low. You can use a pattern like so:

if ( textureColor.a < 0.5 ) discard;

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

Another option is to set material.depthTest = false or material.depthWrite = false. You might not like the side effects, however, if you have other objects in the scene.

three.js r.71

three.js r.71

这篇关于Three.js,自定义着色器和具有透明性的png纹理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆