GLSL写vertex shader和fragment shader

0.一般来说vertex shader处理顶点坐标,然后向后传输,经过光栅化之后,传给fragment shader,其负责颜色、纹理、光照等等。

前者处理之后变成裁剪坐标系(三维),光栅化之后一般认为变成二维的设备坐标系

1.每个顶点有多个属性时的顶点着色器:

 1 #version 330 core
 2 layout (location = 0) in vec3 aPos;
 3 layout (location = 1) in vec3 aColor;
 4 layout (location = 2) in vec2 aTexCoord;
 5 
 6 out vec3 ourColor;
 7 out vec2 TexCoord;
 8 
 9 void main()
10 {
11     gl_Position = vec4(aPos, 1.0);
12     ourColor = aColor;
13     TexCoord = aTexCoord;
14 }
View Code

2.只处理纹理的片元着色器:

 1 #version 330 core
 2 out vec4 FragColor;
 3 
 4 in vec3 ourColor;
 5 in vec2 TexCoord;
 6 
 7 uniform sampler2D ourTexture;
 8 
 9 void main()
10 {
11     FragColor = texture(ourTexture, TexCoord);
12 }
View Code

3.将2中的纹理添加之后再加入顶点的颜色,片元着色器咋写呢:

 1 #version 330 core
 2 out vec4 FragColor;
 3 
 4 in vec3 ourColor;
 5 in vec2 TexCoord;
 6 
 7 uniform sampler2D ourTexture;
 8 
 9 void main()
10 {
11     FragColor = texture(ourTexture, TexCoord);
12     FragColor = texture(ourTexture, TexCoord) * vec4(ourColor, 1.0);
13 }
View Code

4.渲染多个纹理咋办呢?

 1 #version 330 core
 2 ...
 3 
 4 uniform sampler2D texture1;
 5 uniform sampler2D texture2;
 6 
 7 void main()
 8 {
 9     FragColor = mix(texture(texture1, TexCoord), texture(texture2, TexCoord), 0.2);
10 }
View Code

 5.带有坐标变换的顶点着色器

 1 #version 330 core
 2 layout (location = 0) in vec3 aPos;
 3 layout (location = 1) in vec2 aTexCoord;
 4 
 5 out vec2 TexCoord;
 6 
 7 uniform mat4 transform;
 8 
 9 void main()
10 {
11     gl_Position = transform * vec4(aPos, 1.0f);
12     TexCoord = vec2(aTexCoord.x, 1.0 - aTexCoord.y);
13 }
View Code

注意照片像素y轴和opengl中纹理坐标的y轴是反向的,所以用个1.0-y,或者加载纹理图片时候可以设置一下std_image库的api,也能解决问题

6.坐标系转换,加入相机后,标准的模型矩阵,观察矩阵,投影矩阵作用下的顶点着色器

 1 #version 330 core
 2 layout (location = 0) in vec3 aPos;
 3 layout (location = 1) in vec2 aTexCoord;
 4 
 5 out vec2 TexCoord;
 6 
 7 uniform mat4 model;
 8 uniform mat4 view;
 9 uniform mat4 projection;
10 
11 void main()
12 {
13     gl_Position = projection * view * model * vec4(aPos, 1.0f);
14     TexCoord = vec2(aTexCoord.x, aTexCoord.y);
15 
16 }
View Code

7.加入光照和材质的顶点着色器

 1 #version 330 core
 2 layout (location = 0) in vec3 aPos;
 3 layout (location = 1) in vec3 aNormal;
 4 
 5 out vec3 FragPos;
 6 out vec3 Normal;
 7 
 8 uniform mat4 model;
 9 uniform mat4 view;
10 uniform mat4 projection;
11 
12 void main()
13 {
14     FragPos = vec3(model * vec4(aPos, 1.0));
15     Normal = mat3(transpose(inverse(model))) * aNormal;  
16     
17     gl_Position = projection * view * vec4(FragPos, 1.0);
18 }
View Code

8.加入光照和材质的片元着色器

 1 #version 330 core
 2 out vec4 FragColor;
 3 
 4 struct Material {
 5     vec3 ambient;
 6     vec3 diffuse;
 7     vec3 specular;    
 8     float shininess;
 9 }; 
