着色器语言
VAO和 VBO和EBO的关系
相当于 vao中包含 attribute buffer object和 element buffer object属性, 而vbo,ebo, 是给这两个属性赋值的方式.
数据类型
变量修饰符
attribute 变量(属性变量)只能用于顶点着色器中,不能用于片元着色器。 一般用该变量来表示一些顶点数据,如:顶点坐标、纹理坐标、颜色等。
uniforms (只能用, 不修改)是一种从CPU中的应用向GPU中的着色器发送数据的方式,但uniform和顶点属性有些不同。首先,uniform是全局的(Global)。全局意味着uniform变量必须在每个着色器程序对象中都是独一无二的,而且它可以被着色器程序的任意着色器在任意阶段访问。第二,无论你把uniform值设置成什么,uniform会一直保存它们的数据,直到它们被重置或更新。三, 他一般用来存储不怎么修改的数据被uniform 修饰的变量一般只能用, 不修改;
samplers (修饰纹理单元)一种特殊的 uniform,用于呈现纹理。sampler 可用于顶点着色器和片元着色器。
varying 变量(易变变量)是从顶点着色器传递到片元着色器的数据变量。顶点着色器可以使用易变变量来传递需要插值的颜色、法向量、纹理坐标等任意值。 在顶点与片元shader程序间传递数据是很容易的,一般在顶点shader中修改varying变量值,然后片元shader中使用该值,当然,该变量在顶点及片元这两段shader程序中声明必须是一致的 。例
precision (片元着色器中浮点必须指明精度)可以用来确定默认精度修饰符。类型可以是int或float或采样器类型,precision-qualifier可以是lowp, mediump, 或者highp。任何其他类型和修饰符都会引起错误。如果type是float类型,那么该精度(precision-qualifier)将适用于所有无精度修饰符的浮点数声明(标量,向量,矩阵)。如果type是int类型,那么该精度(precision-qualifier)将适用于所有无精度修饰符的整型数声明(标量,向量)。包括全局变量声明,函数返回值声明,函数参数声明,和本地变量声明等。没有声明精度修饰符的变量将使用和它最近的precision语句中的精度。
内建变量
gl_Position 顶点着色器内建变量,表示变换后点的空间位置。 顶点着色器从应用程序中获得原始的顶点位置数据,这些原始的顶点数据在顶点着色器中经过平移、旋转、缩放等数学变换后,生成新的顶点位置。新的顶点位置通过在顶点着色器中写入gl_Position传递到渲染管线的后继阶段继续处理。(必须赋值)
gl_PointSize 顶点着色器内置变量,设置栅格化点的直径,也就是点的大小,通常用于点精灵,粒子等绘制。
gl_FragColor 片元着色器内置变量,用来保存片元着色器计算完成的片元颜色值,此颜色值将送入渲染管线的后继阶段进行处理。(必须赋值)
使用
// - 工程中如何设置和获取这些通道
// - 定义结构体
typedef struct {
GLuint position;
GLuint textCoordinate;
GLuint projectionMat;
GLuint modelMat;
GLuint viewMat;
}ShaderV;
// - 值
_lint.position = glGetAttribLocation(_programHandle, "position");
_lint.textCoordinate = glGetAttribLocation(_programHandle, "textCoordinate");
_lint.projectionMat = glGetUniformLocation(_programHandle, "projectionMat");
_lint.modelMat = glGetUniformLocation(_programHandle, "modelMat");
_lint.viewMat = glGetUniformLocation(_programHandle, "viewMat");
// - 赋值
glVertexAttribPointer(_lint.position, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GL_FLOAT), NULL);
glVertexAttribPointer(_lint.textCoordinate, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GL_FLOAT), NULL);
glUniformMatrix4fv(_lint.modelMat, 1, GL_FALSE, (GLfloat*)&modelMat.m[0][0]);
// - 顶点着色器
attribute vec3 position;
attribute vec2 textCoordinate;
uniform mat4 projectionMat;
uniform mat4 modelMat;
uniform mat4 viewMat;
varying lowp vec2 varyTextCoord;
void main(){
varyTextCoord = textCoordinate;
vec4 vPos;
vPos = projectionMat * viewMat * modelMat * vec4(position, 1.0);
gl_Position = vPos;
}
// - 片元着色器
varying lowp vec2 varyTextCoord;
uniform sampler2D colorMap;
void main(void){
// - 读取纹素(某个纹理的像素的颜色值)
gl_FragColor = texture2D(colorMap, varyTextCoord);
}
// - 1. attribute 只能在顶点着色器中使用
// - 2. 顶点着色器和片元着色器总都有 varying lowp vec2 varyTextCoord; 这个是用来传值的
// - 3. uniform 用来修饰一些不改变的变量(只读不写的变量);
在顶点着色器中, 因为是有默认的精度修饰符的, 所以可以不写精度修饰符, 但是在片元着色器中, 没有默认的精度修饰符, 所以需要开发者自己去写精度修饰符, 但是为了简单, 是可以定义一个全局的精度修饰符的 , 如下所示 :
// - vsh
attribute vec4 Position;
attribute vec2 TextureCoords;
varying vec2 TextureCoordsVarying;
void main (void) {
gl_Position = Position;
TextureCoordsVarying = TextureCoords;
}
// - fsh
precision highp float; // - 定义一个全局的精度修饰符
uniform sampler2D Texture;
varying vec2 TextureCoordsVarying;
void main (void) {
vec4 mask = texture2D(Texture, TextureCoordsVarying);
gl_FragColor = vec4(mask.rgb, 1.0);
}
向量点乘和叉乘的数学和几何意义
-
点乘 : 结果是标量
两个向量的点乘等于它们的数乘结果乘以两个向量之间夹角的余弦值
v¯⋅k¯=||v¯||⋅||k¯||⋅cosθ
你也可以通过点乘的结果计算两个非单位向量的夹角,点乘的结果除以两个向量的长度之积,得到的结果就是夹角的余弦值,即cosθ。
cosθ=v¯⋅k¯||v¯||⋅||k¯||
-
叉乘 : 结果是向量
叉乘的结果的几何意义是 会产生一个垂直于相乘的两个向量所组成的平面的向量;(让A B 两个向量叉乘结果是C, C是一个垂直于 A B所组成平面的的向量)
矩阵相乘
矩阵乘向量
把向量当做 n *1 阶矩阵
弧度转角度
项目地址(带注释)