uniform 变量

uniform 的中文意思是“一致的,统一的”。Vertex 和 Fragment 着色器都能使用。
将其赋值给 gl_FragColor: gl_FragColor = u_FragColor; 表明每一个点都是同一种颜色。

向 uniform 变量传数据的方式与向 attribute 变量的类似,首先获取变量的存储地址,然后在 JavaScript 中按地址传递过去。 获取地址的方法为 gl.getUniformLocation( program, name ),也就是把 getAttribLocation 中间的 ‘Attrib’ 换成 ‘Uniform’。 但能否获取成功是看返回值是否为 null。最后传值的方法是 gl.uniform[1234]f( location, [v0, v1, v2, v3];

uniform 变量的类型是除了数组和结构体之外的任意类型。如果顶点着色器和片元着色器中声明了同名的 uniform 变量, 那么它就会被两种着色器共享。

1. 统一顶点颜色 <script id="fragmentShader" type="x-shader/x-fragment"> precision mediump float; uniform vec4 u_FragColor; void main(){ gl_FragColor = u_FragColor; } </script> // 获取地址 var u_FragColor = gl.getUniformLocation(gl.program, 'u_FragColor'); // 检查返回值:指定的 uniform 变量不存在,或者其命名具有 gl_ 或 webgl_ 前缀 if(!u_FragColor){ console.log('Failed to get the location of u_FragColor'); return; } // 传值 gl.uniform4f( u_FragColor, r, g, b, a ); 2. 统一偏移量

因为 uniform 传的是统一值,当做平移 translation 时,它能为每个顶点都加一个相同的偏移量。

var VSHADER_SOURCE = 'attribute vec4 a_Position;' + 'uniform vec4 u_translate;' + 'void main(){' + 'gl_Position = a_Position + u_translate;' + // 顶点平移 '}'; 2. 统一缩放 <script id="vertexShader" type="x-shader/x-vertex"> attribute vec4 a_Position; uniform vec4 u_translate; void main(){ gl_Position = a_Position + u_translate; } </script> 3. 统一旋转角度 <script id="vertexShader" type="x-shader/x-vertex"> attribute vec4 a_Position; uniform float u_sinB, u_cosB; void main(){ gl_Position.x = a_Position.x * u_cosB - a_Position.y * u_sinB; gl_Position.y = a_Position.x * u_sinB + a_Position.y * u_cosB; gl_Position.z = a_Position.z; gl_Position.w = 1.0; } </script> 4. 统一投影矩阵 <script id="vertexShader" type="x-shader/x-vertex"> attribute vec4 a_Position; attribute vec4 a_Color; uniform mat4 u_mvpMatrix; varying vec4 v_Color; void main(){ gl_Position = u_mvpMatrix * a_Position; v_Color = a_Color; } </script> 5. 将纹理单元传给片元着色器 <script id="fragmentShader" type="x-shader/x-fragment"> precision mediump float; uniform sampler2D u_Sampler; // 采样器 varying vec2 v_TexCoord; void main(){ gl_FragColor = texture2D(u_Sampler, v_TexCoord); } </script> 6. 计算光的漫反射 <script id="fragmentShader" type="x-shader/x-fragment"> precision mediump float; uniform mat4 u_ModelMatrix; uniform mat4 u_NormalMatrix; uniform vec3 u_AmbientLight_color; uniform vec3 u_DirectionlLight_color; uniform vec3 u_LightDirection; uniform vec3 u_PointLight_color; uniform vec3 u_PointLight_position; varying vec4 v_Normal; varying vec4 v_Position; varying vec4 v_Color; void main(){ // 环境光 vec3 ambient = u_AmbientLight_color * v_Color.rgb; // 方向光 vec3 normal = normalize( vec3( u_NormalMatrix * v_Normal ) ); float cosAngle_D = max( dot( u_LightDirection, normal ), 0.0 ); vec3 directionalLight = u_DirectionlLight_color * v_Color.rgb * cosAngle_D; // 点光源 vec3 vertexPosition = vec3( u_ModelMatrix * v_Position ); vec3 pointLightDirection = normalize( u_PointLight_position - vertexPosition ); float cosAngle_P = max( dot( pointLightDirection, normal ), 0.0 ); vec3 pointLight = u_PointLight_color * v_Color.rgb * cosAngle_P; gl_FragColor = vec4( ambient + directionalLight + pointLight, v_Color.a ); } </script>