着色器文件

1.最基本的顶点着色器

(1)attribute变量:是只能在顶点着色器中使用的变量,表示一些顶点的数据,cpp传值获取。

(2)uniform变量:是外部程序传递给顶点/片段的变量,函数glUniform**()函数赋值。相当于常量,不可改。如果uniform变量在顶点和片段两者之间声明方式完全一样,则它可以在vertex和fragment共享使用。一般用来表示变换矩阵,材质,光照参数和颜色等信息。

(3)“vertexPosition_modelspace”变量名:可以任取,其中保存的是顶点位置,顶点着色器每次运行时都会用到。

(4)gl_Position:内置变量之一,必须赋值。

(5)“layout(location = 0)“:指向存储vertexPosition_modelspace属性的缓冲。每个顶点有多种属性,因此我们必须将glvertexAttribPointer函数的第一个参数值赋给layout,以此告知OpenGL每个缓冲对应的是哪种属性数据。第二个参数“0”并不重要,也可以换成12(但是不能超过glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &v)),关键是C++和GLSL两边数值必须保持一致。

或使用GLuint vertexPosition_modelspaceID = glGetAttribLocation(programID, “vertexPosition_modelspace”);将glvertexAttribPointer函数的第一个参数值设置为vertexPosition_modelspaceID

1
2
3
4
5
6
7
attribute vec3 vertexPosition_modelspace;
//layout(location=*0) in vec3 vertexPosition_modelspace;
uniform mat4 MVP;
void main(){
//MVP变换顶点
gl_Position = MVP * vec4(vertexPosition_modelspace,1);
}

2.最基本的片段着色器

直接在着色器用vec4向量给内置变量gl_FragColor赋值

1
2
3
4
5
6
7
8
#version 120
//out vec3 color;
void main()
{
//color = vec3(1,0,0);
gl_FragColor = vec4(1,0,0, 1);
}

3.加入颜色数组

varying变量是顶点和片段之间做数据传递用的。一般顶点修改varying变量的值,然后片段使用该varying变量的值。因此varying变量在二者之间的声明必须是一致的。cpp中不能使用该变量。

顶点着色器声明添加如下

1
2
3
4
//in vec3 vertexColor;
//out vec3 fragmentColor;
varying vec3 fragmentColor;
attribute vec3 vertexColor;

顶点着色器主函数添加如下

1
fragmentColor = vertexColor;

片段着色器声明添加如下

1
2
3
//in vec3 fragmentColor;
//out vec3 color;
varying vec3 fragmentColor;

片段着色器主函数添加如下

1
2
//color = fragmentColor;
gl_FragColor = vec4(fragmentColor, 1);

如果要使用透明效果,片段着色器单独设置内置变量gl_FragColor的a值(或传值)

1
gl_FragColor.a = 0.3;

4.UV坐标纹理渲染

顶点着色器声明添加如下

1
2
3
//UV坐标
varying vec2 UV;
attribute vec2 vertexUV;

顶点着色器主函数添加如下

1
UV = vertexUV;

片段着色器声明添加如下

1
2
3
//采样器
uniform sampler2D myTextureSampler;
varying vec2 UV;

片段着色器主函数添加如下

1
2
//采样器根据UV坐标插值采样渲染图像
gl_FragColor = texture2D( myTextureSampler, UV );

6.2D文本

为了让代码在640*480和1080p分辨率下都能正常工作,x和y的范围分别设为[0-800]和[0-600]。顶点着色器将根据实际屏幕大小做对它做调整到[-1,1]之间。

1
2
vec2 vertexPosition_homoneneousspace = vertexPosition_screenspace - vec2(400,300); // [0..800][0..600] -> [-400..400][-300..300]
vertexPosition_homoneneousspace /= vec2(400,300);

7.法线贴图

顶点着色器

对比光照的顶点着色器,先不计算观察空间下的法线数组,替换成如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
// model to camera = ModelView
vec3 vertexTangent_cameraspace = MV3x3 * vertexTangent_modelspace;
vec3 vertexBitangent_cameraspace = MV3x3 * vertexBitangent_modelspace;
vec3 vertexNormal_cameraspace = MV3x3 * vertexNormal_modelspace;

mat3 TBN = transpose(mat3(
vertexTangent_cameraspace,
vertexBitangent_cameraspace,
vertexNormal_cameraspace
)); // You can use dot products instead of building this matrix and transposing it. See References for details.

LightDirection_tangentspace = TBN * LightDirection_cameraspace;
EyeDirection_tangentspace = TBN * EyeDirection_cameraspace;

片段着色器

不直接使用观察空间下计算的法线数组,改成如下代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#version 130
uniform sampler2D DiffuseTextureSampler;
uniform sampler2D NormalTextureSampler;
uniform sampler2D SpecularTextureSampler;
uniform mat3 MV3x3;
void main(){

vec3 MaterialDiffuseColor = texture2D( DiffuseTextureSampler, UV ).rgb;
vec3 MaterialAmbientColor = vec3(0.1,0.1,0.1) * MaterialDiffuseColor;
vec3 MaterialSpecularColor = texture2D( SpecularTextureSampler, UV ).rgb * 0.3;

// Local normal, in tangent space. V tex coordinate is inverted because normal map is in TGA (not in DDS) for better quality
vec3 TextureNormal_tangentspace = normalize(texture2D( NormalTextureSampler, vec2(UV.x,-UV.y) ).rgb*2.0 - 1.0);

}
Donate
  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.

扫一扫,分享到微信

微信分享二维码

请我喝杯咖啡吧~

支付宝
微信