我的渲染点的方式来自以下示例:
http://threejs.org/examples/#webgl_interactive_points
即。我使用通过缓冲几何体使用disc.png图像纹理化的点。
但是,当我向场景中添加更多对象(此特定示例中的线条)时,纹理点会消失。如果我从场景中删除这些对象,纹理点会重新出现。
消失的行为是不可预测的:它们有时会显示得恰到好处,有时它们也不会显示出来。如果我在代码中从一个地方生成一个对象,添加该对象会导致纹理点消失,但是如果我以完全相同的方式从代码中的另一个地方生成它,那么一切都很好。
与原始示例中一样,使用以下代码创建点本身:
obj.material = new THREE.ShaderMaterial({
uniforms: {
color: { type: "c", value: new THREE.Color(0xffffff) },
texture: { type: "t", value: new THREE.TextureLoader().load('img/disc.png') }
},
vertexShader: document.getElementById('vertexshader').textContent,
fragmentShader: document.getElementById('fragmentshader').textContent,
alphaTest: 0.9
});
obj.geometry = geometryFromCoordinates([[x1, y1, z1], [x2, y2, z2], ...]);
obj.mesh = new THREE.Points(obj.geometry, obj.material);
其中geometryFromCoordinates
定义为
function geometryFromCoordinates (coordinates, building) {
var helper = geometryFromArray(coordinates);
var positions = new Float32Array(3 * coordinates.length);
var colors = new Float32Array(3 * coordinates.length);
var sizes = new Float32Array(coordinates.length);
for (var i = 0; i < coordinates.length; ++i) {
var vertex = helper.vertices[i];
vertex.toArray(positions, 3*i);
MESH.NODE_COLOR.NORMAL.toArray(colors, i*3);
sizes[i] = MESH.NODE_SIZE.NORMAL;
}
var geometry = new THREE.BufferGeometry();
geometry.addAttribute('position', new THREE.BufferAttribute(positions, 3));
geometry.addAttribute('customColor', new THREE.BufferAttribute(colors, 3));
geometry.addAttribute('size', new THREE.BufferAttribute(sizes, 1));
return geometry;
};
并且geometryFromArray
助手由
function geometryFromArray(vertices) {
var geometry = new THREE.Geometry();
for (var i = 0; i < vertices.length; ++i) {
var v = vertices[i];
geometry.vertices.push(new THREE.Vector3(v[0], v[2], v[1]));
}
return geometry;
};
着色器在html文档的标题中提供,就像在原始示例中一样:
<script type="x-shader/x-vertex" id="vertexshader">
attribute float size;
attribute vec3 customColor;
varying vec3 vColor;
void main() {
vColor = customColor;
vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
gl_PointSize = size * ( 300.0 / -mvPosition.z );
gl_Position = projectionMatrix * mvPosition;
}
</script>
<script type="x-shader/x-fragment" id="fragmentshader">
uniform vec3 color;
uniform sampler2D texture;
varying vec3 vColor;
void main() {
gl_FragColor = vec4( color * vColor, 1.0 );
gl_FragColor = gl_FragColor * texture2D( texture, gl_PointCoord );
if ( gl_FragColor.a < ALPHATEST ) discard;
}
</script>
我添加到场景的线框对象是使用box
和wireframe
函数生成的:
function wireframe(vertices) {
var wireframe = {};
wireframe.geometry = geometryFromArray(vertices);
wireframe.material = new THREE.MeshBasicMaterial({ color : 0x777777});
wireframe.mesh = new THREE.LineSegments(wireframe.geometry, wireframe.material);
return wireframe;
};
function box(X, Y, Z, W, D, H) {
return [
[ X , Y , Z ], [ X , Y ,Z+H],
[ X , Y ,Z+H], [ X ,Y+D,Z+H],
[ X ,Y+D,Z+H], [ X ,Y+D, Z ],
[ X ,Y+D, Z ], [ X , Y , Z ],
[X+W, Y , Z ], [X+W, Y ,Z+H],
[X+W, Y ,Z+H], [X+W,Y+D,Z+H],
[X+W,Y+D,Z+H], [X+W,Y+D, Z ],
[X+W,Y+D, Z ], [X+W, Y , Z ],
[ X , Y , Z ], [X+W, Y , Z ],
[ X ,Y+D, Z ], [X+W,Y+D, Z ],
[ X , Y ,Z+H], [X+W, Y ,Z+H],
[ X ,Y+D,Z+H], [X+W,Y+D,Z+H]
];
};
我生成了很多方框,并使用Array.concat
加入坐标,然后将它们传递给wireframe
函数,然后调用scene.add
:
var vetices = [];
for(var i = 0; i < boxes.length; ++i) {
var b = boxes[i];
vertices.concat(box(b.x, b.y, b.z, b.w, b.d, b.h));
}
var skeleton = wireframe(vertices);
scene.add(skeleton.mesh);
有人可以解释这可能导致这种不当行为的原因以及如何找到解决方法吗?正如我提到的那样,错误的再现是不可预测的,并且已经为我工作了几个月的代码突然停止工作,虽然我没有对它进行任何修改。
另外,我不需要使用纹理,如果我可以用其他方式渲染可点击的圆圈或球体 - 但我需要一些建议,因为我对WebGL知之甚少。
提前致谢