我使用three.js创建交互式数据可视化。此可视化涉及渲染68000个节点,其中每个不同的节点具有不同的大小和颜色。
最初我试图通过渲染网格来做到这一点,但事实证明这非常昂贵。我目前的尝试是使用three.js粒子系统,每个点都是可视化中的一个节点。
我可以控制点的颜色*大小,但只能控制到某一点。在我的卡上,gl点的最大大小似乎是63.当我放大到可视化时,点变得更大 - 到一个点,然后保持在63像素。
我正在使用顶点&片段着色器目前:
顶点着色器:
attribute float size;
attribute vec3 ca;
varying vec3 vColor;
void main() {
vColor = ca;
vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
gl_PointSize = size * ( 300.0 / length( mvPosition.xyz ) );
gl_Position = projectionMatrix * mvPosition;
}
片段着色器:
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 );
}
这些几乎是从三个.js例子之一逐字复制的。
我对GLSL很新,但我正在寻找一种方法来绘制大于63像素的点。我可以为大于特定大小的任何点绘制网格物体,但是否则使用gl_point?有没有其他的解决办法可以用来绘制大于63像素的点?
答案 0 :(得分:4)
你可以通过制作单位四边形阵列+中心点然后在GLSL中按尺寸扩展来制作自己的点系统。
所以,你有2个缓冲区。一个缓冲区只是一个2D单元,重复了你想要绘制的点数。
var unitQuads = new Float32Array([
-0.5, 0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5,
-0.5, 0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5,
-0.5, 0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5,
-0.5, 0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5,
-0.5, 0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5,
];
第二个是你的分数,除了需要重复4次的位置
var points = new Float32Array([
p1.x, p1.y, p1.z, p1.x, p1.y, p1.z, p1.x, p1.y, p1.z, p1.x, p1.y, p1.z,
p2.x, p2.y, p2.z, p2.x, p2.y, p2.z, p2.x, p2.y, p2.z, p2.x, p2.y, p2.z,
p3.x, p3.y, p3.z, p3.x, p3.y, p3.z, p3.x, p3.y, p3.z, p3.x, p3.y, p3.z,
p4.x, p4.y, p4.z, p4.x, p4.y, p4.z, p4.x, p4.y, p4.z, p4.x, p4.y, p4.z,
p5.x, p5.y, p5.z, p5.x, p5.y, p5.z, p5.x, p5.y, p5.z, p5.x, p5.y, p5.z,
]);
设置缓冲区和属性
var buf = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buf);
gl.bufferData(gl.ARRAY_BUFFER, unitQuads, gl.STATIC_DRAW);
gl.enableVertexAttribArray(unitQuadLoc);
gl.vertexAttribPointer(unitQuadLoc, 2, gl.FLOAT, false, 0, 0);
var buf = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buf);
gl.bufferData(gl.ARRAY_BUFFER, points, gl.STATIC_DRAW);
gl.enableVertexAttribArray(pointLoc);
gl.vertexAttribPointer(pointLoc, 3, gl.FLOAT, false, 0, 0);
在您的GLSL着色器中,计算您想要的gl_PointSize,然后在视图空间或屏幕空间中将unitQuad乘以该大小。屏幕空间与gl_Point的作用相匹配,但人们通常希望他们的点在3D中缩放,就像普通的东西一样,在这种情况下,视图空间就是你想要的。
attribute vec2 a_unitQuad;
attribute vec4 a_position;
uniform mat4 u_view;
uniform mat4 u_viewProjection;
void main() {
float fake_gl_pointsize = 150;
// Get the xAxis and yAxis in view space
// these are unit vectors so they represent moving perpendicular to the view.
vec3 x_axis = view[0].xyz;
vec3 y_axis = view[1].xyz;
// multiply them by the desired size
x_axis *= fake_gl_pointsize;
y_axis *= fake_gl_pointsize;
// multiply them by the unitQuad to make a quad around the origin
vec3 local_point = vec3(x_axis * a_unitQuad.x + y_axis * a_unitQuad.y);
// add in the position you actually want the quad.
local_point += a_position;
// now do the normal math you'd do in a shader.
gl_Position = u_viewProjection * local_point;
}
我不确定这有什么意义,但有更复杂但a working sample here
答案 1 :(得分:0)
我可以为大于特定大小的任何点绘制网格物体,但是否则使用gl_point?
不在WebGL中。
您可以将粒子系统绘制为一系列四边形(即:两个三角形)。但就是这样。