我将使用ShaderMaterial以单个PointCloud中使用多个纹理。我会向着色器传递一个纹理数组以及纹理索引属性,并在片段着色器中选择要使用的适当纹理。
问题是一些点(那些使用纹理索引高于0的点)闪烁,原因不明。其他尝试看起来也会在不透明度和纹理之间闪烁。
可以在http://jsfiddle.net/6qrubbk6/4/上看到这个问题的示例。
我在多个项目中都放弃了解决此问题,但我很想找到一个彻底的解决方案。非常感谢任何帮助。
编辑:检查vTexIndex是否小于n,而不是等于n,可以解决这个问题。
相关设置代码:
var particleCount = 100;
var uniforms = {
textures: {
type: 'tv',
value: this.getTextures()
}
};
var attributes = {
texIndex: {
type: 'f',
value: []
},
color: {
type: 'c',
value: []
},
};
var material = new THREE.ShaderMaterial({
uniforms: uniforms,
attributes: attributes,
vertexShader: document.getElementById('vertexShader').textContent,
fragmentShader: document.getElementById('fragmentShader').textContent,
transparent: true
});
var geometry = new THREE.Geometry();
for (var i = 0; i < particleCount; i++) {
geometry.vertices.push(new THREE.Vector3(
(Math.random() - 0.5) * 50, (Math.random() - 0.5) * 50, (Math.random() - 0.5) * 50));
attributes.texIndex.value.push(Math.random() * 3 | 0);
attributes.color.value.push(new THREE.Color(0xffffff));
}
var particles = new THREE.PointCloud(geometry, material);
particles.sortParticles = true;
this.container.add(particles);
顶点着色器:
attribute vec3 color;
attribute float texIndex;
varying vec3 vColor;
varying float vTexIndex;
void main() {
vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);
vColor = color;
vTexIndex = texIndex;
gl_PointSize = 50.0;
gl_Position = projectionMatrix * mvPosition;
}
片元着色器:
uniform sampler2D textures[3];
varying vec3 vColor;
varying float vTexIndex;
void main() {
vec4 startColor = vec4(vColor, 1.0);
vec4 finalColor;
if (vTexIndex == 0.0) {
finalColor = texture2D(textures[0], gl_PointCoord);
} else if (vTexIndex == 1.0) {
finalColor = texture2D(textures[1], gl_PointCoord);
} else if (vTexIndex == 2.0) {
finalColor = texture2D(textures[2], gl_PointCoord);
}
gl_FragColor = startColor * finalColor;
}
问题是一些点(那些使用纹理索引高于0的点)闪烁,原因不明。其他尝试看起来也会在不透明度和纹理之间闪烁。
可以在http://jsfiddle.net/6qrubbk6/4/上看到这个问题的示例。
我在多个项目中都放弃了解决此问题,但我很想找到一个彻底的解决方案。非常感谢任何帮助。
编辑:检查vTexIndex是否小于n,而不是等于n,可以解决这个问题。
if (vTexIndex < 0.5) {
finalColor = texture2D(textures[0], gl_PointCoord);
} else if (vTexIndex < 1.5) {
finalColor = texture2D(textures[1], gl_PointCoord);
} else if (vTexIndex < 2.5) {
finalColor = texture2D(textures[2], gl_PointCoord);
}
As seen here: http://jsfiddle.net/6qrubbk6/5/