10 
11 struct Light {
12     vec3 position;
13 
14     vec3 ambient;
15     vec3 diffuse;
16     vec3 specular;
17 };
18 
19 in vec3 FragPos;  
20 in vec3 Normal;  
21   
22 uniform vec3 viewPos;
23 uniform Material material;
24 uniform Light light;
25 
26 void main()
27 {
28     // ambient
29     vec3 ambient = light.ambient * material.ambient;
30       
31     // diffuse 
32     vec3 norm = normalize(Normal);
33     vec3 lightDir = normalize(light.position - FragPos);
34     float diff = max(dot(norm, lightDir), 0.0);
35     vec3 diffuse = light.diffuse * (diff * material.diffuse);
36     
37     // specular
38     vec3 viewDir = normalize(viewPos - FragPos);
39     vec3 reflectDir = reflect(-lightDir, norm);  
40     float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
41     vec3 specular = light.specular * (spec * material.specular);  
42         
43     vec3 result = ambient + diffuse + specular;
44     FragColor = vec4(result, 1.0);
45 } 
View Code

 9.带光照纹理贴图的顶点着色器(光照射在纹理贴图上,贴图颜色代表物体颜色)

 1 #version 330 core
 2 layout (location = 0) in vec3 aPos;
 3 layout (location = 1) in vec3 aNormal;
 4 layout (location = 2) in vec2 aTexCoords;
 5 
 6 out vec3 FragPos;
 7 out vec3 Normal;
 8 out vec2 TexCoords;
 9 
10 uniform mat4 model;
11 uniform mat4 view;
12 uniform mat4 projection;
13 
14 void main()
15 {
16     FragPos = vec3(model * vec4(aPos, 1.0));
17     Normal = mat3(transpose(inverse(model))) * aNormal;  
18     TexCoords = aTexCoords;
19     
20     gl_Position = projection * view * vec4(FragPos, 1.0);
21 }
View Code

10.带光照纹理贴图的片元着色器(光照射在纹理贴图上,贴图颜色代表物体颜色)

 1 #version 330 core
 2 out vec4 FragColor;
 3 
 4 struct Material {
 5     sampler2D diffuse;
 6     sampler2D specular;    
 7     float shininess;
 8 }; 
 9 
10 struct Light {
11     vec3 position;
12 
13     vec3 ambient;
14     vec3 diffuse;
15     vec3 specular;
16 };
17 
18 in vec3 FragPos;  
19 in vec3 Normal;  
20 in vec2 TexCoords;
21   
22 uniform vec3 viewPos;
23 uniform Material material;
24 uniform Light light;
25 
26 void main()
27 {
28     // ambient
29     vec3 ambient = light.ambient * texture(material.diffuse, TexCoords).rgb;
30       
31     // diffuse 
32     vec3 norm = normalize(Normal);
33     vec3 lightDir = normalize(light.position - FragPos);
34     float diff = max(dot(norm, lightDir), 0.0);
35     vec3 diffuse = light.diffuse * diff * texture(material.diffuse, TexCoords).rgb;  
36     
37     // specular
38     vec3 viewDir = normalize(viewPos - FragPos);
39     vec3 reflectDir = reflect(-lightDir, norm);  
40     float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
41     vec3 specular = light.specular * spec * texture(material.specular, TexCoords).rgb;  
42         
43     vec3 result = ambient + diffuse + specular;
44     FragColor = vec4(result, 1.0);
45 } 
View Code

 11.关于9、10的补充说明:

光照模型其实也分为好多种:平行光(也叫定向光direction light)、点光源(point light)、聚光(spotlight),每种具体的光源渲染细节不同,但是大概结构相似,都满足1中的基本模型解释,只不过在细节和逼真度方面做了调整。具体参看https://learnopengl-cn.github.io/02%20Lighting/05%20Light%20casters/和12

12.带有三种不同光照模型的带纹理的顶点着色器跟片元着色器(终极版)

 1 #version 330 core
 2 layout (location = 0) in vec3 aPos;
 3 layout (location = 1) in vec3 aNormal;
 4 layout (location = 2) in vec2 aTexCoords;
 5 
 6 out vec3 FragPos;
 7 out vec3 Normal;
 8 out vec2 TexCoords;
 9 
