前言
WEBGL中的着色器变量包括以下种类:
-
属性变量(Attribute Variables):这些变量用于接收从应用程序中传递的顶点数据,比如顶点位置和颜色。
-
统一变量(Uniform Variables):这些变量是着色器中的全局变量,用于接收从应用程序中传递的值,比如投影矩阵,旋转矩阵等。
-
纹理坐标变量(Texture Coordinate Variables):这些变量用于指定在纹理图像中采样的位置。
-
法线向量变量(Normal Vector Variables):这些变量用于计算光照效果,用于标识几何体表面的法向量。
-
输出变量(Output Variables):这些变量用于将着色器的输出传递给渲染管线的下一阶段,比如像素着色器的颜色值。
一、varying变量
1.varying变量定义
在WebGL中,varying变量是在顶点着色器和片元着色器之间传递数据的一种特殊类型的变量。它们被用于在顶点着色器和片元着色器之间传递信息,以便在渲染过程中进行插值。在顶点着色器中,varying变量的值被计算并传递到片元着色器中,然后在片元着色器中进行插值,然后被用来确定要绘制的像素的颜色。
Varying变量通常被用于将光照和纹理坐标等信息从顶点着色器传递到片元着色器中。由于它们是在渲染过程中插值的,所以它们可以用来创建平滑的过渡,使得渲染出来的图像更加真实和细腻。
例如,如果你想在三角形中使用纹理映射,那么你需要将纹理坐标从顶点着色器传递到片元着色器中。你可以通过定义一个varying变量来传递这个纹理坐标,然后在片元着色器中使用它来获取纹理的颜色,从而创建一个真实的纹理映射效果。
2.varying执行流程
在WebGL中,varying变量用于在顶点着色器和片元着色器之间传递数据。它们的执行原理如下:
-
在顶点着色器中声明一个varying变量,并对其进行赋值。
-
这个varying变量的值会被传递到片元着色器中。
-
在片元着色器中,可以通过读取这个varying变量的值来进行后续的计算。
-
由于每个像素都会执行片元着色器,因此varying变量的值也会被相应地插值,以便在不同像素之间进行平滑的过渡。
-
最终的像素颜色将由片元着色器中的计算结果和其他因素(如光照)共同决定。
varying变量的执行原理是通过在顶点着色器和片元着色器之间传递数据,使得像素颜色可以根据这些数据进行计算。
3.案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="../lib/index.js"></script>
<style>
* {
margin: 0;
padding: 0;
}
canvas{
margin: 50px auto 0;
display: block;
background: yellow;
}
</style>
</head>
<body>
<canvas id="canvas" width="400" height="400">
此浏览器不支持canvas
</canvas>
</body>
</html>
<script>
const ctx = document.getElementById('canvas')
const gl = ctx.getContext('webgl')
// 创建着色器源码
const VERTEX_SHADER_SOURCE = `
attribute vec4 aPosition;
varying vec4 vColor;
void main() {
vColor = aPosition;
gl_Position = aPosition;
}
`; // 顶点着色器
const FRAGMENT_SHADER_SOURCE = `
precision lowp float;
varying vec4 vColor;
void main() {
gl_FragColor = vColor;
}
`; // 片元着色器
const program = initShader(gl, VERTEX_SHADER_SOURCE, FRAGMENT_SHADER_SOURCE)
const aPosition = gl.getAttribLocation(program, 'aPosition');
const points = new Float32Array([
-0.5, -0.5,
0.5, -0.5,
0.0, 0.5,
])
const buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.bufferData(gl.ARRAY_BUFFER, points, gl.STATIC_DRAW);
gl.vertexAttribPointer(aPosition, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(aPosition)
gl.drawArrays(gl.TRIANGLES, 0, 3);
</script>