Android OpenGL ES 2.0 (四) 灯光per-fragment 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     }

看看效果图:

Android OpenGL ES 2.0 (四) 灯光per-fragment lighting

Android OpenGL ES 2.0 (四) 灯光per-fragment lighting

你可能感兴趣的:(openGL ES)