当前位置: 首页 > news >正文

苏州建网站提国外设计师

苏州建网站提,国外设计师,好的h5网站模板,wordpress手机页面悬浮导航文章目录 一、材质二、设置材质三、光的属性四、不同的光源颜色 一、材质 在现实世界里#xff0c;每个物体会对光产生不同的反应。 比如#xff0c;钢制物体看起来通常会比陶土花瓶更闪闪发光#xff0c;一个木头箱子也不会与一个钢制箱子反射同样程度的光。 有些物体反… 文章目录 一、材质二、设置材质三、光的属性四、不同的光源颜色 一、材质 在现实世界里每个物体会对光产生不同的反应。 比如钢制物体看起来通常会比陶土花瓶更闪闪发光一个木头箱子也不会与一个钢制箱子反射同样程度的光。 有些物体反射光的时候不会有太多的散射(Scatter)因而产生较小的高光点而有些物体则会散射很多产生一个有着更大半径的高光点。 如果我们想要在OpenGL中模拟多种类型的物体我们必须针对每种表面定义不同的材质(Material)属性。 在跟着LearnOpenGL学习10–基础光照这一篇中我们定义了一个物体和光的颜色并结合环境光与镜面强度分量来决定物体的视觉输出。 当描述一个表面时我们可以分别为三个光照分量定义一个材质颜色(Material Color) 环境光照(Ambient Lighting)漫反射光照(Diffuse Lighting)镜面光照(Specular Lighting) 通过为每个分量指定一个颜色我们就能够对表面的颜色输出有细粒度的控制了。 现在我们再添加一个反光度(Shininess)分量结合上述的三个颜色我们就有了全部所需的材质属性了 片段着色器 struct Material { //材质描述结构体vec3 ambient; //环境光照vec3 diffuse; //漫反射光照vec3 specular; //镜面反射光照float shininess; //反光度 };uniform Material material; //材质在片段着色器中我们创建一个结构体(Struct)来储存物体的材质属性。 我们也可以把它们储存为独立的uniform值但是作为一个结构体来储存会更有条理一些。 我们首先定义结构体的布局(Layout)然后简单地以刚创建的结构体作为类型声明一个uniform变量。 如你所见我们为冯氏光照模型的每个分量都定义一个颜色向量 ambient材质向量定义了在环境光照下这个表面反射的是什么颜色通常与表面的颜色相同。diffuse材质向量定义了在漫反射光照下表面的颜色。漫反射颜色和环境光照一样也被设置为我们期望的物体颜色。specular材质向量设置的是表面上镜面高光的颜色或者甚至可能反映一个特定表面的颜色。shininess材质向量影响镜面高光的散射/半径。 有这4个元素定义一个物体的材质我们能够模拟很多现实世界中的材质。如下表格展示了一系列材质属性它们模拟了现实世界中的真实材质。下图展示了几组现实世界的材质参数值对我们的立方体的影响 材质表格 名字环境光照漫反射光照镜面反射光照反射强度emerald(翡翠)0.0215 0.1745 0.02150.07568 0.61424 0.075680.633 0.727811 0.6330.6jade(玉)0.135 0.2225 0.15750.54 0.89 0.630.316228 0.316228 0.3162280.1obsidian(黑曜石)0.05375 0.05 0.066250.18275 0.17 0.225250.332741 0.328634 0.3464350.3pearl(珍珠)0.25 0.20725 0.207251 0.829 0.8290.296648 0.296648 0.2966480.088ruby(红宝石)0.1745 0.01175 0.011750.61424 0.04136 0.041360.727811 0.626959 0.6269590.6turquoise()绿松石0.1 0.18725 0.17450.396 0.74151 0.691020.297254 0.30829 0.3066780.1brass(黄铜)0.329412 0.223529 0.0274510.780392 0.568627 0.1137250.992157 0.941176 0.8078430.21794872bronze(青铜)0.2125 0.1275 0.0540.714 0.4284 0.181440.393548 0.271906 0.1667210.2chrome(铬)0.25 0.25 0.250.4 0.4 0.40.774597 0.774597 0.7745970.6copper(铜)0.19125 0.0735 0.02250.7038 0.27048 0.08280.256777 0.137622 0.0860140.1gold(黄金)0.24725 0.1995 0.07450.75164 0.60648,0.226480.628281 0.555802 0.3660650.4silver(银)0.19225 0.19225 0.192250.50754 0.50754 0.507540.508273 0.508273 0.5082730.4black plastic(黑色塑料)0.0 0.0 0.00.01 0.01 0.010.50 0.50 0.500.25cyan plastic(青色塑料)0.0 0.1 0.060.0 0.50980392 0.509803920.50196078 0.50196078 0.501960780.25green plastic(绿色塑料)0.0 0.0 0.00.1 0.35 0.10.45 0.55 0.450.25red plastic(红色塑料)0.0 0.0 0.00.5 0.0 0.00.7 0.6 0.60.25white plastic(白色塑料)0.0 0.0 0.00.55 0.55 0.550.70 0.70 0.700.25yellow plastic(黄色塑料)0.0 0.0 0.00.5 0.5 0.00.60 0.60 0.500.25black rubber(黑色橡胶)0.02 0.02 0.020.01 0.01 0.010.4 0.4 0.40.78125cyan rubber(青色橡胶)0.0 0.05 0.050.4 0.5 0.50.04 0.7 0.70.78125green rubber(绿色橡胶)0.0 0.05 0.00.4 0.5 0.40.04 0.7 0.040.78125red rubber(红色橡胶)0.05 0.0 0.00.5 0.4 0.40.7 0.04 0.040.78125white rubber(白色橡胶)0.05 0.05 0.050.5 0.5 0.50.7 0.7 0.70.78125yellow rubber(黄色橡胶)0.05 0.05 0.00.5 0.5 0.40.7 0.7 0.040.78125 可以看到通过正确地指定一个物体的材质属性我们对这个物体的感知也就不同了。效果非常明显但是要想获得更真实的效果我们需要以更复杂的形状替换这个立方体。 搞清楚一个物体正确的材质设定是个困难的工程这主要需要实验和丰富的经验。用了不合适的材质而毁了物体的视觉质量是件经常发生的事。 让我们试着在着色器中实现这样的一个材质系统。 二、设置材质 我们在片段着色器中创建了一个材质结构体的uniform所以下面我们希望修改一下光照的计算来遵从新的材质属性。由于所有材质变量都储存在一个结构体中我们可以从uniform变量material中访问它们 片段着色器 #version 330 corein vec3 FragPos; in vec3 Normal;out vec4 FragColor;uniform vec3 objectColor; uniform vec3 lightColor; uniform vec3 lightPos; uniform vec3 viewPos; //观察者坐标struct Material { //材质描述结构体vec3 ambient; //环境光照vec3 diffuse; //漫反射光照vec3 specular; //镜面反射光照float shininess; //反光度 };uniform Material material; //材质void main() {//环境光照vec3 ambient material.ambient * lightColor;//漫反射光照vec3 norm normalize(Normal);vec3 lightDir normalize(lightColor - FragPos);float diff max(dot(norm, lightDir), 0.0);vec3 diffuse (diff *material.diffuse) * lightColor;//镜面反射光照vec3 viewDir normalize(viewPos - FragPos);vec3 reflectDir reflect(-lightDir, norm);float spec pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);vec3 specular (material.specular * spec) * lightColor;vec3 result ambient diffuse specular;FragColor vec4(result, 1.0); }可以看到我们现在在需要的地方访问了材质结构体中的所有属性并且这次是根据材质的颜色来计算最终的输出颜色的。物体的每个材质属性都乘上了它们各自对应的光照分量。 我们现在可以通过设置适当的uniform来设置应用中物体的材质了。GLSL中一个结构体在设置uniform时并无任何区别结构体只是充当uniform变量们的一个命名空间。所以如果想填充这个结构体的话我们必须设置每个单独的uniform但要以结构体名为前缀 lightingShader.setVec3(material.ambient, 1.0f, 0.5f, 0.31f); lightingShader.setVec3(material.diffuse, 1.0f, 0.5f, 0.31f); lightingShader.setVec3(material.specular, 0.5f, 0.5f, 0.5f); lightingShader.setFloat(material.shininess, 32.0f);我们将环境光和漫反射分量设置成我们想要让物体所拥有的颜色而将镜面分量设置为一个中等亮度的颜色我们不希望镜面分量过于强烈。我们仍将反光度保持为32。 现在我们能够轻松地在应用中影响物体的材质了。运行程序你会得到像这样的结果 全部代码 main.cpp #include mainwindow.h #include QApplication//在包含GLFW的头文件之前包含了GLAD的头文件; //GLAD的头文件包含了正确的OpenGL头文件例如GL/gl.h; //所以需要在其它依赖于OpenGL的头文件之前包含GLAD; #include glad/glad.h #include GLFW/glfw3.h//GLM //#include glm/glm.hpp //#include glm/gtc/matrix_transform.hpp //#include glm/gtc/type_ptr.hpp#include iostream #include QDebug#include shader.h #include stb_image.h #include camera.hvoid framebuffer_size_callback(GLFWwindow* window, int width, int height); void mouse_callback(GLFWwindow* window, double xposIn, double yposIn); void scroll_callback(GLFWwindow* window, double xoffset, double yoffset); void processInput(GLFWwindow *window);// settings const unsigned int SCR_WIDTH 1920; const unsigned int SCR_HEIGHT 1080;//Camera Camera camera(glm::vec3(0.0f, 0.0f, 3.0f)); float lastX SCR_WIDTH / 2.0; float lastY SCR_HEIGHT / 2.0; bool firstMouse true;float deltaTime 0.0f; // 当前帧与上一帧的时间差 float lastFrame 0.0f; // 上一帧的时间//Light glm::vec3 lightPos(1.2f, 1.0f, 2.0f);using namespace std;int main(int argc, char *argv[]) {QApplication a(argc, argv);//MainWindow w;//w.show();//初始化GLFW//--------------------glfwInit();//配置GLFW//--------------------//告诉GLFW使用的OpenGL本是3.3glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);//告诉GLFW使用的是核心模式Core-profileglfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);//创建一个新的OpenGL环境和窗口//-----------------------------------GLFWwindow* window glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, LearnOpenGL, NULL, NULL);if (window NULL){std::cout Failed to create GLFW window std::endl;glfwTerminate(); //glfw销毁窗口和OpenGL环境并释放资源return -1;}//设置参数window中的窗口所关联的OpenGL环境为当前环境//-----------------------------------glfwMakeContextCurrent(window);//设置窗口尺寸改变大小时的回调函数窗口尺寸发送改变时会自动调用//-----------------------------------glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);//设置鼠标事件的回调函数鼠标移动时会自动调用//-----------------------------------glfwSetCursorPosCallback(window, mouse_callback);//设置鼠标滚轮事件的回调函数鼠标滚轮移动时会自动调用//-----------------------------------glfwSetScrollCallback(window, scroll_callback);//告诉GLFW捕捉鼠标glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);//glad加载系统相关的OpenGL函数指针//---------------------------------------if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)){std::cout Failed to initialize GLAD std::endl;return -1;}//开启深度测试glEnable(GL_DEPTH_TEST);Shader objectShader(C:/Qt_Pro/OpenGL_GLFW/shader/shader.vs,C:/Qt_Pro/OpenGL_GLFW/shader/shader.fs);Shader lightShader(C:/Qt_Pro/OpenGL_GLFW/shader/light_cube.vs,C:/Qt_Pro/OpenGL_GLFW/shader/light_cube.fs);//顶点数据//---------------------------------------------------------------------float vertices[] {//顶点数据 //顶点法向量-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f,0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f,-0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f,-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,-0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,-0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f,-0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f,-0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f,-0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f,-0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f,-0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f,0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f,0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f,0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f,0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f,0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f,0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f,-0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,-0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,-0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,-0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,-0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,-0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f};//物体//----------------------------------------------------------------unsigned int VBO, objectVAO;glGenVertexArrays(1, objectVAO); //创建顶点数组对象glGenBuffers(1, VBO); //创建顶点缓冲对象glBindBuffer(GL_ARRAY_BUFFER, VBO); //将VBO与GL_ARRAY_BUFFER缓冲区绑定glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); //将顶点数据复制到GL_ARRAY_BUFFER缓冲区之后可通过VBO进行操作glBindVertexArray(objectVAO); //绑定VAO//设定顶点属性指针//位置属性glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);glEnableVertexAttribArray(0);//法向量属性glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float)));glEnableVertexAttribArray(1);//光源(VBO用上面的)//----------------------------------------------------------------unsigned int lightVAO;glGenVertexArrays(1, lightVAO); //创建顶点数组对象glBindVertexArray(lightVAO); //绑定VAOglBindBuffer(GL_ARRAY_BUFFER, VBO); //将VBO与GL_ARRAY_BUFFER缓冲区绑定glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);glEnableVertexAttribArray(0);//渲染循环//我们可不希望只绘制一个图像之后我们的应用程序就立即退出并关闭窗口;//我们希望程序在我们主动关闭它之前不断绘制图像并能够接受用户输入;//因此我们需要在程序中添加一个while循环它能在我们让GLFW退出前一直保持运行;//------------------------------------------------------------------------------while (!glfwWindowShouldClose(window)) //如果用户准备关闭参数window所指定的窗口那么此接口将会返回GL_TRUE否则将会返回GL_FALSE{//更新时间差float currentFrame static_castfloat(glfwGetTime());deltaTime currentFrame - lastFrame;lastFrame currentFrame;//用户输入//------------------------------------------------------------------------------processInput(window); //检测是否有输入//渲染指令//------------------------------------------------------------------------------glClearColor(0.2f, 0.3f, 0.3f, 1.0f);glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);//被投光物体////激活着色器程序对象objectShader.use();objectShader.setVec3(objectColor, 1.0f, 0.5f, 0.31f);objectShader.setVec3(lightColor, 1.0f, 1.0f, 1.0f);objectShader.setVec3(lightPos, lightPos);objectShader.setVec3(viewPos, camera.Position);objectShader.setVec3(material.ambient, 1.0f, 0.5f, 0.31f);objectShader.setVec3(material.diffuse, 1.0f, 0.5f, 0.31f);objectShader.setVec3(material.specular, 0.5f, 0.5f, 0.5f);objectShader.setFloat(material.shininess, 32.0f);//创建变换矩阵glm::mat4 model glm::mat4(1.0f);objectShader.setMat4(model, model);glm::mat4 view camera.GetViewMatrix();objectShader.setMat4(view, view);glm::mat4 projection glm::perspective(glm::radians(camera.Zoom), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);objectShader.setMat4(projection, projection);//绘制三角形glBindVertexArray(objectVAO); //绑定VAOglDrawArrays(GL_TRIANGLES, 0, 36);////光源////激活着色器程序对象lightShader.use();lightShader.setMat4(view, view);lightShader.setMat4(projection, projection);model glm::mat4(1.0f);model glm::translate(model, lightPos);model glm::scale(model, glm::vec3(0.2f));lightShader.setMat4(model, model);//绘制三角形glBindVertexArray(lightVAO); //绑定VAOglDrawArrays(GL_TRIANGLES, 0, 36);////告诉GLFW检查所有等待处理的事件和消息包括操作系统和窗口系统中应当处理的消息。如果有消息正在等待它会先处理这些消息再返回否则该函数会立即返回//---------------------------------------------------------------------------------------------------------------------------------glfwPollEvents();//请求窗口系统将参数window关联的后缓存画面呈现给用户(双缓冲绘图)//------------------------------------------------------------------------------glfwSwapBuffers(window);}//释放资源glDeleteVertexArrays(1, objectVAO);glDeleteVertexArrays(1, lightVAO);glDeleteBuffers(1, VBO);//glDeleteProgram(objectShader);//glDeleteProgram(lightShader);//glfw销毁窗口和OpenGL环境并释放资源之后必须再次调用glfwInit()才能使用大多数GLFW函数//------------------------------------------------------------------glfwTerminate();return a.exec(); }//检测是否有输入 //--------------------------------------------------------------------------------------------------------- void processInput(GLFWwindow *window) {if(glfwGetKey(window, GLFW_KEY_ESCAPE) GLFW_PRESS) //ESC键退出glfwSetWindowShouldClose(window, true);float cameraSpeed static_castfloat(2.5 * deltaTime);if (glfwGetKey(window, GLFW_KEY_W) GLFW_PRESS)camera.ProcessKeyboard(FORWARD, deltaTime);if (glfwGetKey(window, GLFW_KEY_S) GLFW_PRESS)camera.ProcessKeyboard(BACKWARD, deltaTime);if (glfwGetKey(window, GLFW_KEY_A) GLFW_PRESS)camera.ProcessKeyboard(LEFT, deltaTime);if (glfwGetKey(window, GLFW_KEY_D) GLFW_PRESS)camera.ProcessKeyboard(RIGHT, deltaTime); }//给glfw窗口注册的尺寸改变回调函数 //--------------------------------------------------------------------------------------------- void framebuffer_size_callback(GLFWwindow* window, int width, int height) {//确保视口匹配新的窗口尺寸请注意宽度和高度将比视网膜显示器上指定的大得多glViewport(0, 0, width, height); } // 鼠标移动时的回调函数 // ------------------------------------------------------- void mouse_callback(GLFWwindow* window, double xposIn, double yposIn) {float xpos static_castfloat(xposIn);float ypos static_castfloat(yposIn);if (firstMouse){lastX xpos;lastY ypos;firstMouse false;}float xoffset lastX - xpos;float yoffset ypos - lastY; //翻转因为Y轴是从下到上越来越大lastX xpos;lastY ypos;camera.ProcessMouseMovement(xoffset, yoffset); }//鼠标滚轮的回调函数 // ---------------------------------------------------------------------- void scroll_callback(GLFWwindow* window, double xoffset, double yoffset) {camera.ProcessMouseScroll(static_castfloat(yoffset)); }三、光的属性 不过看起来真的不太对劲这个物体太亮了。 物体过亮的原因是环境光、漫反射和镜面光这三个颜色对任何一个光源都全力反射。 光源对环境光、漫反射和镜面光分量也分别具有不同的强度。前面的章节中我们通过使用一个强度值改变环境光和镜面光强度的方式解决了这个问题。我们想做类似的事情但是这次是要为每个光照分量分别指定一个强度向量。 如果我们假设lightColor是vec3(1.0)代码会看起来像这样 vec3 ambient vec3(1.0) * material.ambient; vec3 diffuse vec3(1.0) * (diff * material.diffuse); vec3 specular vec3(1.0) * (spec * material.specular);所以物体的每个材质属性对每一个光照分量都返回了最大的强度。 对单个光源来说这些vec3(1.0)值同样可以对每种光源分别改变而这通常就是我们想要的。 现在物体的环境光分量完全地影响了立方体的颜色可是环境光分量实际上不应该对最终的颜色有这么大的影响所以我们会将光源的环境光强度设置为一个小一点的值从而限制环境光颜色 vec3 ambient vec3(0.1) * material.ambient;我们可以用同样的方式影响光源的漫反射和镜面光强度。这和我们在上一节中所做的极为相似你可以认为我们已经创建了一些光照属性来影响各个光照分量。我们希望为光照属性创建类似材质结构体的东西 struct Light {vec3 position;vec3 ambient;vec3 diffuse;vec3 specular; };uniform Light light;一个光源对它的ambient、diffuse和specular光照分量有着不同的强度。环境光照通常被设置为一个比较低的强度因为我们不希望环境光颜色太过主导。光源的漫反射分量通常被设置为我们希望光所具有的那个颜色通常是一个比较明亮的白色。镜面光分量通常会保持为vec3(1.0)以最大强度发光。注意我们也将光源的位置向量加入了结构体。 和材质uniform一样我们需要更新片段着色器 片段着色器 #version 330 corein vec3 FragPos; in vec3 Normal;out vec4 FragColor;uniform vec3 objectColor; uniform vec3 lightColor; uniform vec3 lightPos; uniform vec3 viewPos; //观察者坐标struct Material { //材质描述结构体vec3 ambient; //环境光照vec3 diffuse; //漫反射光照vec3 specular; //镜面反射光照float shininess; //反光度 }; uniform Material material; //材质struct Light { //光照强度vec3 position;vec3 ambient;vec3 diffuse;vec3 specular; }; uniform Light light;void main() {//环境光照vec3 ambient material.ambient * light.ambient;//漫反射光照vec3 norm normalize(Normal);vec3 lightDir normalize(lightColor - FragPos);float diff max(dot(norm, lightDir), 0.0);vec3 diffuse (diff *material.diffuse) * light.diffuse;//镜面反射光照vec3 viewDir normalize(viewPos - FragPos);vec3 reflectDir reflect(-lightDir, norm);float spec pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);vec3 specular (material.specular * spec) * light.specular;vec3 result ambient diffuse specular;FragColor vec4(result, 1.0); } 我们接下来在应用中设置光照强度 objectShader.setVec3(light.ambient, 0.2f, 0.2f, 0.2f); objectShader.setVec3(light.diffuse, 0.5f, 0.5f, 0.5f); // 将光照调暗了一些以搭配场景 objectShader.setVec3(light.specular, 1.0f, 1.0f, 1.0f);现在我们已经调整了光照对物体材质的影响我们得到了一个与上一节很相似的视觉效果。但这次我们有了对光照和物体材质的完全掌控 四、不同的光源颜色 到目前为止我们都只对光源设置了从白到灰到黑范围内的颜色这样只会改变物体各个分量的强度而不是它的真正颜色。 由于现在能够非常容易地访问光照的属性了我们可以随着时间改变它们的颜色从而获得一些非常有意思的效果。 由于所有的东西都在片段着色器中配置好了修改光源的颜色非常简单并立刻创造一些很有趣的效果 //光照强度 glm::vec3 lightColor; lightColor.x static_castfloat(sin(glfwGetTime() * 2.0)); lightColor.y static_castfloat(sin(glfwGetTime() * 0.7)); lightColor.z static_castfloat(sin(glfwGetTime() * 1.3)); glm::vec3 diffuseColor lightColor * glm::vec3(0.5f); // decrease the influence glm::vec3 ambientColor diffuseColor * glm::vec3(0.2f); // low influence objectShader.setVec3(light.ambient, ambientColor); objectShader.setVec3(light.diffuse, diffuseColor); objectShader.setVec3(light.specular, 1.0f, 1.0f, 1.0f);你可以看到不同的光照颜色能够极大地影响物体的最终颜色输出。由于光照颜色能够直接影响物体能够反射的颜色这对视觉输出有着显著的影响。 全部代码 #include mainwindow.h #include QApplication//在包含GLFW的头文件之前包含了GLAD的头文件; //GLAD的头文件包含了正确的OpenGL头文件例如GL/gl.h; //所以需要在其它依赖于OpenGL的头文件之前包含GLAD; #include glad/glad.h #include GLFW/glfw3.h//GLM //#include glm/glm.hpp //#include glm/gtc/matrix_transform.hpp //#include glm/gtc/type_ptr.hpp#include iostream #include QDebug#include shader.h #include stb_image.h #include camera.hvoid framebuffer_size_callback(GLFWwindow* window, int width, int height); void mouse_callback(GLFWwindow* window, double xposIn, double yposIn); void scroll_callback(GLFWwindow* window, double xoffset, double yoffset); void processInput(GLFWwindow *window);// settings const unsigned int SCR_WIDTH 1920; const unsigned int SCR_HEIGHT 1080;//Camera Camera camera(glm::vec3(0.0f, 0.0f, 3.0f)); float lastX SCR_WIDTH / 2.0; float lastY SCR_HEIGHT / 2.0; bool firstMouse true;float deltaTime 0.0f; // 当前帧与上一帧的时间差 float lastFrame 0.0f; // 上一帧的时间//Light glm::vec3 lightPos(1.2f, 1.0f, 2.0f);using namespace std;int main(int argc, char *argv[]) {QApplication a(argc, argv);//MainWindow w;//w.show();//初始化GLFW//--------------------glfwInit();//配置GLFW//--------------------//告诉GLFW使用的OpenGL本是3.3glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);//告诉GLFW使用的是核心模式Core-profileglfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);//创建一个新的OpenGL环境和窗口//-----------------------------------GLFWwindow* window glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, LearnOpenGL, NULL, NULL);if (window NULL){std::cout Failed to create GLFW window std::endl;glfwTerminate(); //glfw销毁窗口和OpenGL环境并释放资源return -1;}//设置参数window中的窗口所关联的OpenGL环境为当前环境//-----------------------------------glfwMakeContextCurrent(window);//设置窗口尺寸改变大小时的回调函数窗口尺寸发送改变时会自动调用//-----------------------------------glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);//设置鼠标事件的回调函数鼠标移动时会自动调用//-----------------------------------glfwSetCursorPosCallback(window, mouse_callback);//设置鼠标滚轮事件的回调函数鼠标滚轮移动时会自动调用//-----------------------------------glfwSetScrollCallback(window, scroll_callback);//告诉GLFW捕捉鼠标glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);//glad加载系统相关的OpenGL函数指针//---------------------------------------if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)){std::cout Failed to initialize GLAD std::endl;return -1;}//开启深度测试glEnable(GL_DEPTH_TEST);Shader objectShader(C:/Qt_Pro/OpenGL_GLFW/shader/shader.vs,C:/Qt_Pro/OpenGL_GLFW/shader/shader.fs);Shader lightShader(C:/Qt_Pro/OpenGL_GLFW/shader/light_cube.vs,C:/Qt_Pro/OpenGL_GLFW/shader/light_cube.fs);//顶点数据//---------------------------------------------------------------------float vertices[] {//顶点数据 //顶点法向量-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f,0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f,-0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f,-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,-0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,-0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f,-0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f,-0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f,-0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f,-0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f,-0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f,0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f,0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f,0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f,0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f,0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f,0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f,-0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,-0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,-0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,-0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,-0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,-0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f};//物体//----------------------------------------------------------------unsigned int VBO, objectVAO;glGenVertexArrays(1, objectVAO); //创建顶点数组对象glGenBuffers(1, VBO); //创建顶点缓冲对象glBindBuffer(GL_ARRAY_BUFFER, VBO); //将VBO与GL_ARRAY_BUFFER缓冲区绑定glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); //将顶点数据复制到GL_ARRAY_BUFFER缓冲区之后可通过VBO进行操作glBindVertexArray(objectVAO); //绑定VAO//设定顶点属性指针//位置属性glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);glEnableVertexAttribArray(0);//法向量属性glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float)));glEnableVertexAttribArray(1);//光源(VBO用上面的)//----------------------------------------------------------------unsigned int lightVAO;glGenVertexArrays(1, lightVAO); //创建顶点数组对象glBindVertexArray(lightVAO); //绑定VAOglBindBuffer(GL_ARRAY_BUFFER, VBO); //将VBO与GL_ARRAY_BUFFER缓冲区绑定glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);glEnableVertexAttribArray(0);//渲染循环//我们可不希望只绘制一个图像之后我们的应用程序就立即退出并关闭窗口;//我们希望程序在我们主动关闭它之前不断绘制图像并能够接受用户输入;//因此我们需要在程序中添加一个while循环它能在我们让GLFW退出前一直保持运行;//------------------------------------------------------------------------------while (!glfwWindowShouldClose(window)) //如果用户准备关闭参数window所指定的窗口那么此接口将会返回GL_TRUE否则将会返回GL_FALSE{//更新时间差float currentFrame static_castfloat(glfwGetTime());deltaTime currentFrame - lastFrame;lastFrame currentFrame;//用户输入//------------------------------------------------------------------------------processInput(window); //检测是否有输入//渲染指令//------------------------------------------------------------------------------glClearColor(0.2f, 0.3f, 0.3f, 1.0f);glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);//被投光物体////激活着色器程序对象objectShader.use();objectShader.setVec3(objectColor, 1.0f, 0.5f, 0.31f);objectShader.setVec3(lightColor, 1.0f, 1.0f, 1.0f);objectShader.setVec3(lightPos, lightPos);objectShader.setVec3(viewPos, camera.Position);//光照强度glm::vec3 lightColor;lightColor.x static_castfloat(sin(glfwGetTime() * 2.0));lightColor.y static_castfloat(sin(glfwGetTime() * 0.7));lightColor.z static_castfloat(sin(glfwGetTime() * 1.3));glm::vec3 diffuseColor lightColor * glm::vec3(0.5f); // decrease the influenceglm::vec3 ambientColor diffuseColor * glm::vec3(0.2f); // low influenceobjectShader.setVec3(light.ambient, ambientColor);objectShader.setVec3(light.diffuse, diffuseColor);objectShader.setVec3(light.specular, 1.0f, 1.0f, 1.0f);//材质objectShader.setVec3(material.ambient, 1.0f, 0.5f, 0.31f);objectShader.setVec3(material.diffuse, 1.0f, 0.5f, 0.31f);objectShader.setVec3(material.specular, 0.5f, 0.5f, 0.5f);objectShader.setFloat(material.shininess, 32.0f);//创建变换矩阵glm::mat4 model glm::mat4(1.0f);objectShader.setMat4(model, model);glm::mat4 view camera.GetViewMatrix();objectShader.setMat4(view, view);glm::mat4 projection glm::perspective(glm::radians(camera.Zoom), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);objectShader.setMat4(projection, projection);//绘制三角形glBindVertexArray(objectVAO); //绑定VAOglDrawArrays(GL_TRIANGLES, 0, 36);////光源////激活着色器程序对象lightShader.use();lightShader.setMat4(view, view);lightShader.setMat4(projection, projection);model glm::mat4(1.0f);model glm::translate(model, lightPos);model glm::scale(model, glm::vec3(0.2f));lightShader.setMat4(model, model);//绘制三角形glBindVertexArray(lightVAO); //绑定VAOglDrawArrays(GL_TRIANGLES, 0, 36);////告诉GLFW检查所有等待处理的事件和消息包括操作系统和窗口系统中应当处理的消息。如果有消息正在等待它会先处理这些消息再返回否则该函数会立即返回//---------------------------------------------------------------------------------------------------------------------------------glfwPollEvents();//请求窗口系统将参数window关联的后缓存画面呈现给用户(双缓冲绘图)//------------------------------------------------------------------------------glfwSwapBuffers(window);}//释放资源glDeleteVertexArrays(1, objectVAO);glDeleteVertexArrays(1, lightVAO);glDeleteBuffers(1, VBO);//glDeleteProgram(objectShader);//glDeleteProgram(lightShader);//glfw销毁窗口和OpenGL环境并释放资源之后必须再次调用glfwInit()才能使用大多数GLFW函数//------------------------------------------------------------------glfwTerminate();return a.exec(); }//检测是否有输入 //--------------------------------------------------------------------------------------------------------- void processInput(GLFWwindow *window) {if(glfwGetKey(window, GLFW_KEY_ESCAPE) GLFW_PRESS) //ESC键退出glfwSetWindowShouldClose(window, true);float cameraSpeed static_castfloat(2.5 * deltaTime);if (glfwGetKey(window, GLFW_KEY_W) GLFW_PRESS)camera.ProcessKeyboard(FORWARD, deltaTime);if (glfwGetKey(window, GLFW_KEY_S) GLFW_PRESS)camera.ProcessKeyboard(BACKWARD, deltaTime);if (glfwGetKey(window, GLFW_KEY_A) GLFW_PRESS)camera.ProcessKeyboard(LEFT, deltaTime);if (glfwGetKey(window, GLFW_KEY_D) GLFW_PRESS)camera.ProcessKeyboard(RIGHT, deltaTime); }//给glfw窗口注册的尺寸改变回调函数 //--------------------------------------------------------------------------------------------- void framebuffer_size_callback(GLFWwindow* window, int width, int height) {//确保视口匹配新的窗口尺寸请注意宽度和高度将比视网膜显示器上指定的大得多glViewport(0, 0, width, height); } // 鼠标移动时的回调函数 // ------------------------------------------------------- void mouse_callback(GLFWwindow* window, double xposIn, double yposIn) {float xpos static_castfloat(xposIn);float ypos static_castfloat(yposIn);if (firstMouse){lastX xpos;lastY ypos;firstMouse false;}float xoffset lastX - xpos;float yoffset ypos - lastY; //翻转因为Y轴是从下到上越来越大lastX xpos;lastY ypos;camera.ProcessMouseMovement(xoffset, yoffset); }//鼠标滚轮的回调函数 // ---------------------------------------------------------------------- void scroll_callback(GLFWwindow* window, double xoffset, double yoffset) {camera.ProcessMouseScroll(static_castfloat(yoffset)); }
http://www.zqtcl.cn/news/195323/

