首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >不能使用regl绘制Z方向的点

不能使用regl绘制Z方向的点
EN

Stack Overflow用户
提问于 2018-09-23 23:10:00
回答 1查看 77关注 0票数 2

我从regl开始,我试图为所有三个轴的绘图点制作一个小演示。首先,我使用了这个链接

在上面的例子中,这些点被初始化为

代码语言:javascript
复制
const points = d3.range(numPoints).map(i => ({
                x: //Code,
                y: //Code,
                color: [1, 0, 0],
            }));

我把它修改成下面的那个,得到一个进入无穷远的螺旋。

代码语言:javascript
复制
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],
            }));

我修改了顶点着色器,以考虑额外的轴线。下面是绘制点的代码

代码语言:javascript
复制
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的任何其他值似乎都不会产生任何效果。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-09-24 00:20:14

添加的z坐标没有效果的原因是,当前呈现管道中没有“深度投影”的概念。

通常,当将这些3D顶点位置映射到2D屏幕时,您需要向渲染管道中添加一个“投影矩阵”,该管道将考虑顶点中的z坐标。

您应该能够通过使用类似于canvas-orbit-camera模块的东西来公平地添加这个投影。一旦将该模块添加到项目中,请考虑对代码进行以下调整(请参阅带有Add标记的注释):

代码语言:javascript
复制
// 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();
    }
});

希望这能有所帮助!

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52471045

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档