在WebGL中每次绘制调用都可以运行一次代码吗?

时间:2017-01-30 09:49:15

标签: glsl webgl vertex-shader

我在NTNU参加WebGL课程。我目前正在探索着色器的作用以及如何使用它们。

我们的一个例子向我们展示了我们计算投影矩阵,然后在顶点着色器中设置它,然后进行绘制调用。我想尝试在着色器中进行这种矩阵计算。

这意味着我必须将代码放在顶点着色器中除main()函数之外的其他位置,因为每个绘制调用会多次调用该代码。

顶点着色器:

uniform vec3 camRotation;
attribute vec3 position;
void main() {

    // I want this code to run only once per draw call
    float rX = camRotation[0];
    float rY = camRotation[1];
    float rZ = camRotation[2];
    mat4 camMatrix = mat4(
        cos(rY) * cos(rZ), cos(rZ) * sin(rX) * sin(rY) - cos(rX) * sin(rZ), sin(rX) * sin(rZ) + cos(rX) * cos(rZ) * sin(rY), 0, //
        cos(rY) * sin(rZ), cos(rX) * cos(rZ) + sin(rX) * sin(rY) * sin(rZ), cos(rX) * sin(rY) * sin(rZ) - cos(rZ) * sin(rX), 0, //
        -sin(rY), cos(rY) * sin(rX), cos(rX) * cos(rY), 0, //
        0, 0, 0, 1
    );
    // End of code in question

    gl_Position = camMatrix * vec4(position, 1);
    gl_PointSize = 5.0;
}

有可能吗?我是个傻瓜吗?

2 个答案:

答案 0 :(得分:3)

AFAIK,没有办法做到这一点。您应该在JS代码中计算Traceback (most recent call last): File "python", line 8, in <module> File "python", line 6, in functionA NameError: name 'self' is not defined 并通过uniform:

将其传递给着色器
camMatrix

现在你需要在JS中计算矩阵:

uniform mat4 camMatrix;
attribute vec3 position;
void main() {
    gl_Position = camMatrix * vec4(position, 1);
    gl_PointSize = 5.0;
}

答案 1 :(得分:2)

不可能,着色器的整个概念是可矢量化的,因此它们可以并行运行。即使你可能没有太大的收益,因为GPU的速度优势(除了其他东西)固有地基于其并行执行计算的能力。除此之外,通常你有一个组合的视图投影矩阵,在所有绘制调用(帧)和附加到你正在绘制的每个对象的模型/世界矩阵中保持静态。

投影矩阵的名称意味着以透视或正交方式投影点(您可以将其视为相机的镜头)。 视图矩阵是用于平移/旋转投影(相机位置和方向)的变换,而每个对象的世界/模型矩阵包含单个对象的变换(平移,旋转和缩放)。

在着色器中,然后使用每个对象的模型/世界矩阵将顶点位置转换为世界空间,然后使用预乘的ViewProjection矩阵将其转换为相机空间:

gl_Position = matViewProjection * (matWorld * vPosition)

当您根据用例绘制点数时,可以将世界矩阵缩减为只是一个平移向量。