相关文章:

  • 两学一做纪实评价系统网站如何做好百度推广
  • 网站设置手机才能播放企业网站开发需求
  • 网站建设微信运营销售做网站用啥语言
  • dw建设网站步骤活动汪活动策划网站
  • 民和县公司网站建设网站开发的特点
  • 模板企业快速建站上传网站中ftp地址写什么
  • 云南本地企业做网站太原网站制作公司哪家好
  • 西部数码域名网站模板wordpress抓取股票行情
  • 丰台深圳网站建设公司关于服装店网站建设的策划方案
  • win7 iis网站无法显示随州网站建设哪家实惠
  • 利用网站新媒体宣传法治建设建站哪个平台好
  • 网站seo课设wordpress 500 根目录
  • 电子商务网站建设的阶段化分析如何利用视频网站做数字营销推广
  • 电子商务网站建设ppt模板国外注册机网站
  • 西部数码做跳转网站百度seo排名培训优化
  • 农业网站素材wordpress all in one
  • 学习网站建设有前景没wordpress 和dokuwiki
  • 服装网站开发方案网站设计美工排版编辑
  • 旅游网站首页模板下载广州市建设工程检测中心网站
  • 餐饮加盟网站建设wordpress 首行缩进
  • kkday是哪里做的网站橙云 php网站建设
  • 站长之家0网站规划作品
  • 物流公司网站建设系统规划广告设计怎么学
  • 异地备案 网站中信建设有限责任公司经济性质
  • 网站没有备案怎么申请广告宿迁莱布拉网站建设
  • 太原适合网站设计地址网站建设 教学视频教程
  • 建商城网站需要多少钱网站开发维护报价单
  • 唐山网站建设冀icp备婚纱网站页面设计
  • 做购物网站支付需要怎么做手机网站建设教程
  • 国外网站空间租用哪个好建站快车打电话