零基础学习OpenGL(一)--光照

       序:今天开始主要写写OpenGL,顺带写写其他的Unity,C#,Shader,优化等。这个系列参考自https://learnopengl-cn.github.io,作者不详,系翻译了经典的OpenGL教程,讲的通俗易懂,大家可以参考一下。所以我也不知道该定义我的文章是转载还是原创还是翻译,因为文章里也有加自己的理解,不懂的欢迎大家来探讨。

       定义:  OpenGL:是个规范,规范了一个函数的执行和输出。     

       渲染模式:  早期的OpenGL使用立即渲染模式(固定渲染管线),3.2版本后废弃之,鼓励核心模式下开发。

       状态机:OpenGL其实是个巨大的状态机,有一系列的上下文描述、更改OpenGL的状态,然后来渲染。

       着色器:在GPU上为每一个(渲染管线)阶段运行各自的小程序。用来在图形渲染管线中快速处理数据。

       OpenGL着色器用GLSL(OpenGL Shading Language)编写。渲染流程参考我的那篇:深入理解渲染流水线----学习Shader的基础(入门必备)

                                                                             颜色

        世界上的颜色很多,任何颜色都可以由红色,绿色,蓝色三个分量组成(RGB),即这三个值可以组合成任意一种颜色。我们看到物体的颜色其实是物体反射的颜色,即不能被物体吸收的颜色。蓝色的物体之所以看到是蓝色,是因为白色的光照在物体上,蓝色以外的都被吸收了,剩下不被吸收的蓝色反射到眼中。

        我们看到的颜色就是:光的颜色 * 物体的颜色(所以使用不同颜色的光源会使物体呈现不同颜色,而且这个颜色和光的颜色有点像)

                                                                              光照

        现实中的光照很复杂,影响因素比较多。但是有很多简化的模型,比如:

        Phong光照模型:环境光 (简化的全局照明,永远会给物体一些颜色);

                                     漫反射(如果光线垂直于物体表面,这束光对物体的影响就最大,引入了垂直于顶点表面的向量--法向量);

                                     镜面光照。

环境光的计算:

           float ambientStrength = 0.1;

            vec3 ambient = ambientStrength * lightColor;

            vec3 result = ambient * objectColor;

            FragColor = vec4(result, 1.0);

漫反射计算(opengl):

           1.将法线和方向向量标准化:

               vec3 norm = normalize(Normal);

               vec3 lightDir = normalize(lightPos - FragPos);

            2.上面两个向量点乘,结果再乘以光的颜色,就是漫反射和的分量。(法线和方向向量的夹角越大,cos值越小,点积的值也就越小):

                float diff = max(dot(norm, lightDir), 0.0); //使用max是因为当法线和方向向量的夹角大于90度时,点积的结果是负数。

                 vec3 diffuse = diff * lightColor;

      最后将环境光分量+漫反射分量,再乘物体的颜色,搞定:

                 vec3 result = (ambient + diffuse) * objectColor;

                 FragColor = vec4(result, 1.0);

       法线矩阵:片段着色器中的计算都是世界坐标下的,我们需要把法向量也转到世界空间坐标系中,使用法线矩阵乘以法向量即可。

镜面光照的计算:

        镜面光照除了依赖光的方向向量和物体的法向量,还依赖于观察方向。反射向量和视线方向的夹角越小,镜面光的影响就越大。

         float specularStrength = 0.5;

         vec3 viewDir = normalize(viewPos - FragPos);

         vec3 reflectDir = reflect(-lightDir, norm);

         float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32); //视线和反射方向点乘,然后取32次幂,32指反光度。反光度越高,散射越少,高光点越小。

          vec3 specular = specularStrength * spec * lightColor;

最终结果:

          vec3 result = (ambient + diffuse + specular) * objectColor;

          FragColor = vec4(result, 1.0);

猜你喜欢

转载自blog.csdn.net/jfy307596479/article/details/84285911