Three.js,自定义着色器和具有透明度的 png 纹理
Three.js, custom shader and png texture with transparency
我有一个非常简单的 PNG 纹理:一个带有透明背景的灰色圆圈。
我用它作为制服 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 );
我将 material 应用于一些粒子(THREE.PointCloud
网格)并且效果很好:
但是如果我将相机旋转超过 180 度,我会看到:
我知道片段着色器没有正确考虑 PNG 纹理的 alpha 值。
在这种情况下,获得正确的颜色和不透明度(从自定义属性)并仍然从 PNG 获得正确的 alpha 的最佳方法是什么?
为什么它在一侧表现正确?
透明对象必须从后向前渲染——从远到近。这是因为深度缓冲区。
但是 PointCloud
粒子不会根据与相机的距离进行排序。那样效率太低了。无论相机位置如何,粒子总是以相同的顺序渲染。
你有几个变通办法。
首先是丢弃 alpha 较低的片段。您可以使用这样的模式:
if ( textureColor.a < 0.5 ) discard;
另一种选择是设置 material.depthTest = false
或 material.depthWrite = false.
但是,如果场景中有其他对象,您可能不喜欢这些副作用。
three.js r.71
我有一个非常简单的 PNG 纹理:一个带有透明背景的灰色圆圈。
我用它作为制服 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 );
我将 material 应用于一些粒子(THREE.PointCloud
网格)并且效果很好:
但是如果我将相机旋转超过 180 度,我会看到:
我知道片段着色器没有正确考虑 PNG 纹理的 alpha 值。
在这种情况下,获得正确的颜色和不透明度(从自定义属性)并仍然从 PNG 获得正确的 alpha 的最佳方法是什么?
为什么它在一侧表现正确?
透明对象必须从后向前渲染——从远到近。这是因为深度缓冲区。
但是 PointCloud
粒子不会根据与相机的距离进行排序。那样效率太低了。无论相机位置如何,粒子总是以相同的顺序渲染。
你有几个变通办法。
首先是丢弃 alpha 较低的片段。您可以使用这样的模式:
if ( textureColor.a < 0.5 ) discard;
另一种选择是设置 material.depthTest = false
或 material.depthWrite = false.
但是,如果场景中有其他对象,您可能不喜欢这些副作用。
three.js r.71