Webgl 无法使用regl在Z方向打印点
我从regl开始,我试着做一个小演示,在所有三个轴上绘制点。我一开始就用这个 在上面的示例中,点被初始化为Webgl 无法使用regl在Z方向打印点,webgl,regl,Webgl,Regl,我从regl开始,我试着做一个小演示,在所有三个轴上绘制点。我一开始就用这个 在上面的示例中,点被初始化为 const points = d3.range(numPoints).map(i => ({ x: //Code, y: //Code, color: [1, 0, 0], })); 我把它修改成下面的那个,得到一个无限大的螺旋 const points = d3
const points = d3.range(numPoints).map(i => ({
x: //Code,
y: //Code,
color: [1, 0, 0],
}));
我把它修改成下面的那个,得到一个无限大的螺旋
const points = d3.range(numPoints).map(i => ({
x: 200+radius*Math.cos(i*Math.PI/180),
y: 200+radius*Math.sin(i*Math.PI/180),
z: i,
color: [1, 0, 0],
}));
我修改了顶点着色器以考虑附加轴。以下是绘制点的代码
const drawPoints = regl({
frag:`
precision highp float;
varying vec3 fragColor;
void main()
{
gl_FragColor = vec4(fragColor, 1);
}
`,
vert:`
attribute vec3 position;
attribute vec3 color;
varying vec3 fragColor;
uniform float pointWidth;
uniform float stageWidth;
uniform float stageHeight;
uniform float stageDepth;
vec3 normalizeCoords(vec3 position)
{
float x = position[0];
float y = position[1];
float z = position[2];
return vec3(2.0 * ((x / stageWidth) - 0.5),-(2.0 * ((y / stageHeight) - 0.5)),1.0 * ((z / stageDepth) - 0.0));
}
void main()
{
gl_PointSize = pointWidth;
fragColor = color;
gl_Position = vec4(normalizeCoords(position), 1.0);
}
`,
attributes:
{
position: points.map(d => [d.x, d.y, d.z]),
color: points.map(d => d.color),
},
uniforms:
{
pointWidth: regl.prop('pointWidth'),
stageWidth: regl.prop('stageWidth'),
stageHeight: regl.prop('stageHeight'),
stageDepth: regl.prop('stageDepth'),
},
count: points.length,
depth:
{
enable: true,
mask: true,
func: 'less',
range: [0, 1]
},
primitive: 'points',
});
frameLoop = regl.frame(() => {
// clear the buffer
regl.clear({
// background color (black)
color: [0, 0, 0, 1],
depth: 1,
});
drawPoints({
pointWidth,
stageWidth: width,
stageHeight: height,
});
if (frameLoop) {
frameLoop.cancel();
}
});
但结果是在同一平面上绘制了一个圆。该位置的第三个输入似乎没有任何效果。我试着在这个位置交换y和z值,得到了一条正弦曲线。所以z的值被正确地分配了。我注意到的另一件事是,如果z的值为零,则不会绘制任何图形。z的任何其他值似乎都不会产生任何效果 添加的
z
坐标无效的原因是当前渲染管道中没有“深度投影”的概念
通常,将这些3D顶点位置映射到2D屏幕时,需要将“投影矩阵”添加到渲染管道中,以说明顶点中的z
坐标
通过使用类似于canvas-orbit-camera
模块的东西,您应该能够非常简单地添加此投影。一旦将该模块添加到项目中,就考虑对代码进行以下调整(见添加[Ad]标记的注释):
希望这有帮助
// Your init code ..
// [Add] Register camera middleware with canvas
const camera = require('canvas-orbit-camera')(canvas)
// Your init code ..
const drawPoints = regl({
frag:`
precision highp float;
varying vec3 fragColor;
void main()
{
gl_FragColor = vec4(fragColor, 1);
}
`,
vert:`
attribute vec3 position;
attribute vec3 color;
varying vec3 fragColor;
uniform float pointWidth;
uniform float stageWidth;
uniform float stageHeight;
uniform float stageDepth;
uniform mat4 proj; // [Add] Projection matrix uniform
vec3 normalizeCoords(vec3 position)
{
float x = position[0];
float y = position[1];
float z = position[2];
return vec3(2.0 * ((x / stageWidth) - 0.5),-(2.0 * ((y / stageHeight) - 0.5)),1.0 * ((z / stageDepth) - 0.0));
}
void main()
{
gl_PointSize = pointWidth;
fragColor = color;
gl_Position = proj * vec4(normalizeCoords(position), 1.0); // [Add] Multiply vertex by projection matrix
}
`,
attributes:
{
position: points.map(d => [d.x, d.y, d.z]),
color: points.map(d => d.color),
},
uniforms:
{
pointWidth: regl.prop('pointWidth'),
stageWidth: regl.prop('stageWidth'),
stageHeight: regl.prop('stageHeight'),
stageDepth: regl.prop('stageDepth'),
// [Add] Projection matrix calculation
proj: ({viewportWidth, viewportHeight}) =>
mat4.perspective([],
Math.PI / 2,
viewportWidth / viewportHeight,
0.01,
1000),
},
count: points.length,
depth:
{
enable: true,
mask: true,
func: 'less',
range: [0, 1]
},
primitive: 'points',
});
frameLoop = regl.frame(() => {
// clear the buffer
regl.clear({
// background color (black)
color: [0, 0, 0, 1],
depth: 1,
});
// [Add] Camera re computation
camera.tick()
drawPoints({
pointWidth,
stageWidth: width,
stageHeight: height,
});
if (frameLoop) {
frameLoop.cancel();
}
});