Android OpenGL ES 2.0 (四) 灯光perfragment lighting

这一篇跟上一篇差不多,只是改成了per-fragment lighting.

把对光的计算从vertex shader移到了fragment shader.

可以看到效果,在光移动到立方体顶点时,立方体面的顶点周围扇形比较亮,接近真实世界的效果。

因改动较小,只修改了shader source部分,所以只给出这部分的代码吧。

 1     private String getVertexShader()
 2     {
 3         final String vertexShader =
 4                 "uniform mat4 u_MVPMatrix;      \n"        // A constant representing the combined model/view/projection matrix.
 5               + "uniform mat4 u_MVMatrix;       \n"        // A constant representing the combined model/view matrix.    
 6                 
 7               + "attribute vec4 a_Position;     \n"        // Per-vertex position information we will pass in.
 8               + "attribute vec4 a_Color;        \n"        // Per-vertex color information we will pass in.
 9               + "attribute vec3 a_Normal;       \n"        // Per-vertex normal information we will pass in.
10               
11               + "varying vec3 v_Position;       \n"        // This will be passed into the fragment shader.
12               + "varying vec4 v_Color;          \n"        // This will be passed into the fragment shader.
13               + "varying vec3 v_Normal;         \n"        // This will be passed into the fragment shader.
14               
15               + "void main()                    \n"     // The entry point for our vertex shader.
16               + "{                              \n"        
17               // Transform the vertex into eye space.
18               + "   v_Position = vec3(u_MVMatrix * a_Position);             \n"
19               // Pass through the color.
20               + "   v_Color = a_Color;                                      \n"
21               // Transform the normal's orientation into eye space.
22               + "   v_Normal = vec3(u_MVMatrix * vec4(a_Normal, 0.0));      \n"
23               // gl_Position is a special variable used to store the final position.
24               // Multiply the vertex by the matrix to get the final point in normalized screen coordinates.
25               + "   gl_Position = u_MVPMatrix * a_Position;                 \n"   
26               + "}                                                                     \n"; 
27             
28         return vertexShader;    
29     }
30     
31     private String getFragmentShader()
32     {
33         final String fragmentShader =
34                 "precision mediump float;       \n"        // Set the default precision to medium. We don't need as high of a 
35                                                         // precision in the fragment shader.
36               + "uniform vec3 u_LightPos;       \n"        // The position of the light in eye space.    
37               
38               + "varying vec3 v_Position;        \n"        // Interpolated position for this fragment.
39               + "varying vec4 v_Color;          \n"        // This is the color from the vertex shader interpolated across the 
40                                                               // triangle per fragment.
41               + "varying vec3 v_Normal;         \n"        // Interpolated normal for this fragment.
42               
43               + "void main()                    \n"        // The entry point for our fragment shader.
44               + "{                              \n"
45               // Will be used for attenuation.
46               + "   float distance = length(u_LightPos - v_Position);                  \n"
47               // Get a lighting direction vector from the light to the vertex.
48               + "   vec3 lightVector = normalize(u_LightPos - v_Position);             \n"     
49               // Calculate the dot product of the light vector and vertex normal. If the normal and light vector are
50               // pointing in the same direction then it will get max illumination.
51               + "   float diffuse = max(dot(v_Normal, lightVector), 0.1);              \n"                                                                       
52               // Add attenuation. 
53               + "   diffuse = diffuse * (1.0 / (1.0 + (0.25 * distance * distance)));  \n"
54               // Multiply the color by the diffuse illumination level to get final output color.
55               + "   gl_FragColor = v_Color * diffuse;                                  \n"              
56               + "}                              \n";
57             
58         return fragmentShader;        
59     }

看看效果图:

原文地址:https://www.cnblogs.com/jayceli/p/2475163.html