OpenGL超级宝典(第7版)笔记20 统一变量 一致区块 uniform相关内容 清单5.9-5.28
文章目录
前言
上一篇我们用顶点数组和缓冲区向着色器传输顶点数据,避免了在着色器中内置大量的数据,方便了我们添加顶点。虽然现在的顶点还是通过数组的方式,我们还是要手动输入,但是相比内置在着色器中,我们在自己的内存中可以更灵活的对它进行修改。当然我们并不会一直手动输入顶点,等我们把第五章的内容全部介绍完之后,我们再说一说怎么通过读取obj文件来自动获取顶点数据,到时候直接读取建模软件生成的obj文件就行了(obj文件中含有成千上万的顶点,可以表示很复杂的几何图形)。
说回来,这一篇我们将介绍统一变量(或叫做uniform变量),uniform变量也可以向着色器传递数据,而且数据修改起来更方便,数据的形式也更多。通过uniform变量我们可以占用一个顶点着色器上的一个location来传入一个矩阵(现在我们不是占用了4个位置才传入变换矩阵吗)。而且uniform变量可以传递到不同的着色器中去(之前我们用缓冲的方法只能输入到VS中,再通过着色器之间传递才能让其他着色器获取数据,而uniform可以直接传到对应的着色器中去)。
1 统一变量 (uniform变量)
还记的我们之前在传矩阵的时候调用了4个location来传入,十分的麻烦:
//顶点着色器中的4个向量组成变换矩阵
layout (location=0) in vec4 cam0;
layout (location=1) in vec4 cam1;
layout (location=2) in vec4 cam2;
layout (location=3) in vec4 cam3;
//每次渲染render()的时候都要传入四个位置的向量,才能在着色器中合成矩阵
glVertexAttrib4fv(0, &matrix_ok.m_mat4f[0]);
glVertexAttrib4fv(1, &matrix_ok.m_mat4f[4]);
glVertexAttrib4fv(2, &matrix_ok.m_mat4f[8]);
glVertexAttrib4fv(3, &matrix_ok.m_mat4f[12]);
如果有一种方法能够一次就把这些数据传递给着色器就好了。我们的方法就是uniform变量。
首先说说uniform变量的特点:
1,uniform变量之所以叫统一(即uniform),是因为其在基元处理的过程中其值并不会发生改变,比如说我们传入变换矩阵,在顶点绘制的过程中,物体上的每个顶点进行变换的时候都是用同一个矩阵进行变换,矩阵中的数据是统一的,这样避免了渲染的时候不同顶点使用不同的变换矩阵进行变换(那样会导致画面扭曲)
2,任何的着色器变量都可以被指定为uniform变量,uniform变量可以存着于任何着色器阶段。
3,uniform变量可以直接传入到任意的着色器中去,不像顶点属性:
#version 450 core //清单3.1
layout (location = 0) in vec4 offset;
void main(void){
const vec4 vertices[3] = vec4[3](
vec4(0.25,-0.25,0.5,1.0),
vec4(-0.25,-0.25,0.5,1.0),
vec4(0.25,0.25,0.5,1.0));
gl_Position = vertices[gl_VertexID]+offset;
}
只能传到顶点着色器中去,想要给片段着色器传数据还要用in out来实现。uniform可以直接把数据传到片段着色器中,不经过顶点着色器。例如:
#version 330 core
in vec3 ourColor;
in vec2 TexCoord;//平面贴图纹理坐标
in vec3 Normal0;//片元在世界中的法线方向,用于光照计算
in vec3 apos;//片元在世界中的位置,用于光照计算
in vec4 shadowpos;//点在阴影变换后的坐标
out vec4 color;
out vec4 FragColor;//最终的片元颜色
uniform sampler2D ourTexture;//物体平面贴图
uniform sampler2D shadowTexture;//二次渲染阴影贴图
struct DirectionalLight{
vec3 Color;//光线颜色
float AmbientIntensity;//全局光照线性强度
vec3 Lightpos;//点光源位置
...
};
uniform DirectionalLight dlight;
uniform float constant;//光源衰减系数 常量
uniform float linear;//光源衰减系数 一次系数
uniform float exp;//光源衰减系数 二次系数
void main()