10 uniform mat4 model;
11 uniform mat4 view;
12 uniform mat4 projection;
13 
14 void main()
15 {
16     FragPos = vec3(model * vec4(aPos, 1.0));
17     Normal = mat3(transpose(inverse(model))) * aNormal;  
18     TexCoords = aTexCoords;
19     
20     gl_Position = projection * view * vec4(FragPos, 1.0);
21 }
vertex shader
  1 #version 330 core
  2 out vec4 FragColor;
  3 
  4 struct Material {
  5     sampler2D diffuse;
  6     sampler2D specular;
  7     float shininess;
  8 }; 
  9 
 10 struct DirLight {
 11     vec3 direction;
 12     
 13     vec3 ambient;
 14     vec3 diffuse;
 15     vec3 specular;
 16 };
 17 
 18 struct PointLight {
 19     vec3 position;
 20     
 21     float constant;
 22     float linear;
 23     float quadratic;
 24     
 25     vec3 ambient;
 26     vec3 diffuse;
 27     vec3 specular;
 28 };
 29 
 30 struct SpotLight {
 31     vec3 position;
 32     vec3 direction;
 33     float cutOff;
 34     float outerCutOff;
 35   
 36     float constant;
 37     float linear;
 38     float quadratic;
 39   
 40     vec3 ambient;
 41     vec3 diffuse;
 42     vec3 specular;       
 43 };
 44 
 45 #define NR_POINT_LIGHTS 4
 46 
 47 in vec3 FragPos;
 48 in vec3 Normal;
 49 in vec2 TexCoords;
 50 
 51 uniform vec3 viewPos;
 52 uniform DirLight dirLight;
 53 uniform PointLight pointLights[NR_POINT_LIGHTS];
 54 uniform SpotLight spotLight;
 55 uniform Material material;
 56 
 57 // function prototypes
 58 vec3 CalcDirLight(DirLight light, vec3 normal, vec3 viewDir);
 59 vec3 CalcPointLight(PointLight light, vec3 normal, vec3 fragPos, vec3 viewDir);
 60 vec3 CalcSpotLight(SpotLight light, vec3 normal, vec3 fragPos, vec3 viewDir);
 61 
 62 void main()
 63 {    
 64     // properties
 65     vec3 norm = normalize(Normal);
 66     vec3 viewDir = normalize(viewPos - FragPos);
 67     
 68     // == =====================================================
 69     // Our lighting is set up in 3 phases: directional, point lights and an optional flashlight
 70     // For each phase, a calculate function is defined that calculates the corresponding color
 71     // per lamp. In the main() function we take all the calculated colors and sum them up for
 72     // this fragment's final color.
 73     // == =====================================================
 74     // phase 1: directional lighting
 75     vec3 result = CalcDirLight(dirLight, norm, viewDir);
 76     // phase 2: point lights
 77     for(int i = 0; i < NR_POINT_LIGHTS; i++)
 78         result += CalcPointLight(pointLights[i], norm, FragPos, viewDir);    
 79     // phase 3: spot light
 80     result += CalcSpotLight(spotLight, norm, FragPos, viewDir);    
 81     
 82     FragColor = vec4(result, 1.0);
 83 }
 84 
 85 // calculates the color when using a directional light.
 86 vec3 CalcDirLight(DirLight light, vec3 normal, vec3 viewDir)
 87 {
 88     vec3 lightDir = normalize(-light.direction);
 89     // diffuse shading
 90     float diff = max(dot(normal, lightDir), 0.0);
 91     // specular shading
 92     vec3 reflectDir = reflect(-lightDir, normal);
 93     float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
 94     // combine results
 95     vec3 ambient = light.ambient * vec3(texture(material.diffuse, TexCoords));
 96     vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse, TexCoords));
 97     vec3 specular = light.specular * spec * vec3(texture(material.specular, TexCoords));
 98     return (ambient + diffuse + specular);
 99 }
100 
101 // calculates the color when using a point light.
102 vec3 CalcPointLight(PointLight light, vec3 normal, vec3 fragPos, vec3 viewDir)
103 {
104     vec3 lightDir = normalize(light.position - fragPos);
105     // diffuse shading
106     float diff = max(dot(normal, lightDir), 0.0);
107     // specular shading
108     vec3 reflectDir = reflect(-lightDir, normal);
109     float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
110     // attenuation
111     float distance = length(light.position - fragPos);
112     float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * (distance * distance));    
113     // combine results
114     vec3 ambient = light.ambient * vec3(texture(material.diffuse, TexCoords));
115     vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse, TexCoords));
116     vec3 specular = light.specular * spec * vec3(texture(material.specular, TexCoords));
117     ambient *= attenuation;
118     diffuse *= attenuation;
119     specular *= attenuation;
120     return (ambient + diffuse + specular);
121 }
122 
123 // calculates the color when using a spot light.
124 vec3 CalcSpotLight(SpotLight light, vec3 normal, vec3 fragPos, vec3 viewDir)
125 {
126     vec3 lightDir = normalize(light.position - fragPos);
127     // diffuse shading
128     float diff = max(dot(normal, lightDir), 0.0);
129     // specular shading
130     vec3 reflectDir = reflect(-lightDir, normal);
131     float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
132     // attenuation
133     float distance = length(light.position - fragPos);
134     float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * (distance * distance));    
135     // spotlight intensity
136     float theta = dot(lightDir, normalize(-light.direction)); 
137     float epsilon = light.cutOff - light.outerCutOff;
138     float intensity = clamp((theta - light.outerCutOff) / epsilon, 0.0, 1.0);
139     // combine results
140     vec3 ambient = light.ambient * vec3(texture(material.diffuse, TexCoords));
141     vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse, TexCoords));
142     vec3 specular = light.specular * spec * vec3(texture(material.specular, TexCoords));
143     ambient *= attenuation * intensity;
144     diffuse *= attenuation * intensity;
145     specular *= attenuation * intensity;
146     return (ambient + diffuse + specular);
147 }
fragment shader

 

posted @ 2018-10-19 17:48  回溯法  阅读(4443)  评论(0编辑  收藏  举报