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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM