I'm taking a course in WebGL at NTNU. I'm currently exploring what the shaders do and how I can use them.
An example we have shows us that we compute a projection matrix, then set it in the vertex shader, then make a draw call. I wanted to try to do this matrix computation in a shader.
This means I have to put the code somewhere else than the main()
function in the vertex shader, since that one is invoked many times per draw call.
Vertex shader:
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;
}
Is it possible? Am I a fool for trying?
AFAIK, there's no way to do that. You should compute camMatrix
in your JS code and pass it to the shader via uniform:
uniform mat4 camMatrix;
attribute vec3 position;
void main() {
gl_Position = camMatrix * vec4(position, 1);
gl_PointSize = 5.0;
}
Now you need to compute matrix in JS:
// assuming that program is your compiled shader program and
// gl is your WebGL context.
const cos = Math.cos;
const sin = Math.sin;
gl.uniformMatrix4fv(gl.getUniformLocation(program, 'camMatrix'), [
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
]);